-
Notifications
You must be signed in to change notification settings - Fork 386
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
Migrate SQL Warehouse to Go SDK #3044
Conversation
# Conflicts: # Makefile # scripts/diff-schema.sh
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #3044 +/- ##
==========================================
- Coverage 84.55% 84.21% -0.35%
==========================================
Files 161 161
Lines 14187 14260 +73
==========================================
+ Hits 11996 12009 +13
- Misses 1508 1559 +51
- Partials 683 692 +9
|
common/reflect_resource.go
Outdated
@@ -175,26 +191,52 @@ func diffSuppressor(zero string) func(k, old, new string, d *schema.ResourceData | |||
log.Printf("[DEBUG] Suppressing diff for %v: platform=%#v config=%#v", k, old, new) | |||
return true | |||
} | |||
if strings.HasSuffix(".#", k) && new == "0" && old != "0" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lists and sets are compared first for size, which end with .#
and the values provided are the sizes of the list/set as a string. If the API returned a non-nil value like {}
, the resulting state will have an entry (e.g. for SQL Warehouses, it will be a [{"custom_tags": []}]. The "new" config will be completely empty because it is not defined in the resource itself.
if err != nil { | ||
return err | ||
} | ||
name_contains := (*data).WarehouseNameContains | ||
for _, e := range list.Endpoints { | ||
for _, e := range list { | ||
match_name := strings.Contains(strings.ToLower(e.Name), name_contains) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I was just preserving the existing behavior. Can we make any changes as a follow-up?
common/resource.go
Outdated
}, false) | ||
} | ||
|
||
func WorkspaceData2[SdkType, OtherType any](read func(context.Context, OtherType, *SdkType, *databricks.WorkspaceClient) error) *schema.Resource { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this name is not very good. I was planning on revisiting this & adding the account-level version in this PR as well.
@@ -214,33 +85,58 @@ func ResourceSqlEndpoint() *schema.Resource { | |||
Create: schema.DefaultTimeout(30 * time.Minute), | |||
}, | |||
Create: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error { | |||
var se SQLEndpoint | |||
common.DataToStructPointer(d, s, &se) | |||
if err := NewSQLEndpointsAPI(ctx, c).Create(&se, d.Timeout(schema.TimeoutCreate)); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the context itself has a timeout. https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts#default-timeouts-and-deadline-exceeded-errors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Halfway through reviewing, need a bit more time understanding context on the WorkspaceData and AccountData
@@ -260,7 +317,7 @@ func typeToSchema(v reflect.Value, t reflect.Type, path []string) map[string]*sc | |||
scm[fieldName].Type = schema.TypeList | |||
elem := typeField.Type.Elem() | |||
sv := reflect.New(elem).Elem() | |||
nestedSchema := typeToSchema(sv, elem, append(path, fieldName, "0")) | |||
nestedSchema := typeToSchema(sv, append(path, fieldName, "0")) | |||
if strings.Contains(tfTag, "suppress_diff") { | |||
blockCount := strings.Join(append(path, fieldName, "#"), ".") | |||
scm[fieldName].DiffSuppressFunc = makeEmptyBlockSuppressFunc(blockCount) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the new suffix checking in diffSuppressor
, can we replace makeEmptyBlockSuppressFunc
calls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can do this as a separate PR?
m map[string]*schema.Schema) map[string]*schema.Schema { | ||
m["id"].Computed = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use common.SetReadOnly
for this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in general, looks good for me from the first pass...
common/reflect_resource.go
Outdated
|
||
func listAllFields(v reflect.Value) []field { | ||
t := v.Type() | ||
fields := make([]field, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about doing
fields := make([]field, 0, v.NumField())
to avoid reallocations?
common/resource.go
Outdated
// } | ||
// | ||
// WorkspaceDataWithParams( | ||
// func(ctx context.Context, data SqlWarehouseDataParams, w *databricks.WorkspaceClient) (*Warehouse, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*Warehouse
should be *SqlWarehouse
?
@@ -313,7 +314,7 @@ var emptyWorkspace = qa.HTTPFixture{ | |||
|
|||
var emptySqlEndpoints = qa.HTTPFixture{ | |||
Method: "GET", | |||
Resource: "/api/2.0/sql/warehouses", | |||
Resource: "/api/2.0/sql/warehouses?", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we fix SDK to not to add ?
if there are no parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could. Let's talk online about testing for TF, we just added some testing interfaces which should hide the network layer from you (if you want). Take a look at databricks/databricks-sdk-go@b3cdc97 for the change. That would allow you to mock the responses from Databricks more easily.
m["cluster_size"].ValidateDiagFunc = validation.ToDiagFunc( | ||
validation.StringInSlice(ClusterSizes, false)) | ||
common.SetDefault(m["enable_photon"], true) | ||
common.SetSuppressDiff(m["enable_serverless_compute"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we try to handle force send fields here for serverless & photon?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to do that in a follow-up PR, in case that change causes issues and we need to revert.
common/reflect_resource_test.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mgyucht I think that we need to add at least two new test cases:
- For inherited structure - so we can see that it's flattened correctly into schema
- For a structure with a field from Go SDK
Changes
This PR migrates the SQL Warehouse resource to the Go SDK. It also modifies all tests that used the original API client, which means appending
?
to resource URIs in fixtures.To do this, some changes to supporting code are also made:
common
to simplify customizing schemas computed by StructToSchema for several common cases:SetSuppressDiff
: sets a diff suppressor on the field so that fields not populated by the user in their configuration are not treated as a diff, even if the API returned some value for that field.SetDefault
: marks a schema as optional and sets a default value for it.SetReadOnly
: marks a schema as not configurable by users but that can be referenced in Terraform.new
is"0"
(not in config) andold
is not"0"
(state captured something).StructToSchema
on structs likeThe fields of the embedded field are expanded into the schema. This way, maintainers can reuse the Go type as-is without having to copy all of its fields into a new structure.
collectionToMaps
that assumed that a data structure is a list iffMaxItems
is 1.MaxItems
can't be set on read-only fields. This now checks the underlying type is a slice or array.WorkspaceDataWithCustomAttrs
andAccountDataWithCustomAttrs
. These functions are similar toWorkspaceData
andAccountData
except that they permit two type parameters. The first corresponds to the type used for the resource, ensuring that the schema of the data source and that of the resource are identical. The second corresponds to any additional data that a user might specify in the data source.Side note: we should probably look into changing suppress diff from being a schema-level configuration to actually adjusting the returned value from the
Read
method. Otherwise, if the only change made by a user is e.g. to remove all tags, that won't show up as a diff.Tests
make test
run locallydocs/
folderinternal/acceptance