func KRMResourceToTFResourceConfigFull()

in pkg/krmtotf/krmtotf.go [57:152]


func KRMResourceToTFResourceConfigFull(r *Resource, c client.Client, smLoader *servicemappingloader.ServiceMappingLoader,
	liveState *terraform.InstanceState, jsonSchema *apiextensions.JSONSchemaProps, mustResolveSensitiveFields bool) (tfConfig *terraform.ResourceConfig, secretVersions map[string]string, err error) {
	config := deepcopy.MapStringInterface(r.Spec)
	if config == nil {
		config = make(map[string]interface{})
	}
	if jsonSchema != nil {
		if err := ResolveLegacyGCPManagedFields(r, liveState, config); err != nil {
			return nil, nil, fmt.Errorf("error resolving legacy GCP-managed fields: %w", err)
		}
		config, err = resolveUnmanagedFields(config, r, liveState, jsonSchema)
		if err != nil {
			return nil, nil, fmt.Errorf("error resolving externally-managed fields: %w", err)
		}
	}
	if err := handleUserSpecifiedID(config, r, smLoader, c); err != nil {
		return nil, nil, err
	}
	if r.ResourceConfig.MetadataMapping.Labels != "" {
		path := text.SnakeCaseToLowerCamelCase(r.ResourceConfig.MetadataMapping.Labels)
		labels := label.ToJSONCompatibleFormat(label.NewGCPLabelsFromK8sLabels(r.GetLabels()))
		if err := setValue(config, path, labels); err != nil {
			return nil, nil, fmt.Errorf("error mapping 'metadata.labels': %w", err)
		}
	}
	if r.ResourceConfig.Locationality != "" {
		switch r.ResourceConfig.Locationality {
		case gcp.Global:
			delete(config, "location")
		case gcp.Regional:
			config["region"] = config["location"]
			delete(config, "location")
		case gcp.Zonal:
			config["zone"] = config["location"]
			delete(config, "location")
		default:
			return nil, nil, fmt.Errorf("INTERNAL_ERROR: %v locationality is not supported", r.ResourceConfig.Locationality)
		}
	}
	for _, refConfig := range r.ResourceConfig.ResourceReferences {
		if err := handleResourceReference(config, refConfig, r, c, smLoader); err != nil {
			return nil, nil, err
		}
	}
	config, secretVersions, err = resolveSensitiveFields(config, r.TFResource, r.GetNamespace(), c, mustResolveSensitiveFields)
	if err != nil {
		return nil, nil, err
	}
	config, err = KRMObjectToTFObjectWithConfigurableFieldsOnly(config, r.TFResource)
	if err != nil {
		return nil, nil, fmt.Errorf("error converting to config: %w", err)
	}
	for _, d := range r.ResourceConfig.Directives {
		key := k8s.FormatAnnotation(text.SnakeCaseToKebabCase(d))
		if val, ok := k8s.GetAnnotation(key, r); ok {
			if val == "" {
				return nil, nil, fmt.Errorf("the value for directive '%v' must not be empty", key)
			}
			if err := setValue(config, d, val); err != nil {
				return nil, nil, fmt.Errorf("error mapping directive '%v': %w", d, err)
			}
		}
	}
	if err := resolveContainerValue(config, r, c, smLoader); err != nil {
		return nil, nil, fmt.Errorf("error resolving container value: %w", err)
	}
	config, err = withCustomFlatteners(config, r.Kind)
	if err != nil {
		return nil, nil, fmt.Errorf("error running custom flatteners: %w", err)
	}
	// Set desired state with default values.
	defaultingMap := map[string]map[string]string{
		"CloudBuildTrigger": {
			"location": "global",
		},
		"CloudIdentityGroup": {
			"initial_group_config": "EMPTY",
		},
		"FirestoreIndex": {
			"database": "(default)",
		},
	}
	if defaults, ok := defaultingMap[r.Kind]; ok {
		for field, value := range defaults {
			if v, ok := config[field]; !ok || v == "" {
				config[field] = value
			}
		}
	}
	state := InstanceStateToMap(r.TFResource, liveState)
	config, err = withResourceCustomResolvers(config, state, r.Kind, r.TFResource)
	if err != nil {
		return nil, nil, fmt.Errorf("error running resource custom resolver: %w", err)
	}
	return MapToResourceConfig(r.TFResource, config), secretVersions, nil
}