Skip to content

Commit a285f58

Browse files
Jobs GoSDK schema migration (#3532)
* update * update * address comments
1 parent c71f798 commit a285f58

File tree

5 files changed

+315
-126
lines changed

5 files changed

+315
-126
lines changed

clusters/resource_cluster.go

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,34 @@ type ClusterSpec struct {
163163
Libraries []compute.Library `json:"libraries,omitempty" tf:"slice_set,alias:library"`
164164
}
165165

166+
func (ClusterSpec) CustomizeSchemaResourceSpecific(s *common.CustomizableSchema) *common.CustomizableSchema {
167+
s.SchemaPath("autotermination_minutes").SetDefault(60)
168+
s.AddNewField("default_tags", &schema.Schema{
169+
Type: schema.TypeMap,
170+
Computed: true,
171+
})
172+
s.AddNewField("is_pinned", &schema.Schema{
173+
Type: schema.TypeBool,
174+
Optional: true,
175+
Default: false,
176+
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
177+
if old == "" && new == "false" {
178+
return true
179+
}
180+
return old == new
181+
},
182+
})
183+
s.AddNewField("state", &schema.Schema{
184+
Type: schema.TypeString,
185+
Computed: true,
186+
})
187+
s.AddNewField("url", &schema.Schema{
188+
Type: schema.TypeString,
189+
Computed: true,
190+
})
191+
return s
192+
}
193+
166194
func (ClusterSpec) CustomizeSchema(s *common.CustomizableSchema) *common.CustomizableSchema {
167195
s.SchemaPath("cluster_source").SetReadOnly()
168196
s.SchemaPath("enable_elastic_disk").SetComputed()
@@ -198,7 +226,6 @@ func (ClusterSpec) CustomizeSchema(s *common.CustomizableSchema) *common.Customi
198226
s.SchemaPath("aws_attributes", "zone_id").SetCustomSuppressDiff(ZoneDiffSuppress)
199227
s.SchemaPath("azure_attributes").SetSuppressDiff().SetConflictsWith([]string{"aws_attributes", "gcp_attributes"})
200228
s.SchemaPath("gcp_attributes").SetSuppressDiff().SetConflictsWith([]string{"aws_attributes", "azure_attributes"})
201-
s.SchemaPath("autotermination_minutes").SetDefault(60)
202229
s.SchemaPath("autoscale", "max_workers").SetOptional()
203230
s.SchemaPath("autoscale", "min_workers").SetOptional()
204231
s.SchemaPath("cluster_log_conf", "dbfs", "destination").SetRequired()
@@ -208,31 +235,8 @@ func (ClusterSpec) CustomizeSchema(s *common.CustomizableSchema) *common.Customi
208235
Type: schema.TypeString,
209236
Computed: true,
210237
})
211-
s.AddNewField("default_tags", &schema.Schema{
212-
Type: schema.TypeMap,
213-
Computed: true,
214-
})
215-
s.AddNewField("state", &schema.Schema{
216-
Type: schema.TypeString,
217-
Computed: true,
218-
})
219238
s.SchemaPath("instance_pool_id").SetConflictsWith([]string{"driver_node_type_id", "node_type_id"})
220239
s.SchemaPath("runtime_engine").SetValidateFunc(validation.StringInSlice([]string{"PHOTON", "STANDARD"}, false))
221-
s.AddNewField("is_pinned", &schema.Schema{
222-
Type: schema.TypeBool,
223-
Optional: true,
224-
Default: false,
225-
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
226-
if old == "" && new == "false" {
227-
return true
228-
}
229-
return old == new
230-
},
231-
})
232-
s.AddNewField("url", &schema.Schema{
233-
Type: schema.TypeString,
234-
Computed: true,
235-
})
236240
s.SchemaPath("num_workers").SetDefault(0).SetValidateDiagFunc(validation.ToDiagFunc(validation.IntAtLeast(0)))
237241
s.AddNewField("cluster_mount_info", &schema.Schema{
238242
Type: schema.TypeList,

clusters/resource_library.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@ type LibraryResource struct {
1616
compute.Library
1717
}
1818

19-
func (LibraryResource) CustomizeSchema(s *common.CustomizableSchema) *common.CustomizableSchema {
19+
func (LibraryResource) CustomizeSchemaResourceSpecific(s *common.CustomizableSchema) *common.CustomizableSchema {
2020
s.AddNewField("cluster_id", &schema.Schema{
2121
Type: schema.TypeString,
2222
Required: true,
2323
})
2424
return s
2525
}
2626

27+
func (LibraryResource) CustomizeSchema(s *common.CustomizableSchema) *common.CustomizableSchema {
28+
return s
29+
}
30+
2731
func ResourceLibrary() common.Resource {
2832
libraySdkSchema := common.StructToSchema(LibraryResource{}, nil)
2933
parseId := func(id string) (string, string) {

common/customizable_schema.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -253,17 +253,24 @@ func (s *CustomizableSchema) SetValidateDiagFunc(validate func(interface{}, cty.
253253
}
254254

255255
func (s *CustomizableSchema) AddNewField(key string, newField *schema.Schema) *CustomizableSchema {
256-
cv, ok := s.Schema.Elem.(*schema.Resource)
257-
if !ok {
258-
panic("Cannot add new field, target is not nested resource")
259-
}
260-
_, exists := cv.Schema[key]
256+
scm := s.GetSchemaMap()
257+
_, exists := scm[key]
261258
if exists {
262259
panic("Cannot add new field, " + key + " already exists in the schema")
263260
}
264-
cv.Schema[key] = newField
261+
scm[key] = newField
265262
if s.isSuppressDiff {
266263
newField.DiffSuppressFunc = diffSuppressor(key, newField)
267264
}
268265
return s
269266
}
267+
268+
func (s *CustomizableSchema) RemoveField(key string) *CustomizableSchema {
269+
scm := s.GetSchemaMap()
270+
_, exists := scm[key]
271+
if !exists {
272+
panic("Cannot remove new field, " + key + " does not exist in the schema")
273+
}
274+
delete(scm, key)
275+
return s
276+
}

common/reflect_resource.go

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var kindMap = map[reflect.Kind]string{
4242
// Global registry for ResoureProvider, the goal is to make StructToSchema able to find pre-registered ResourceProvider for a
4343
// given struct so that we don't have to specify aliases and customizations redundantly if one schema references the another
4444
// schema.
45-
var resourceProviderRegistry map[string]ResourceProvider
45+
var resourceProviderRegistry map[reflect.Type]ResourceProvider
4646

4747
// Pre-registered ResourceProvider for a given struct into resourceProviderRegistry.
4848
// This function should be called in the init() function in packages with ResourceProvider.
@@ -53,14 +53,27 @@ var resourceProviderRegistry map[string]ResourceProvider
5353
// }
5454
func RegisterResourceProvider(v any, r ResourceProvider) {
5555
if resourceProviderRegistry == nil {
56-
resourceProviderRegistry = make(map[string]ResourceProvider)
56+
resourceProviderRegistry = make(map[reflect.Type]ResourceProvider)
5757
}
58-
typeName := getNameForType(reflect.ValueOf(v).Type())
59-
if _, ok := resourceProviderRegistry[typeName]; ok {
60-
errMsg := fmt.Sprintf("%s has already been registered, please avoid registering the same type repeatedly.", typeName)
58+
t := getResourceProviderRegistryKey(v)
59+
if _, ok := resourceProviderRegistry[t]; ok {
60+
errMsg := fmt.Sprintf("%s has already been registered, please avoid registering the same type repeatedly.", getNameForType(t))
6161
panic(errMsg)
6262
}
63-
resourceProviderRegistry[typeName] = r
63+
resourceProviderRegistry[t] = r
64+
}
65+
66+
func getResourceProviderRegistryKey(v any) reflect.Type {
67+
t := reflect.ValueOf(v).Type()
68+
return getNonPointerType(t)
69+
}
70+
71+
func getNonPointerType(t reflect.Type) reflect.Type {
72+
if t.Kind() == reflect.Ptr {
73+
return t.Elem()
74+
} else {
75+
return t
76+
}
6477
}
6578

6679
// Generic interface for ResourceProvider. Using CustomizeSchema function to keep track of additional information
@@ -69,6 +82,19 @@ type ResourceProvider interface {
6982
CustomizeSchema(*CustomizableSchema) *CustomizableSchema
7083
}
7184

85+
// Interface for ResourcePrivider that needs certain customizaitons that shouldn't be shared.
86+
type ResourceProviderWithResourceSpecificCustomization interface {
87+
ResourceProvider
88+
// Customizations in this function will not be applied when this type is referenced from another resource by resourceProviderRegistry.
89+
// Example use case:
90+
// // autotermination_minutes should only have a default value of 60 for the clusters resource, but not in the nested cluster schema in jobs
91+
// func (ClusterSpec) CustomizeSchemaResourceSpecific(s *common.CustomizableSchema) *common.CustomizableSchema {
92+
// s.SchemaPath("autotermination_minutes").SetDefault(60)
93+
// return s
94+
// }
95+
CustomizeSchemaResourceSpecific(*CustomizableSchema) *CustomizableSchema
96+
}
97+
7298
// Interface for ResourceProvider instances that need aliases for fields.
7399
type ResourceProviderWithAlias interface {
74100
ResourceProvider
@@ -100,8 +126,19 @@ type RecursiveResourceProvider interface {
100126
MaxDepthForTypes() map[string]int
101127
}
102128

103-
// Takes in a ResourceProvider and converts that into a map from string to schema.
129+
// Used by StructToSchema, after executing typeToSchema and applying the standard customizations,
130+
// it also applies the resource specific customizations, if applicable.
104131
func resourceProviderStructToSchema(v ResourceProvider, scp schemaPathContext) map[string]*schema.Schema {
132+
customizedScm := resourceProviderStructToSchemaInternal(v, scp)
133+
if rps, ok := v.(ResourceProviderWithResourceSpecificCustomization); ok {
134+
// Apply resource specific customizations, if applicable.
135+
return rps.CustomizeSchemaResourceSpecific(customizedScm).GetSchemaMap()
136+
} else {
137+
return customizedScm.GetSchemaMap()
138+
}
139+
}
140+
141+
func resourceProviderStructToSchemaInternal(v ResourceProvider, scp schemaPathContext) *CustomizableSchema {
105142
rv := reflect.ValueOf(v)
106143
var scm map[string]*schema.Schema
107144
aliases := map[string]map[string]string{}
@@ -115,8 +152,7 @@ func resourceProviderStructToSchema(v ResourceProvider, scp schemaPathContext) m
115152
}
116153
cs := CustomizeSchemaPath(scm)
117154
cs.context = scp
118-
scm = v.CustomizeSchema(cs).GetSchemaMap()
119-
return scm
155+
return v.CustomizeSchema(cs)
120156
}
121157

122158
func reflectKind(k reflect.Kind) string {
@@ -372,6 +408,9 @@ func listAllFields(v reflect.Value) []field {
372408
}
373409

374410
func typeToSchema(v reflect.Value, aliases map[string]map[string]string, tc trackingContext) map[string]*schema.Schema {
411+
if rpStruct, ok := resourceProviderRegistry[getNonPointerType(v.Type())]; ok {
412+
return resourceProviderStructToSchemaInternal(rpStruct, tc.pathCtx).GetSchemaMap()
413+
}
375414
scm := map[string]*schema.Schema{}
376415
rk := v.Kind()
377416
if rk == reflect.Ptr {

0 commit comments

Comments
 (0)