From 4eb09b45782d88ebac81f4e22e33ff204b57e574 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:43:34 +0200 Subject: [PATCH 01/15] Fix field description in docs for environments --- docs/data-sources/environment.md | 8 ++++---- docs/data-sources/environments.md | 10 +++++----- pkg/framework/objects/environment/schema.go | 18 +++++++++--------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/data-sources/environment.md b/docs/data-sources/environment.md index ef87c1d7..0223047d 100644 --- a/docs/data-sources/environment.md +++ b/docs/data-sources/environment.md @@ -23,10 +23,10 @@ Retrieve data for a single environment ### Read-Only - `credentials_id` (Number) The project ID to which the environment belong -- `custom_branch` (String) The type of deployment environment (currently 'production', 'staging' or empty) -- `dbt_version` (String) Version number of dbt to use in this environment, usually in the format 1.2.0-latest rather than core versions -- `deployment_type` (String) The name of the environment +- `custom_branch` (String) The custom branch name to use +- `dbt_version` (String) Version number of dbt to use in this environment. +- `deployment_type` (String) The type of deployment environment (currently 'production', 'staging' or empty) - `extended_attributes_id` (Number) The ID of the extended attributes applied - `name` (String) The name of the environment -- `type` (String) The name of the environment +- `type` (String) The type of environment (must be either development or deployment) - `use_custom_branch` (Boolean) Whether to use a custom git branch in this environment diff --git a/docs/data-sources/environments.md b/docs/data-sources/environments.md index 101bf885..d12a6c25 100644 --- a/docs/data-sources/environments.md +++ b/docs/data-sources/environments.md @@ -28,13 +28,13 @@ Retrieve data for multiple environments Read-Only: -- `credentials_id` (Number) The project ID to which the environment belong -- `custom_branch` (String) The type of deployment environment (currently 'production', 'staging' or empty) -- `dbt_version` (String) Version number of dbt to use in this environment, usually in the format 1.2.0-latest rather than core versions -- `deployment_type` (String) The name of the environment +- `credentials_id` (Number) Credential ID to create the environment with. A credential is not required for development environments but is required for deployment environments +- `custom_branch` (String) The custom branch name to use +- `dbt_version` (String) Version number of dbt to use in this environment. +- `deployment_type` (String) The type of deployment environment (currently 'production', 'staging' or empty) - `environment_id` (Number) The ID of the environment - `extended_attributes_id` (Number) The ID of the extended attributes applied - `name` (String) The name of the environment - `project_id` (Number) The project ID to which the environment belong -- `type` (String) The name of the environment +- `type` (String) The type of environment (must be either development or deployment) - `use_custom_branch` (Boolean) Whether to use a custom git branch in this environment diff --git a/pkg/framework/objects/environment/schema.go b/pkg/framework/objects/environment/schema.go index d7e2c162..fa7bd19a 100644 --- a/pkg/framework/objects/environment/schema.go +++ b/pkg/framework/objects/environment/schema.go @@ -33,11 +33,11 @@ func (r *environmentDataSource) Schema( }, "dbt_version": schema.StringAttribute{ Computed: true, - Description: "Version number of dbt to use in this environment, usually in the format 1.2.0-latest rather than core versions", + Description: "Version number of dbt to use in this environment.", }, "type": schema.StringAttribute{ Computed: true, - Description: "The name of the environment", + Description: "The type of environment (must be either development or deployment)", }, "use_custom_branch": schema.BoolAttribute{ Computed: true, @@ -45,11 +45,11 @@ func (r *environmentDataSource) Schema( }, "custom_branch": schema.StringAttribute{ Computed: true, - Description: "The type of deployment environment (currently 'production', 'staging' or empty)", + Description: "The custom branch name to use", }, "deployment_type": schema.StringAttribute{ Computed: true, - Description: "The name of the environment", + Description: "The type of deployment environment (currently 'production', 'staging' or empty)", }, "extended_attributes_id": schema.Int64Attribute{ Computed: true, @@ -86,7 +86,7 @@ func (r *environmentsDataSources) Schema( }, "credentials_id": schema.Int64Attribute{ Computed: true, - Description: "The project ID to which the environment belong", + Description: "Credential ID to create the environment with. A credential is not required for development environments but is required for deployment environments", }, "name": schema.StringAttribute{ Computed: true, @@ -94,11 +94,11 @@ func (r *environmentsDataSources) Schema( }, "dbt_version": schema.StringAttribute{ Computed: true, - Description: "Version number of dbt to use in this environment, usually in the format 1.2.0-latest rather than core versions", + Description: "Version number of dbt to use in this environment.", }, "type": schema.StringAttribute{ Computed: true, - Description: "The name of the environment", + Description: "The type of environment (must be either development or deployment)", }, "use_custom_branch": schema.BoolAttribute{ Computed: true, @@ -106,11 +106,11 @@ func (r *environmentsDataSources) Schema( }, "custom_branch": schema.StringAttribute{ Computed: true, - Description: "The type of deployment environment (currently 'production', 'staging' or empty)", + Description: "The custom branch name to use", }, "deployment_type": schema.StringAttribute{ Computed: true, - Description: "The name of the environment", + Description: "The type of deployment environment (currently 'production', 'staging' or empty)", }, "extended_attributes_id": schema.Int64Attribute{ Computed: true, From f55a5902d7ff3ef52b5fef015b0578645747422a Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:44:24 +0200 Subject: [PATCH 02/15] Add helper functions for comparing non comparable structs --- pkg/helper/lo.go | 88 +++++++++++++ pkg/helper/lo_test.go | 291 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 379 insertions(+) create mode 100644 pkg/helper/lo.go create mode 100644 pkg/helper/lo_test.go diff --git a/pkg/helper/lo.go b/pkg/helper/lo.go new file mode 100644 index 00000000..69c8c6c3 --- /dev/null +++ b/pkg/helper/lo.go @@ -0,0 +1,88 @@ +package helper + +// Additional functions to the samber/lo package. + +// Same as Intersect but with a predicate function to compare elements. +func IntersectBy[T any](list1 []T, list2 []T, predicate func(T, T) bool) []T { + result := []T{} + + for _, aValue := range list1 { + found := false + for _, bValue := range list2 { + if predicate(aValue, bValue) { + found = true + break + } + } + if found { + result = append(result, aValue) + } + } + + return result +} + +// Same as Difference but with a predicate function to compare elements. +func DifferenceBy[T any]( + list1 []T, + list2 []T, + predicate func(T, T) bool, +) ([]T, []T) { + left := []T{} + right := []T{} + + for _, aValue := range list1 { + found := false + for _, bValue := range list2 { + if predicate(aValue, bValue) { + found = true + break + } + } + if !found { + left = append(left, aValue) + } + } + + for _, bValue := range list2 { + found := false + for _, aValue := range list1 { + if predicate(bValue, aValue) { + found = true + break + } + } + if !found { + right = append(right, bValue) + } + } + + return left, right +} + +// Same as Union but with a predicate function to compare elements. +// Note that items need to be unique already in list1 and list2 +func UnionBy[T any]( + list1 []T, + list2 []T, + predicate func(T, T) bool, +) []T { + response := []T{} + + response = append(response, list1...) + + for _, aValue := range list2 { + found := false + for _, bValue := range list1 { + if predicate(aValue, bValue) { + found = true + break + } + } + if !found { + response = append(response, aValue) + } + } + + return response +} diff --git a/pkg/helper/lo_test.go b/pkg/helper/lo_test.go new file mode 100644 index 00000000..ce733cb9 --- /dev/null +++ b/pkg/helper/lo_test.go @@ -0,0 +1,291 @@ +package helper + +import ( + "reflect" + "testing" +) + +func TestDifferenceBy(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + list1 []int + list2 []int + predicate func(list1 int, list2 int) bool + expectedLeft []int + expectedRight []int + }{ + { + name: "differences in left and right", + list1: []int{0, 1, 2, 3, 4, 5}, + list2: []int{0, 2, 6}, + predicate: func(l int, r int) bool { + return l == r + }, + expectedLeft: []int{1, 3, 4, 5}, + expectedRight: []int{6}, + }, + { + name: "no differences", + list1: []int{0, 1, 2, 3, 4, 5}, + list2: []int{0, 1, 2, 3, 4, 5}, + predicate: func(l int, r int) bool { + return l == r + }, + expectedLeft: []int{}, + expectedRight: []int{}, + }, + { + name: "differences in left only", + list1: []int{0, 1, 2, 3, 4, 5}, + list2: []int{0, 1, 2}, + predicate: func(l int, r int) bool { + return l == r + }, + expectedLeft: []int{3, 4, 5}, + expectedRight: []int{}, + }, + { + name: "differences in right only", + list1: []int{0, 1, 2}, + list2: []int{0, 1, 2, 3, 4, 5}, + predicate: func(l int, r int) bool { + return l == r + }, + expectedLeft: []int{}, + expectedRight: []int{3, 4, 5}, + }, + { + name: "differences in right only, (list1 is empty)", + list1: []int{}, + list2: []int{0, 1, 2, 3, 4, 5}, + predicate: func(l int, r int) bool { + return l == r + }, + expectedLeft: []int{}, + expectedRight: []int{0, 1, 2, 3, 4, 5}, + }, + { + name: "differences in left only (list2 is empty)", + list1: []int{0, 1, 2, 3, 4, 5}, + list2: []int{}, + predicate: func(l int, r int) bool { + return l == r + }, + expectedLeft: []int{0, 1, 2, 3, 4, 5}, + expectedRight: []int{}, + }, + { + name: "no differences (both list1 and list2 are empty)", + list1: []int{}, + list2: []int{}, + predicate: func(l int, r int) bool { + return l == r + }, + expectedLeft: []int{}, + expectedRight: []int{}, + }, + { + name: "no differences (both list1 and list2 are nil)", + list1: nil, + list2: nil, + predicate: func(l int, r int) bool { + return l == r + }, + expectedLeft: []int{}, + expectedRight: []int{}, + }, + { + name: "differences in right only (list1 is nil)", + list1: nil, + list2: []int{1, 2, 3}, + predicate: func(l int, r int) bool { + return l == r + }, + expectedLeft: []int{}, + expectedRight: []int{1, 2, 3}, + }, + { + name: "differences in left only (list2 is nil)", + list1: []int{1, 2, 3}, + list2: nil, + predicate: func(l int, r int) bool { + return l == r + }, + expectedLeft: []int{1, 2, 3}, + expectedRight: []int{}, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + left, right := DifferenceBy( + testCase.list1, + testCase.list2, + func(l int, r int) bool { + return l == r + }, + ) + if !reflect.DeepEqual(left, testCase.expectedLeft) { + t.Errorf( + "Test case %s failed: expected left: %v, got: %v", + testCase.name, + testCase.expectedLeft, + left, + ) + } + if !reflect.DeepEqual(right, testCase.expectedRight) { + t.Errorf( + "Test case %s failed: expected right: %v, got: %v", + testCase.name, + testCase.expectedRight, + right, + ) + } + }) + } + +} + +func TestIntersectBy(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + list1 []int + list2 []int + predicate func(list1 int, list2 int) bool + expected []int + }{ + { + name: "differences in left and right", + list1: []int{0, 1, 2, 3, 4, 5}, + list2: []int{0, 2, 6}, + predicate: func(l int, r int) bool { + return l == r + }, + expected: []int{0, 2}, + }, + { + name: "no differences", + list1: []int{0, 1, 2, 3, 4, 5}, + list2: []int{0, 1, 2, 3, 4, 5}, + predicate: func(l int, r int) bool { + return l == r + }, + expected: []int{0, 1, 2, 3, 4, 5}, + }, + { + name: "list1 empty", + list1: []int{}, + list2: []int{0, 1, 2, 3, 4, 5}, + predicate: func(l int, r int) bool { + return l == r + }, + expected: []int{}, + }, + { + name: "list2 empty", + list1: []int{0, 1, 2, 3, 4, 5}, + list2: []int{}, + predicate: func(l int, r int) bool { + return l == r + }, + expected: []int{}, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + result := IntersectBy( + testCase.list1, + testCase.list2, + func(l int, r int) bool { + return l == r + }, + ) + if !reflect.DeepEqual(result, testCase.expected) { + t.Errorf( + "Test case %s failed: expected left: %v, got: %v", + testCase.name, + testCase.expected, + result, + ) + } + + }) + } + +} + +func TestUnionBy(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + list1 []int + list2 []int + predicate func(list1 int, list2 int) bool + expected []int + }{ + { + name: "differences in left and right", + list1: []int{0, 1, 2, 3, 4, 5}, + list2: []int{0, 2, 6}, + predicate: func(l int, r int) bool { + return l == r + }, + expected: []int{0, 1, 2, 3, 4, 5, 6}, + }, + { + name: "no differences", + list1: []int{0, 1, 2, 3, 4, 5}, + list2: []int{0, 1, 2, 3, 4, 5}, + predicate: func(l int, r int) bool { + return l == r + }, + expected: []int{0, 1, 2, 3, 4, 5}, + }, + { + name: "list1 empty", + list1: []int{}, + list2: []int{0, 1, 2, 3, 4, 5}, + predicate: func(l int, r int) bool { + return l == r + }, + expected: []int{0, 1, 2, 3, 4, 5}, + }, + { + name: "list2 empty", + list1: []int{0, 1, 2, 3, 4, 5}, + list2: []int{}, + predicate: func(l int, r int) bool { + return l == r + }, + expected: []int{0, 1, 2, 3, 4, 5}, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + result := UnionBy( + testCase.list1, + testCase.list2, + func(l int, r int) bool { + return l == r + }, + ) + if !reflect.DeepEqual(result, testCase.expected) { + t.Errorf( + "Test case %s failed: expected left: %v, got: %v", + testCase.name, + testCase.expected, + result, + ) + } + + }) + } + +} From f6ac9d6a4dd2ed2c5c0130469fcdae817328a218 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:45:38 +0200 Subject: [PATCH 03/15] Refactor code to the same structure as other objects --- .../objects/notification/data_source.go | 1 - pkg/framework/objects/notification/model.go | 44 ++++++++++++++++++- .../objects/notification/resource.go | 41 +---------------- .../notification/resource_acceptance_test.go | 12 +---- 4 files changed, 46 insertions(+), 52 deletions(-) diff --git a/pkg/framework/objects/notification/data_source.go b/pkg/framework/objects/notification/data_source.go index b65cb90d..acad955d 100644 --- a/pkg/framework/objects/notification/data_source.go +++ b/pkg/framework/objects/notification/data_source.go @@ -131,7 +131,6 @@ func (d *notificationDataSource) Read( ) data.State = types.Int64Value(int64(notification.State)) data.NotificationType = types.Int64Value(int64(notification.NotificationType)) - data.NotificationType = types.Int64Value(int64(notification.NotificationType)) data.ExternalEmail = types.StringPointerValue(notification.ExternalEmail) data.SlackChannelID = types.StringPointerValue(notification.SlackChannelID) data.SlackChannelName = types.StringPointerValue(notification.SlackChannelName) diff --git a/pkg/framework/objects/notification/model.go b/pkg/framework/objects/notification/model.go index 11d42b08..ab53dd85 100644 --- a/pkg/framework/objects/notification/model.go +++ b/pkg/framework/objects/notification/model.go @@ -1,6 +1,12 @@ package notification -import "github.com/hashicorp/terraform-plugin-framework/types" +import ( + "strconv" + + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/helper" + "github.com/hashicorp/terraform-plugin-framework/types" +) type NotificationResourceModel struct { ID types.String `tfsdk:"id"` @@ -27,3 +33,39 @@ type NotificationDataSourceModel struct { SlackChannelID types.String `tfsdk:"slack_channel_id"` SlackChannelName types.String `tfsdk:"slack_channel_name"` } + +func ConvertNotificationModelToData(model NotificationResourceModel) dbt_cloud.Notification { + notification := dbt_cloud.Notification{ + UserId: int(model.UserID.ValueInt64()), + OnCancel: helper.Int64SetToIntSlice(model.OnCancel), + OnFailure: helper.Int64SetToIntSlice(model.OnFailure), + OnSuccess: helper.Int64SetToIntSlice(model.OnSuccess), + State: int(model.State.ValueInt64()), + NotificationType: int(model.NotificationType.ValueInt64()), + } + + if !model.ID.IsNull() { + idStr := model.ID.ValueString() + id, err := strconv.Atoi(idStr) + if err == nil { + notification.Id = &id + } + } + + if !model.ExternalEmail.IsNull() { + externalEmail := model.ExternalEmail.ValueString() + notification.ExternalEmail = &externalEmail + } + + if !model.SlackChannelID.IsNull() { + slackChannelID := model.SlackChannelID.ValueString() + notification.SlackChannelID = &slackChannelID + } + + if !model.SlackChannelName.IsNull() { + slackChannelName := model.SlackChannelName.ValueString() + notification.SlackChannelName = &slackChannelName + } + + return notification +} diff --git a/pkg/framework/objects/notification/resource.go b/pkg/framework/objects/notification/resource.go index 85ceed2a..93363dc1 100644 --- a/pkg/framework/objects/notification/resource.go +++ b/pkg/framework/objects/notification/resource.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" - "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/helper" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" @@ -176,7 +175,7 @@ func (r *notificationResource) Create( data.ID = types.StringValue(strconv.Itoa(*notif.Id)) - // TODO; Revise later maybe. We are saving the config instead of the value we get back from the notification call + // TODO Revise later maybe. We are saving the config instead of the value we get back from the notification call resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } @@ -258,7 +257,7 @@ func (r *notificationResource) Update( state.SlackChannelName = plan.SlackChannelName } - notification := ConvertStateToNotification(state) + notification := ConvertNotificationModelToData(state) notification.AccountId = r.client.AccountID // Update the notification @@ -296,39 +295,3 @@ func (r *notificationResource) Configure( r.client = req.ProviderData.(*dbt_cloud.Client) } - -func ConvertStateToNotification(model NotificationResourceModel) dbt_cloud.Notification { - notification := dbt_cloud.Notification{ - UserId: int(model.UserID.ValueInt64()), - OnCancel: helper.Int64SetToIntSlice(model.OnCancel), - OnFailure: helper.Int64SetToIntSlice(model.OnFailure), - OnSuccess: helper.Int64SetToIntSlice(model.OnSuccess), - State: int(model.State.ValueInt64()), - NotificationType: int(model.NotificationType.ValueInt64()), - } - - if !model.ID.IsNull() { - idStr := model.ID.ValueString() - id, err := strconv.Atoi(idStr) - if err == nil { - notification.Id = &id - } - } - - if !model.ExternalEmail.IsNull() { - externalEmail := model.ExternalEmail.ValueString() - notification.ExternalEmail = &externalEmail - } - - if !model.SlackChannelID.IsNull() { - slackChannelID := model.SlackChannelID.ValueString() - notification.SlackChannelID = &slackChannelID - } - - if !model.SlackChannelName.IsNull() { - slackChannelName := model.SlackChannelName.ValueString() - notification.SlackChannelName = &slackChannelName - } - - return notification -} diff --git a/pkg/framework/objects/notification/resource_acceptance_test.go b/pkg/framework/objects/notification/resource_acceptance_test.go index ebdf3f98..efe4c521 100644 --- a/pkg/framework/objects/notification/resource_acceptance_test.go +++ b/pkg/framework/objects/notification/resource_acceptance_test.go @@ -2,7 +2,6 @@ package notification_test import ( "fmt" - "os" "regexp" "strings" "testing" @@ -29,7 +28,7 @@ func TestAccDbtCloudNotificationResource(t *testing.T) { projectName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { acctest_helper.TestAccPreCheck(t) }, ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, CheckDestroy: testAccCheckDbtCloudNotificationDestroy, Steps: []resource.TestStep{ @@ -263,12 +262,3 @@ func testAccCheckDbtCloudNotificationDestroy(s *terraform.State) error { return nil } - -func testAccPreCheck(t *testing.T) { - if v := os.Getenv("DBT_CLOUD_ACCOUNT_ID"); v == "" { - t.Fatal("DBT_CLOUD_ACCOUNT_ID must be set for acceptance tests") - } - if v := os.Getenv("DBT_CLOUD_TOKEN"); v == "" { - t.Fatal("DBT_CLOUD_TOKEN must be set for acceptance tests") - } -} From 9a5a4ab37867b6eaa54f214ccdaf1cd985e3e53e Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:46:24 +0200 Subject: [PATCH 04/15] Move common function to helper package --- pkg/helper/helper.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkg/helper/helper.go b/pkg/helper/helper.go index 62f4257a..435801d2 100644 --- a/pkg/helper/helper.go +++ b/pkg/helper/helper.go @@ -35,6 +35,15 @@ func Int64SetToIntSlice(set types.Set) []int { return result } +func StringSetToStringSlice(set types.Set) []string { + elements := set.Elements() + result := make([]string, len(elements)) + for i, el := range elements { + result[i] = el.(types.String).ValueString() + } + return result +} + func DocString(inp string) string { newString := strings.ReplaceAll(inp, "~~~", "`") return regexp.MustCompile(`(?m)^\t+`).ReplaceAllString(newString, "") From 59760519a90dd7ab51de316e6bd621bffc4ddab2 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:46:58 +0200 Subject: [PATCH 05/15] Change lo functions used for comparing objects --- .../objects/partial_license_map/resource.go | 11 ++++---- .../objects/partial_notification/resource.go | 27 +++++++++---------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/pkg/framework/objects/partial_license_map/resource.go b/pkg/framework/objects/partial_license_map/resource.go index c81edce9..3773099a 100644 --- a/pkg/framework/objects/partial_license_map/resource.go +++ b/pkg/framework/objects/partial_license_map/resource.go @@ -171,7 +171,7 @@ func (r *partialLicenseMapResource) Create( // and we calculate all the partial fields // the global ones are already set in the plan remoteSsoMapping := fullLicenseMap.SSOLicenseMappingGroups - missingSsoMapping := lo.Without(configSsoMapping, remoteSsoMapping...) + missingSsoMapping, _ := lo.Difference(configSsoMapping, remoteSsoMapping) // we only update if something global, but not part of the ID is different or if something partial needs to be added if len(missingSsoMapping) == 0 { @@ -247,7 +247,7 @@ func (r *partialLicenseMapResource) Delete( } remoteSsoMapping := licenseMap.SSOLicenseMappingGroups - requiredSsoMapping := lo.Without(remoteSsoMapping, configSsoMapping...) + requiredSsoMapping, _ := lo.Difference(remoteSsoMapping, configSsoMapping) if len(requiredSsoMapping) > 0 { // we update the object if there are some partial values left @@ -318,11 +318,10 @@ func (r *partialLicenseMapResource) Update( } remoteSsoMapping := licenseMap.SSOLicenseMappingGroups - deletedSsoMapping := lo.Without(stateSsoMapping, planSsoMapping...) - newSsoMapping := lo.Without(planSsoMapping, stateSsoMapping...) - requiredSsoMapping := lo.Without( + deletedSsoMapping, newSsoMapping := lo.Difference(stateSsoMapping, planSsoMapping) + requiredSsoMapping, _ := lo.Difference( lo.Union(remoteSsoMapping, newSsoMapping), - deletedSsoMapping...) + deletedSsoMapping) // we check if there are changes to be sent, both global and local if len(deletedSsoMapping) > 0 || diff --git a/pkg/framework/objects/partial_notification/resource.go b/pkg/framework/objects/partial_notification/resource.go index 0d2e4877..4933beb4 100644 --- a/pkg/framework/objects/partial_notification/resource.go +++ b/pkg/framework/objects/partial_notification/resource.go @@ -222,15 +222,15 @@ func (r *partialNotificationResource) Create( // the global ones are already set in the plan configOnCancel := intOnCancel remoteOnCancel := fullNotification.OnCancel - missingOnCancel := lo.Without(configOnCancel, remoteOnCancel...) + missingOnCancel, _ := lo.Difference(configOnCancel, remoteOnCancel) configOnFailure := intOnFailure remoteOnFailure := fullNotification.OnFailure - missingOnFailure := lo.Without(configOnFailure, remoteOnFailure...) + missingOnFailure, _ := lo.Difference(configOnFailure, remoteOnFailure) configOnSuccess := intOnSuccess remoteOnSuccess := fullNotification.OnSuccess - missingOnSuccess := lo.Without(configOnSuccess, remoteOnSuccess...) + missingOnSuccess, _ := lo.Difference(configOnSuccess, remoteOnSuccess) // we only update if something global, but not part of the ID is different or if something partial needs to be added if plan.State == types.Int64Value(int64(fullNotification.State)) && @@ -329,15 +329,15 @@ func (r *partialNotificationResource) Delete( configOnCancel := intOnCancel remoteOnCancel := notification.OnCancel - requiredOnCancel := lo.Without(remoteOnCancel, configOnCancel...) + requiredOnCancel, _ := lo.Difference(remoteOnCancel, configOnCancel) configOnFailure := intOnFailure remoteOnFailure := notification.OnFailure - requiredOnFailure := lo.Without(remoteOnFailure, configOnFailure...) + requiredOnFailure, _ := lo.Difference(remoteOnFailure, configOnFailure) configOnSuccess := intOnSuccess remoteOnSuccess := notification.OnSuccess - requiredOnSuccess := lo.Without(remoteOnSuccess, configOnSuccess...) + requiredOnSuccess, _ := lo.Difference(remoteOnSuccess, configOnSuccess) if len(requiredOnCancel) > 0 || len(requiredOnFailure) > 0 || len(requiredOnSuccess) > 0 { // we update the notification if there are some jobs left @@ -413,19 +413,16 @@ func (r *partialNotificationResource) Update( } remoteOnCancel := notification.OnCancel - deletedOnCancel := lo.Without(intOnCancelState, intOnCancelPlan...) - newOnCancel := lo.Without(intOnCancelPlan, intOnCancelState...) - requiredOnCancel := lo.Without(lo.Union(remoteOnCancel, newOnCancel), deletedOnCancel...) + deletedOnCancel, newOnCancel := lo.Difference(intOnCancelState, intOnCancelPlan) + requiredOnCancel, _ := lo.Difference(lo.Union(remoteOnCancel, newOnCancel), deletedOnCancel) remoteOnFailure := notification.OnFailure - deletedOnFailure := lo.Without(intOnFailureState, intOnFailurePlan...) - newOnFailure := lo.Without(intOnFailurePlan, intOnFailureState...) - requiredOnFailure := lo.Without(lo.Union(remoteOnFailure, newOnFailure), deletedOnFailure...) + deletedOnFailure, newOnFailure := lo.Difference(intOnFailureState, intOnFailurePlan) + requiredOnFailure, _ := lo.Difference(lo.Union(remoteOnFailure, newOnFailure), deletedOnFailure) remoteOnSuccess := notification.OnSuccess - deletedOnSuccess := lo.Without(intOnSuccessState, intOnSuccessPlan...) - newOnSuccess := lo.Without(intOnSuccessPlan, intOnSuccessState...) - requiredOnSuccess := lo.Without(lo.Union(remoteOnSuccess, newOnSuccess), deletedOnSuccess...) + deletedOnSuccess, newOnSuccess := lo.Difference(intOnSuccessState, intOnSuccessPlan) + requiredOnSuccess, _ := lo.Difference(lo.Union(remoteOnSuccess, newOnSuccess), deletedOnSuccess) // we check if there are changes to be sent, both global and local if plan.UserID != state.UserID || From a5f7027ad1262f918277393649d2c59beb81ee14 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:47:35 +0200 Subject: [PATCH 06/15] Send and receive data about env level access --- pkg/dbt_cloud/group.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pkg/dbt_cloud/group.go b/pkg/dbt_cloud/group.go index 45843de2..5d477652 100644 --- a/pkg/dbt_cloud/group.go +++ b/pkg/dbt_cloud/group.go @@ -9,14 +9,15 @@ import ( ) type GroupPermission struct { - ID *int `json:"id,omitempty"` - AccountID int `json:"account_id"` - GroupID int `json:"group_id"` - ProjectID int `json:"project_id,omitempty"` - AllProjects bool `json:"all_projects"` - State int `json:"state,omitempty"` - Set string `json:"permission_set,omitempty"` - Level string `json:"permission_level,omitempty"` + ID *int `json:"id,omitempty"` + AccountID int `json:"account_id"` + GroupID int `json:"group_id"` + ProjectID int `json:"project_id,omitempty"` + AllProjects bool `json:"all_projects"` + State int `json:"state,omitempty"` + Set string `json:"permission_set,omitempty"` + Level string `json:"permission_level,omitempty"` + WritableEnvironmentCategories []string `json:"writable_environment_categories,omitempty"` } type Group struct { From a1ed3232e3533c126989daec2dda505090f2da24 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:53:01 +0200 Subject: [PATCH 07/15] Move model for group_partial_permission to group --- pkg/framework/objects/group/model.go | 95 +++++++++++ .../group_partial_permissions/model.go | 53 ------- .../group_partial_permissions/resource.go | 150 +++++++++++------- 3 files changed, 187 insertions(+), 111 deletions(-) create mode 100644 pkg/framework/objects/group/model.go delete mode 100644 pkg/framework/objects/group_partial_permissions/model.go diff --git a/pkg/framework/objects/group/model.go b/pkg/framework/objects/group/model.go new file mode 100644 index 00000000..a7ee47d4 --- /dev/null +++ b/pkg/framework/objects/group/model.go @@ -0,0 +1,95 @@ +package group + +import ( + "context" + + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/helper" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/samber/lo" +) + +type GroupResourceModel struct { + ID types.Int64 `tfsdk:"id"` + Name types.String `tfsdk:"name"` + AssignByDefault types.Bool `tfsdk:"assign_by_default"` + SSOMappingGroups types.Set `tfsdk:"sso_mapping_groups"` + GroupPermissions []GroupPermission `tfsdk:"group_permissions"` +} + +// we need a different one just because historically the data source uses `group_id` instead of `id` +type GroupDatasourceModel struct { + ID types.Int64 `tfsdk:"id"` + GroupID types.Int64 `tfsdk:"group_id"` + Name types.String `tfsdk:"name"` + AssignByDefault types.Bool `tfsdk:"assign_by_default"` + SSOMappingGroups types.Set `tfsdk:"sso_mapping_groups"` + GroupPermissions []GroupPermission `tfsdk:"group_permissions"` +} + +type GroupPermission struct { + PermissionSet types.String `tfsdk:"permission_set"` + ProjectID types.Int64 `tfsdk:"project_id"` + AllProjects types.Bool `tfsdk:"all_projects"` + WritableEnvironmentCategories types.Set `tfsdk:"writable_environment_categories"` +} + +func ConvertGroupPermissionModelToData( + requiredAllPermissions []GroupPermission, + groupID int, + accountID int, +) []dbt_cloud.GroupPermission { + allPermissionsRequest := make([]dbt_cloud.GroupPermission, len(requiredAllPermissions)) + for i, permission := range requiredAllPermissions { + allPermissionsRequest[i] = dbt_cloud.GroupPermission{ + GroupID: groupID, + AccountID: accountID, + Set: permission.PermissionSet.ValueString(), + ProjectID: int(permission.ProjectID.ValueInt64()), + AllProjects: permission.AllProjects.ValueBool(), + WritableEnvironmentCategories: helper.StringSetToStringSlice( + permission.WritableEnvironmentCategories, + ), + } + } + return allPermissionsRequest +} + +func ConvertGroupPermissionDataToModel( + allPermissions []dbt_cloud.GroupPermission, +) []GroupPermission { + allPermissionsModel := make([]GroupPermission, len(allPermissions)) + for i, permission := range allPermissions { + + writeableEnvs, _ := types.SetValueFrom( + context.Background(), + types.StringType, + permission.WritableEnvironmentCategories, + ) + + allPermissionsModel[i] = GroupPermission{ + PermissionSet: types.StringValue(permission.Set), + ProjectID: helper.SetIntToInt64OrNull(permission.ProjectID), + AllProjects: types.BoolValue(permission.AllProjects), + WritableEnvironmentCategories: writeableEnvs, + } + } + return allPermissionsModel +} + +func CompareGroupPermissions( + group1, group2 GroupPermission, +) bool { + listGroup1Envs := helper.StringSetToStringSlice(group1.WritableEnvironmentCategories) + listGroup2Envs := helper.StringSetToStringSlice(group2.WritableEnvironmentCategories) + + diffEnv1, diffEnv2 := lo.Difference( + listGroup1Envs, + listGroup2Envs, + ) + return group1.PermissionSet == group2.PermissionSet && + group1.ProjectID == group2.ProjectID && + group1.AllProjects == group2.AllProjects && + len(diffEnv1) == 0 && + len(diffEnv2) == 0 +} diff --git a/pkg/framework/objects/group_partial_permissions/model.go b/pkg/framework/objects/group_partial_permissions/model.go deleted file mode 100644 index becb78fd..00000000 --- a/pkg/framework/objects/group_partial_permissions/model.go +++ /dev/null @@ -1,53 +0,0 @@ -package group_partial_permissions - -import ( - "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" - "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/helper" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -type GroupPartialPermissionsResourceModel struct { - ID types.Int64 `tfsdk:"id"` - Name types.String `tfsdk:"name"` - AssignByDefault types.Bool `tfsdk:"assign_by_default"` - SSOMappingGroups types.Set `tfsdk:"sso_mapping_groups"` - GroupPermissions []GroupPermission `tfsdk:"group_permissions"` -} - -type GroupPermission struct { - PermissionSet types.String `tfsdk:"permission_set"` - ProjectID types.Int64 `tfsdk:"project_id"` - AllProjects types.Bool `tfsdk:"all_projects"` -} - -func convertGroupPermissionModelToData( - requiredAllPermissions []GroupPermission, - groupID int, - accountID int, -) []dbt_cloud.GroupPermission { - allPermissionsRequest := make([]dbt_cloud.GroupPermission, len(requiredAllPermissions)) - for i, permission := range requiredAllPermissions { - allPermissionsRequest[i] = dbt_cloud.GroupPermission{ - GroupID: groupID, - AccountID: accountID, - Set: permission.PermissionSet.ValueString(), - ProjectID: int(permission.ProjectID.ValueInt64()), - AllProjects: permission.AllProjects.ValueBool(), - } - } - return allPermissionsRequest -} - -func convertGroupPermissionDataToModel( - allPermissions []dbt_cloud.GroupPermission, -) []GroupPermission { - allPermissionsModel := make([]GroupPermission, len(allPermissions)) - for i, permission := range allPermissions { - allPermissionsModel[i] = GroupPermission{ - PermissionSet: types.StringValue(permission.Set), - ProjectID: helper.SetIntToInt64OrNull(permission.ProjectID), - AllProjects: types.BoolValue(permission.AllProjects), - } - } - return allPermissionsModel -} diff --git a/pkg/framework/objects/group_partial_permissions/resource.go b/pkg/framework/objects/group_partial_permissions/resource.go index 6cde18cd..0ba31097 100644 --- a/pkg/framework/objects/group_partial_permissions/resource.go +++ b/pkg/framework/objects/group_partial_permissions/resource.go @@ -2,12 +2,15 @@ package group_partial_permissions import ( "context" + "fmt" "strings" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/objects/group" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/helper" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/samber/lo" ) @@ -37,13 +40,13 @@ func (r *groupPartialPermissionsResource) Read( req resource.ReadRequest, resp *resource.ReadResponse, ) { - var state GroupPartialPermissionsResourceModel + var state group.GroupResourceModel resp.Diagnostics.Append(req.State.Get(ctx, &state)...) // check if the ID exists groupIDFromState := state.ID.ValueInt64() - group, err := r.client.GetGroup(int(groupIDFromState)) + retrievedGroup, err := r.client.GetGroup(int(groupIDFromState)) if err != nil { if strings.HasPrefix(err.Error(), "resource-not-found") { resp.Diagnostics.AddWarning( @@ -61,7 +64,7 @@ func (r *groupPartialPermissionsResource) Read( } // if the ID exists, make sure that it is the one we are looking for - if group.Name != state.Name.ValueString() { + if retrievedGroup.Name != state.Name.ValueString() { // it doesn't match, we need to find the correct one groupIDs := r.client.GetAllGroupIDsByName(state.Name.ValueString()) if len(groupIDs) > 1 { @@ -81,7 +84,7 @@ func (r *groupPartialPermissionsResource) Read( } groupID := groupIDs[0] - group, err = r.client.GetGroup(groupID) + retrievedGroup, err = r.client.GetGroup(groupID) if err != nil { resp.Diagnostics.AddError( "Issue getting Group", @@ -92,27 +95,34 @@ func (r *groupPartialPermissionsResource) Read( } // we set the "global" values - state.ID = types.Int64Value(int64(*group.ID)) - state.Name = types.StringValue(group.Name) - state.AssignByDefault = types.BoolValue(group.AssignByDefault) + state.ID = types.Int64Value(int64(*retrievedGroup.ID)) + state.Name = types.StringValue(retrievedGroup.Name) + state.AssignByDefault = types.BoolValue(retrievedGroup.AssignByDefault) state.SSOMappingGroups, _ = types.SetValueFrom( context.Background(), types.StringType, - group.SSOMappingGroups, + retrievedGroup.SSOMappingGroups, ) // we set the "partial" values - var remotePermissions []GroupPermission - for _, permission := range group.Permissions { - perm := GroupPermission{ - PermissionSet: types.StringValue(permission.Set), - ProjectID: helper.SetIntToInt64OrNull(permission.ProjectID), - AllProjects: types.BoolValue(permission.AllProjects), - } - remotePermissions = append(remotePermissions, perm) - } + remotePermissions := group.ConvertGroupPermissionDataToModel(retrievedGroup.Permissions) + + relevantPermissions := helper.IntersectBy( + state.GroupPermissions, + remotePermissions, + group.CompareGroupPermissions, + ) + + tflog.Info( + ctx, + "READ - Intersection of local and remote", + map[string]any{ + "Relevant intersected Permissions": fmt.Sprintf("%+v", relevantPermissions), + "State Permissions": fmt.Sprintf("%+v", state.GroupPermissions), + "Remote Permissions": fmt.Sprintf("%+v", remotePermissions), + }, + ) - relevantPermissions := lo.Intersect(state.GroupPermissions, remotePermissions) state.GroupPermissions = relevantPermissions resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) @@ -124,7 +134,7 @@ func (r *groupPartialPermissionsResource) Create( req resource.CreateRequest, resp *resource.CreateResponse, ) { - var plan GroupPartialPermissionsResourceModel + var plan group.GroupResourceModel resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) if resp.Diagnostics.HasError() { @@ -155,7 +165,7 @@ func (r *groupPartialPermissionsResource) Create( // B. add the permission needed for the partial field groupID := groupIDs[0] - group, err := r.client.GetGroup(groupID) + retrievedGroup, err := r.client.GetGroup(groupID) if err != nil { resp.Diagnostics.AddError( "Issue getting Group", @@ -165,22 +175,26 @@ func (r *groupPartialPermissionsResource) Create( } // A. update the "global" fields if required - sameAssignByDefault := group.AssignByDefault == assignByDefault - sameSSOGroups := lo.Every(group.SSOMappingGroups, ssoMappingGroups) && - lo.Every(ssoMappingGroups, group.SSOMappingGroups) + sameAssignByDefault := retrievedGroup.AssignByDefault == assignByDefault + sameSSOGroups := lo.Every(retrievedGroup.SSOMappingGroups, ssoMappingGroups) && + lo.Every(ssoMappingGroups, retrievedGroup.SSOMappingGroups) if !sameAssignByDefault || !sameSSOGroups { - group.AssignByDefault = assignByDefault - group.SSOMappingGroups = ssoMappingGroups + retrievedGroup.AssignByDefault = assignByDefault + retrievedGroup.SSOMappingGroups = ssoMappingGroups - r.client.UpdateGroup(groupID, *group) + r.client.UpdateGroup(groupID, *retrievedGroup) } // B. add the permissions that are missing configPermissions := plan.GroupPermissions - remotePermissions := convertGroupPermissionDataToModel(group.Permissions) + remotePermissions := group.ConvertGroupPermissionDataToModel(retrievedGroup.Permissions) - missingPermissions := lo.Without(configPermissions, remotePermissions...) + missingPermissions, _ := helper.DifferenceBy( + configPermissions, + remotePermissions, + group.CompareGroupPermissions, + ) if len(missingPermissions) == 0 { plan.ID = types.Int64Value(int64(groupID)) @@ -189,13 +203,13 @@ func (r *groupPartialPermissionsResource) Create( } allPermissions := append(remotePermissions, missingPermissions...) - allPermissionsRequest := convertGroupPermissionModelToData( + allPermissionsRequest := group.ConvertGroupPermissionModelToData( allPermissions, groupID, - group.AccountID, + retrievedGroup.AccountID, ) - _, err = r.client.UpdateGroupPermissions(*group.ID, allPermissionsRequest) + _, err = r.client.UpdateGroupPermissions(*retrievedGroup.ID, allPermissionsRequest) if err != nil { resp.Diagnostics.AddError( "Unable to assign permissions to the group", @@ -208,9 +222,7 @@ func (r *groupPartialPermissionsResource) Create( } else { // if the group with the name given doesn't exist , create it - // TODO: Move this to the group resources once the resource is move to the Framework - - group, err := r.client.CreateGroup(name, assignByDefault, ssoMappingGroups) + createdGroup, err := r.client.CreateGroup(name, assignByDefault, ssoMappingGroups) if err != nil { resp.Diagnostics.AddError( "Unable to create group", @@ -219,9 +231,9 @@ func (r *groupPartialPermissionsResource) Create( return } - groupPermissions := convertGroupPermissionModelToData(plan.GroupPermissions, *group.ID, group.AccountID) + groupPermissions := group.ConvertGroupPermissionModelToData(plan.GroupPermissions, *createdGroup.ID, createdGroup.AccountID) - _, err = r.client.UpdateGroupPermissions(*group.ID, groupPermissions) + _, err = r.client.UpdateGroupPermissions(*createdGroup.ID, groupPermissions) if err != nil { resp.Diagnostics.AddError( "Unable to assign permissions to the group", @@ -229,7 +241,7 @@ func (r *groupPartialPermissionsResource) Create( ) return } - plan.ID = types.Int64Value(int64(*group.ID)) + plan.ID = types.Int64Value(int64(*createdGroup.ID)) resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) } @@ -240,14 +252,14 @@ func (r *groupPartialPermissionsResource) Delete( req resource.DeleteRequest, resp *resource.DeleteResponse, ) { - var state GroupPartialPermissionsResourceModel + var state group.GroupResourceModel resp.Diagnostics.Append(req.State.Get(ctx, &state)...) if resp.Diagnostics.HasError() { return } groupID := int(state.ID.ValueInt64()) - group, err := r.client.GetGroup(groupID) + retrievedGroup, err := r.client.GetGroup(groupID) if err != nil { resp.Diagnostics.AddError( "Issue getting Group", @@ -255,16 +267,20 @@ func (r *groupPartialPermissionsResource) Delete( ) } - remotePermissions := convertGroupPermissionDataToModel(group.Permissions) - requiredAllPermissions := lo.Without(remotePermissions, state.GroupPermissions...) + remotePermissions := group.ConvertGroupPermissionDataToModel(retrievedGroup.Permissions) + requiredAllPermissions, _ := helper.DifferenceBy( + remotePermissions, + state.GroupPermissions, + group.CompareGroupPermissions, + ) if len(requiredAllPermissions) > 0 { // if there are permissions left, we delete the ones from the resource // but we keep the remote group - allPermissionsRequest := convertGroupPermissionModelToData( + allPermissionsRequest := group.ConvertGroupPermissionModelToData( requiredAllPermissions, groupID, - group.AccountID, + retrievedGroup.AccountID, ) _, err = r.client.UpdateGroupPermissions(groupID, allPermissionsRequest) @@ -278,8 +294,8 @@ func (r *groupPartialPermissionsResource) Delete( } else { // otherwise, we delete the group entirely if there is no permission - group.State = dbt_cloud.STATE_DELETED - _, err = r.client.UpdateGroup(groupID, *group) + retrievedGroup.State = dbt_cloud.STATE_DELETED + _, err = r.client.UpdateGroup(groupID, *retrievedGroup) if err != nil { resp.Diagnostics.AddError( "Unable to delete group", @@ -296,14 +312,14 @@ func (r *groupPartialPermissionsResource) Update( req resource.UpdateRequest, resp *resource.UpdateResponse, ) { - var plan, state GroupPartialPermissionsResourceModel + var plan, state group.GroupResourceModel // Read plan and state values into the models resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) resp.Diagnostics.Append(req.State.Get(ctx, &state)...) groupID := int(state.ID.ValueInt64()) - group, err := r.client.GetGroup(groupID) + retrievedGroup, err := r.client.GetGroup(groupID) if err != nil { resp.Diagnostics.AddError( "Issue getting Group", @@ -333,10 +349,10 @@ func (r *groupPartialPermissionsResource) Update( if !sameAssignByDefault || !sameSSOGroups { - group.AssignByDefault = planAssignByDefault - group.SSOMappingGroups = planSsoMappingGroups + retrievedGroup.AssignByDefault = planAssignByDefault + retrievedGroup.SSOMappingGroups = planSsoMappingGroups - _, err = r.client.UpdateGroup(groupID, *group) + _, err = r.client.UpdateGroup(groupID, *retrievedGroup) if err != nil { resp.Diagnostics.AddError( "Unable to update group", @@ -353,21 +369,39 @@ func (r *groupPartialPermissionsResource) Update( statePermissions := state.GroupPermissions planPermissions := plan.GroupPermissions - remotePermissions := convertGroupPermissionDataToModel(group.Permissions) + remotePermissions := group.ConvertGroupPermissionDataToModel(retrievedGroup.Permissions) - deletedPermissions := lo.Without(statePermissions, planPermissions...) - newPermissions := lo.Without(planPermissions, statePermissions...) + deletedPermissions, newPermissions := helper.DifferenceBy( + statePermissions, + planPermissions, + group.CompareGroupPermissions, + ) - requiredAllPermissions := lo.Without( - lo.Union(remotePermissions, newPermissions), - deletedPermissions...) + requiredAllPermissions, _ := helper.DifferenceBy( + helper.UnionBy(remotePermissions, newPermissions, group.CompareGroupPermissions), + deletedPermissions, group.CompareGroupPermissions) + + tflog.Info( + ctx, + "UPDATE - Intersection of local and remote", + map[string]any{ + "Deleted Permissions": fmt.Sprintf("%+v", deletedPermissions), + "New Permissions": fmt.Sprintf("%+v", newPermissions), + "Required all Permission": fmt.Sprintf("%+v", requiredAllPermissions), + "Remote Permissions": fmt.Sprintf("%+v", remotePermissions), + "Remote Permissions and New Permissions": fmt.Sprintf( + "%+v", + helper.UnionBy(remotePermissions, newPermissions, group.CompareGroupPermissions), + ), + }, + ) if len(deletedPermissions) > 0 || len(newPermissions) > 0 { - allPermissionsRequest := convertGroupPermissionModelToData( + allPermissionsRequest := group.ConvertGroupPermissionModelToData( requiredAllPermissions, groupID, - group.AccountID, + retrievedGroup.AccountID, ) _, err = r.client.UpdateGroupPermissions(groupID, allPermissionsRequest) From 9f52bffb00fcbd227c4135c69d0e15dea3375850 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:53:25 +0200 Subject: [PATCH 08/15] Add env level restrictions for group_partial_permissions --- .../resource_acceptance_test.go | 19 +++++++++++++++---- .../group_partial_permissions/schema.go | 13 +++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/pkg/framework/objects/group_partial_permissions/resource_acceptance_test.go b/pkg/framework/objects/group_partial_permissions/resource_acceptance_test.go index 7ea8bd92..876ba22c 100644 --- a/pkg/framework/objects/group_partial_permissions/resource_acceptance_test.go +++ b/pkg/framework/objects/group_partial_permissions/resource_acceptance_test.go @@ -138,7 +138,7 @@ func TestAccDbtCloudGroupPartialPermissionsResource(t *testing.T) { resource.TestCheckResourceAttr( "dbtcloud_group_partial_permissions.test_group_partial_permission2", "group_permissions.#", - "2", + "3", ), resource.TestCheckTypeSetElemNestedAttrs( "dbtcloud_group_partial_permissions.test_group_partial_permission2", @@ -184,7 +184,7 @@ func TestAccDbtCloudGroupPartialPermissionsResource(t *testing.T) { resource.TestCheckResourceAttr( "dbtcloud_group_partial_permissions.test_group_partial_permission2", "group_permissions.#", - "2", + "3", ), resource.TestCheckTypeSetElemNestedAttrs( "dbtcloud_group_partial_permissions.test_group_partial_permission2", @@ -220,7 +220,12 @@ func TestAccDbtCloudGroupPartialPermissionsResource(t *testing.T) { resource.TestCheckResourceAttr( "dbtcloud_group_partial_permissions.test_group_partial_permission2", "group_permissions.0.permission_set", - "admin", + "analyst", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group_partial_permissions.test_group_partial_permission2", + "group_permissions.0.writable_environment_categories.#", + "2", ), ), }, @@ -336,6 +341,11 @@ resource "dbtcloud_group_partial_permissions" "test_group_partial_permission2" { permission_set = "job_viewer" all_projects = true }, + { + permission_set = "developer" + all_projects = true + writable_environment_categories = ["development"] + }, ] depends_on = [ dbtcloud_group_partial_permissions.test_group_partial_permission @@ -360,9 +370,10 @@ resource "dbtcloud_group_partial_permissions" "test_group_partial_permission2" { sso_mapping_groups = ["group1", "group2"] group_permissions = [ { - permission_set = "admin" + permission_set = "analyst" project_id = dbtcloud_project.test_group_project.id all_projects = false + writable_environment_categories = ["other", "production"] }, ] } diff --git a/pkg/framework/objects/group_partial_permissions/schema.go b/pkg/framework/objects/group_partial_permissions/schema.go index cd68b079..8108ae6a 100644 --- a/pkg/framework/objects/group_partial_permissions/schema.go +++ b/pkg/framework/objects/group_partial_permissions/schema.go @@ -66,8 +66,10 @@ func (r *groupPartialPermissionsResource) Schema( Description: "Whether the group will be assigned by default to users. The value needs to be the same for all partial permissions for the same group.", }, "sso_mapping_groups": schema.SetAttribute{ + Computed: true, Optional: true, ElementType: types.StringType, + Default: helper.EmptySetDefault(types.StringType), Description: "Mapping groups from the IdP. At the moment the complete list needs to be provided in each partial permission for the same group.", }, "group_permissions": schema.SetNestedAttribute{ @@ -89,6 +91,17 @@ func (r *groupPartialPermissionsResource) Schema( Required: true, Description: "Whether access should be provided for all projects or not.", }, + "writable_environment_categories": schema.SetAttribute{ + ElementType: types.StringType, + Optional: true, + Description: helper.DocString( + `What types of environments to apply Write permissions to. + Even if Write access is restricted to some environment types, the permission set will have Read access to all environments. + The values allowed are ~~~all~~~, ~~~development~~~, ~~~staging~~~, ~~~production~~~ and ~~~other~~~. + Not setting a value is the same as selecting ~~~all~~~. + Not all permission sets support environment level write settings, only ~~~analyst~~~, ~~~database_admin~~~, ~~~developer~~~, ~~~git_admin~~~ and ~~~team_admin~~~.`, + ), + }, }, }, Optional: true, From 7da4d5c77950c70553f2b241ab76cc655776b3c1 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:53:49 +0200 Subject: [PATCH 09/15] Move group to plugin framework and add env level restrictions --- pkg/framework/objects/group/data_source.go | 85 +++++ .../group/data_source_acceptance_test.go | 48 +++ pkg/framework/objects/group/resource.go | 295 ++++++++++++++++++ .../objects/group/resource_acceptance_test.go | 220 +++++++++++++ pkg/framework/objects/group/schema.go | 194 ++++++++++++ 5 files changed, 842 insertions(+) create mode 100644 pkg/framework/objects/group/data_source.go create mode 100644 pkg/framework/objects/group/data_source_acceptance_test.go create mode 100644 pkg/framework/objects/group/resource.go create mode 100644 pkg/framework/objects/group/resource_acceptance_test.go create mode 100644 pkg/framework/objects/group/schema.go diff --git a/pkg/framework/objects/group/data_source.go b/pkg/framework/objects/group/data_source.go new file mode 100644 index 00000000..c5152769 --- /dev/null +++ b/pkg/framework/objects/group/data_source.go @@ -0,0 +1,85 @@ +package group + +import ( + "context" + "strings" + + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var ( + _ datasource.DataSource = &groupDataSource{} + _ datasource.DataSourceWithConfigure = &groupDataSource{} +) + +func GroupDataSource() datasource.DataSource { + return &groupDataSource{} +} + +type groupDataSource struct { + client *dbt_cloud.Client +} + +func (d *groupDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { + resp.TypeName = req.ProviderTypeName + "_group" +} + +func (d *groupDataSource) Read( + ctx context.Context, + req datasource.ReadRequest, + resp *datasource.ReadResponse, +) { + + var data GroupDatasourceModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + groupID := data.GroupID.ValueInt64() + retrievedGroup, err := d.client.GetGroup(int(groupID)) + + if err != nil { + if strings.HasPrefix(err.Error(), "resource-not-found") { + resp.Diagnostics.AddWarning( + "Resource not found", + "The group was not found and has been removed from the state.", + ) + resp.State.RemoveResource(ctx) + return + } + resp.Diagnostics.AddError("Error getting the group", err.Error()) + return + } + + data.GroupID = types.Int64Value(int64(*retrievedGroup.ID)) + data.ID = types.Int64Value(int64(*retrievedGroup.ID)) + data.Name = types.StringValue(retrievedGroup.Name) + data.AssignByDefault = types.BoolValue(retrievedGroup.AssignByDefault) + data.SSOMappingGroups, _ = types.SetValueFrom( + context.Background(), + types.StringType, + retrievedGroup.SSOMappingGroups, + ) + + remotePermissions := ConvertGroupPermissionDataToModel(retrievedGroup.Permissions) + data.GroupPermissions = remotePermissions + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (d *groupDataSource) Configure( + _ context.Context, + req datasource.ConfigureRequest, + _ *datasource.ConfigureResponse, +) { + if req.ProviderData == nil { + return + } + + d.client = req.ProviderData.(*dbt_cloud.Client) +} diff --git a/pkg/framework/objects/group/data_source_acceptance_test.go b/pkg/framework/objects/group/data_source_acceptance_test.go new file mode 100644 index 00000000..79e0b3d1 --- /dev/null +++ b/pkg/framework/objects/group/data_source_acceptance_test.go @@ -0,0 +1,48 @@ +package group_test + +import ( + "fmt" + "testing" + + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccDbtCloudGroupDataSource(t *testing.T) { + + groupName := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + + config := group(groupName) + + check := resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.dbtcloud_group.test_group_read", "name", groupName), + resource.TestCheckResourceAttrSet("data.dbtcloud_group.test_group_read", "is_active"), + resource.TestCheckResourceAttrSet( + "data.dbtcloud_group.test_group_read", + "assign_by_default", + ), + ) + + resource.ParallelTest(t, resource.TestCase{ + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: config, + Check: check, + }, + }, + }) +} + +func group(groupName string) string { + return fmt.Sprintf(` +resource "dbtcloud_group" "test_group" { + name = "%s" +} + +data "dbtcloud_group" "test_group_read" { + group_id = dbtcloud_group.test_group.id +} +`, groupName) +} diff --git a/pkg/framework/objects/group/resource.go b/pkg/framework/objects/group/resource.go new file mode 100644 index 00000000..1548b14b --- /dev/null +++ b/pkg/framework/objects/group/resource.go @@ -0,0 +1,295 @@ +package group + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/helper" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/samber/lo" +) + +var ( + _ resource.Resource = &groupResource{} + _ resource.ResourceWithConfigure = &groupResource{} + _ resource.ResourceWithImportState = &groupResource{} +) + +func GroupResource() resource.Resource { + return &groupResource{} +} + +type groupResource struct { + client *dbt_cloud.Client +} + +func (r *groupResource) Metadata( + _ context.Context, + req resource.MetadataRequest, + resp *resource.MetadataResponse, +) { + resp.TypeName = req.ProviderTypeName + "_group" +} + +func (r *groupResource) Read( + ctx context.Context, + req resource.ReadRequest, + resp *resource.ReadResponse, +) { + var state GroupResourceModel + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + + groupID := state.ID.ValueInt64() + retrievedGroup, err := r.client.GetGroup(int(groupID)) + + if err != nil { + if strings.HasPrefix(err.Error(), "resource-not-found") { + resp.Diagnostics.AddWarning( + "Resource not found", + "The group was not found and has been removed from the state.", + ) + resp.State.RemoveResource(ctx) + return + } + resp.Diagnostics.AddError("Error getting the group", err.Error()) + return + } + + state.ID = types.Int64Value(int64(*retrievedGroup.ID)) + state.ID = types.Int64Value(int64(*retrievedGroup.ID)) + state.Name = types.StringValue(retrievedGroup.Name) + state.AssignByDefault = types.BoolValue(retrievedGroup.AssignByDefault) + + stateSSOMappingGroups, diags := types.SetValueFrom( + context.Background(), + types.StringType, + retrievedGroup.SSOMappingGroups, + ) + if diags.HasError() { + resp.Diagnostics.Append(diags.Errors()...) + return + } + + state.SSOMappingGroups = stateSSOMappingGroups + + remotePermissions := ConvertGroupPermissionDataToModel(retrievedGroup.Permissions) + state.GroupPermissions = remotePermissions + + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) + +} + +func (r *groupResource) Create( + ctx context.Context, + req resource.CreateRequest, + resp *resource.CreateResponse, +) { + var plan GroupResourceModel + + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + name := plan.Name.ValueString() + assignByDefault := plan.AssignByDefault.ValueBool() + var ssoMappingGroups []string + diags := plan.SSOMappingGroups.ElementsAs(context.Background(), &ssoMappingGroups, false) + if diags.HasError() { + return + } + + createdGroup, err := r.client.CreateGroup(name, assignByDefault, ssoMappingGroups) + if err != nil { + resp.Diagnostics.AddError( + "Unable to create group", + "Error: "+err.Error(), + ) + return + } + + groupPermissions := ConvertGroupPermissionModelToData( + plan.GroupPermissions, + *createdGroup.ID, + createdGroup.AccountID, + ) + + _, err = r.client.UpdateGroupPermissions(*createdGroup.ID, groupPermissions) + if err != nil { + resp.Diagnostics.AddError( + "Unable to assign permissions to the group", + "Error: "+err.Error(), + ) + return + } + plan.ID = types.Int64Value(int64(*createdGroup.ID)) + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) +} + +func (r *groupResource) Delete( + ctx context.Context, + req resource.DeleteRequest, + resp *resource.DeleteResponse, +) { + var state GroupResourceModel + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + groupID := int(state.ID.ValueInt64()) + retrievedGroup, err := r.client.GetGroup(groupID) + if err != nil { + resp.Diagnostics.AddError( + "Issue getting Group", + "Error: "+err.Error(), + ) + } + retrievedGroup.State = dbt_cloud.STATE_DELETED + _, err = r.client.UpdateGroup(groupID, *retrievedGroup) + if err != nil { + resp.Diagnostics.AddError( + "Unable to delete group", + "Error: "+err.Error(), + ) + return + } +} + +func (r *groupResource) Update( + ctx context.Context, + req resource.UpdateRequest, + resp *resource.UpdateResponse, +) { + var plan, state GroupResourceModel + + // Read plan and state values into the models + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + + if resp.Diagnostics.HasError() { + return + } + + groupID := int(state.ID.ValueInt64()) + retrievedGroup, err := r.client.GetGroup(groupID) + if err != nil { + resp.Diagnostics.AddError( + "Issue getting Group", + "Error: "+err.Error(), + ) + return + } + + planAssignByDefault := plan.AssignByDefault.ValueBool() + var planSsoMappingGroups []string + diags := plan.SSOMappingGroups.ElementsAs(context.Background(), &planSsoMappingGroups, false) + if diags.HasError() { + return + } + + stateAssignByDefault := state.AssignByDefault.ValueBool() + var stateSsoMappingGroups []string + diags = state.SSOMappingGroups.ElementsAs(context.Background(), &stateSsoMappingGroups, false) + if diags.HasError() { + return + } + + // we check the group data + sameAssignByDefault := planAssignByDefault == stateAssignByDefault + sameSSOGroups := lo.Every(planSsoMappingGroups, stateSsoMappingGroups) && + lo.Every(stateSsoMappingGroups, planSsoMappingGroups) + + if !sameAssignByDefault || !sameSSOGroups { + + retrievedGroup.AssignByDefault = planAssignByDefault + retrievedGroup.SSOMappingGroups = planSsoMappingGroups + + _, err = r.client.UpdateGroup(groupID, *retrievedGroup) + if err != nil { + resp.Diagnostics.AddError( + "Unable to update group", + "Error: "+err.Error(), + ) + } + state.AssignByDefault = plan.AssignByDefault + state.SSOMappingGroups = plan.SSOMappingGroups + } + + // we check the permission data + statePermissions := state.GroupPermissions + planPermissions := plan.GroupPermissions + + diff1, diff2 := helper.DifferenceBy( + statePermissions, + planPermissions, + CompareGroupPermissions) + // if there is any difference, we update the group permissions + if len(diff1) > 0 || len(diff2) > 0 { + groupPermissions := ConvertGroupPermissionModelToData( + planPermissions, + groupID, + retrievedGroup.AccountID, + ) + + _, err = r.client.UpdateGroupPermissions(groupID, groupPermissions) + if err != nil { + resp.Diagnostics.AddError( + "Unable to update group permissions", + "Error: "+err.Error(), + ) + } + state.GroupPermissions = plan.GroupPermissions + } + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) +} + +func (r *groupResource) ImportState( + ctx context.Context, + req resource.ImportStateRequest, + resp *resource.ImportStateResponse, +) { + + // I think we need this conversion because the ID is a string + groupIDStr := req.ID + groupID, err := strconv.Atoi(groupIDStr) + if err != nil { + fmt.Println(err) + return + } + + // and for some arcane reason, we need to initiate the SSO Set to its type + // ¯\_(ツ)_/¯ + ssoSetVal, _ := types.SetValue(types.StringType, nil) + state := GroupResourceModel{ + ID: types.Int64Value(int64(groupID)), + SSOMappingGroups: ssoSetVal, + } + + diags := resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +func (r *groupResource) Configure( + _ context.Context, + req resource.ConfigureRequest, + _ *resource.ConfigureResponse, +) { + if req.ProviderData == nil { + return + } + + r.client = req.ProviderData.(*dbt_cloud.Client) +} diff --git a/pkg/framework/objects/group/resource_acceptance_test.go b/pkg/framework/objects/group/resource_acceptance_test.go new file mode 100644 index 00000000..93344fda --- /dev/null +++ b/pkg/framework/objects/group/resource_acceptance_test.go @@ -0,0 +1,220 @@ +package group_test + +import ( + "fmt" + "regexp" + "strconv" + "testing" + + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" +) + +func TestAccDbtCloudGroupResource(t *testing.T) { + + groupName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + groupName2 := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + projectName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest_helper.TestAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDbtCloudGroupResourceBasicConfig(groupName, projectName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDbtCloudGroupExists("dbtcloud_group.test_group"), + resource.TestCheckResourceAttr("dbtcloud_group.test_group", "name", groupName), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "group_permissions.#", + "2", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "group_permissions.1.permission_set", + "member", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "group_permissions.1.all_projects", + "true", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "group_permissions.0.permission_set", + "developer", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "group_permissions.0.all_projects", + "false", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_group.test_group", + "group_permissions.0.project_id", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "sso_mapping_groups.0", + "group1", + ), + ), + }, + // MODIFY + { + Config: testAccDbtCloudGroupResourceFullConfig(groupName2, projectName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDbtCloudGroupExists("dbtcloud_group.test_group"), + resource.TestCheckResourceAttr("dbtcloud_group.test_group", "name", groupName2), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "assign_by_default", + "true", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "group_permissions.#", + "2", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "group_permissions.0.permission_set", + "member", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "group_permissions.0.all_projects", + "false", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_group.test_group", + "group_permissions.0.project_id", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "group_permissions.1.all_projects", + "true", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "group_permissions.1.permission_set", + "developer", + ), + resource.TestCheckResourceAttr( + "dbtcloud_group.test_group", + "sso_mapping_groups.#", + "2", + ), + ), + }, + // IMPORT + { + ResourceName: "dbtcloud_group.test_group", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccDbtCloudGroupResourceBasicConfig(groupName, projectName string) string { + return fmt.Sprintf(` +resource "dbtcloud_project" "test_project" { + name = "%s" +} +resource "dbtcloud_group" "test_group" { + name = "%s" + group_permissions { + permission_set = "member" + all_projects = true + } + group_permissions { + permission_set = "developer" + all_projects = false + project_id = dbtcloud_project.test_project.id + writable_environment_categories = ["production", "other"] + } + sso_mapping_groups = ["group1"] +} +`, projectName, groupName) +} + +func testAccDbtCloudGroupResourceFullConfig(groupName, projectName string) string { + return fmt.Sprintf(` +resource "dbtcloud_project" "test_project" { + name = "%s" +} +resource "dbtcloud_group" "test_group" { + name = "%s" + assign_by_default = true + group_permissions { + permission_set = "member" + all_projects = false + project_id = dbtcloud_project.test_project.id + } + group_permissions { + permission_set = "developer" + all_projects = true + writable_environment_categories = ["development", "staging"] + } + sso_mapping_groups = ["group1", "group2"] +} +`, projectName, groupName) +} + +func testAccCheckDbtCloudGroupExists(resource string) resource.TestCheckFunc { + return func(state *terraform.State) error { + rs, ok := state.RootModule().Resources[resource] + if !ok { + return fmt.Errorf("Not found: %s", resource) + } + if rs.Primary.ID == "" { + return fmt.Errorf("No Record ID is set") + } + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } + groupID, err := strconv.Atoi(rs.Primary.ID) + if err != nil { + return fmt.Errorf("Can't get groupID") + } + _, err = apiClient.GetGroup(groupID) + if err != nil { + return fmt.Errorf("error fetching item with resource %s. %s", resource, err) + } + return nil + } +} + +func testAccCheckDbtCloudGroupDestroy(s *terraform.State) error { + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } + + for _, rs := range s.RootModule().Resources { + if rs.Type != "dbtcloud_group" { + continue + } + groupID, err := strconv.Atoi(rs.Primary.ID) + if err != nil { + return fmt.Errorf("Can't get groupID") + } + _, err = apiClient.GetGroup(groupID) + if err == nil { + return fmt.Errorf("Group still exists") + } + notFoundErr := "resource-not-found" + expectedErr := regexp.MustCompile(notFoundErr) + if !expectedErr.Match([]byte(err.Error())) { + return fmt.Errorf("expected %s, got %s", notFoundErr, err) + } + } + + return nil +} diff --git a/pkg/framework/objects/group/schema.go b/pkg/framework/objects/group/schema.go new file mode 100644 index 00000000..2fbb04b4 --- /dev/null +++ b/pkg/framework/objects/group/schema.go @@ -0,0 +1,194 @@ +package group + +import ( + "context" + + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/helper" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/datasource" + datasource_schema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource" + resource_schema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func (r *groupResource) Schema( + _ context.Context, + _ resource.SchemaRequest, + resp *resource.SchemaResponse, +) { + resp.Schema = resource_schema.Schema{ + Description: helper.DocString( + `Provide a complete set of permissions for a group. This is different from ~~~dbt_cloud_partial_group_permissions~~~. + + With this resource type only one resource can be used to manage the permissions for a given group. + `, + ), + Attributes: map[string]resource_schema.Attribute{ + "id": resource_schema.Int64Attribute{ + Computed: true, + Description: "The ID of the group", + // this is used so that we don't show that ID is going to change + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), + }, + }, + "name": resource_schema.StringAttribute{ + Required: true, + Description: "The name of the group. This is used to identify an existing group", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "assign_by_default": resource_schema.BoolAttribute{ + Computed: true, + Optional: true, + Default: booldefault.StaticBool(false), + Description: "Whether the group will be assigned by default to users. The value needs to be the same for all partial permissions for the same group.", + }, + "sso_mapping_groups": resource_schema.SetAttribute{ + Computed: true, + Optional: true, + ElementType: types.StringType, + Default: helper.EmptySetDefault(types.StringType), + Description: "Mapping groups from the IdP. At the moment the complete list needs to be provided in each partial permission for the same group.", + }, + // "group_permissions": resource_schema.SetNestedAttribute{ + // Description: "Partial permissions for the group. Those permissions will be added/removed when config is added/removed.", + // NestedObject: resource_schema.NestedAttributeObject{ + // Attributes: map[string]resource_schema.Attribute{ + // "permission_set": resource_schema.StringAttribute{ + // Required: true, + // Validators: []validator.String{ + // stringvalidator.OneOf(dbt_cloud.PermissionSets...), + // }, + // Description: "Set of permissions to apply. The permissions allowed are the same as the ones for the `dbtcloud_group` resource.", + // }, + // "project_id": resource_schema.Int64Attribute{ + // Optional: true, + // Description: "Project ID to apply this permission to for this group.", + // }, + // "all_projects": resource_schema.BoolAttribute{ + // Required: true, + // Description: "Whether access should be provided for all projects or not.", + // }, + // "writable_environment_categories": resource_schema.SetAttribute{ + // ElementType: types.StringType, + // Optional: true, + // Description: helper.DocString( + // `What types of environments to apply Write permissions to. + // Even if Write access is restricted to some environment types, the permission set will have Read access to all environments. + // The values allowed are ~~~all~~~, ~~~development~~~, ~~~staging~~~, ~~~production~~~ and ~~~other~~~. + // Not setting a value is the same as selecting ~~~all~~~. + // Not all permission sets support environment level write settings, only ~~~analyst~~~, ~~~database_admin~~~, ~~~developer~~~, ~~~git_admin~~~ and ~~~team_admin~~~.`, + // ), + // }, + // }, + // }, + // Optional: true, + // }, + }, + // For now we use a Block to move from SDKv2 to PLugin Framework, but we might change to a SetAttribute in the future, using the code from above + Blocks: map[string]resource_schema.Block{ + "group_permissions": resource_schema.SetNestedBlock{ + Description: "Partial permissions for the group. Those permissions will be added/removed when config is added/removed.", + NestedObject: resource_schema.NestedBlockObject{ + Attributes: map[string]resource_schema.Attribute{ + "permission_set": resource_schema.StringAttribute{ + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf(dbt_cloud.PermissionSets...), + }, + Description: "Set of permissions to apply. The permissions allowed are the same as the ones for the `dbtcloud_group` resource.", + }, + "project_id": resource_schema.Int64Attribute{ + Optional: true, + Description: "Project ID to apply this permission to for this group.", + }, + "all_projects": resource_schema.BoolAttribute{ + Required: true, + Description: "Whether access should be provided for all projects or not.", + }, + "writable_environment_categories": resource_schema.SetAttribute{ + ElementType: types.StringType, + Optional: true, + Computed: true, + Default: helper.EmptySetDefault(types.StringType), + Description: helper.DocString( + `What types of environments to apply Write permissions to. + Even if Write access is restricted to some environment types, the permission set will have Read access to all environments. + The values allowed are ~~~all~~~, ~~~development~~~, ~~~staging~~~, ~~~production~~~ and ~~~other~~~. + Not setting a value is the same as selecting ~~~all~~~. + Not all permission sets support environment level write settings, only ~~~analyst~~~, ~~~database_admin~~~, ~~~developer~~~, ~~~git_admin~~~ and ~~~team_admin~~~.`, + ), + }, + }, + }, + }, + }, + } +} + +func (d *groupDataSource) Schema( + _ context.Context, + _ datasource.SchemaRequest, + resp *datasource.SchemaResponse, +) { + resp.Schema = datasource_schema.Schema{ + Description: "Retrieve group details", + Attributes: map[string]datasource_schema.Attribute{ + "group_id": datasource_schema.Int64Attribute{ + Required: true, + Description: "The ID of the group", + }, + "id": datasource_schema.Int64Attribute{ + Computed: true, + Description: "The ID of this resource", + }, + "name": datasource_schema.StringAttribute{ + Computed: true, + Description: "Group name", + }, + "assign_by_default": datasource_schema.BoolAttribute{ + Computed: true, + Description: "Whether the group will be assigned by default to users. The value needs to be the same for all partial permissions for the same group.", + }, + "sso_mapping_groups": datasource_schema.SetAttribute{ + ElementType: types.StringType, + Computed: true, + Description: "SSO mapping group names for this group", + }, + "group_permissions": datasource_schema.SetNestedAttribute{ + Computed: true, + Description: "Partial permissions for the group. Those permissions will be added/removed when config is added/removed.", + NestedObject: datasource_schema.NestedAttributeObject{ + Attributes: map[string]datasource_schema.Attribute{ + "permission_set": datasource_schema.StringAttribute{ + Computed: true, + Description: "Set of permissions to apply. The permissions allowed are the same as the ones for the `dbtcloud_group` resource.", + }, + "project_id": datasource_schema.Int64Attribute{ + Computed: true, + Description: "Project ID to apply this permission to for this group.", + }, + "all_projects": datasource_schema.BoolAttribute{ + Computed: true, + Description: "Whether access should be provided for all projects or not.", + }, + "writable_environment_categories": datasource_schema.SetAttribute{ + Computed: true, + ElementType: types.StringType, + Description: "What types of environments to apply Write permissions to.", + }, + }, + }, + }, + }, + } +} From f8a6339a96c59d6bd6501e7cd26d2885ca77808f Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:54:06 +0200 Subject: [PATCH 10/15] Move group to the plugin framework --- pkg/provider/framework_provider.go | 3 +++ pkg/provider/sdk_provider.go | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/provider/framework_provider.go b/pkg/provider/framework_provider.go index 760b11e7..355e00e8 100644 --- a/pkg/provider/framework_provider.go +++ b/pkg/provider/framework_provider.go @@ -7,6 +7,7 @@ import ( "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/objects/environment" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/objects/group" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/objects/group_partial_permissions" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/objects/notification" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/objects/partial_license_map" @@ -176,6 +177,7 @@ func (p *dbtCloudProvider) DataSources(_ context.Context) []func() datasource.Da notification.NotificationDataSource, environment.EnvironmentDataSource, environment.EnvironmentsDataSources, + group.GroupDataSource, } } @@ -185,5 +187,6 @@ func (p *dbtCloudProvider) Resources(_ context.Context) []func() resource.Resour group_partial_permissions.GroupPartialPermissionsResource, partial_notification.PartialNotificationResource, partial_license_map.PartialLicenseMapResource, + group.GroupResource, } } diff --git a/pkg/provider/sdk_provider.go b/pkg/provider/sdk_provider.go index d221e337..7b6b1643 100644 --- a/pkg/provider/sdk_provider.go +++ b/pkg/provider/sdk_provider.go @@ -42,7 +42,6 @@ func SDKProvider(version string) func() *schema.Provider { }, }, DataSourcesMap: map[string]*schema.Resource{ - "dbtcloud_group": data_sources.DatasourceGroup(), "dbtcloud_job": data_sources.DatasourceJob(), "dbtcloud_project": data_sources.DatasourceProject(), "dbtcloud_environment_variable": data_sources.DatasourceEnvironmentVariable(), @@ -77,7 +76,6 @@ func SDKProvider(version string) func() *schema.Provider { "dbtcloud_connection": resources.ResourceConnection(), "dbtcloud_bigquery_connection": resources.ResourceBigQueryConnection(), "dbtcloud_repository": resources.ResourceRepository(), - "dbtcloud_group": resources.ResourceGroup(), "dbtcloud_service_token": resources.ResourceServiceToken(), "dbtcloud_webhook": resources.ResourceWebhook(), "dbtcloud_user_groups": resources.ResourceUserGroups(), From dbf9a32b25514acae22a04e809cc5e1da7eb8809 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:54:21 +0200 Subject: [PATCH 11/15] Update docs and Changelog --- CHANGELOG.md | 17 ++++++++++++- docs/data-sources/group.md | 24 ++++++++++++------ docs/resources/group.md | 27 +++++++++++++-------- docs/resources/group_partial_permissions.md | 5 ++++ 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c404f12..4bb219bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,22 @@ All notable changes to this project will be documented in this file. -## [Unreleased](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.6...HEAD) +## [Unreleased](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.7...HEAD) + +## [0.3.7](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.6...v0.3.7) + +### Changes + +- [#232](https://github.com/dbt-labs/terraform-provider-dbtcloud/issues/232) Add env level permissions for `dbtcloud_group` and `dbtcloud_group_partial_permissions`. As of June 5 this feature is not yet active for all customers. + +### Docs + +- Fix description of fields for some datasources + +### Internals + +- Move the `dbcloud_group` resource and datasource from the SDKv2 to the Framework +- Create new helpers for comparing Go structs ## [0.3.6](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.5...v0.3.6) diff --git a/docs/data-sources/group.md b/docs/data-sources/group.md index 9d330007..6ed96f57 100644 --- a/docs/data-sources/group.md +++ b/docs/data-sources/group.md @@ -3,12 +3,12 @@ page_title: "dbtcloud_group Data Source - dbtcloud" subcategory: "" description: |- - + Retrieve group details --- # dbtcloud_group (Data Source) - +Retrieve group details @@ -17,12 +17,22 @@ description: |- ### Required -- `group_id` (Number) ID of the group +- `group_id` (Number) The ID of the group ### Read-Only -- `assign_by_default` (Boolean) Whether or not to assign this group to users by default -- `id` (String) The ID of this resource. -- `is_active` (Boolean) Whether the group is active +- `assign_by_default` (Boolean) Whether the group will be assigned by default to users. The value needs to be the same for all partial permissions for the same group. +- `group_permissions` (Attributes Set) Partial permissions for the group. Those permissions will be added/removed when config is added/removed. (see [below for nested schema](#nestedatt--group_permissions)) +- `id` (Number) The ID of this resource - `name` (String) Group name -- `sso_mapping_groups` (List of String) SSO mapping group names for this group +- `sso_mapping_groups` (Set of String) SSO mapping group names for this group + + +### Nested Schema for `group_permissions` + +Read-Only: + +- `all_projects` (Boolean) Whether access should be provided for all projects or not. +- `permission_set` (String) Set of permissions to apply. The permissions allowed are the same as the ones for the `dbtcloud_group` resource. +- `project_id` (Number) Project ID to apply this permission to for this group. +- `writable_environment_categories` (Set of String) What types of environments to apply Write permissions to. diff --git a/docs/resources/group.md b/docs/resources/group.md index 17379c2b..9b4f7765 100644 --- a/docs/resources/group.md +++ b/docs/resources/group.md @@ -2,7 +2,8 @@ page_title: "dbtcloud_group Resource - dbtcloud" subcategory: "" description: |- - + Provide a complete set of permissions for a group. This is different from dbt_cloud_partial_group_permissions. + With this resource type only one resource can be used to manage the permissions for a given group. --- # dbtcloud_group (Resource) @@ -34,7 +35,9 @@ The mapping of permission names [from the docs](https://docs.getdbt.com/docs/clo |Webhooks Only | webhooks_only| +Provide a complete set of permissions for a group. This is different from `dbt_cloud_partial_group_permissions`. +With this resource type only one resource can be used to manage the permissions for a given group. ## Example Usage @@ -58,30 +61,34 @@ resource "dbtcloud_group" "tf_group_1" { ### Required -- `name` (String) Group name +- `name` (String) The name of the group. This is used to identify an existing group ### Optional -- `assign_by_default` (Boolean) Whether or not to assign this group to users by default -- `group_permissions` (Block Set) (see [below for nested schema](#nestedblock--group_permissions)) -- `is_active` (Boolean) Whether the group is active -- `sso_mapping_groups` (List of String) SSO mapping group names for this group +- `assign_by_default` (Boolean) Whether the group will be assigned by default to users. The value needs to be the same for all partial permissions for the same group. +- `group_permissions` (Block Set) Partial permissions for the group. Those permissions will be added/removed when config is added/removed. (see [below for nested schema](#nestedblock--group_permissions)) +- `sso_mapping_groups` (Set of String) Mapping groups from the IdP. At the moment the complete list needs to be provided in each partial permission for the same group. ### Read-Only -- `id` (String) The ID of this resource. +- `id` (Number) The ID of the group ### Nested Schema for `group_permissions` Required: -- `all_projects` (Boolean) Whether or not to apply this permission to all projects for this group -- `permission_set` (String) Set of permissions to apply +- `all_projects` (Boolean) Whether access should be provided for all projects or not. +- `permission_set` (String) Set of permissions to apply. The permissions allowed are the same as the ones for the `dbtcloud_group` resource. Optional: -- `project_id` (Number) Project ID to apply this permission to for this group +- `project_id` (Number) Project ID to apply this permission to for this group. +- `writable_environment_categories` (Set of String) What types of environments to apply Write permissions to. +Even if Write access is restricted to some environment types, the permission set will have Read access to all environments. +The values allowed are `all`, `development`, `staging`, `production` and `other`. +Not setting a value is the same as selecting `all`. +Not all permission sets support environment level write settings, only `analyst`, `database_admin`, `developer`, `git_admin` and `team_admin`. ## Import diff --git a/docs/resources/group_partial_permissions.md b/docs/resources/group_partial_permissions.md index 154ed6aa..7626a634 100644 --- a/docs/resources/group_partial_permissions.md +++ b/docs/resources/group_partial_permissions.md @@ -96,3 +96,8 @@ Required: Optional: - `project_id` (Number) Project ID to apply this permission to for this group. +- `writable_environment_categories` (Set of String) What types of environments to apply Write permissions to. +Even if Write access is restricted to some environment types, the permission set will have Read access to all environments. +The values allowed are `all`, `development`, `staging`, `production` and `other`. +Not setting a value is the same as selecting `all`. +Not all permission sets support environment level write settings, only `analyst`, `database_admin`, `developer`, `git_admin` and `team_admin`. From b8df8d1b80604683b184248b6c37bb5aeb40117d Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 11:36:00 +0200 Subject: [PATCH 12/15] Remove legacy sdkv2 groups --- pkg/sdkv2/data_sources/group.go | 78 ----- .../data_sources/group_acceptance_test.go | 47 --- pkg/sdkv2/resources/group.go | 268 ------------------ pkg/sdkv2/resources/group_acceptance_test.go | 217 -------------- 4 files changed, 610 deletions(-) delete mode 100644 pkg/sdkv2/data_sources/group.go delete mode 100644 pkg/sdkv2/data_sources/group_acceptance_test.go delete mode 100644 pkg/sdkv2/resources/group.go delete mode 100644 pkg/sdkv2/resources/group_acceptance_test.go diff --git a/pkg/sdkv2/data_sources/group.go b/pkg/sdkv2/data_sources/group.go deleted file mode 100644 index 744540f6..00000000 --- a/pkg/sdkv2/data_sources/group.go +++ /dev/null @@ -1,78 +0,0 @@ -package data_sources - -import ( - "context" - "strconv" - - "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/schema" -) - -var groupSchema = map[string]*schema.Schema{ - "group_id": &schema.Schema{ - Type: schema.TypeInt, - Required: true, - Description: "ID of the group", - }, - "is_active": &schema.Schema{ - Type: schema.TypeBool, - Computed: true, - Description: "Whether the group is active", - }, - "name": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - Description: "Group name", - }, - "assign_by_default": &schema.Schema{ - Type: schema.TypeBool, - Computed: true, - Description: "Whether or not to assign this group to users by default", - }, - "sso_mapping_groups": &schema.Schema{ - Type: schema.TypeList, - Computed: true, - Description: "SSO mapping group names for this group", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, -} - -func DatasourceGroup() *schema.Resource { - return &schema.Resource{ - ReadContext: datasourceGroupRead, - Schema: groupSchema, - } -} - -func datasourceGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - c := m.(*dbt_cloud.Client) - - var diags diag.Diagnostics - - groupID := d.Get("group_id").(int) - - group, err := c.GetGroup(groupID) - if err != nil { - return diag.FromErr(err) - } - - if err := d.Set("is_active", group.State == dbt_cloud.STATE_ACTIVE); err != nil { - return diag.FromErr(err) - } - if err := d.Set("name", group.Name); err != nil { - return diag.FromErr(err) - } - if err := d.Set("assign_by_default", group.AssignByDefault); err != nil { - return diag.FromErr(err) - } - if err := d.Set("sso_mapping_groups", group.SSOMappingGroups); err != nil { - return diag.FromErr(err) - } - - d.SetId(strconv.Itoa(*group.ID)) - - return diags -} diff --git a/pkg/sdkv2/data_sources/group_acceptance_test.go b/pkg/sdkv2/data_sources/group_acceptance_test.go deleted file mode 100644 index 15f07c90..00000000 --- a/pkg/sdkv2/data_sources/group_acceptance_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package data_sources_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-testing/helper/acctest" - "github.com/hashicorp/terraform-plugin-testing/helper/resource" -) - -func TestAccDbtCloudGroupDataSource(t *testing.T) { - - groupName := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) - - config := group(groupName) - - check := resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("data.dbtcloud_group.test_group_read", "name", groupName), - resource.TestCheckResourceAttrSet("data.dbtcloud_group.test_group_read", "is_active"), - resource.TestCheckResourceAttrSet( - "data.dbtcloud_group.test_group_read", - "assign_by_default", - ), - ) - - resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), - Steps: []resource.TestStep{ - { - Config: config, - Check: check, - }, - }, - }) -} - -func group(groupName string) string { - return fmt.Sprintf(` -resource "dbtcloud_group" "test_group" { - name = "%s" -} - -data "dbtcloud_group" "test_group_read" { - group_id = dbtcloud_group.test_group.id -} -`, groupName) -} diff --git a/pkg/sdkv2/resources/group.go b/pkg/sdkv2/resources/group.go deleted file mode 100644 index b3fce898..00000000 --- a/pkg/sdkv2/resources/group.go +++ /dev/null @@ -1,268 +0,0 @@ -package resources - -import ( - "context" - "strconv" - "strings" - - "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/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" -) - -func ResourceGroup() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceGroupCreate, - ReadContext: resourceGroupRead, - UpdateContext: resourceGroupUpdate, - DeleteContext: resourceGroupDelete, - - Schema: map[string]*schema.Schema{ - "is_active": &schema.Schema{ - Type: schema.TypeBool, - Optional: true, - Default: true, - Description: "Whether the group is active", - }, - "name": &schema.Schema{ - Type: schema.TypeString, - Required: true, - Description: "Group name", - }, - "assign_by_default": &schema.Schema{ - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "Whether or not to assign this group to users by default", - }, - "sso_mapping_groups": &schema.Schema{ - Type: schema.TypeList, - Optional: true, - Description: "SSO mapping group names for this group", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "group_permissions": &schema.Schema{ - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "permission_set": { - Type: schema.TypeString, - Required: true, - Description: "Set of permissions to apply", - ValidateFunc: validation.StringInSlice(dbt_cloud.PermissionSets, false), - }, - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "Project ID to apply this permission to for this group", - }, - "all_projects": { - Type: schema.TypeBool, - Required: true, - Description: "Whether or not to apply this permission to all projects for this group", - }, - }, - }, - }, - }, - - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - } -} - -func resourceGroupCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - c := m.(*dbt_cloud.Client) - - var diags diag.Diagnostics - - name := d.Get("name").(string) - assignByDefault := d.Get("assign_by_default").(bool) - ssoMappingGroupsRaw := d.Get("sso_mapping_groups").([]interface{}) - ssoMappingGroups := make([]string, len(ssoMappingGroupsRaw)) - for i := range ssoMappingGroupsRaw { - ssoMappingGroups[i] = ssoMappingGroupsRaw[i].(string) - } - - group, err := c.CreateGroup(name, assignByDefault, ssoMappingGroups) - if err != nil { - return diag.FromErr(err) - } - - groupPermissionsRaw := d.Get("group_permissions").(*schema.Set).List() - groupPermissions := make([]dbt_cloud.GroupPermission, len(groupPermissionsRaw)) - for i, p := range groupPermissionsRaw { - permission := p.(map[string]interface{}) - groupPermission := dbt_cloud.GroupPermission{ - GroupID: *group.ID, - AccountID: group.AccountID, - Set: permission["permission_set"].(string), - ProjectID: permission["project_id"].(int), - AllProjects: permission["all_projects"].(bool), - } - groupPermissions[i] = groupPermission - } - - _, err = c.UpdateGroupPermissions(*group.ID, groupPermissions) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(strconv.Itoa(*group.ID)) - - resourceGroupRead(ctx, d, m) - - return diags -} - -func resourceGroupRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - c := m.(*dbt_cloud.Client) - - var diags diag.Diagnostics - - groupID, err := strconv.Atoi(d.Id()) - if err != nil { - return diag.FromErr(err) - } - - group, err := c.GetGroup(groupID) - if err != nil { - if strings.HasPrefix(err.Error(), "resource-not-found") { - d.SetId("") - return diags - } - return diag.FromErr(err) - } - - if err := d.Set("is_active", group.State == dbt_cloud.STATE_ACTIVE); err != nil { - return diag.FromErr(err) - } - if err := d.Set("name", group.Name); err != nil { - return diag.FromErr(err) - } - if err := d.Set("assign_by_default", group.AssignByDefault); err != nil { - return diag.FromErr(err) - } - if err := d.Set("sso_mapping_groups", group.SSOMappingGroups); err != nil { - return diag.FromErr(err) - } - permissions := make([]interface{}, len(group.Permissions)) - for i, permission := range group.Permissions { - p := make(map[string]interface{}) - p["permission_set"] = permission.Set - p["project_id"] = permission.ProjectID - p["all_projects"] = permission.AllProjects - permissions[i] = p - } - if err := d.Set("group_permissions", permissions); err != nil { - return diag.FromErr(err) - } - - return diags -} - -func resourceGroupUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - c := m.(*dbt_cloud.Client) - - groupID, err := strconv.Atoi(d.Id()) - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("name") || - d.HasChange("assign_by_default") || - d.HasChange("sso_mapping_groups") { - group, err := c.GetGroup(groupID) - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("name") { - name := d.Get("name").(string) - group.Name = name - } - if d.HasChange("assign_by_default") { - assignByDefault := d.Get("assign_by_default").(bool) - group.AssignByDefault = assignByDefault - } - if d.HasChange("sso_mapping_groups") { - ssoMappingGroupsRaw := d.Get("sso_mapping_groups").([]interface{}) - ssoMappingGroups := make([]string, len(ssoMappingGroupsRaw)) - for i := range ssoMappingGroupsRaw { - ssoMappingGroups[i] = ssoMappingGroupsRaw[i].(string) - } - group.SSOMappingGroups = ssoMappingGroups - } - _, err = c.UpdateGroup(groupID, *group) - if err != nil { - return diag.FromErr(err) - } - } - - if d.HasChange("group_permissions") { - // TODO(GtheSheep): Extract this to a function - groupPermissionsRaw := d.Get("group_permissions").(*schema.Set).List() - groupPermissions := make([]dbt_cloud.GroupPermission, len(groupPermissionsRaw)) - for i, p := range groupPermissionsRaw { - permission := p.(map[string]interface{}) - groupPermission := dbt_cloud.GroupPermission{ - GroupID: groupID, - AccountID: c.AccountID, - Set: permission["permission_set"].(string), - ProjectID: permission["project_id"].(int), - AllProjects: permission["all_projects"].(bool), - } - groupPermissions[i] = groupPermission - } - _, err = c.UpdateGroupPermissions(groupID, groupPermissions) - if err != nil { - return diag.FromErr(err) - } - } - return resourceGroupRead(ctx, d, m) -} - -func resourceGroupDelete( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - c := m.(*dbt_cloud.Client) - - groupID, err := strconv.Atoi(d.Id()) - if err != nil { - return diag.FromErr(err) - } - - var diags diag.Diagnostics - - group, err := c.GetGroup(groupID) - if err != nil { - return diag.FromErr(err) - } - - group.State = dbt_cloud.STATE_DELETED - _, err = c.UpdateGroup(groupID, *group) - if err != nil { - return diag.FromErr(err) - } - - return diags -} diff --git a/pkg/sdkv2/resources/group_acceptance_test.go b/pkg/sdkv2/resources/group_acceptance_test.go deleted file mode 100644 index 50c0d746..00000000 --- a/pkg/sdkv2/resources/group_acceptance_test.go +++ /dev/null @@ -1,217 +0,0 @@ -package resources_test - -import ( - "fmt" - "regexp" - "strconv" - "testing" - - "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" - "github.com/hashicorp/terraform-plugin-testing/helper/acctest" - "github.com/hashicorp/terraform-plugin-testing/helper/resource" - "github.com/hashicorp/terraform-plugin-testing/terraform" -) - -func TestAccDbtCloudGroupResource(t *testing.T) { - - groupName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) - groupName2 := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) - projectName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccDbtCloudGroupResourceBasicConfig(groupName, projectName), - Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudGroupExists("dbtcloud_group.test_group"), - resource.TestCheckResourceAttr("dbtcloud_group.test_group", "name", groupName), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "group_permissions.#", - "2", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "group_permissions.1.permission_set", - "member", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "group_permissions.1.all_projects", - "true", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "group_permissions.0.permission_set", - "developer", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "group_permissions.0.all_projects", - "false", - ), - resource.TestCheckResourceAttrSet( - "dbtcloud_group.test_group", - "group_permissions.0.project_id", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "sso_mapping_groups.0", - "group1", - ), - ), - }, - // MODIFY - { - Config: testAccDbtCloudGroupResourceFullConfig(groupName2, projectName), - Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudGroupExists("dbtcloud_group.test_group"), - resource.TestCheckResourceAttr("dbtcloud_group.test_group", "name", groupName2), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "assign_by_default", - "true", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "group_permissions.#", - "2", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "group_permissions.0.permission_set", - "member", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "group_permissions.0.all_projects", - "false", - ), - resource.TestCheckResourceAttrSet( - "dbtcloud_group.test_group", - "group_permissions.0.project_id", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "group_permissions.1.all_projects", - "true", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "group_permissions.1.permission_set", - "developer", - ), - resource.TestCheckResourceAttr( - "dbtcloud_group.test_group", - "sso_mapping_groups.#", - "2", - ), - ), - }, - // IMPORT - { - ResourceName: "dbtcloud_group.test_group", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{ - // being a set we need to ignore all, but * doesn't work - "group_permissions.0.project_id", - "group_permissions.1.project_id", - }, - }, - }, - }) -} - -func testAccDbtCloudGroupResourceBasicConfig(groupName, projectName string) string { - return fmt.Sprintf(` -resource "dbtcloud_project" "test_project" { - name = "%s" -} -resource "dbtcloud_group" "test_group" { - name = "%s" - group_permissions { - permission_set = "member" - all_projects = true - } - group_permissions { - permission_set = "developer" - all_projects = false - project_id = dbtcloud_project.test_project.id - } - sso_mapping_groups = ["group1"] -} -`, projectName, groupName) -} - -func testAccDbtCloudGroupResourceFullConfig(groupName, projectName string) string { - return fmt.Sprintf(` -resource "dbtcloud_project" "test_project" { - name = "%s" -} -resource "dbtcloud_group" "test_group" { - name = "%s" - assign_by_default = true - group_permissions { - permission_set = "member" - all_projects = false - project_id = dbtcloud_project.test_project.id - } - group_permissions { - permission_set = "developer" - all_projects = true - } - sso_mapping_groups = ["group1", "group2"] -} -`, projectName, groupName) -} - -func testAccCheckDbtCloudGroupExists(resource string) resource.TestCheckFunc { - return func(state *terraform.State) error { - rs, ok := state.RootModule().Resources[resource] - if !ok { - return fmt.Errorf("Not found: %s", resource) - } - if rs.Primary.ID == "" { - return fmt.Errorf("No Record ID is set") - } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) - groupID, err := strconv.Atoi(rs.Primary.ID) - if err != nil { - return fmt.Errorf("Can't get groupID") - } - _, err = apiClient.GetGroup(groupID) - if err != nil { - return fmt.Errorf("error fetching item with resource %s. %s", resource, err) - } - return nil - } -} - -func testAccCheckDbtCloudGroupDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) - - for _, rs := range s.RootModule().Resources { - if rs.Type != "dbtcloud_group" { - continue - } - groupID, err := strconv.Atoi(rs.Primary.ID) - if err != nil { - return fmt.Errorf("Can't get groupID") - } - _, err = apiClient.GetGroup(groupID) - if err == nil { - return fmt.Errorf("Group still exists") - } - notFoundErr := "resource-not-found" - expectedErr := regexp.MustCompile(notFoundErr) - if !expectedErr.Match([]byte(err.Error())) { - return fmt.Errorf("expected %s, got %s", notFoundErr, err) - } - } - - return nil -} From 84d19eba8dd1d2ede27cf687b191e596ab777953 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 11:36:15 +0200 Subject: [PATCH 13/15] Update test to remove check on is_active --- pkg/framework/objects/group/data_source_acceptance_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/framework/objects/group/data_source_acceptance_test.go b/pkg/framework/objects/group/data_source_acceptance_test.go index 79e0b3d1..6f8f86b7 100644 --- a/pkg/framework/objects/group/data_source_acceptance_test.go +++ b/pkg/framework/objects/group/data_source_acceptance_test.go @@ -17,7 +17,6 @@ func TestAccDbtCloudGroupDataSource(t *testing.T) { check := resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("data.dbtcloud_group.test_group_read", "name", groupName), - resource.TestCheckResourceAttrSet("data.dbtcloud_group.test_group_read", "is_active"), resource.TestCheckResourceAttrSet( "data.dbtcloud_group.test_group_read", "assign_by_default", From 77183e9985a68ea4a419533be412dafb6ae731e5 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 11:36:38 +0200 Subject: [PATCH 14/15] Use muxing for all tests --- .../bigquery_connection_acceptance_test.go | 3 +- .../bigquery_credential_acceptance_test.go | 3 +- .../connection_acceptance_test.go | 3 +- .../databricks_credential_acceptance_test.go | 3 +- .../environment_variable_acceptance_test.go | 3 +- .../group_users_acceptance_test.go | 3 +- pkg/sdkv2/data_sources/job_acceptance_test.go | 3 +- .../postgres_credential_acceptance_test.go | 3 +- .../privatelink_endpoint_acceptance_test.go | 3 +- .../data_sources/project_acceptance_test.go | 3 +- .../repository_acceptance_test.go | 3 +- .../service_token_acceptance_test.go | 3 +- .../snowflake_credential_acceptance_test.go | 3 +- .../user_groups_acceptance_test.go | 3 +- .../data_sources/webhook_acceptance_test.go | 3 +- .../bigquery_connection_acceptance_test.go | 12 ++-- .../bigquery_credential_acceptance_test.go | 17 ++++-- .../resources/connection_acceptance_test.go | 43 +++++++++------ .../databricks_credential_acceptance_test.go | 17 ++++-- .../resources/environment_acceptance_test.go | 17 ++++-- pkg/sdkv2/resources/environment_test.go | 48 ---------------- .../environment_variable_acceptance_test.go | 17 ++++-- ...t_variable_job_override_acceptance_test.go | 17 ++++-- .../extended_attributes_acceptance_test.go | 17 ++++-- .../fabric_connection_acceptance_test.go | 12 ++-- .../fabric_credential_acceptance_test.go | 17 ++++-- pkg/sdkv2/resources/job_acceptance_test.go | 32 ++++++----- pkg/sdkv2/resources/job_test.go | 55 ------------------- .../resources/license_map_acceptance_test.go | 18 ++++-- .../postgres_credential_acceptance_test.go | 17 ++++-- .../resources/project_acceptance_test.go | 20 ++++--- .../project_artefacts_acceptance_test.go | 22 ++++++-- .../project_connection_acceptance_test.go | 22 ++++++-- .../project_repository_acceptance_test.go | 22 ++++++-- pkg/sdkv2/resources/project_test.go | 38 ------------- .../resources/repository_acceptance_test.go | 51 ++++++----------- .../service_token_acceptance_test.go | 18 ++++-- .../snowflake_credential_acceptance_test.go | 23 +++++--- .../resources/user_groups_acceptance_test.go | 5 +- .../resources/webhook_acceptance_test.go | 20 ++++--- 40 files changed, 318 insertions(+), 324 deletions(-) delete mode 100644 pkg/sdkv2/resources/environment_test.go delete mode 100644 pkg/sdkv2/resources/job_test.go delete mode 100644 pkg/sdkv2/resources/project_test.go diff --git a/pkg/sdkv2/data_sources/bigquery_connection_acceptance_test.go b/pkg/sdkv2/data_sources/bigquery_connection_acceptance_test.go index b9b3ae7a..ca2138a6 100644 --- a/pkg/sdkv2/data_sources/bigquery_connection_acceptance_test.go +++ b/pkg/sdkv2/data_sources/bigquery_connection_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -114,7 +115,7 @@ func TestAccDbtCloudBigQueryConnectionDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/bigquery_credential_acceptance_test.go b/pkg/sdkv2/data_sources/bigquery_credential_acceptance_test.go index 3e11b991..c4c725b7 100644 --- a/pkg/sdkv2/data_sources/bigquery_credential_acceptance_test.go +++ b/pkg/sdkv2/data_sources/bigquery_credential_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -25,7 +26,7 @@ func TestAccDbtCloudBigQueryCredentialDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/connection_acceptance_test.go b/pkg/sdkv2/data_sources/connection_acceptance_test.go index b02b12d5..d88257c4 100644 --- a/pkg/sdkv2/data_sources/connection_acceptance_test.go +++ b/pkg/sdkv2/data_sources/connection_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -34,7 +35,7 @@ func TestAccDbtCloudConnectionDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/databricks_credential_acceptance_test.go b/pkg/sdkv2/data_sources/databricks_credential_acceptance_test.go index 44985dda..f82d3f8a 100644 --- a/pkg/sdkv2/data_sources/databricks_credential_acceptance_test.go +++ b/pkg/sdkv2/data_sources/databricks_credential_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -33,7 +34,7 @@ func TestAccDbtCloudDatabricksCredentialDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/environment_variable_acceptance_test.go b/pkg/sdkv2/data_sources/environment_variable_acceptance_test.go index 6ff07f0e..605fde7e 100644 --- a/pkg/sdkv2/data_sources/environment_variable_acceptance_test.go +++ b/pkg/sdkv2/data_sources/environment_variable_acceptance_test.go @@ -5,6 +5,7 @@ import ( "strings" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -47,7 +48,7 @@ func TestAccDbtCloudEnvironmentVariableDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/group_users_acceptance_test.go b/pkg/sdkv2/data_sources/group_users_acceptance_test.go index 4fc8da81..9b2c9637 100644 --- a/pkg/sdkv2/data_sources/group_users_acceptance_test.go +++ b/pkg/sdkv2/data_sources/group_users_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -28,7 +29,7 @@ func TestAccDbtCloudGroupUsersDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/job_acceptance_test.go b/pkg/sdkv2/data_sources/job_acceptance_test.go index d7c89947..ac2ee2ce 100644 --- a/pkg/sdkv2/data_sources/job_acceptance_test.go +++ b/pkg/sdkv2/data_sources/job_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -29,7 +30,7 @@ func TestDbtCloudJobDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/postgres_credential_acceptance_test.go b/pkg/sdkv2/data_sources/postgres_credential_acceptance_test.go index 7763317d..7c5e7a88 100644 --- a/pkg/sdkv2/data_sources/postgres_credential_acceptance_test.go +++ b/pkg/sdkv2/data_sources/postgres_credential_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -29,7 +30,7 @@ func TestAccDbtCloudPostgresCredentialDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/privatelink_endpoint_acceptance_test.go b/pkg/sdkv2/data_sources/privatelink_endpoint_acceptance_test.go index da7dfeac..9ccae68d 100644 --- a/pkg/sdkv2/data_sources/privatelink_endpoint_acceptance_test.go +++ b/pkg/sdkv2/data_sources/privatelink_endpoint_acceptance_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -45,7 +46,7 @@ func TestAccDbtCloudPrivatelinkEndpointDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/project_acceptance_test.go b/pkg/sdkv2/data_sources/project_acceptance_test.go index 16ab310f..a2611e68 100644 --- a/pkg/sdkv2/data_sources/project_acceptance_test.go +++ b/pkg/sdkv2/data_sources/project_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -33,7 +34,7 @@ func TestAccDbtCloudProjectDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/repository_acceptance_test.go b/pkg/sdkv2/data_sources/repository_acceptance_test.go index 89ee5499..dc64f3c6 100644 --- a/pkg/sdkv2/data_sources/repository_acceptance_test.go +++ b/pkg/sdkv2/data_sources/repository_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -23,7 +24,7 @@ func TestAccDbtCloudRepositoryDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/service_token_acceptance_test.go b/pkg/sdkv2/data_sources/service_token_acceptance_test.go index 4e813035..e7570eb9 100644 --- a/pkg/sdkv2/data_sources/service_token_acceptance_test.go +++ b/pkg/sdkv2/data_sources/service_token_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -31,7 +32,7 @@ func TestAccDbtCloudServiceTokenDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/snowflake_credential_acceptance_test.go b/pkg/sdkv2/data_sources/snowflake_credential_acceptance_test.go index eb74448c..dffc6601 100644 --- a/pkg/sdkv2/data_sources/snowflake_credential_acceptance_test.go +++ b/pkg/sdkv2/data_sources/snowflake_credential_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -28,7 +29,7 @@ func TestAccDbtCloudSnowflakeCredentialDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/user_groups_acceptance_test.go b/pkg/sdkv2/data_sources/user_groups_acceptance_test.go index 480fb3de..f8d8f2f6 100644 --- a/pkg/sdkv2/data_sources/user_groups_acceptance_test.go +++ b/pkg/sdkv2/data_sources/user_groups_acceptance_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -28,7 +29,7 @@ func TestDbtCloudUserGroupsDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/data_sources/webhook_acceptance_test.go b/pkg/sdkv2/data_sources/webhook_acceptance_test.go index 2a1b394f..60396fe6 100644 --- a/pkg/sdkv2/data_sources/webhook_acceptance_test.go +++ b/pkg/sdkv2/data_sources/webhook_acceptance_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -35,7 +36,7 @@ func TestDbtCloudWebhookDataSource(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - Providers: providers(), + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: config, diff --git a/pkg/sdkv2/resources/bigquery_connection_acceptance_test.go b/pkg/sdkv2/resources/bigquery_connection_acceptance_test.go index 0a25a98a..f77acd27 100644 --- a/pkg/sdkv2/resources/bigquery_connection_acceptance_test.go +++ b/pkg/sdkv2/resources/bigquery_connection_acceptance_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -20,9 +21,9 @@ func TestAccDbtCloudBigQueryConnectionResource(t *testing.T) { privateKey := strings.ToUpper(acctest.RandStringFromCharSet(100, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudBigQueryConnectionDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudBigQueryConnectionDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudBigQueryConnectionResourceBasicConfig( @@ -243,7 +244,10 @@ resource "dbtcloud_bigquery_connection" "test_connection" { } func testAccCheckDbtCloudBigQueryConnectionDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_bigquery_connection" { diff --git a/pkg/sdkv2/resources/bigquery_credential_acceptance_test.go b/pkg/sdkv2/resources/bigquery_credential_acceptance_test.go index 5938c0d5..ac8f56ba 100644 --- a/pkg/sdkv2/resources/bigquery_credential_acceptance_test.go +++ b/pkg/sdkv2/resources/bigquery_credential_acceptance_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -19,9 +20,9 @@ func TestAccDbtCloudBigQueryCredentialResource(t *testing.T) { dataset := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudBigQueryCredentialDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudBigQueryCredentialDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudBigQueryCredentialResourceBasicConfig(projectName, dataset), @@ -81,7 +82,10 @@ func testAccCheckDbtCloudBigQueryCredentialExists(resource string) resource.Test return fmt.Errorf("Can't get credentialId") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } _, err = apiClient.GetBigQueryCredential(projectId, credentialId) if err != nil { return fmt.Errorf("error fetching item with resource %s. %s", resource, err) @@ -91,7 +95,10 @@ func testAccCheckDbtCloudBigQueryCredentialExists(resource string) resource.Test } func testAccCheckDbtCloudBigQueryCredentialDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_bigquery_credential" { diff --git a/pkg/sdkv2/resources/connection_acceptance_test.go b/pkg/sdkv2/resources/connection_acceptance_test.go index 676c5cea..75d102bf 100644 --- a/pkg/sdkv2/resources/connection_acceptance_test.go +++ b/pkg/sdkv2/resources/connection_acceptance_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -22,9 +23,9 @@ func TestAccDbtCloudConnectionResource(t *testing.T) { oAuthClientSecret := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudConnectionDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudConnectionDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudConnectionResourceBasicConfig( @@ -86,9 +87,9 @@ func TestAccDbtCloudRedshiftConnectionResource(t *testing.T) { projectName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudConnectionDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudConnectionDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudConnectionResourceRedshiftConfig( @@ -160,9 +161,9 @@ func TestAccDbtCloudPostgresConnectionResource(t *testing.T) { projectName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudConnectionDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudConnectionDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudConnectionResourcePostgresConfig( @@ -235,9 +236,9 @@ func TestAccDbtCloudDatabricksConnectionResource(t *testing.T) { databricksHost := "databricks.com" resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudConnectionDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudConnectionDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudConnectionResourceDatabricksConfig( @@ -396,9 +397,9 @@ func TestAccDbtCloudConnectionPrivateLinkResource(t *testing.T) { projectName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudConnectionDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudConnectionDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudConnectionResourcePrivateLinkConfig( @@ -582,11 +583,14 @@ func testAccCheckDbtCloudConnectionExists(resource string) resource.TestCheckFun if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } projectId := strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[0] connectionId := strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[1] - _, err := apiClient.GetConnection(connectionId, projectId) + _, err = apiClient.GetConnection(connectionId, projectId) if err != nil { return fmt.Errorf("error fetching item with resource %s. %s", resource, err) } @@ -595,7 +599,10 @@ func testAccCheckDbtCloudConnectionExists(resource string) resource.TestCheckFun } func testAccCheckDbtCloudConnectionDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_connection" { diff --git a/pkg/sdkv2/resources/databricks_credential_acceptance_test.go b/pkg/sdkv2/resources/databricks_credential_acceptance_test.go index 999f481b..e7b558d6 100644 --- a/pkg/sdkv2/resources/databricks_credential_acceptance_test.go +++ b/pkg/sdkv2/resources/databricks_credential_acceptance_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -20,9 +21,9 @@ func TestAccDbtCloudDatabricksCredentialResource(t *testing.T) { token := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudDatabricksCredentialDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudDatabricksCredentialDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudDatabricksCredentialResourceBasicConfig( @@ -99,7 +100,10 @@ func testAccCheckDbtCloudDatabricksCredentialExists(resource string) resource.Te return fmt.Errorf("Can't get projectId") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } _, err = apiClient.GetDatabricksCredential(projectId, credentialId) if err != nil { return fmt.Errorf("error fetching item with resource %s. %s", resource, err) @@ -109,7 +113,10 @@ func testAccCheckDbtCloudDatabricksCredentialExists(resource string) resource.Te } func testAccCheckDbtCloudDatabricksCredentialDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_databricks_credential" { diff --git a/pkg/sdkv2/resources/environment_acceptance_test.go b/pkg/sdkv2/resources/environment_acceptance_test.go index 8a41ad15..a730a160 100644 --- a/pkg/sdkv2/resources/environment_acceptance_test.go +++ b/pkg/sdkv2/resources/environment_acceptance_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -20,9 +21,9 @@ func TestAccDbtCloudEnvironmentResource(t *testing.T) { projectName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudEnvironmentDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudEnvironmentDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudEnvironmentResourceBasicConfig(projectName, environmentName), @@ -196,7 +197,10 @@ func testAccCheckDbtCloudEnvironmentExists(resource string) resource.TestCheckFu if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } projectId, err := strconv.Atoi(strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[0]) if err != nil { return fmt.Errorf("Can't get projectId") @@ -216,7 +220,10 @@ func testAccCheckDbtCloudEnvironmentExists(resource string) resource.TestCheckFu } func testAccCheckDbtCloudEnvironmentDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_environment" { diff --git a/pkg/sdkv2/resources/environment_test.go b/pkg/sdkv2/resources/environment_test.go deleted file mode 100644 index fb761fa0..00000000 --- a/pkg/sdkv2/resources/environment_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package resources_test - -// -// import ( -// "fmt" -// "testing" -// -// "github.com/hashicorp/terraform-plugin-testing/helper/acctest" -// "github.com/hashicorp/terraform-plugin-testing/helper/resource" -// ) -// -// func TestDbtCloudEnvironmentResource(t *testing.T) { -// -// randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) -// -// config := fmt.Sprintf(` -// resource "dbt_cloud_environment" "test" { -// is_active = true -// name = "dbt-cloud-environment-%s" -// project_id = 123 -// dbt_version = "0.21.0" -// type = "deployment" -// use_custom_branch = true -// custom_branch = "dev" -// } -// `, randomID) -// -// check := resource.ComposeAggregateTestCheckFunc( -// resource.TestCheckResourceAttrSet("dbt_cloud_environment.test", "environment_id"), -// resource.TestCheckResourceAttr("dbt_cloud_environment.test", "is_active", "true"), -// resource.TestCheckResourceAttr("dbt_cloud_environment.test", "name", fmt.Sprintf("dbt-cloud-job-%s", randomID)), -// resource.TestCheckResourceAttr("dbt_cloud_environment.test", "project_id", "123"), -// resource.TestCheckResourceAttr("dbt_cloud_environment.test", "dbt_version", "0.21.0"), -// resource.TestCheckResourceAttr("dbt_cloud_environment.test", "type", "deployment"), -// resource.TestCheckResourceAttr("dbt_cloud_environment.test", "use_custom_branch", "true"), -// resource.TestCheckResourceAttr("dbt_cloud_environment.test", "custom_branch", "dev"), -// ) -// -// resource.ParallelTest(t, resource.TestCase{ -// Providers: providers(), -// Steps: []resource.TestStep{ -// { -// Config: config, -// Check: check, -// }, -// }, -// }) -// } diff --git a/pkg/sdkv2/resources/environment_variable_acceptance_test.go b/pkg/sdkv2/resources/environment_variable_acceptance_test.go index 25803893..667a1929 100644 --- a/pkg/sdkv2/resources/environment_variable_acceptance_test.go +++ b/pkg/sdkv2/resources/environment_variable_acceptance_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -22,9 +23,9 @@ func TestAccDbtCloudEnvironmentVariableResource(t *testing.T) { ) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudEnvironmentVariableDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudEnvironmentVariableDestroy, Steps: []resource.TestStep{ // SECRET ENV VAR { @@ -205,7 +206,10 @@ func testAccCheckDbtCloudEnvironmentVariableExists(resource string) resource.Tes if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } projectId, err := strconv.Atoi(strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[0]) if err != nil { return fmt.Errorf("Can't get projectId") @@ -222,7 +226,10 @@ func testAccCheckDbtCloudEnvironmentVariableExists(resource string) resource.Tes } func testAccCheckDbtCloudEnvironmentVariableDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_environment_variable" { diff --git a/pkg/sdkv2/resources/environment_variable_job_override_acceptance_test.go b/pkg/sdkv2/resources/environment_variable_job_override_acceptance_test.go index 7a05a301..b8c75e54 100644 --- a/pkg/sdkv2/resources/environment_variable_job_override_acceptance_test.go +++ b/pkg/sdkv2/resources/environment_variable_job_override_acceptance_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -29,9 +30,9 @@ func TestAccDbtCloudEnvironmentVariableJobOverrideResource(t *testing.T) { ) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudEnvironmentVariableJobOverrideDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudEnvironmentVariableJobOverrideDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudEnvironmentVariableJobOverrideResourceBasicConfig( @@ -173,7 +174,10 @@ func testAccCheckDbtCloudEnvironmentVariableJobOverrideExists( if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } projectId, err := strconv.Atoi(strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[0]) if err != nil { @@ -203,7 +207,10 @@ func testAccCheckDbtCloudEnvironmentVariableJobOverrideExists( } func testAccCheckDbtCloudEnvironmentVariableJobOverrideDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_environment_variable_job_override" { diff --git a/pkg/sdkv2/resources/extended_attributes_acceptance_test.go b/pkg/sdkv2/resources/extended_attributes_acceptance_test.go index 3da1e984..db02fe90 100644 --- a/pkg/sdkv2/resources/extended_attributes_acceptance_test.go +++ b/pkg/sdkv2/resources/extended_attributes_acceptance_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -18,9 +19,9 @@ func TestAccDbtCloudExtendedAttributesResource(t *testing.T) { projectName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudExtendedAttributesDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudExtendedAttributesDestroy, Steps: []resource.TestStep{ // CREATE { @@ -192,7 +193,10 @@ func testAccCheckDbtCloudExtendedAttributesExists(resource string) resource.Test if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } projectId, err := strconv.Atoi(strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[0]) if err != nil { @@ -214,7 +218,10 @@ func testAccCheckDbtCloudExtendedAttributesExists(resource string) resource.Test } func testAccCheckDbtCloudExtendedAttributesDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_extended_attributes" { diff --git a/pkg/sdkv2/resources/fabric_connection_acceptance_test.go b/pkg/sdkv2/resources/fabric_connection_acceptance_test.go index ed6f155c..2b26f019 100644 --- a/pkg/sdkv2/resources/fabric_connection_acceptance_test.go +++ b/pkg/sdkv2/resources/fabric_connection_acceptance_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -22,9 +23,9 @@ func TestAccDbtCloudFabricConnectionResource(t *testing.T) { port := 1337 resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudFabricConnectionDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudFabricConnectionDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudFabricConnectionResourceBasicConfig( @@ -167,7 +168,10 @@ func testAccDbtCloudFabricConnectionResourceFullConfig( } func testAccCheckDbtCloudFabricConnectionDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_fabric_connection" { diff --git a/pkg/sdkv2/resources/fabric_credential_acceptance_test.go b/pkg/sdkv2/resources/fabric_credential_acceptance_test.go index 9d6250b3..bf325901 100644 --- a/pkg/sdkv2/resources/fabric_credential_acceptance_test.go +++ b/pkg/sdkv2/resources/fabric_credential_acceptance_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -23,9 +24,9 @@ func TestAccDbtCloudFabricCredentialResource(t *testing.T) { clientSecret := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudFabricCredentialDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudFabricCredentialDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudFabricCredentialResourceUserPassConfig( @@ -159,7 +160,10 @@ func testAccCheckDbtCloudFabricCredentialExists(resource string) resource.TestCh return fmt.Errorf("Can't get projectId") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } _, err = apiClient.GetFabricCredential(projectId, credentialId) if err != nil { return fmt.Errorf("error fetching item with resource %s. %s", resource, err) @@ -169,7 +173,10 @@ func testAccCheckDbtCloudFabricCredentialExists(resource string) resource.TestCh } func testAccCheckDbtCloudFabricCredentialDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_fabric_credential" { diff --git a/pkg/sdkv2/resources/job_acceptance_test.go b/pkg/sdkv2/resources/job_acceptance_test.go index cebe9840..0079dea8 100644 --- a/pkg/sdkv2/resources/job_acceptance_test.go +++ b/pkg/sdkv2/resources/job_acceptance_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -42,9 +42,9 @@ func TestAccDbtCloudJobResource(t *testing.T) { ) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudJobDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudJobDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudJobResourceBasicConfig( @@ -196,9 +196,9 @@ func TestAccDbtCloudJobResourceTriggers(t *testing.T) { environmentName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudJobDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudJobDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudJobResourceBasicConfigTriggers( @@ -464,9 +464,9 @@ func TestAccDbtCloudJobResourceSchedules(t *testing.T) { environmentName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudJobDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudJobDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudJobResourceScheduleConfig( @@ -629,8 +629,11 @@ func testAccCheckDbtCloudJobExists(resource string) resource.TestCheckFunc { if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) - _, err := apiClient.GetJob(rs.Primary.ID) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } + _, err = apiClient.GetJob(rs.Primary.ID) if err != nil { return fmt.Errorf("error fetching item with resource %s. %s", resource, err) } @@ -639,7 +642,10 @@ func testAccCheckDbtCloudJobExists(resource string) resource.TestCheckFunc { } func testAccCheckDbtCloudJobDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_job" { diff --git a/pkg/sdkv2/resources/job_test.go b/pkg/sdkv2/resources/job_test.go deleted file mode 100644 index 99066fc1..00000000 --- a/pkg/sdkv2/resources/job_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package resources_test - -// -// import ( -// "fmt" -// "testing" -// -// "github.com/hashicorp/terraform-plugin-testing/helper/acctest" -// "github.com/hashicorp/terraform-plugin-testing/helper/resource" -// ) -// -// func TestDbtCloudJobResource(t *testing.T) { -// -// randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) -// -// config := fmt.Sprintf(` -// resource "dbt_cloud_job" "test" { -// name = "dbt-cloud-job-%s" -// project_id = 123 -// environment_id = 789 -// execute_steps = [ -// "dbt run", -// "dbt test" -// ] -// dbt_version = "0.20.0" -// is_active = true -// num_threads = 5 -// target_name = "target" -// generate_docs = true -// run_generate_sources = true -// triggers = { -// "github_webhook": true, -// "schedule": true, -// "custom_branch_only": true -// } -// } -// `, randomID) -// -// check := resource.ComposeAggregateTestCheckFunc( -// resource.TestCheckResourceAttrSet("dbt_cloud_job.test", "job_id"), -// resource.TestCheckResourceAttr("dbt_cloud_job.test", "project_id", "123"), -// resource.TestCheckResourceAttr("dbt_cloud_job.test", "environment_id", "789"), -// resource.TestCheckResourceAttr("dbt_cloud_job.test", "name", fmt.Sprintf("dbt-cloud-job-%s", randomID)), -// ) -// -// resource.ParallelTest(t, resource.TestCase{ -// Providers: providers(), -// Steps: []resource.TestStep{ -// { -// Config: config, -// Check: check, -// }, -// }, -// }) -// } diff --git a/pkg/sdkv2/resources/license_map_acceptance_test.go b/pkg/sdkv2/resources/license_map_acceptance_test.go index 9b6ef504..228a5e84 100644 --- a/pkg/sdkv2/resources/license_map_acceptance_test.go +++ b/pkg/sdkv2/resources/license_map_acceptance_test.go @@ -6,7 +6,7 @@ import ( "strconv" "testing" - "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -18,9 +18,9 @@ func TestAccDbtCloudLicenseMapResource(t *testing.T) { groupName2 := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudLicenseMapDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudLicenseMapDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudLicenseMapResourceBasicConfig("developer", groupName), @@ -103,7 +103,10 @@ func testAccCheckDbtCloudLicenseMapExists(resource string) resource.TestCheckFun if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } licenseMapID, err := strconv.Atoi(rs.Primary.ID) if err != nil { return fmt.Errorf("Can't get groupID") @@ -117,7 +120,10 @@ func testAccCheckDbtCloudLicenseMapExists(resource string) resource.TestCheckFun } func testAccCheckDbtCloudLicenseMapDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_license_map" { diff --git a/pkg/sdkv2/resources/postgres_credential_acceptance_test.go b/pkg/sdkv2/resources/postgres_credential_acceptance_test.go index dd35b5e1..40366b43 100644 --- a/pkg/sdkv2/resources/postgres_credential_acceptance_test.go +++ b/pkg/sdkv2/resources/postgres_credential_acceptance_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -21,9 +22,9 @@ func TestAccDbtCloudPostgresCredentialResource(t *testing.T) { password := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudPostgresCredentialDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudPostgresCredentialDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudPostgresCredentialResourceBasicConfig( @@ -108,7 +109,10 @@ func testAccCheckDbtCloudPostgresCredentialExists(resource string) resource.Test return fmt.Errorf("Can't get credentialId") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } _, err = apiClient.GetPostgresCredential(projectId, credentialId) if err != nil { return fmt.Errorf("error fetching item with resource %s. %s", resource, err) @@ -118,7 +122,10 @@ func testAccCheckDbtCloudPostgresCredentialExists(resource string) resource.Test } func testAccCheckDbtCloudPostgresCredentialDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_postgres_credential" { diff --git a/pkg/sdkv2/resources/project_acceptance_test.go b/pkg/sdkv2/resources/project_acceptance_test.go index 50505dd8..b698ca32 100644 --- a/pkg/sdkv2/resources/project_acceptance_test.go +++ b/pkg/sdkv2/resources/project_acceptance_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -18,9 +18,9 @@ func TestAccDbtCloudProjectResource(t *testing.T) { projectName2 := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudProjectDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudProjectDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudProjectResourceBasicConfig(projectName), @@ -99,8 +99,11 @@ func testAccCheckDbtCloudProjectExists(resource string) resource.TestCheckFunc { if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) - _, err := apiClient.GetProject(rs.Primary.ID) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } + _, err = apiClient.GetProject(rs.Primary.ID) if err != nil { return fmt.Errorf("error fetching item with resource %s. %s", resource, err) } @@ -109,7 +112,10 @@ func testAccCheckDbtCloudProjectExists(resource string) resource.TestCheckFunc { } func testAccCheckDbtCloudProjectDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_project" { diff --git a/pkg/sdkv2/resources/project_artefacts_acceptance_test.go b/pkg/sdkv2/resources/project_artefacts_acceptance_test.go index b052694b..c8d3bb57 100644 --- a/pkg/sdkv2/resources/project_artefacts_acceptance_test.go +++ b/pkg/sdkv2/resources/project_artefacts_acceptance_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -19,9 +20,9 @@ func TestAccDbtCloudProjectArtefactsResource(t *testing.T) { environmentName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudProjectArtefactsDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudProjectArtefactsDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudProjectArtefactsResourceBasicConfig( @@ -115,7 +116,10 @@ func testAccCheckDbtCloudProjectArtefactsExists(resource string) resource.TestCh if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } projectId := strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[0] project, err := apiClient.GetProject(projectId) if err != nil { @@ -140,7 +144,10 @@ func testAccCheckDbtCloudProjectArtefactsEmpty(resource string) resource.TestChe if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } project, err := apiClient.GetProject(rs.Primary.ID) if err != nil { return fmt.Errorf("Can't get project") @@ -156,7 +163,10 @@ func testAccCheckDbtCloudProjectArtefactsEmpty(resource string) resource.TestChe } func testAccCheckDbtCloudProjectArtefactsDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_project_artefacts" { diff --git a/pkg/sdkv2/resources/project_connection_acceptance_test.go b/pkg/sdkv2/resources/project_connection_acceptance_test.go index 54c79bcb..5df62f31 100644 --- a/pkg/sdkv2/resources/project_connection_acceptance_test.go +++ b/pkg/sdkv2/resources/project_connection_acceptance_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -18,9 +19,9 @@ func TestAccDbtCloudProjectConnectionResource(t *testing.T) { connectionName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudProjectConnectionDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudProjectConnectionDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudProjectConnectionResourceBasicConfig( @@ -112,7 +113,10 @@ func testAccCheckDbtCloudProjectConnectionExists(resource string) resource.TestC if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } projectId := strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[0] project, err := apiClient.GetProject(projectId) if err != nil { @@ -134,7 +138,10 @@ func testAccCheckDbtCloudProjectConnectionEmpty(resource string) resource.TestCh if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } project, err := apiClient.GetProject(rs.Primary.ID) if err != nil { return fmt.Errorf("Can't get project") @@ -147,7 +154,10 @@ func testAccCheckDbtCloudProjectConnectionEmpty(resource string) resource.TestCh } func testAccCheckDbtCloudProjectConnectionDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_project_connection" { diff --git a/pkg/sdkv2/resources/project_repository_acceptance_test.go b/pkg/sdkv2/resources/project_repository_acceptance_test.go index 90d0a8c3..25c90cac 100644 --- a/pkg/sdkv2/resources/project_repository_acceptance_test.go +++ b/pkg/sdkv2/resources/project_repository_acceptance_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -18,9 +19,9 @@ func TestAccDbtCloudProjectRepositoryResource(t *testing.T) { repoUrlGithub := "git@github.com:dbt-labs/terraform-provider-dbtcloud.git" resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudProjectRepositoryDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudProjectRepositoryDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudProjectRepositoryResourceBasicConfig( @@ -96,7 +97,10 @@ func testAccCheckDbtCloudProjectRepositoryExists(resource string) resource.TestC if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } projectId := strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[0] project, err := apiClient.GetProject(projectId) if err != nil { @@ -118,7 +122,10 @@ func testAccCheckDbtCloudProjectRepositoryEmpty(resource string) resource.TestCh if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } project, err := apiClient.GetProject(rs.Primary.ID) if err != nil { return fmt.Errorf("Can't get project") @@ -131,7 +138,10 @@ func testAccCheckDbtCloudProjectRepositoryEmpty(resource string) resource.TestCh } func testAccCheckDbtCloudProjectRepositoryDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_project_repository" { diff --git a/pkg/sdkv2/resources/project_test.go b/pkg/sdkv2/resources/project_test.go deleted file mode 100644 index d342c856..00000000 --- a/pkg/sdkv2/resources/project_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package resources_test - -// -// import ( -// "fmt" -// "testing" -// -// "github.com/hashicorp/terraform-plugin-testing/helper/acctest" -// "github.com/hashicorp/terraform-plugin-testing/helper/resource" -// ) -// -// func TestDbtCloudProjectResource(t *testing.T) { -// -// randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) -// -// config := fmt.Sprintf(` -// resource "dbt_cloud_project" "test" { -// name = "dbt-cloud-project-%s" -// dbt_project_subdirectory = "/this-way/for/DBT" -// } -// `, randomID) -// -// check := resource.ComposeAggregateTestCheckFunc( -// resource.TestCheckResourceAttrSet("dbt_cloud_project.test", "ID"), -// resource.TestCheckResourceAttr("dbt_cloud_project.test", "name", fmt.Sprintf("dbt-cloud-project-%s", randomID)), -// resource.TestCheckResourceAttr("dbt_cloud_project.test", "dbt_project_subdirectory", "/this-way/for/DBT"), -// ) -// -// resource.ParallelTest(t, resource.TestCase{ -// Providers: providers(), -// Steps: []resource.TestStep{ -// { -// Config: config, -// Check: check, -// }, -// }, -// }) -// } diff --git a/pkg/sdkv2/resources/repository_acceptance_test.go b/pkg/sdkv2/resources/repository_acceptance_test.go index 65af558a..956a8085 100644 --- a/pkg/sdkv2/resources/repository_acceptance_test.go +++ b/pkg/sdkv2/resources/repository_acceptance_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -22,9 +23,9 @@ func TestAccDbtCloudRepositoryResource(t *testing.T) { projectName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudRepositoryDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudRepositoryDestroy, Steps: []resource.TestStep{ // Create Github repository { @@ -61,9 +62,9 @@ func TestAccDbtCloudRepositoryResource(t *testing.T) { ) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudRepositoryDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudRepositoryDestroy, Steps: []resource.TestStep{ // Create Github repository via the GithUb Application { @@ -97,32 +98,6 @@ func TestAccDbtCloudRepositoryResource(t *testing.T) { }, }, }) - - // - // resource.Test(t, resource.TestCase{ - // PreCheck: func() { testAccPreCheck(t) }, - // Providers: testAccProviders, - // CheckDestroy: testAccCheckDbtCloudRepositoryDestroy, - // Steps: []resource.TestStep{ - // // Create Gitlab repository - // { - // Config: testAccDbtCloudRepositoryResourceGitlabConfig(repoUrlGitlab, projectName), - // Check: resource.ComposeTestCheckFunc( - // testAccCheckDbtCloudRepositoryExists("dbtcloud_repository.test_repository_gitlab"), - // resource.TestCheckResourceAttr("dbtcloud_repository.test_repository_gitlab", "remote_url", repoUrlGitlab), - // resource.TestCheckResourceAttr("dbtcloud_repository.test_repository_gitlab", "git_clone_strategy", "deploy_token"), - // ), - // }, - // // MODIFY - // // IMPORT - // { - // ResourceName: "dbtcloud_repository.test_repository_gitlab", - // ImportState: true, - // ImportStateVerify: true, - // ImportStateVerifyIgnore: []string{}, - // }, - // }, - // }) } func testAccDbtCloudRepositoryResourceGithubConfig(repoUrl, projectName string) string { @@ -179,11 +154,14 @@ func testAccCheckDbtCloudRepositoryExists(resource string) resource.TestCheckFun if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } projectId := strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[0] repositoryId := strings.Split(rs.Primary.ID, dbt_cloud.ID_DELIMITER)[1] - _, err := apiClient.GetRepository(repositoryId, projectId) + _, err = apiClient.GetRepository(repositoryId, projectId) if err != nil { return fmt.Errorf("error fetching item with resource %s. %s", resource, err) } @@ -192,7 +170,10 @@ func testAccCheckDbtCloudRepositoryExists(resource string) resource.TestCheckFun } func testAccCheckDbtCloudRepositoryDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_repository" { diff --git a/pkg/sdkv2/resources/service_token_acceptance_test.go b/pkg/sdkv2/resources/service_token_acceptance_test.go index b4d10ff8..76b9a2c4 100644 --- a/pkg/sdkv2/resources/service_token_acceptance_test.go +++ b/pkg/sdkv2/resources/service_token_acceptance_test.go @@ -6,7 +6,7 @@ import ( "strconv" "testing" - "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -19,9 +19,9 @@ func TestAccDbtCloudServiceTokenResource(t *testing.T) { projectName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudServiceTokenDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudServiceTokenDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudServiceTokenResourceBasicConfig( @@ -187,7 +187,10 @@ func testAccCheckDbtCloudServiceTokenExists(resource string) resource.TestCheckF if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } ServiceTokenID, err := strconv.Atoi(rs.Primary.ID) if err != nil { return fmt.Errorf("Can't get ServiceTokenID") @@ -201,7 +204,10 @@ func testAccCheckDbtCloudServiceTokenExists(resource string) resource.TestCheckF } func testAccCheckDbtCloudServiceTokenDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_service_token" { diff --git a/pkg/sdkv2/resources/snowflake_credential_acceptance_test.go b/pkg/sdkv2/resources/snowflake_credential_acceptance_test.go index d486f80f..de149cb0 100644 --- a/pkg/sdkv2/resources/snowflake_credential_acceptance_test.go +++ b/pkg/sdkv2/resources/snowflake_credential_acceptance_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -34,9 +35,9 @@ func TestAccDbtCloudSnowflakeCredentialResource(t *testing.T) { privateKeyPassphrase := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudSnowflakeCredentialDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudSnowflakeCredentialDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudSnowflakeCredentialResourceBasicConfig( @@ -138,9 +139,9 @@ func TestAccDbtCloudSnowflakeCredentialResource(t *testing.T) { }) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudSnowflakeCredentialDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudSnowflakeCredentialDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudSnowflakeCredentialResourceBasicPrivateKeyConfig( @@ -270,7 +271,10 @@ func testAccCheckDbtCloudSnowflakeCredentialExists(resource string) resource.Tes return fmt.Errorf("Can't get projectId") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } _, err = apiClient.GetSnowflakeCredential(projectId, credentialId) if err != nil { return fmt.Errorf("error fetching item with resource %s. %s", resource, err) @@ -280,7 +284,10 @@ func testAccCheckDbtCloudSnowflakeCredentialExists(resource string) resource.Tes } func testAccCheckDbtCloudSnowflakeCredentialDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_snowflake_credential" { diff --git a/pkg/sdkv2/resources/user_groups_acceptance_test.go b/pkg/sdkv2/resources/user_groups_acceptance_test.go index 2a9d3f5a..2e7c9647 100644 --- a/pkg/sdkv2/resources/user_groups_acceptance_test.go +++ b/pkg/sdkv2/resources/user_groups_acceptance_test.go @@ -6,6 +6,7 @@ import ( "strconv" "testing" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) @@ -28,8 +29,8 @@ func TestAccDbtCloudUserGroupsResource(t *testing.T) { GroupName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: testAccDbtCloudUserGroupsResourceAddRole(userID, GroupName, groupIDs), diff --git a/pkg/sdkv2/resources/webhook_acceptance_test.go b/pkg/sdkv2/resources/webhook_acceptance_test.go index cce32e43..8f576239 100644 --- a/pkg/sdkv2/resources/webhook_acceptance_test.go +++ b/pkg/sdkv2/resources/webhook_acceptance_test.go @@ -5,7 +5,7 @@ import ( "regexp" "testing" - "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" + "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/acctest_helper" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -22,9 +22,9 @@ func TestAccDbtCloudWebhookResource(t *testing.T) { projectName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDbtCloudWebhookDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckDbtCloudWebhookDestroy, Steps: []resource.TestStep{ { Config: testAccDbtCloudWebhookResourceBasicConfig(webhookName, projectName), @@ -175,10 +175,13 @@ func testAccCheckDbtCloudWebhookExists(resource string) resource.TestCheckFunc { if rs.Primary.ID == "" { return fmt.Errorf("No Record ID is set") } - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } webhookID := rs.Primary.ID - _, err := apiClient.GetWebhook(webhookID) + _, err = apiClient.GetWebhook(webhookID) if err != nil { return fmt.Errorf("error fetching item with resource %s. %s", resource, err) } @@ -187,7 +190,10 @@ func testAccCheckDbtCloudWebhookExists(resource string) resource.TestCheckFunc { } func testAccCheckDbtCloudWebhookDestroy(s *terraform.State) error { - apiClient := testAccProvider.Meta().(*dbt_cloud.Client) + apiClient, err := acctest_helper.SharedClient() + if err != nil { + return fmt.Errorf("Issue getting the client") + } for _, rs := range s.RootModule().Resources { if rs.Type != "dbtcloud_webhook" { From 28e8ddc71c0ca1ff1dbdfac0c370c802bbea9019 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 5 Jun 2024 11:36:48 +0200 Subject: [PATCH 15/15] Update Changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bb219bd..329cf6c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. ### Changes -- [#232](https://github.com/dbt-labs/terraform-provider-dbtcloud/issues/232) Add env level permissions for `dbtcloud_group` and `dbtcloud_group_partial_permissions`. As of June 5 this feature is not yet active for all customers. +- [#266](https://github.com/dbt-labs/terraform-provider-dbtcloud/issues/266) Add env level permissions for `dbtcloud_group` and `dbtcloud_group_partial_permissions`. As of June 5 this feature is not yet active for all customers. ### Docs @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. - Move the `dbcloud_group` resource and datasource from the SDKv2 to the Framework - Create new helpers for comparing Go structs +- Update all SDKv2 tests to run on the muxed provider to work when some resources have moved to the Plugin Framework ## [0.3.6](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.5...v0.3.6)