Skip to content

Commit 509ebe9

Browse files
pieternclaude
andauthored
Map postgres autoscaling fields to float64 in bundle TF schema (#4398)
## Changes Added allowlist to Terraform schema generator to emit `float64` for postgres autoscaling fields. All other number fields remain `int`. Note: Other fields (cluster_cores, spot_bid_max_price, etc.) also need float64 but are deferred to handle postgres resources first. These are not implemented yet so changing them doesn't impact anything. ## Why Postgres autoscaling supports fractional CU values (e.g., 0.5). The previous implementation mapped all `cty.Number` to `int`, truncating fractional values and mismatching databricks-sdk-go types. ## Tests Verified postgres autoscaling fields are `float64` and other number fields remain `int`. --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent bccc9e5 commit 509ebe9

File tree

8 files changed

+91
-34
lines changed

8 files changed

+91
-34
lines changed

bundle/internal/tf/codegen/generator/named_block.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func (b *namedBlock) camelName() string {
4343
}
4444

4545
func (b *namedBlock) Generate(path string) error {
46-
w, err := walk(b.block, []string{b.typeNamePrefix, b.camelName()})
46+
w, err := walk(b.block, []string{b.typeNamePrefix, b.camelName()}, b.name)
4747
if err != nil {
4848
return err
4949
}

bundle/internal/tf/codegen/generator/walker.go

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,59 @@ type structType struct {
2525
// represent a [tfjson.SchemaBlock] as Go structs.
2626
// See the [walk] function for usage.
2727
type walker struct {
28-
StructTypes []structType
28+
StructTypes []structType
29+
resourceName string // The Terraform resource name (e.g., "databricks_postgres_endpoint")
2930
}
3031

31-
func processAttributeType(typ cty.Type) string {
32+
// floatAttributePaths is an allowlist of attribute paths (resource_name.field_path)
33+
// that should be mapped to float64 instead of int for cty.Number types.
34+
// Generated from Terraform provider schema based on databricks-sdk-go types.
35+
var floatAttributePaths = map[string]bool{
36+
// Postgres Service - autoscaling compute units support fractional values (e.g., 0.5 CU)
37+
"databricks_postgres_endpoint.spec.autoscaling_limit_max_cu": true,
38+
"databricks_postgres_endpoint.spec.autoscaling_limit_min_cu": true,
39+
"databricks_postgres_endpoint.status.autoscaling_limit_max_cu": true,
40+
"databricks_postgres_endpoint.status.autoscaling_limit_min_cu": true,
41+
"databricks_postgres_endpoints.endpoints.spec.autoscaling_limit_max_cu": true,
42+
"databricks_postgres_endpoints.endpoints.spec.autoscaling_limit_min_cu": true,
43+
"databricks_postgres_endpoints.endpoints.status.autoscaling_limit_max_cu": true,
44+
"databricks_postgres_endpoints.endpoints.status.autoscaling_limit_min_cu": true,
45+
"databricks_postgres_project.spec.default_endpoint_settings.autoscaling_limit_max_cu": true,
46+
"databricks_postgres_project.spec.default_endpoint_settings.autoscaling_limit_min_cu": true,
47+
"databricks_postgres_project.status.default_endpoint_settings.autoscaling_limit_max_cu": true,
48+
"databricks_postgres_project.status.default_endpoint_settings.autoscaling_limit_min_cu": true,
49+
"databricks_postgres_projects.projects.spec.default_endpoint_settings.autoscaling_limit_max_cu": true,
50+
"databricks_postgres_projects.projects.spec.default_endpoint_settings.autoscaling_limit_min_cu": true,
51+
"databricks_postgres_projects.projects.status.default_endpoint_settings.autoscaling_limit_max_cu": true,
52+
"databricks_postgres_projects.projects.status.default_endpoint_settings.autoscaling_limit_min_cu": true,
53+
}
54+
55+
// buildAttributePath constructs the attribute path from the type name path.
56+
// For example: ["Resource", "PostgresEndpoint", "Spec"] + "autoscaling_limit_min_cu" -> "spec.autoscaling_limit_min_cu"
57+
func buildAttributePath(name []string, fieldName string) string {
58+
// Skip the type prefix (Resource/DataSource) and resource name (first 2 elements)
59+
// and convert remaining CamelCase to snake_case
60+
var parts []string
61+
for i := 2; i < len(name); i++ {
62+
parts = append(parts, toSnakeCase(name[i]))
63+
}
64+
parts = append(parts, fieldName)
65+
return strings.Join(parts, ".")
66+
}
67+
68+
// toSnakeCase converts CamelCase to snake_case
69+
func toSnakeCase(s string) string {
70+
var result strings.Builder
71+
for i, r := range s {
72+
if i > 0 && 'A' <= r && r <= 'Z' {
73+
result.WriteRune('_')
74+
}
75+
result.WriteRune(r)
76+
}
77+
return strings.ToLower(result.String())
78+
}
79+
80+
func processAttributeType(typ cty.Type, resourceName, attributePath string) string {
3281
var out string
3382

3483
switch {
@@ -37,18 +86,24 @@ func processAttributeType(typ cty.Type) string {
3786
case typ.Equals(cty.Bool):
3887
out = "bool"
3988
case typ.Equals(cty.Number):
40-
out = "int"
89+
// Check if this resource + attribute path should be float64
90+
fullPath := resourceName + "." + attributePath
91+
if floatAttributePaths[fullPath] {
92+
out = "float64"
93+
} else {
94+
out = "int"
95+
}
4196
case typ.Equals(cty.String):
4297
out = "string"
4398
default:
4499
panic("No idea what to do for: " + typ.FriendlyName())
45100
}
46101
case typ.IsMapType():
47-
out = "map[string]" + processAttributeType(*typ.MapElementType())
102+
out = "map[string]" + processAttributeType(*typ.MapElementType(), resourceName, attributePath)
48103
case typ.IsSetType():
49-
out = "[]" + processAttributeType(*typ.SetElementType())
104+
out = "[]" + processAttributeType(*typ.SetElementType(), resourceName, attributePath)
50105
case typ.IsListType():
51-
out = "[]" + processAttributeType(*typ.ListElementType())
106+
out = "[]" + processAttributeType(*typ.ListElementType(), resourceName, attributePath)
52107
case typ.IsObjectType():
53108
out = "any"
54109
default:
@@ -129,7 +184,8 @@ func (w *walker) walk(block *tfjson.SchemaBlock, name []string) error {
129184

130185
// Collect field properties.
131186
fieldName := strcase.ToCamel(k)
132-
fieldType := processAttributeType(v.AttributeType)
187+
attributePath := buildAttributePath(name, k)
188+
fieldType := processAttributeType(v.AttributeType, w.resourceName, attributePath)
133189
fieldTag := k
134190
if v.Required && v.Optional {
135191
return fmt.Errorf("both required and optional are set for attribute %s", k)
@@ -160,8 +216,9 @@ func (w *walker) walk(block *tfjson.SchemaBlock, name []string) error {
160216

161217
// walk recursively traverses [tfjson.SchemaBlock] and returns the
162218
// set of types to declare to represents it as Go structs.
163-
func walk(block *tfjson.SchemaBlock, name []string) (*walker, error) {
164-
w := &walker{}
219+
// The resourceName parameter is the Terraform resource name (e.g., "databricks_postgres_endpoint").
220+
func walk(block *tfjson.SchemaBlock, name []string, resourceName string) (*walker, error) {
221+
w := &walker{resourceName: resourceName}
165222
err := w.walk(block, name)
166223
return w, err
167224
}

bundle/internal/tf/schema/data_source_postgres_endpoint.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/internal/tf/schema/data_source_postgres_endpoints.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/internal/tf/schema/data_source_postgres_project.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/internal/tf/schema/data_source_postgres_projects.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/internal/tf/schema/resource_postgres_endpoint.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/internal/tf/schema/resource_postgres_project.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)