|
| 1 | +// Copyright (c) HashiCorp, Inc. |
| 2 | +// SPDX-License-Identifier: MPL-2.0 |
| 3 | +// ---------------------------------------------------------------------------- |
| 4 | +// |
| 5 | +// *** AUTO GENERATED CODE *** Type: Handwritten *** |
| 6 | +// |
| 7 | +// ---------------------------------------------------------------------------- |
| 8 | +// |
| 9 | +// This code is generated by Magic Modules using the following: |
| 10 | +// |
| 11 | +// Source file: https://github.com/GoogleCloudPlatform/magic-modules/tree/main/mmv1/third_party/terraform/fwresource/framework_import.go |
| 12 | +// |
| 13 | +// DO NOT EDIT this file directly. Any changes made to this file will be |
| 14 | +// overwritten during the next generation cycle. |
| 15 | +// |
| 16 | +// ---------------------------------------------------------------------------- |
| 17 | +package fwresource |
| 18 | + |
| 19 | +import ( |
| 20 | + "context" |
| 21 | + "fmt" |
| 22 | + "regexp" |
| 23 | + "strconv" |
| 24 | + "strings" |
| 25 | + |
| 26 | + "github.com/hashicorp/terraform-plugin-framework/attr" |
| 27 | + "github.com/hashicorp/terraform-plugin-framework/diag" |
| 28 | + "github.com/hashicorp/terraform-plugin-framework/resource" |
| 29 | + "github.com/hashicorp/terraform-plugin-framework/resource/schema" |
| 30 | + "github.com/hashicorp/terraform-plugin-framework/types" |
| 31 | + transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" |
| 32 | +) |
| 33 | + |
| 34 | +// ParseImportId uses a list of regular expressions to parse a resource's import ID. |
| 35 | +// It extracts named capture groups from the regex and converts them to their |
| 36 | +// corresponding type-safe attribute values based on the provided resource schema. |
| 37 | +// It also handles setting default values (project, region, etc) if they are not |
| 38 | +// present in the import ID. |
| 39 | +func ParseImportId( |
| 40 | + ctx context.Context, |
| 41 | + req resource.ImportStateRequest, |
| 42 | + resourceSchema schema.Schema, |
| 43 | + providerConfig *transport_tpg.Config, |
| 44 | + idRegexes []string, |
| 45 | +) (map[string]attr.Value, diag.Diagnostics) { |
| 46 | + var diags diag.Diagnostics |
| 47 | + parsedAttributes := make(map[string]attr.Value) |
| 48 | + |
| 49 | + var matchFound bool |
| 50 | + for _, idFormat := range idRegexes { |
| 51 | + re, err := regexp.Compile(idFormat) |
| 52 | + if err != nil { |
| 53 | + diags.AddError( |
| 54 | + "Invalid Import Regex", |
| 55 | + fmt.Sprintf("Provider developer error: could not compile regex %q. Please report this issue. Error: %s", idFormat, err), |
| 56 | + ) |
| 57 | + // This is a developer error, so we stop immediately. |
| 58 | + return nil, diags |
| 59 | + } |
| 60 | + |
| 61 | + if match := re.FindStringSubmatch(req.ID); match != nil { |
| 62 | + matchFound = true |
| 63 | + subexpNames := re.SubexpNames() |
| 64 | + for i, valueStr := range match { |
| 65 | + // Index 0 is the full match, so we skip it. |
| 66 | + if i == 0 { |
| 67 | + continue |
| 68 | + } |
| 69 | + |
| 70 | + fieldName := subexpNames[i] |
| 71 | + if fieldName == "" { |
| 72 | + continue |
| 73 | + } |
| 74 | + |
| 75 | + // Look up the attribute in the resource's schema. |
| 76 | + attribute, ok := resourceSchema.Attributes[fieldName] |
| 77 | + if !ok { |
| 78 | + diags.AddWarning( |
| 79 | + "Unknown Import Field", |
| 80 | + fmt.Sprintf("Parsed field %q from import ID but it is not defined in the resource schema.", fieldName), |
| 81 | + ) |
| 82 | + continue |
| 83 | + } |
| 84 | + |
| 85 | + // Convert the parsed string value to the correct attr.Value type. |
| 86 | + attrVal, conversionDiags := convertToAttrValue(valueStr, attribute) |
| 87 | + diags.Append(conversionDiags...) |
| 88 | + if conversionDiags.HasError() { |
| 89 | + continue |
| 90 | + } |
| 91 | + parsedAttributes[fieldName] = attrVal |
| 92 | + } |
| 93 | + // Once a match is found, we stop. The most specific regex should be first. |
| 94 | + break |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + if !matchFound { |
| 99 | + diags.AddError( |
| 100 | + "Invalid Import ID", |
| 101 | + fmt.Sprintf("Import ID %q doesn't match any of the accepted formats: %v", req.ID, idRegexes), |
| 102 | + ) |
| 103 | + return nil, diags |
| 104 | + } |
| 105 | + |
| 106 | + // Handle default values like project, region, and zone. |
| 107 | + defaultDiags := addDefaultValues(ctx, parsedAttributes, providerConfig, resourceSchema, idRegexes[0]) |
| 108 | + diags.Append(defaultDiags...) |
| 109 | + |
| 110 | + return parsedAttributes, diags |
| 111 | +} |
| 112 | + |
| 113 | +// convertToAttrValue converts a string to the appropriate attr.Value based on the schema attribute type. |
| 114 | +func convertToAttrValue(valueStr string, attr schema.Attribute) (attr.Value, diag.Diagnostics) { |
| 115 | + var diags diag.Diagnostics |
| 116 | + |
| 117 | + switch attr.(type) { |
| 118 | + case schema.StringAttribute: |
| 119 | + return types.StringValue(valueStr), nil |
| 120 | + case schema.Int64Attribute: |
| 121 | + intVal, err := strconv.ParseInt(valueStr, 10, 64) |
| 122 | + if err != nil { |
| 123 | + diags.AddError( |
| 124 | + "Import Value Conversion Error", |
| 125 | + fmt.Sprintf("Failed to parse %q as an integer: %s", valueStr, err), |
| 126 | + ) |
| 127 | + return nil, diags |
| 128 | + } |
| 129 | + return types.Int64Value(intVal), nil |
| 130 | + case schema.BoolAttribute: |
| 131 | + boolVal, err := strconv.ParseBool(valueStr) |
| 132 | + if err != nil { |
| 133 | + diags.AddError( |
| 134 | + "Import Value Conversion Error", |
| 135 | + fmt.Sprintf("Failed to parse %q as a boolean: %s", valueStr, err), |
| 136 | + ) |
| 137 | + return nil, diags |
| 138 | + } |
| 139 | + return types.BoolValue(boolVal), nil |
| 140 | + case schema.Float64Attribute: |
| 141 | + floatVal, err := strconv.ParseFloat(valueStr, 64) |
| 142 | + if err != nil { |
| 143 | + diags.AddError( |
| 144 | + "Import Value Conversion Error", |
| 145 | + fmt.Sprintf("Failed to parse %q as a float: %s", valueStr, err), |
| 146 | + ) |
| 147 | + return nil, diags |
| 148 | + } |
| 149 | + return types.Float64Value(floatVal), nil |
| 150 | + default: |
| 151 | + // For complex types like List, Object, etc., a simple string conversion is not feasible. |
| 152 | + // The assumption is that import IDs will only contain primitive types. |
| 153 | + diags.AddError( |
| 154 | + "Unsupported Import Attribute Type", |
| 155 | + fmt.Sprintf("Importing attributes of type %T is not supported. This is a provider developer issue.", attr), |
| 156 | + ) |
| 157 | + return nil, diags |
| 158 | + } |
| 159 | +} |
| 160 | + |
| 161 | +// addDefaultValues checks for common provider-level defaults (project, region, zone) |
| 162 | +// and adds them to the parsed attributes map if they were not already set from the import ID. |
| 163 | +func addDefaultValues( |
| 164 | + ctx context.Context, |
| 165 | + parsedAttributes map[string]attr.Value, |
| 166 | + config *transport_tpg.Config, |
| 167 | + resourceSchema schema.Schema, |
| 168 | + primaryRegex string, |
| 169 | +) diag.Diagnostics { |
| 170 | + var diags diag.Diagnostics |
| 171 | + |
| 172 | + defaults := map[string]func(*transport_tpg.Config) (string, error){ |
| 173 | + "project": func(c *transport_tpg.Config) (string, error) { return c.Project, nil }, |
| 174 | + "region": func(c *transport_tpg.Config) (string, error) { return c.Region, nil }, |
| 175 | + "zone": func(c *transport_tpg.Config) (string, error) { return c.Zone, nil }, |
| 176 | + } |
| 177 | + |
| 178 | + for field, getDefault := range defaults { |
| 179 | + // Check if the primary regex expects this field. |
| 180 | + if !strings.Contains(primaryRegex, fmt.Sprintf("(?P<%s>", field)) { |
| 181 | + continue |
| 182 | + } |
| 183 | + // Check if the resource schema actually has this attribute. |
| 184 | + if _, ok := resourceSchema.Attributes[field]; !ok { |
| 185 | + continue |
| 186 | + } |
| 187 | + // Check if the value was already parsed from the import ID. |
| 188 | + if _, ok := parsedAttributes[field]; ok { |
| 189 | + continue |
| 190 | + } |
| 191 | + |
| 192 | + // Get the default value from the provider configuration. |
| 193 | + value, err := getDefault(config) |
| 194 | + if err != nil { |
| 195 | + diags.AddError( |
| 196 | + fmt.Sprintf("Failed to get default value for %s", field), |
| 197 | + err.Error(), |
| 198 | + ) |
| 199 | + continue |
| 200 | + } |
| 201 | + |
| 202 | + if value != "" { |
| 203 | + parsedAttributes[field] = types.StringValue(value) |
| 204 | + } |
| 205 | + } |
| 206 | + |
| 207 | + return diags |
| 208 | +} |
0 commit comments