Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.3.6 #260

Merged
merged 5 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@

All notable changes to this project will be documented in this file.

## [Unreleased](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.5...HEAD)
## [Unreleased](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.6...HEAD)

## [0.3.6](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.5...v0.3.6)

### Changes

- [#232](https://github.com/dbt-labs/terraform-provider-dbtcloud/issues/232) add deprecation notice for `dbtcloud_project_artefacts` as the resource is not required now that dbt Explorer is GA.
- [#208](https://github.com/dbt-labs/terraform-provider-dbtcloud/issues/208) add new `dbtcloud_partial_license_map` for defining SSO group mapping to license types from different Terraform projects/resources

## [0.3.5](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.4...v0.3.5)

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/job.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ resource "dbtcloud_job" "downstream_job" {
- `deferring_job_id` (Number) Job identifier that this job defers to (legacy deferring approach)
- `description` (String) Description for the job
- `generate_docs` (Boolean) Flag for whether the job should generate documentation
- `is_active` (Boolean) Flag for whether the job is marked active or deleted. To create/keep a job in a 'deactivated' state, check the `triggers` config.
- `is_active` (Boolean) Should always be set to true as setting it to false is the same as creating a job in a deleted state. To create/keep a job in a 'deactivated' state, check the `triggers` config.
- `job_completion_trigger_condition` (Block Set, Max: 1) Which other job should trigger this job when it finishes, and on which conditions (sometimes referred as 'job chaining'). (see [below for nested schema](#nestedblock--job_completion_trigger_condition))
- `num_threads` (Number) Number of threads to use in the job
- `run_generate_sources` (Boolean) Flag for whether the job should add a `dbt source freshness` step to the job. The difference between manually adding a step with `dbt source freshness` in the job steps or using this flag is that with this flag, a failed freshness will still allow the following steps to run.
Expand Down
54 changes: 54 additions & 0 deletions docs/resources/partial_license_map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
page_title: "dbtcloud_partial_license_map Resource - dbtcloud"
subcategory: ""
description: |-
Set up partial license maps with only a subset of SSO groups for a given license type.
This resource is different from dbtcloud_license_map as it allows having different resources setting up different groups for the same license type.
If a company uses only one Terraform project/workspace to manage all their dbt Cloud Account config, it is recommended to use dbt_cloud_license_map instead of dbt_cloud_group_partial_license_map.
~> This is a new resource like other "partial" ones and any feedback is welcome in the GitHub repository.
---

# dbtcloud_partial_license_map (Resource)


Set up partial license maps with only a subset of SSO groups for a given license type.

This resource is different from `dbtcloud_license_map` as it allows having different resources setting up different groups for the same license type.

If a company uses only one Terraform project/workspace to manage all their dbt Cloud Account config, it is recommended to use `dbt_cloud_license_map` instead of `dbt_cloud_group_partial_license_map`.

~> This is a new resource like other "partial" ones and any feedback is welcome in the GitHub repository.

## Example Usage

```terraform
# Developer license group mapping
resource "dbtcloud_partial_license_map" "dev_license_map" {
license_type = "developer"
sso_license_mapping_groups = ["DEV-SSO-GROUP"]
}

# Read-only license mapping
resource "dbtcloud_partial_license_map" "read_only_license_map" {
license_type = "read_only"
sso_license_mapping_groups = ["READ-ONLY-SSO-GROUP"]
}

# IT license mapping
resource "dbtcloud_partial_license_map" "it_license_map" {
license_type = "it"
sso_license_mapping_groups = ["IT-SSO-GROUP"]
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `license_type` (String) The license type to update
- `sso_license_mapping_groups` (Set of String) List of SSO groups to map to the license type.

### Read-Only

- `id` (Number) The ID of the notification
4 changes: 2 additions & 2 deletions docs/resources/project_artefacts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
page_title: "dbtcloud_project_artefacts Resource - dbtcloud"
subcategory: ""
description: |-

[Deprecated] Resource for mentioning what jobs are the source of truth for the legacy dbt Docs and dbt Source Freshness pages. dbt Explorer doesn't require this config anymore.
---

# dbtcloud_project_artefacts (Resource)



[Deprecated] Resource for mentioning what jobs are the source of truth for the legacy dbt Docs and dbt Source Freshness pages. dbt Explorer doesn't require this config anymore.

## Example Usage

Expand Down
17 changes: 17 additions & 0 deletions examples/resources/dbtcloud_partial_license_map/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Developer license group mapping
resource "dbtcloud_partial_license_map" "dev_license_map" {
license_type = "developer"
sso_license_mapping_groups = ["DEV-SSO-GROUP"]
}

# Read-only license mapping
resource "dbtcloud_partial_license_map" "read_only_license_map" {
license_type = "read_only"
sso_license_mapping_groups = ["READ-ONLY-SSO-GROUP"]
}

# IT license mapping
resource "dbtcloud_partial_license_map" "it_license_map" {
license_type = "it"
sso_license_mapping_groups = ["IT-SSO-GROUP"]
}
2 changes: 1 addition & 1 deletion pkg/dbt_cloud/bigquery_credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (c *Client) CreateBigQueryCredential(
Account_Id: c.AccountID,
Project_Id: projectId,
Type: type_,
State: STATE_ACTIVE, // TODO: make variable
State: STATE_ACTIVE,
Dataset: dataset,
Threads: numThreads,
}
Expand Down
47 changes: 40 additions & 7 deletions pkg/dbt_cloud/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,16 @@ type GroupPermissionListResponse struct {
}

func (c *Client) GetGroup(groupID int) (*Group, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/v3/accounts/%s/groups/%s/", c.HostURL, strconv.Itoa(c.AccountID), strconv.Itoa(groupID)), nil)
req, err := http.NewRequest(
"GET",
fmt.Sprintf(
"%s/v3/accounts/%s/groups/%s/",
c.HostURL,
strconv.Itoa(c.AccountID),
strconv.Itoa(groupID),
),
nil,
)
if err != nil {
return nil, err
}
Expand All @@ -59,20 +68,28 @@ func (c *Client) GetGroup(groupID int) (*Group, error) {
return &groupResponse.Data, nil
}

func (c *Client) CreateGroup(name string, assignByDefault bool, ssoMappingGroups []string) (*Group, error) {
func (c *Client) CreateGroup(
name string,
assignByDefault bool,
ssoMappingGroups []string,
) (*Group, error) {
newGroup := Group{
AccountID: c.AccountID,
Name: name,
AssignByDefault: assignByDefault,
SSOMappingGroups: ssoMappingGroups,
State: STATE_ACTIVE, // TODO: make variable
State: STATE_ACTIVE,
}
newGroupData, err := json.Marshal(newGroup)
if err != nil {
return nil, err
}

req, err := http.NewRequest("POST", fmt.Sprintf("%s/v3/accounts/%d/groups/", c.HostURL, c.AccountID), strings.NewReader(string(newGroupData)))
req, err := http.NewRequest(
"POST",
fmt.Sprintf("%s/v3/accounts/%d/groups/", c.HostURL, c.AccountID),
strings.NewReader(string(newGroupData)),
)
if err != nil {
return nil, err
}
Expand All @@ -97,7 +114,11 @@ func (c *Client) UpdateGroup(groupID int, group Group) (*Group, error) {
return nil, err
}

req, err := http.NewRequest("POST", fmt.Sprintf("%s/v3/accounts/%s/groups/%d/", c.HostURL, strconv.Itoa(c.AccountID), groupID), strings.NewReader(string(groupData)))
req, err := http.NewRequest(
"POST",
fmt.Sprintf("%s/v3/accounts/%s/groups/%d/", c.HostURL, strconv.Itoa(c.AccountID), groupID),
strings.NewReader(string(groupData)),
)
if err != nil {
return nil, err
}
Expand All @@ -116,13 +137,25 @@ func (c *Client) UpdateGroup(groupID int, group Group) (*Group, error) {
return &groupResponse.Data, nil
}

func (c *Client) UpdateGroupPermissions(groupID int, groupPermissions []GroupPermission) (*[]GroupPermission, error) {
func (c *Client) UpdateGroupPermissions(
groupID int,
groupPermissions []GroupPermission,
) (*[]GroupPermission, error) {
groupPermissionData, err := json.Marshal(groupPermissions)
if err != nil {
return nil, err
}

req, err := http.NewRequest("POST", fmt.Sprintf("%s/v3/accounts/%s/group-permissions/%d/", c.HostURL, strconv.Itoa(c.AccountID), groupID), strings.NewReader(string(groupPermissionData)))
req, err := http.NewRequest(
"POST",
fmt.Sprintf(
"%s/v3/accounts/%s/group-permissions/%d/",
c.HostURL,
strconv.Itoa(c.AccountID),
groupID,
),
strings.NewReader(string(groupPermissionData)),
)
if err != nil {
return nil, err
}
Expand Down
19 changes: 19 additions & 0 deletions pkg/dbt_cloud/paginate.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,22 @@ func (c *Client) GetAllServiceTokens() ([]ServiceToken, error) {
}
return allServiceTokens, nil
}

func (c *Client) GetAllLicenseMaps() ([]LicenseMap, error) {
url := fmt.Sprintf("%s/v3/accounts/%d/license-maps/", c.HostURL, c.AccountID)

allLicenseMapsRaw := c.GetData(url)

allLicenseMaps := []LicenseMap{}
for _, notification := range allLicenseMapsRaw {

data, _ := json.Marshal(notification)
currentLicenseMap := LicenseMap{}
err := json.Unmarshal(data, &currentLicenseMap)
if err != nil {
return nil, err
}
allLicenseMaps = append(allLicenseMaps, currentLicenseMap)
}
return allLicenseMaps, nil
}
71 changes: 63 additions & 8 deletions pkg/dbt_cloud/postgres_credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,21 @@ type PostgresCredentialResponse struct {
}

// GetPostgresCredential retrieves a specific Postgres credential by its ID
func (c *Client) GetPostgresCredential(projectId int, credentialId int) (*PostgresCredential, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/v3/accounts/%d/projects/%d/credentials/%d/", c.HostURL, c.AccountID, projectId, credentialId), nil)
func (c *Client) GetPostgresCredential(
projectId int,
credentialId int,
) (*PostgresCredential, error) {
req, err := http.NewRequest(
"GET",
fmt.Sprintf(
"%s/v3/accounts/%d/projects/%d/credentials/%d/",
c.HostURL,
c.AccountID,
projectId,
credentialId,
),
nil,
)
if err != nil {
return nil, err
}
Expand All @@ -47,12 +60,21 @@ func (c *Client) GetPostgresCredential(projectId int, credentialId int) (*Postgr
}

// CreatePostgresCredential creates a new Postgres credential
func (c *Client) CreatePostgresCredential(projectId int, isActive bool, type_ string, defaultSchema string, targetName string, username string, password string, numThreads int) (*PostgresCredential, error) {
func (c *Client) CreatePostgresCredential(
projectId int,
isActive bool,
type_ string,
defaultSchema string,
targetName string,
username string,
password string,
numThreads int,
) (*PostgresCredential, error) {
newPostgresCredential := PostgresCredential{
Account_Id: c.AccountID,
Project_Id: projectId,
Type: type_,
State: STATE_ACTIVE, // TODO: make variable
State: STATE_ACTIVE,
Threads: numThreads,
Username: username,
Default_Schema: defaultSchema,
Expand All @@ -64,7 +86,16 @@ func (c *Client) CreatePostgresCredential(projectId int, isActive bool, type_ st
return nil, err
}

req, err := http.NewRequest("POST", fmt.Sprintf("%s/v3/accounts/%d/projects/%d/credentials/", c.HostURL, c.AccountID, projectId), strings.NewReader(string(newPostgresCredentialData)))
req, err := http.NewRequest(
"POST",
fmt.Sprintf(
"%s/v3/accounts/%d/projects/%d/credentials/",
c.HostURL,
c.AccountID,
projectId,
),
strings.NewReader(string(newPostgresCredentialData)),
)
if err != nil {
return nil, err
}
Expand All @@ -84,13 +115,27 @@ func (c *Client) CreatePostgresCredential(projectId int, isActive bool, type_ st
}

// UpdatePostgresCredential updates an existing Postgres credential
func (c *Client) UpdatePostgresCredential(projectId int, credentialId int, postgresCredential PostgresCredential) (*PostgresCredential, error) {
func (c *Client) UpdatePostgresCredential(
projectId int,
credentialId int,
postgresCredential PostgresCredential,
) (*PostgresCredential, error) {
postgresCredentialData, err := json.Marshal(postgresCredential)
if err != nil {
return nil, err
}

req, err := http.NewRequest("POST", fmt.Sprintf("%s/v3/accounts/%d/projects/%d/credentials/%d/", c.HostURL, c.AccountID, projectId, credentialId), strings.NewReader(string(postgresCredentialData)))
req, err := http.NewRequest(
"POST",
fmt.Sprintf(
"%s/v3/accounts/%d/projects/%d/credentials/%d/",
c.HostURL,
c.AccountID,
projectId,
credentialId,
),
strings.NewReader(string(postgresCredentialData)),
)
if err != nil {
return nil, err
}
Expand All @@ -111,7 +156,17 @@ func (c *Client) UpdatePostgresCredential(projectId int, credentialId int, postg

// DeletePostgresCredential deletes a Postgres credential by its ID
func (c *Client) DeletePostgresCredential(credentialId, projectId string) (string, error) {
req, err := http.NewRequest("DELETE", fmt.Sprintf("%s/v3/accounts/%d/projects/%s/credentials/%s/", c.HostURL, c.AccountID, projectId, credentialId), nil)
req, err := http.NewRequest(
"DELETE",
fmt.Sprintf(
"%s/v3/accounts/%d/projects/%s/credentials/%s/",
c.HostURL,
c.AccountID,
projectId,
credentialId,
),
nil,
)
if err != nil {
return "", err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/dbt_cloud/snowflake_credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (c *Client) CreateSnowflakeCredential(
Account_Id: c.AccountID,
Project_Id: projectId,
Type: type_,
State: STATE_ACTIVE, // TODO: make variable
State: STATE_ACTIVE,
Database: database,
Role: role,
Warehouse: warehouse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,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 in the Framework
// TODO: Move this to the group resources once the resource is move to the Framework

group, err := r.client.CreateGroup(name, assignByDefault, ssoMappingGroups)
if err != nil {
Expand Down
20 changes: 20 additions & 0 deletions pkg/framework/objects/partial_license_map/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package partial_license_map

import (
"github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud"
"github.com/hashicorp/terraform-plugin-framework/types"
)

// TODO: Move the model to the non partial when moved to the Framework
type LicenseMapResourceModel struct {
ID types.Int64 `tfsdk:"id"`
LicenseType types.String `tfsdk:"license_type"`
SSOLicenseMappingGroups types.Set `tfsdk:"sso_license_mapping_groups"`
}

func matchPartial(
licenseMapModel LicenseMapResourceModel,
licenseTypeResponse dbt_cloud.LicenseMap,
) bool {
return licenseMapModel.LicenseType == types.StringValue(licenseTypeResponse.LicenseType)
}
Loading
Loading