Skip to content

Commit

Permalink
Include data source ID in the endpoint state
Browse files Browse the repository at this point in the history
  • Loading branch information
pietern authored and nfx committed Apr 20, 2021
1 parent 3e02b88 commit 62ca936
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/resources/sql_endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ In addition to all arguments above, the following attributes are exported:

* `jdbc_url` - JDBC connection string.
* `odbc_params` - ODBC connection params: `odbc_params.host`, `odbc_params.path`, `odbc_params.protocol`, and `odbc_params.port`.
* `data_source_id` - ID of the data source for this endpoint. This is used to bind an SQLA query to an endpoint.

## Access Control

Expand Down
41 changes: 41 additions & 0 deletions sqlanalytics/resource_sql_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ type SQLEndpoint struct {
JdbcURL string `json:"jdbc_url,omitempty" tf:"computed"`
OdbcParams *OdbcParams `json:"odbc_params,omitempty" tf:"computed"`
Tags *Tags `json:"tags,omitempty"`

// The data source ID is not part of the endpoint API response.
// We manually resolve it by retrieving the list of data sources
// and matching this entity's endpoint ID.
DataSourceID string `json:"data_source_id,omitempty" tf:"computed"`
}

// OdbcParams ...
Expand All @@ -55,6 +60,16 @@ type Tag struct {
Value string `json:"value"`
}

// DataSource
//
// Note: this object returns more fields than contained in this struct,
// but we only list the ones that are in use here.
//
type DataSource struct {
ID string `json:"id"`
EndpointID string `json:"endpoint_id"`
}

// EndpointList ...
type EndpointList struct {
Endpoints []SQLEndpoint `json:"endpoints"`
Expand Down Expand Up @@ -107,6 +122,28 @@ func (a SQLEndpointsAPI) Create(se *SQLEndpoint, timeout time.Duration) error {
return a.waitForRunning(se.ID, timeout)
}

// ResolveDataSourceID ...
func (a SQLEndpointsAPI) ResolveDataSourceID(endpointID string) (dataSourceID string, err error) {
var dss []DataSource
err = a.client.Get(a.context, "/preview/sql/data_sources", nil, &dss)
if err != nil {
return
}

// Find the data source ID for this endpoint.
for _, ds := range dss {
if ds.EndpointID == endpointID {
dataSourceID = ds.ID
return
}
}

// We assume there is a data source ID for every endpoint.
// It is therefore an error if we can't find it.
err = fmt.Errorf("Unable to find data source ID for endpoint: %v", endpointID)
return
}

func (a SQLEndpointsAPI) waitForRunning(id string, timeout time.Duration) error {
return resource.RetryContext(a.context, timeout, func() *resource.RetryError {
endpoint, err := a.Get(id)
Expand Down Expand Up @@ -167,6 +204,10 @@ func ResourceSQLEndpoint() *schema.Resource {
if err != nil {
return err
}
se.DataSourceID, err = endpointsAPI.ResolveDataSourceID(d.Id())
if err != nil {
return err
}
return common.StructToData(se, s, d)
},
Update: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {
Expand Down
27 changes: 27 additions & 0 deletions sqlanalytics/resource_sql_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sqlanalytics

import (
"context"
"encoding/json"
"os"
"testing"
"time"
Expand Down Expand Up @@ -44,6 +45,26 @@ func TestPreviewAccSQLEndpoints(t *testing.T) {
require.NoError(t, err)
}

// Define fixture for retrieving all data sources.
// Shared between tests that end up performing a read operation.
var dataSourceListHTTPFixture = qa.HTTPFixture{
Method: "GET",
Resource: "/api/2.0/preview/sql/data_sources",
ReuseRequest: true,
Response: json.RawMessage(`
[
{
"id": "2f47f0f9-b4b7-40e2-b130-43103151864c",
"endpoint_id": "def"
},
{
"id": "d7c9d05c-7496-4c69-b089-48823edad40c",
"endpoint_id": "abc"
}
]
`),
}

func TestResourceSQLEndpointCreate(t *testing.T) {
d, err := qa.ResourceFixture{
Fixtures: []qa.HTTPFixture{
Expand Down Expand Up @@ -71,6 +92,7 @@ func TestResourceSQLEndpointCreate(t *testing.T) {
MaxNumClusters: 1,
},
},
dataSourceListHTTPFixture,
},
Resource: ResourceSQLEndpoint(),
Create: true,
Expand All @@ -81,6 +103,7 @@ func TestResourceSQLEndpointCreate(t *testing.T) {
}.Apply(t)
require.NoError(t, err, err)
assert.Equal(t, "abc", d.Id(), "Id should not be empty")
assert.Equal(t, "d7c9d05c-7496-4c69-b089-48823edad40c", d.Get("data_source_id"))
}

func TestResourceSQLEndpointCreate_ErrorDisabled(t *testing.T) {
Expand Down Expand Up @@ -124,6 +147,7 @@ func TestResourceSQLEndpointRead(t *testing.T) {
State: "RUNNING",
},
},
dataSourceListHTTPFixture,
},
Resource: ResourceSQLEndpoint(),
ID: "abc",
Expand All @@ -135,6 +159,7 @@ func TestResourceSQLEndpointRead(t *testing.T) {
}.Apply(t)
require.NoError(t, err, err)
assert.Equal(t, "abc", d.Id(), "Id should not be empty")
assert.Equal(t, "d7c9d05c-7496-4c69-b089-48823edad40c", d.Get("data_source_id"))
}

func TestResourceSQLEndpointUpdate(t *testing.T) {
Expand All @@ -161,6 +186,7 @@ func TestResourceSQLEndpointUpdate(t *testing.T) {
State: "RUNNING",
},
},
dataSourceListHTTPFixture,
},
Resource: ResourceSQLEndpoint(),
ID: "abc",
Expand All @@ -172,6 +198,7 @@ func TestResourceSQLEndpointUpdate(t *testing.T) {
}.Apply(t)
require.NoError(t, err, err)
assert.Equal(t, "abc", d.Id(), "Id should not be empty")
assert.Equal(t, "d7c9d05c-7496-4c69-b089-48823edad40c", d.Get("data_source_id"))
}

func TestResourceSQLEndpointDelete(t *testing.T) {
Expand Down

0 comments on commit 62ca936

Please sign in to comment.