From 23717a5fd234ffa40ad6a8f74236546302e7f9df Mon Sep 17 00:00:00 2001 From: edwardfeng-db Date: Mon, 8 Jan 2024 23:30:57 +0100 Subject: [PATCH] update --- clusters/resource_cluster.go | 250 ----------------------------------- common/reflect_resource.go | 103 +-------------- 2 files changed, 7 insertions(+), 346 deletions(-) diff --git a/clusters/resource_cluster.go b/clusters/resource_cluster.go index 68450325cb..0216a78aa5 100644 --- a/clusters/resource_cluster.go +++ b/clusters/resource_cluster.go @@ -166,256 +166,6 @@ func (ClusterResourceProvider) CustomizeSchema(s map[string]*schema.Schema) map[ return s } -func (ClusterResourceProvider) TfOverlay() map[string]*schema.Schema { - return map[string]*schema.Schema{ - // "runtime_engine": { - // ValidateFunc: validation.StringInSlice([]string{"PHOTON", "STANDARD"}, false), - // }, - // "is_pinned": { - // Type: schema.TypeBool, - // Optional: true, - // Default: false, - // DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // if old == "" && new == "false" { - // return true - // } - // return old == new - // }, - // }, - // "state": { - // Type: schema.TypeString, - // Computed: true, - // Optional: false, // Explicitly set it to override the value from StructToSchema - // }, - // "default_tags": { - // Type: schema.TypeMap, - // Computed: true, - // Optional: false, // Explicitly set it to override the value from StructToSchema - // }, - // "num_workers": { - // Type: schema.TypeInt, - // Optional: true, - // Default: 0, - // ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(0)), - // }, - // "url": { - // Type: schema.TypeString, - // Computed: true, - // }, - // "cluster_mount_info": { - // Type: schema.TypeList, - // Optional: true, - // Elem: &schema.Resource{ - // Schema: common.StructToSchema(MountInfo{}, func(ss map[string]*schema.Schema) map[string]*schema.Schema { - // return ss - // }), - // }, - // }, - // "enable_elastic_disk": { - // Computed: true, - // }, - // "enable_local_disk_encryption": { - // Computed: true, - // }, - // "node_type_id": { - // ConflictsWith: []string{"driver_instance_pool_id", "instance_pool_id"}, - // Computed: true, - // }, - // "driver_node_type_id": { - // ConflictsWith: []string{"driver_instance_pool_id", "instance_pool_id"}, - // Computed: true, - // }, - // "driver_instance_pool_id": { - // ConflictsWith: []string{"driver_node_type_id", "node_type_id"}, - // Computed: true, - // }, - // "ssh_public_keys": { - // MaxItems: 10, - // }, - // "init_scripts": { - // MaxItems: 10, - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "dbfs": { - // Deprecated: DbfsDeprecationWarning, - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "destination": { - // Required: true, - // }, - // }, - // }, - // }, - // "s3": { - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "destination": { - // Required: true, - // }, - // }, - // }, - // }, - // "abfss": common.StructToSchema(InitScriptStorageInfo{}, func(ss map[string]*schema.Schema) map[string]*schema.Schema { - // return ss - // })["abfss"], - // "gcs": common.StructToSchema(InitScriptStorageInfo{}, func(ss map[string]*schema.Schema) map[string]*schema.Schema { - // return ss - // })["gcs"], - // }, - // }, - // }, - // "workload_type": { - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "clients": { - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "notebooks": { - // Optional: true, - // Default: true, - // }, - // "jobs": { - // Optional: true, - // Default: true, - // }, - // }, - // }, - // Required: true, - // }, - // }, - // }, - // }, - // "idempotency_token": { - // Type: schema.TypeString, - // Optional: true, - // ForceNew: true, - // }, - // "data_security_mode": { - // DiffSuppressFunc: common.GetDiffSuppressor(""), - // }, - // "docker_image": { - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "url": { - // Required: true, - // }, - // "basic_auth": { - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "password": { - // Sensitive: true, - // Required: true, - // }, - // "username": { - // Required: true, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // "spark_conf": { - // DiffSuppressFunc: SparkConfDiffSuppressFunc, - // }, - // "aws_attributes": { - // DiffSuppressFunc: common.MakeEmptyBlockSuppressFuncNoRegex(), - // ConflictsWith: []string{"azure_attributes", "gcp_attributes"}, - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "zone_id": { - // DiffSuppressFunc: ZoneDiffSuppress, - // }, - // }, - // }, - // }, - // "azure_attributes": { - // DiffSuppressFunc: common.MakeEmptyBlockSuppressFuncNoRegex(), - // ConflictsWith: []string{"aws_attributes", "gcp_attributes"}, - // }, - // "gcp_attributes": { - // DiffSuppressFunc: common.MakeEmptyBlockSuppressFuncNoRegex(), - // ConflictsWith: []string{"azure_attributes", "aws_attributes"}, - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "use_preemptible_executors": { - // Type: schema.TypeBool, - // Optional: true, - // Deprecated: "Please use 'availability' instead.", - // }, - // "zone_id": { - // Type: schema.TypeString, - // Optional: true, - // }, - // }, - // }, - // }, - // "library": common.StructToSchema(libraries.ClusterLibraryList{}, - // func(ss map[string]*schema.Schema) map[string]*schema.Schema { - // ss["library"].Set = func(i any) int { - // lib := libraries.NewLibraryFromInstanceState(i) - // return schema.HashString(lib.String()) - // } - // return ss - // })["library"], - // "autotermination_minutes": { - // Default: 60, - // }, - // "autoscale": { - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "max_workers": { - // Optional: true, - // }, - // "min_workers": { - // Optional: true, - // }, - // }, - // }, - // }, - // "apply_policy_default_values": { - // Optional: true, - // Type: schema.TypeBool, - // }, - // "cluster_log_conf": { - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "dbfs": { - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "destination": { - // Required: true, - // }, - // }, - // }, - // }, - // "s3": { - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "destination": { - // Required: true, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // "spark_version": { - // Required: true, - // }, - // "cluster_id": { - // Type: schema.TypeString, - // Optional: true, - // Computed: true, - // }, - // "instance_pool_id": { - // ConflictsWith: []string{"driver_node_type_id", "node_type_id"}, - // }, - - } -} - func resourceClusterSchema() map[string]*schema.Schema { return common.ResourceProviderStructToSchema[compute.ClusterDetails](ClusterResourceProvider{}) } diff --git a/common/reflect_resource.go b/common/reflect_resource.go index 6786836cab..91e9083179 100644 --- a/common/reflect_resource.go +++ b/common/reflect_resource.go @@ -40,11 +40,10 @@ var kindMap = map[reflect.Kind]string{ reflect.UnsafePointer: "UnsafePointer", } -// Generic interface for resource provider struct. Using TfOverlay and Aliases functions to keep track of additional information +// Generic interface for resource provider struct. Using CustomizeSchema and Aliases functions to keep track of additional information // on top of the generated go-sdk struct. This is used to replace manually maintained structs with `tf` tags. type ResourceProviderStruct[T any] interface { UnderlyingType() T - TfOverlay() map[string]*schema.Schema Aliases() map[string]string CustomizeSchema(map[string]*schema.Schema) map[string]*schema.Schema } @@ -53,12 +52,12 @@ type ResourceProviderStruct[T any] interface { func ResourceProviderStructToSchema[T any](v ResourceProviderStruct[T]) map[string]*schema.Schema { underlyingType := v.UnderlyingType() rv := reflect.ValueOf(underlyingType) - scm := resourceProviderTypeToSchema(rv, rv.Type(), []string{}, v.Aliases(), v.TfOverlay()) + scm := resourceProviderTypeToSchema(rv, rv.Type(), []string{}, v.Aliases()) scm = v.CustomizeSchema(scm) return scm } -func resourceProviderTypeToSchema(v reflect.Value, t reflect.Type, fieldNamePath []string, aliases map[string]string, tfOverlay map[string]*schema.Schema) map[string]*schema.Schema { +func resourceProviderTypeToSchema(v reflect.Value, t reflect.Type, fieldNamePath []string, aliases map[string]string) map[string]*schema.Schema { scm := map[string]*schema.Schema{} rk := v.Kind() if rk == reflect.Ptr { @@ -74,26 +73,11 @@ func resourceProviderTypeToSchema(v reflect.Value, t reflect.Type, fieldNamePath fieldName := chooseFieldNameWithAliases(typeField, fieldNamePath, aliases) - var tfOverlaySchema *schema.Schema - - if value, ok := tfOverlay[fieldName]; ok { - tfOverlaySchema = value - } else { - tfOverlaySchema = &schema.Schema{} - } - - var nextLevelTfOverlay map[string]*schema.Schema - - if resource, ok := tfOverlaySchema.Elem.(*schema.Resource); ok { - nextLevelTfOverlay = resource.Schema - } else { - nextLevelTfOverlay = map[string]*schema.Schema{} - } - if fieldName == "-" { continue } scm[fieldName] = &schema.Schema{} + handleOptional(typeField, scm[fieldName]) switch typeField.Type.Kind() { case reflect.Int, reflect.Int32, reflect.Int64: scm[fieldName].Type = schema.TypeInt @@ -119,7 +103,7 @@ func resourceProviderTypeToSchema(v reflect.Value, t reflect.Type, fieldNamePath scm[fieldName].Type = schema.TypeList elem := typeField.Type.Elem() sv := reflect.New(elem).Elem() - nestedSchema := resourceProviderTypeToSchema(sv, elem, append(fieldNamePath, fieldName), aliases, nextLevelTfOverlay) + nestedSchema := resourceProviderTypeToSchema(sv, elem, append(fieldNamePath, fieldName), aliases) if scm[fieldName].DiffSuppressFunc != nil { for _, v := range nestedSchema { // to those relatively new to GoLang: we must explicitly pass down v by copy @@ -136,7 +120,7 @@ func resourceProviderTypeToSchema(v reflect.Value, t reflect.Type, fieldNamePath elem := typeField.Type // changed from ptr sv := reflect.New(elem) // changed from ptr - nestedSchema := resourceProviderTypeToSchema(sv, elem, append(fieldNamePath, fieldName), aliases, nextLevelTfOverlay) + nestedSchema := resourceProviderTypeToSchema(sv, elem, append(fieldNamePath, fieldName), aliases) if scm[fieldName].DiffSuppressFunc != nil { for _, v := range nestedSchema { // to those relatively new to GoLang: we must explicitly pass down v by copy @@ -162,64 +146,16 @@ func resourceProviderTypeToSchema(v reflect.Value, t reflect.Type, fieldNamePath case reflect.Struct: sv := reflect.New(elem).Elem() scm[fieldName].Elem = &schema.Resource{ - Schema: resourceProviderTypeToSchema(sv, elem, append(fieldNamePath, fieldName), aliases, nextLevelTfOverlay), + Schema: resourceProviderTypeToSchema(sv, elem, append(fieldNamePath, fieldName), aliases), } } default: panic(fmt.Errorf("unknown type for %s: %s", fieldName, reflectKind(typeField.Type.Kind()))) } - // Apply TfOverlay after processing the fields in the original struct. - applyTfOverlay(typeField, tfOverlaySchema, scm[fieldName]) - } - // Add the fields that only exist in tfOverlay. - for key, value := range tfOverlay { - _, exists := scm[key] - if !exists { - scm[key] = value - } } return scm } -func applyTfOverlay(typeField reflect.StructField, overlay, base *schema.Schema) { - handleOptionalOverlay(typeField, base, overlay) - mergeTfOverlay(base, overlay) -} - -func mergeTfOverlay(base, overlay *schema.Schema) { - baseVal := reflect.ValueOf(base) - overlayVal := reflect.ValueOf(overlay) - - baseVal = baseVal.Elem() - overlayVal = overlayVal.Elem() - - for i := 0; i < baseVal.NumField(); i++ { - // Get the field's metadata - fieldInfo := baseVal.Type().Field(i) - - // Skip if the field name is "Elem" - if fieldInfo.Name == "Elem" { - continue - } - - baseField := baseVal.Field(i) - overlayField := overlayVal.Field(i) - - // Merge logic, preferring the overlay's field if it's not set to zero value - if !reflect.DeepEqual(overlayField.Interface(), reflect.Zero(overlayField.Type()).Interface()) { - baseField.Set(overlayField) - } - } -} - -func handleOptionalOverlay(typeField reflect.StructField, base, overlay *schema.Schema) { - if !overlay.Required && (overlay.Optional || strings.Contains(typeField.Tag.Get("json"), "omitempty")) { - base.Optional = true - } else { - base.Required = true - } -} - func reflectKind(k reflect.Kind) string { n, ok := kindMap[k] if !ok { @@ -274,23 +210,6 @@ func SchemaPath(s map[string]*schema.Schema, path ...string) (*schema.Schema, er return nil, fmt.Errorf("%v does not compute", path) } -// // Helps to navigate given a path and a map, but returns the map instead of the schema object. -// func SchemaMapPath(s map[string]*schema.Schema, path []string) (map[string]*schema.Schema, error) { -// cs := s -// for _, p := range path { -// v, ok := cs[p] -// if !ok { -// return nil, fmt.Errorf("missing key %s", p) -// } -// cv, ok := v.Elem.(*schema.Resource) -// if !ok { -// return nil, fmt.Errorf("%s is not nested resource", p) -// } -// cs = cv.Schema -// } -// return cs, nil -// } - func MustSchemaPath(s map[string]*schema.Schema, path ...string) *schema.Schema { sch, err := SchemaPath(s, path...) if err != nil { @@ -404,14 +323,6 @@ func (s *CustomizableSchema) AddNewField(key string, newField *schema.Schema) *C return s } -// func AddNewFieldToSchemaMap(schema map[string]*schema.Schema, path []string, newField *schema.Schema) { -// targetLevelMap, err := SchemaMapPath(schema, path[:len(path)-1]) -// if err != nil { -// panic(err) -// } -// targetLevelMap[path[len(path)-1]] = newField -// } - // StructToSchema makes schema from a struct type & applies customizations from callback given func StructToSchema(v any, customize func(map[string]*schema.Schema) map[string]*schema.Schema) map[string]*schema.Schema { rv := reflect.ValueOf(v)