Skip to content

Use the Go SDK for databricks_mws_workspaces #4633

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

Merged
merged 18 commits into from
Apr 14, 2025
2 changes: 2 additions & 0 deletions NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@
### Exporter

### Internal Changes

* Refactor `databricks_mws_workspaces` resource and datasource, as well as `databricks_mws_ncc_binding`, to use the Go SDK ([#4633](https://github.com/databricks/terraform-provider-databricks/pull/4633)).
59 changes: 56 additions & 3 deletions common/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

98 changes: 98 additions & 0 deletions common/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@ package common

import (
"context"
"fmt"
"log"
"net/http"
"path/filepath"
"strings"
"testing"

"github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/client"
"github.com/databricks/databricks-sdk-go/config"
"github.com/databricks/databricks-sdk-go/experimental/mocks"
"github.com/databricks/databricks-sdk-go/service/iam"
"github.com/databricks/databricks-sdk-go/service/provisioning"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -335,3 +340,96 @@ func TestCachedMe_Me_MakesSingleRequest(t *testing.T) {
cm.Me(context.Background())
assert.Equal(t, 1, mock.count)
}

func TestWorkspaceClientForWorkspace_WorkspaceDoesNotExist(t *testing.T) {
mockAcc := mocks.NewMockAccountClient(t)
mockWorkspacesAPI := mockAcc.GetMockWorkspacesAPI()

// Setup the mock to return an error for non-existent workspace
mockWorkspacesAPI.EXPECT().Get(mock.Anything, provisioning.GetWorkspaceRequest{
WorkspaceId: 12345,
}).Return(nil, fmt.Errorf("workspace not found"))

// Create a DatabricksClient with the mock account client
dc := &DatabricksClient{
DatabricksClient: &client.DatabricksClient{
Config: &config.Config{},
},
}
dc.SetAccountClient(mockAcc.AccountClient)

// Call the method with a non-existent workspace ID
_, err := dc.WorkspaceClientForWorkspace(context.Background(), 12345)

// Verify the error
assert.Error(t, err)
assert.Contains(t, err.Error(), "workspace not found")
}

func TestWorkspaceClientForWorkspace_WorkspaceExistsNotInCache(t *testing.T) {
mockAcc := mocks.NewMockAccountClient(t)
mockAcc.AccountClient.Config = &config.Config{
Token: "dapi123", // Instantiating WorkspaceClient attempts authentication, this allows Configure() to complete quickly.
}
mockWorkspacesAPI := mockAcc.GetMockWorkspacesAPI()

// Create a mock workspace
mockWorkspace := &provisioning.Workspace{
WorkspaceId: 12345,
WorkspaceName: "test-workspace",
DeploymentName: "test-deployment",
}

// Setup the mock to return the workspace
mockWorkspacesAPI.EXPECT().Get(mock.Anything, provisioning.GetWorkspaceRequest{
WorkspaceId: 12345,
}).Return(mockWorkspace, nil)

// Create a DatabricksClient with the mock account client
dc := &DatabricksClient{
DatabricksClient: &client.DatabricksClient{
Config: &config.Config{},
},
}
dc.SetAccountClient(mockAcc.AccountClient)

// Call the method with the workspace ID
workspaceClient, err := dc.WorkspaceClientForWorkspace(context.Background(), 12345)

// Verify no error and client is returned
assert.NoError(t, err)
assert.NotNil(t, workspaceClient)

// Verify the workspace client is configured correctly
assert.Equal(t, fmt.Sprintf("https://%s.cloud.databricks.com", mockWorkspace.DeploymentName), workspaceClient.Config.Host)

// Verify the client is cached
dc.mu.Lock()
cachedClient, exists := dc.cachedWorkspaceClients[12345]
dc.mu.Unlock()

assert.True(t, exists)
assert.Equal(t, workspaceClient, cachedClient)
}

func TestWorkspaceClientForWorkspace_WorkspaceExistsInCache(t *testing.T) {
// Create a mock workspace client
mockWorkspaceClient := &databricks.WorkspaceClient{}

// Create a DatabricksClient with the mock workspace client in cache
dc := &DatabricksClient{
DatabricksClient: &client.DatabricksClient{
Config: &config.Config{},
},
}

// Set the workspace client in cache
dc.SetWorkspaceClientForWorkspace(12345, mockWorkspaceClient)

// Call the method with the workspace ID
workspaceClient, err := dc.WorkspaceClientForWorkspace(context.Background(), 12345)

// Verify no error and the cached client is returned
assert.NoError(t, err)
assert.Equal(t, mockWorkspaceClient, workspaceClient)
}
29 changes: 29 additions & 0 deletions internal/acceptance/expect_not_destroyed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package acceptance

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-testing/plancheck"
)

type expectNotDestroyed struct {
addr string
}

func ExpectNotDestroyed(addr string) expectNotDestroyed {
return expectNotDestroyed{addr: addr}
}

func (e expectNotDestroyed) CheckPlan(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) {
for _, resource := range req.Plan.ResourceChanges {
if resource.Address != e.addr {
continue
}
actions := resource.Change.Actions
if actions.DestroyBeforeCreate() || actions.CreateBeforeDestroy() || actions.Delete() {
resp.Error = fmt.Errorf("resource %s is marked for destruction", e.addr)
return
}
}
}
8 changes: 6 additions & 2 deletions mws/data_mws_workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ func DataSourceMwsWorkspaces() common.Resource {
if c.Config.AccountID == "" {
return fmt.Errorf("provider block is missing `account_id` property")
}
workspaces, err := NewWorkspacesAPI(ctx, c).List(c.Config.AccountID)
a, err := c.AccountClient()
if err != nil {
return err
}
workspaces, err := a.Workspaces.List(ctx)
if err != nil {
return err
}
data.Ids = map[string]int64{}
for _, v := range workspaces {
data.Ids[v.WorkspaceName] = v.WorkspaceID
data.Ids[v.WorkspaceName] = v.WorkspaceId
}
return nil
})
Expand Down
44 changes: 20 additions & 24 deletions mws/data_mws_workspaces_test.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
package mws

import (
"errors"
"testing"

"github.com/databricks/databricks-sdk-go/experimental/mocks"
"github.com/databricks/databricks-sdk-go/service/provisioning"
"github.com/databricks/terraform-provider-databricks/qa"
"github.com/stretchr/testify/mock"
)

func TestDataSourceMwsWorkspaces(t *testing.T) {
qa.ResourceFixture{
Fixtures: []qa.HTTPFixture{
{
Method: "GET",
Resource: "/api/2.0/accounts/abc/workspaces",

Response: []Workspace{
{
WorkspaceName: "bcd",
WorkspaceID: 123,
},
{
WorkspaceName: "def",
WorkspaceID: 456,
},
MockAccountClientFunc: func(a *mocks.MockAccountClient) {
a.GetMockWorkspacesAPI().EXPECT().List(mock.Anything).Return([]provisioning.Workspace{
{
WorkspaceName: "bcd",
WorkspaceId: 123,
},
{
WorkspaceName: "def",
WorkspaceId: 456,
},
},
}, nil)
},
AccountID: "abc",
Resource: DataSourceMwsWorkspaces(),
Expand All @@ -38,10 +37,12 @@ func TestDataSourceMwsWorkspaces(t *testing.T) {
})
}

func TestCatalogsData_Error(t *testing.T) {
func TestDataSourceMwsWorkspaces_Error(t *testing.T) {
qa.ResourceFixture{
MockAccountClientFunc: func(a *mocks.MockAccountClient) {
a.GetMockWorkspacesAPI().EXPECT().List(mock.Anything).Return(nil, errors.New("i'm a teapot"))
},
AccountID: "abc",
Fixtures: qa.HTTPFailures,
Resource: DataSourceMwsWorkspaces(),
Read: true,
NonWritable: true,
Expand All @@ -51,13 +52,8 @@ func TestCatalogsData_Error(t *testing.T) {

func TestDataSourceMwsWorkspaces_Empty(t *testing.T) {
qa.ResourceFixture{
Fixtures: []qa.HTTPFixture{
{
Method: "GET",
Resource: "/api/2.0/accounts/abc/workspaces",

Response: []Workspace{},
},
MockAccountClientFunc: func(a *mocks.MockAccountClient) {
a.GetMockWorkspacesAPI().EXPECT().List(mock.Anything).Return([]provisioning.Workspace{}, nil)
},
AccountID: "abc",
Resource: DataSourceMwsWorkspaces(),
Expand Down
Loading