| // Copyright (c) HashiCorp, Inc. |
| // SPDX-License-Identifier: MPL-2.0 |
| |
| // ---------------------------------------------------------------------------- |
| // |
| // *** AUTO GENERATED CODE *** Type: MMv1 *** |
| // |
| // ---------------------------------------------------------------------------- |
| // |
| // This file is automatically generated by Magic Modules and manual |
| // changes will be clobbered when the file is regenerated. |
| // |
| // Please read more about how to change this file in |
| // .github/CONTRIBUTING.md. |
| // |
| // ---------------------------------------------------------------------------- |
| |
| package filestore |
| |
| import ( |
| "context" |
| "fmt" |
| "log" |
| "net/http" |
| "reflect" |
| "strings" |
| "time" |
| |
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" |
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" |
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" |
| |
| "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" |
| transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" |
| "github.com/hashicorp/terraform-provider-google-beta/google-beta/verify" |
| ) |
| |
| func ResourceFilestoreInstance() *schema.Resource { |
| return &schema.Resource{ |
| Create: resourceFilestoreInstanceCreate, |
| Read: resourceFilestoreInstanceRead, |
| Update: resourceFilestoreInstanceUpdate, |
| Delete: resourceFilestoreInstanceDelete, |
| |
| Importer: &schema.ResourceImporter{ |
| State: resourceFilestoreInstanceImport, |
| }, |
| |
| Timeouts: &schema.ResourceTimeout{ |
| Create: schema.DefaultTimeout(20 * time.Minute), |
| Update: schema.DefaultTimeout(20 * time.Minute), |
| Delete: schema.DefaultTimeout(20 * time.Minute), |
| }, |
| |
| SchemaVersion: 1, |
| |
| StateUpgraders: []schema.StateUpgrader{ |
| { |
| Type: resourceFilestoreInstanceResourceV0().CoreConfigSchema().ImpliedType(), |
| Upgrade: ResourceFilestoreInstanceUpgradeV0, |
| Version: 0, |
| }, |
| }, |
| CustomizeDiff: customdiff.All( |
| tpgresource.SetLabelsDiff, |
| tpgresource.DefaultProviderProject, |
| ), |
| |
| Schema: map[string]*schema.Schema{ |
| "file_shares": { |
| Type: schema.TypeList, |
| Required: true, |
| Description: `File system shares on the instance. For this version, only a |
| single file share is supported.`, |
| MaxItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "capacity_gb": { |
| Type: schema.TypeInt, |
| Required: true, |
| Description: `File share capacity in GiB. This must be at least 1024 GiB |
| for the standard tier, or 2560 GiB for the premium tier.`, |
| }, |
| "name": { |
| Type: schema.TypeString, |
| Required: true, |
| ForceNew: true, |
| Description: `The name of the fileshare (16 characters or less)`, |
| }, |
| "nfs_export_options": { |
| Type: schema.TypeList, |
| Optional: true, |
| Description: `Nfs Export Options. There is a limit of 10 export options per file share.`, |
| MaxItems: 10, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "access_mode": { |
| Type: schema.TypeString, |
| Optional: true, |
| ValidateFunc: verify.ValidateEnum([]string{"READ_ONLY", "READ_WRITE", ""}), |
| Description: `Either READ_ONLY, for allowing only read requests on the exported directory, |
| or READ_WRITE, for allowing both read and write requests. The default is READ_WRITE. Default value: "READ_WRITE" Possible values: ["READ_ONLY", "READ_WRITE"]`, |
| Default: "READ_WRITE", |
| }, |
| "anon_gid": { |
| Type: schema.TypeInt, |
| Optional: true, |
| Description: `An integer representing the anonymous group id with a default value of 65534. |
| Anon_gid may only be set with squashMode of ROOT_SQUASH. An error will be returned |
| if this field is specified for other squashMode settings.`, |
| }, |
| "anon_uid": { |
| Type: schema.TypeInt, |
| Optional: true, |
| Description: `An integer representing the anonymous user id with a default value of 65534. |
| Anon_uid may only be set with squashMode of ROOT_SQUASH. An error will be returned |
| if this field is specified for other squashMode settings.`, |
| }, |
| "ip_ranges": { |
| Type: schema.TypeList, |
| Optional: true, |
| Description: `List of either IPv4 addresses, or ranges in CIDR notation which may mount the file share. |
| Overlapping IP ranges are not allowed, both within and across NfsExportOptions. An error will be returned. |
| The limit is 64 IP ranges/addresses for each FileShareConfig among all NfsExportOptions.`, |
| Elem: &schema.Schema{ |
| Type: schema.TypeString, |
| }, |
| }, |
| "squash_mode": { |
| Type: schema.TypeString, |
| Optional: true, |
| ValidateFunc: verify.ValidateEnum([]string{"NO_ROOT_SQUASH", "ROOT_SQUASH", ""}), |
| Description: `Either NO_ROOT_SQUASH, for allowing root access on the exported directory, or ROOT_SQUASH, |
| for not allowing root access. The default is NO_ROOT_SQUASH. Default value: "NO_ROOT_SQUASH" Possible values: ["NO_ROOT_SQUASH", "ROOT_SQUASH"]`, |
| Default: "NO_ROOT_SQUASH", |
| }, |
| }, |
| }, |
| }, |
| "source_backup": { |
| Type: schema.TypeString, |
| Optional: true, |
| ForceNew: true, |
| Description: `The resource name of the backup, in the format |
| projects/{projectId}/locations/{locationId}/backups/{backupId}, |
| that this file share has been restored from.`, |
| }, |
| }, |
| }, |
| }, |
| "name": { |
| Type: schema.TypeString, |
| Required: true, |
| Description: `The resource name of the instance.`, |
| }, |
| "networks": { |
| Type: schema.TypeList, |
| Required: true, |
| ForceNew: true, |
| Description: `VPC networks to which the instance is connected. For this version, |
| only a single network is supported.`, |
| MinItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "modes": { |
| Type: schema.TypeList, |
| Required: true, |
| ForceNew: true, |
| Description: `IP versions for which the instance has |
| IP addresses assigned. Possible values: ["ADDRESS_MODE_UNSPECIFIED", "MODE_IPV4", "MODE_IPV6"]`, |
| Elem: &schema.Schema{ |
| Type: schema.TypeString, |
| ValidateFunc: verify.ValidateEnum([]string{"ADDRESS_MODE_UNSPECIFIED", "MODE_IPV4", "MODE_IPV6"}), |
| }, |
| }, |
| "network": { |
| Type: schema.TypeString, |
| Required: true, |
| ForceNew: true, |
| DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName, |
| Description: `The name of the GCE VPC network to which the |
| instance is connected.`, |
| }, |
| "connect_mode": { |
| Type: schema.TypeString, |
| Optional: true, |
| ForceNew: true, |
| ValidateFunc: verify.ValidateEnum([]string{"DIRECT_PEERING", "PRIVATE_SERVICE_ACCESS", ""}), |
| Description: `The network connect mode of the Filestore instance. |
| If not provided, the connect mode defaults to |
| DIRECT_PEERING. Default value: "DIRECT_PEERING" Possible values: ["DIRECT_PEERING", "PRIVATE_SERVICE_ACCESS"]`, |
| Default: "DIRECT_PEERING", |
| }, |
| "reserved_ip_range": { |
| Type: schema.TypeString, |
| Computed: true, |
| Optional: true, |
| ForceNew: true, |
| Description: `A /29 CIDR block that identifies the range of IP |
| addresses reserved for this instance.`, |
| }, |
| "ip_addresses": { |
| Type: schema.TypeList, |
| Computed: true, |
| Description: `A list of IPv4 or IPv6 addresses.`, |
| Elem: &schema.Schema{ |
| Type: schema.TypeString, |
| }, |
| }, |
| }, |
| }, |
| }, |
| "tier": { |
| Type: schema.TypeString, |
| Required: true, |
| ForceNew: true, |
| Description: `The service tier of the instance. |
| Possible values include: STANDARD, PREMIUM, BASIC_HDD, BASIC_SSD, HIGH_SCALE_SSD, ZONAL, REGIONAL and ENTERPRISE`, |
| }, |
| "description": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `A description of the instance.`, |
| }, |
| "kms_key_name": { |
| Type: schema.TypeString, |
| Optional: true, |
| ForceNew: true, |
| Description: `KMS key name used for data encryption.`, |
| }, |
| "labels": { |
| Type: schema.TypeMap, |
| Optional: true, |
| Description: `Resource labels to represent user-provided metadata. |
| |
| |
| **Note**: This field is non-authoritative, and will only manage the labels present in your configuration. |
| Please refer to the field 'effective_labels' for all of the labels present on the resource.`, |
| Elem: &schema.Schema{Type: schema.TypeString}, |
| }, |
| "location": { |
| Type: schema.TypeString, |
| Computed: true, |
| Optional: true, |
| ForceNew: true, |
| Description: `The name of the location of the instance. This can be a region for ENTERPRISE tier instances.`, |
| ExactlyOneOf: []string{}, |
| }, |
| "protocol": { |
| Type: schema.TypeString, |
| Optional: true, |
| ForceNew: true, |
| ValidateFunc: verify.ValidateEnum([]string{"NFS_V3", "NFS_V4_1", ""}), |
| Description: `Either NFSv3, for using NFS version 3 as file sharing protocol, |
| or NFSv4.1, for using NFS version 4.1 as file sharing protocol. |
| NFSv4.1 can be used with HIGH_SCALE_SSD, ZONAL, REGIONAL and ENTERPRISE. |
| The default is NFSv3. Default value: "NFS_V3" Possible values: ["NFS_V3", "NFS_V4_1"]`, |
| Default: "NFS_V3", |
| }, |
| "zone": { |
| Type: schema.TypeString, |
| Computed: true, |
| Optional: true, |
| Deprecated: "`zone` is deprecated and will be removed in a future major release. Use `location` instead.", |
| ForceNew: true, |
| Description: `The name of the Filestore zone of the instance.`, |
| ExactlyOneOf: []string{}, |
| }, |
| "create_time": { |
| Type: schema.TypeString, |
| Computed: true, |
| Description: `Creation timestamp in RFC3339 text format.`, |
| }, |
| "effective_labels": { |
| Type: schema.TypeMap, |
| Computed: true, |
| Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, |
| Elem: &schema.Schema{Type: schema.TypeString}, |
| }, |
| "etag": { |
| Type: schema.TypeString, |
| Computed: true, |
| Description: `Server-specified ETag for the instance resource to prevent |
| simultaneous updates from overwriting each other.`, |
| }, |
| "terraform_labels": { |
| Type: schema.TypeMap, |
| Computed: true, |
| Description: `The combination of labels configured directly on the resource |
| and default labels configured on the provider.`, |
| Elem: &schema.Schema{Type: schema.TypeString}, |
| }, |
| "project": { |
| Type: schema.TypeString, |
| Optional: true, |
| Computed: true, |
| ForceNew: true, |
| }, |
| }, |
| UseJSONNumber: true, |
| } |
| } |
| |
| func resourceFilestoreInstanceCreate(d *schema.ResourceData, meta interface{}) error { |
| config := meta.(*transport_tpg.Config) |
| userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) |
| if err != nil { |
| return err |
| } |
| |
| obj := make(map[string]interface{}) |
| descriptionProp, err := expandFilestoreInstanceDescription(d.Get("description"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { |
| obj["description"] = descriptionProp |
| } |
| tierProp, err := expandFilestoreInstanceTier(d.Get("tier"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("tier"); !tpgresource.IsEmptyValue(reflect.ValueOf(tierProp)) && (ok || !reflect.DeepEqual(v, tierProp)) { |
| obj["tier"] = tierProp |
| } |
| protocolProp, err := expandFilestoreInstanceProtocol(d.Get("protocol"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("protocol"); !tpgresource.IsEmptyValue(reflect.ValueOf(protocolProp)) && (ok || !reflect.DeepEqual(v, protocolProp)) { |
| obj["protocol"] = protocolProp |
| } |
| fileSharesProp, err := expandFilestoreInstanceFileShares(d.Get("file_shares"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("file_shares"); !tpgresource.IsEmptyValue(reflect.ValueOf(fileSharesProp)) && (ok || !reflect.DeepEqual(v, fileSharesProp)) { |
| obj["fileShares"] = fileSharesProp |
| } |
| networksProp, err := expandFilestoreInstanceNetworks(d.Get("networks"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("networks"); !tpgresource.IsEmptyValue(reflect.ValueOf(networksProp)) && (ok || !reflect.DeepEqual(v, networksProp)) { |
| obj["networks"] = networksProp |
| } |
| kmsKeyNameProp, err := expandFilestoreInstanceKmsKeyName(d.Get("kms_key_name"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("kms_key_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(kmsKeyNameProp)) && (ok || !reflect.DeepEqual(v, kmsKeyNameProp)) { |
| obj["kmsKeyName"] = kmsKeyNameProp |
| } |
| labelsProp, err := expandFilestoreInstanceEffectiveLabels(d.Get("effective_labels"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { |
| obj["labels"] = labelsProp |
| } |
| |
| url, err := tpgresource.ReplaceVars(d, config, "{{FilestoreBasePath}}projects/{{project}}/locations/{{location}}/instances?instanceId={{name}}") |
| if err != nil { |
| return err |
| } |
| |
| log.Printf("[DEBUG] Creating new Instance: %#v", obj) |
| billingProject := "" |
| |
| project, err := tpgresource.GetProject(d, config) |
| if err != nil { |
| return fmt.Errorf("Error fetching project for Instance: %s", err) |
| } |
| billingProject = project |
| |
| // err == nil indicates that the billing_project value was found |
| if bp, err := tpgresource.GetBillingProject(d, config); err == nil { |
| billingProject = bp |
| } |
| |
| headers := make(http.Header) |
| if d.Get("location") == "" { |
| zone, err := tpgresource.GetZone(d, config) |
| if err != nil { |
| return err |
| } |
| err = d.Set("location", zone) |
| if err != nil { |
| return err |
| } |
| } |
| if strings.Contains(url, "locations//") { |
| // re-compute url now that location must be set |
| url, err = tpgresource.ReplaceVars(d, config, "{{FilestoreBasePath}}projects/{{project}}/locations/{{location}}/instances?instanceId={{name}}") |
| if err != nil { |
| return err |
| } |
| } |
| res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ |
| Config: config, |
| Method: "POST", |
| Project: billingProject, |
| RawURL: url, |
| UserAgent: userAgent, |
| Body: obj, |
| Timeout: d.Timeout(schema.TimeoutCreate), |
| Headers: headers, |
| ErrorAbortPredicates: []transport_tpg.RetryErrorPredicateFunc{transport_tpg.Is429QuotaError}, |
| }) |
| if err != nil { |
| return fmt.Errorf("Error creating Instance: %s", err) |
| } |
| |
| // Store the ID now |
| id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/instances/{{name}}") |
| if err != nil { |
| return fmt.Errorf("Error constructing id: %s", err) |
| } |
| d.SetId(id) |
| |
| // Use the resource in the operation response to populate |
| // identity fields and d.Id() before read |
| var opRes map[string]interface{} |
| err = FilestoreOperationWaitTimeWithResponse( |
| config, res, &opRes, project, "Creating Instance", userAgent, |
| d.Timeout(schema.TimeoutCreate)) |
| if err != nil { |
| // The resource didn't actually create |
| d.SetId("") |
| |
| return fmt.Errorf("Error waiting to create Instance: %s", err) |
| } |
| |
| // This may have caused the ID to update - update it if so. |
| id, err = tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/instances/{{name}}") |
| if err != nil { |
| return fmt.Errorf("Error constructing id: %s", err) |
| } |
| d.SetId(id) |
| |
| log.Printf("[DEBUG] Finished creating Instance %q: %#v", d.Id(), res) |
| |
| return resourceFilestoreInstanceRead(d, meta) |
| } |
| |
| func resourceFilestoreInstanceRead(d *schema.ResourceData, meta interface{}) error { |
| config := meta.(*transport_tpg.Config) |
| userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) |
| if err != nil { |
| return err |
| } |
| |
| url, err := tpgresource.ReplaceVars(d, config, "{{FilestoreBasePath}}projects/{{project}}/locations/{{location}}/instances/{{name}}") |
| if err != nil { |
| return err |
| } |
| |
| billingProject := "" |
| |
| project, err := tpgresource.GetProject(d, config) |
| if err != nil { |
| return fmt.Errorf("Error fetching project for Instance: %s", err) |
| } |
| billingProject = project |
| |
| // err == nil indicates that the billing_project value was found |
| if bp, err := tpgresource.GetBillingProject(d, config); err == nil { |
| billingProject = bp |
| } |
| |
| headers := make(http.Header) |
| res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ |
| Config: config, |
| Method: "GET", |
| Project: billingProject, |
| RawURL: url, |
| UserAgent: userAgent, |
| Headers: headers, |
| ErrorAbortPredicates: []transport_tpg.RetryErrorPredicateFunc{transport_tpg.Is429QuotaError}, |
| }) |
| if err != nil { |
| return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("FilestoreInstance %q", d.Id())) |
| } |
| |
| if err := d.Set("project", project); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| |
| if err := d.Set("description", flattenFilestoreInstanceDescription(res["description"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| if err := d.Set("create_time", flattenFilestoreInstanceCreateTime(res["createTime"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| if err := d.Set("tier", flattenFilestoreInstanceTier(res["tier"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| if err := d.Set("protocol", flattenFilestoreInstanceProtocol(res["protocol"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| if err := d.Set("labels", flattenFilestoreInstanceLabels(res["labels"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| if err := d.Set("file_shares", flattenFilestoreInstanceFileShares(res["fileShares"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| if err := d.Set("networks", flattenFilestoreInstanceNetworks(res["networks"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| if err := d.Set("etag", flattenFilestoreInstanceEtag(res["etag"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| if err := d.Set("kms_key_name", flattenFilestoreInstanceKmsKeyName(res["kmsKeyName"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| if err := d.Set("terraform_labels", flattenFilestoreInstanceTerraformLabels(res["labels"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| if err := d.Set("effective_labels", flattenFilestoreInstanceEffectiveLabels(res["labels"], d, config)); err != nil { |
| return fmt.Errorf("Error reading Instance: %s", err) |
| } |
| |
| return nil |
| } |
| |
| func resourceFilestoreInstanceUpdate(d *schema.ResourceData, meta interface{}) error { |
| config := meta.(*transport_tpg.Config) |
| userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) |
| if err != nil { |
| return err |
| } |
| |
| billingProject := "" |
| |
| project, err := tpgresource.GetProject(d, config) |
| if err != nil { |
| return fmt.Errorf("Error fetching project for Instance: %s", err) |
| } |
| billingProject = project |
| |
| obj := make(map[string]interface{}) |
| descriptionProp, err := expandFilestoreInstanceDescription(d.Get("description"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { |
| obj["description"] = descriptionProp |
| } |
| fileSharesProp, err := expandFilestoreInstanceFileShares(d.Get("file_shares"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("file_shares"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, fileSharesProp)) { |
| obj["fileShares"] = fileSharesProp |
| } |
| labelsProp, err := expandFilestoreInstanceEffectiveLabels(d.Get("effective_labels"), d, config) |
| if err != nil { |
| return err |
| } else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelsProp)) { |
| obj["labels"] = labelsProp |
| } |
| |
| url, err := tpgresource.ReplaceVars(d, config, "{{FilestoreBasePath}}projects/{{project}}/locations/{{location}}/instances/{{name}}") |
| if err != nil { |
| return err |
| } |
| |
| log.Printf("[DEBUG] Updating Instance %q: %#v", d.Id(), obj) |
| headers := make(http.Header) |
| updateMask := []string{} |
| |
| if d.HasChange("description") { |
| updateMask = append(updateMask, "description") |
| } |
| |
| if d.HasChange("file_shares") { |
| updateMask = append(updateMask, "fileShares") |
| } |
| |
| if d.HasChange("effective_labels") { |
| updateMask = append(updateMask, "labels") |
| } |
| // updateMask is a URL parameter but not present in the schema, so ReplaceVars |
| // won't set it |
| url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) |
| if err != nil { |
| return err |
| } |
| |
| // err == nil indicates that the billing_project value was found |
| if bp, err := tpgresource.GetBillingProject(d, config); err == nil { |
| billingProject = bp |
| } |
| |
| // if updateMask is empty we are not updating anything so skip the post |
| if len(updateMask) > 0 { |
| res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ |
| Config: config, |
| Method: "PATCH", |
| Project: billingProject, |
| RawURL: url, |
| UserAgent: userAgent, |
| Body: obj, |
| Timeout: d.Timeout(schema.TimeoutUpdate), |
| Headers: headers, |
| ErrorAbortPredicates: []transport_tpg.RetryErrorPredicateFunc{transport_tpg.Is429QuotaError}, |
| }) |
| |
| if err != nil { |
| return fmt.Errorf("Error updating Instance %q: %s", d.Id(), err) |
| } else { |
| log.Printf("[DEBUG] Finished updating Instance %q: %#v", d.Id(), res) |
| } |
| |
| err = FilestoreOperationWaitTime( |
| config, res, project, "Updating Instance", userAgent, |
| d.Timeout(schema.TimeoutUpdate)) |
| |
| if err != nil { |
| return err |
| } |
| } |
| |
| return resourceFilestoreInstanceRead(d, meta) |
| } |
| |
| func resourceFilestoreInstanceDelete(d *schema.ResourceData, meta interface{}) error { |
| config := meta.(*transport_tpg.Config) |
| userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) |
| if err != nil { |
| return err |
| } |
| |
| billingProject := "" |
| |
| project, err := tpgresource.GetProject(d, config) |
| if err != nil { |
| return fmt.Errorf("Error fetching project for Instance: %s", err) |
| } |
| billingProject = project |
| |
| url, err := tpgresource.ReplaceVars(d, config, "{{FilestoreBasePath}}projects/{{project}}/locations/{{location}}/instances/{{name}}") |
| if err != nil { |
| return err |
| } |
| |
| var obj map[string]interface{} |
| |
| // err == nil indicates that the billing_project value was found |
| if bp, err := tpgresource.GetBillingProject(d, config); err == nil { |
| billingProject = bp |
| } |
| |
| headers := make(http.Header) |
| |
| log.Printf("[DEBUG] Deleting Instance %q", d.Id()) |
| res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ |
| Config: config, |
| Method: "DELETE", |
| Project: billingProject, |
| RawURL: url, |
| UserAgent: userAgent, |
| Body: obj, |
| Timeout: d.Timeout(schema.TimeoutDelete), |
| Headers: headers, |
| ErrorAbortPredicates: []transport_tpg.RetryErrorPredicateFunc{transport_tpg.Is429QuotaError}, |
| }) |
| if err != nil { |
| return transport_tpg.HandleNotFoundError(err, d, "Instance") |
| } |
| |
| err = FilestoreOperationWaitTime( |
| config, res, project, "Deleting Instance", userAgent, |
| d.Timeout(schema.TimeoutDelete)) |
| |
| if err != nil { |
| return err |
| } |
| |
| log.Printf("[DEBUG] Finished deleting Instance %q: %#v", d.Id(), res) |
| return nil |
| } |
| |
| func resourceFilestoreInstanceImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { |
| config := meta.(*transport_tpg.Config) |
| if err := tpgresource.ParseImportId([]string{ |
| "^projects/(?P<project>[^/]+)/locations/(?P<location>[^/]+)/instances/(?P<name>[^/]+)$", |
| "^(?P<project>[^/]+)/(?P<location>[^/]+)/(?P<name>[^/]+)$", |
| "^(?P<location>[^/]+)/(?P<name>[^/]+)$", |
| }, d, config); err != nil { |
| return nil, err |
| } |
| |
| // Replace import id for the resource id |
| id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/instances/{{name}}") |
| if err != nil { |
| return nil, fmt.Errorf("Error constructing id: %s", err) |
| } |
| d.SetId(id) |
| |
| return []*schema.ResourceData{d}, nil |
| } |
| |
| func flattenFilestoreInstanceDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceTier(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceProtocol(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil || tpgresource.IsEmptyValue(reflect.ValueOf(v)) { |
| return "NFS_V3" |
| } |
| |
| return v |
| } |
| |
| func flattenFilestoreInstanceLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return v |
| } |
| |
| transformed := make(map[string]interface{}) |
| if l, ok := d.GetOkExists("labels"); ok { |
| for k := range l.(map[string]interface{}) { |
| transformed[k] = v.(map[string]interface{})[k] |
| } |
| } |
| |
| return transformed |
| } |
| |
| func flattenFilestoreInstanceFileShares(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return v |
| } |
| l := v.([]interface{}) |
| transformed := make([]interface{}, 0, len(l)) |
| for _, raw := range l { |
| original := raw.(map[string]interface{}) |
| if len(original) < 1 { |
| // Do not include empty json objects coming back from the api |
| continue |
| } |
| transformed = append(transformed, map[string]interface{}{ |
| "name": flattenFilestoreInstanceFileSharesName(original["name"], d, config), |
| "capacity_gb": flattenFilestoreInstanceFileSharesCapacityGb(original["capacityGb"], d, config), |
| "source_backup": flattenFilestoreInstanceFileSharesSourceBackup(original["sourceBackup"], d, config), |
| "nfs_export_options": flattenFilestoreInstanceFileSharesNfsExportOptions(original["nfsExportOptions"], d, config), |
| }) |
| } |
| return transformed |
| } |
| func flattenFilestoreInstanceFileSharesName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceFileSharesCapacityGb(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| // Handles the string fixed64 format |
| if strVal, ok := v.(string); ok { |
| if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { |
| return intVal |
| } |
| } |
| |
| // number values are represented as float64 |
| if floatVal, ok := v.(float64); ok { |
| intVal := int(floatVal) |
| return intVal |
| } |
| |
| return v // let terraform core handle it otherwise |
| } |
| |
| func flattenFilestoreInstanceFileSharesSourceBackup(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceFileSharesNfsExportOptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return v |
| } |
| l := v.([]interface{}) |
| transformed := make([]interface{}, 0, len(l)) |
| for _, raw := range l { |
| original := raw.(map[string]interface{}) |
| if len(original) < 1 { |
| // Do not include empty json objects coming back from the api |
| continue |
| } |
| transformed = append(transformed, map[string]interface{}{ |
| "ip_ranges": flattenFilestoreInstanceFileSharesNfsExportOptionsIpRanges(original["ipRanges"], d, config), |
| "access_mode": flattenFilestoreInstanceFileSharesNfsExportOptionsAccessMode(original["accessMode"], d, config), |
| "squash_mode": flattenFilestoreInstanceFileSharesNfsExportOptionsSquashMode(original["squashMode"], d, config), |
| "anon_uid": flattenFilestoreInstanceFileSharesNfsExportOptionsAnonUid(original["anonUid"], d, config), |
| "anon_gid": flattenFilestoreInstanceFileSharesNfsExportOptionsAnonGid(original["anonGid"], d, config), |
| }) |
| } |
| return transformed |
| } |
| func flattenFilestoreInstanceFileSharesNfsExportOptionsIpRanges(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceFileSharesNfsExportOptionsAccessMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceFileSharesNfsExportOptionsSquashMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceFileSharesNfsExportOptionsAnonUid(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| // Handles the string fixed64 format |
| if strVal, ok := v.(string); ok { |
| if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { |
| return intVal |
| } |
| } |
| |
| // number values are represented as float64 |
| if floatVal, ok := v.(float64); ok { |
| intVal := int(floatVal) |
| return intVal |
| } |
| |
| return v // let terraform core handle it otherwise |
| } |
| |
| func flattenFilestoreInstanceFileSharesNfsExportOptionsAnonGid(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| // Handles the string fixed64 format |
| if strVal, ok := v.(string); ok { |
| if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { |
| return intVal |
| } |
| } |
| |
| // number values are represented as float64 |
| if floatVal, ok := v.(float64); ok { |
| intVal := int(floatVal) |
| return intVal |
| } |
| |
| return v // let terraform core handle it otherwise |
| } |
| |
| func flattenFilestoreInstanceNetworks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return v |
| } |
| l := v.([]interface{}) |
| transformed := make([]interface{}, 0, len(l)) |
| for _, raw := range l { |
| original := raw.(map[string]interface{}) |
| if len(original) < 1 { |
| // Do not include empty json objects coming back from the api |
| continue |
| } |
| transformed = append(transformed, map[string]interface{}{ |
| "network": flattenFilestoreInstanceNetworksNetwork(original["network"], d, config), |
| "modes": flattenFilestoreInstanceNetworksModes(original["modes"], d, config), |
| "reserved_ip_range": flattenFilestoreInstanceNetworksReservedIpRange(original["reservedIpRange"], d, config), |
| "ip_addresses": flattenFilestoreInstanceNetworksIpAddresses(original["ipAddresses"], d, config), |
| "connect_mode": flattenFilestoreInstanceNetworksConnectMode(original["connectMode"], d, config), |
| }) |
| } |
| return transformed |
| } |
| func flattenFilestoreInstanceNetworksNetwork(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceNetworksModes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceNetworksReservedIpRange(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return d.Get("networks.0.reserved_ip_range") |
| } |
| |
| func flattenFilestoreInstanceNetworksIpAddresses(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceNetworksConnectMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil || tpgresource.IsEmptyValue(reflect.ValueOf(v)) { |
| return "DIRECT_PEERING" |
| } |
| |
| return v |
| } |
| |
| func flattenFilestoreInstanceEtag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceKmsKeyName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func flattenFilestoreInstanceTerraformLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| if v == nil { |
| return v |
| } |
| |
| transformed := make(map[string]interface{}) |
| if l, ok := d.GetOkExists("terraform_labels"); ok { |
| for k := range l.(map[string]interface{}) { |
| transformed[k] = v.(map[string]interface{})[k] |
| } |
| } |
| |
| return transformed |
| } |
| |
| func flattenFilestoreInstanceEffectiveLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { |
| return v |
| } |
| |
| func expandFilestoreInstanceDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceTier(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceProtocol(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceFileShares(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| l := v.([]interface{}) |
| req := make([]interface{}, 0, len(l)) |
| for _, raw := range l { |
| if raw == nil { |
| continue |
| } |
| original := raw.(map[string]interface{}) |
| transformed := make(map[string]interface{}) |
| |
| transformedName, err := expandFilestoreInstanceFileSharesName(original["name"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedName); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["name"] = transformedName |
| } |
| |
| transformedCapacityGb, err := expandFilestoreInstanceFileSharesCapacityGb(original["capacity_gb"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedCapacityGb); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["capacityGb"] = transformedCapacityGb |
| } |
| |
| transformedSourceBackup, err := expandFilestoreInstanceFileSharesSourceBackup(original["source_backup"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedSourceBackup); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["sourceBackup"] = transformedSourceBackup |
| } |
| |
| transformedNfsExportOptions, err := expandFilestoreInstanceFileSharesNfsExportOptions(original["nfs_export_options"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedNfsExportOptions); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["nfsExportOptions"] = transformedNfsExportOptions |
| } |
| |
| req = append(req, transformed) |
| } |
| return req, nil |
| } |
| |
| func expandFilestoreInstanceFileSharesName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceFileSharesCapacityGb(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceFileSharesSourceBackup(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceFileSharesNfsExportOptions(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| l := v.([]interface{}) |
| req := make([]interface{}, 0, len(l)) |
| for _, raw := range l { |
| if raw == nil { |
| continue |
| } |
| original := raw.(map[string]interface{}) |
| transformed := make(map[string]interface{}) |
| |
| transformedIpRanges, err := expandFilestoreInstanceFileSharesNfsExportOptionsIpRanges(original["ip_ranges"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedIpRanges); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["ipRanges"] = transformedIpRanges |
| } |
| |
| transformedAccessMode, err := expandFilestoreInstanceFileSharesNfsExportOptionsAccessMode(original["access_mode"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedAccessMode); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["accessMode"] = transformedAccessMode |
| } |
| |
| transformedSquashMode, err := expandFilestoreInstanceFileSharesNfsExportOptionsSquashMode(original["squash_mode"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedSquashMode); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["squashMode"] = transformedSquashMode |
| } |
| |
| transformedAnonUid, err := expandFilestoreInstanceFileSharesNfsExportOptionsAnonUid(original["anon_uid"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedAnonUid); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["anonUid"] = transformedAnonUid |
| } |
| |
| transformedAnonGid, err := expandFilestoreInstanceFileSharesNfsExportOptionsAnonGid(original["anon_gid"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedAnonGid); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["anonGid"] = transformedAnonGid |
| } |
| |
| req = append(req, transformed) |
| } |
| return req, nil |
| } |
| |
| func expandFilestoreInstanceFileSharesNfsExportOptionsIpRanges(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceFileSharesNfsExportOptionsAccessMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceFileSharesNfsExportOptionsSquashMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceFileSharesNfsExportOptionsAnonUid(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceFileSharesNfsExportOptionsAnonGid(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceNetworks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| l := v.([]interface{}) |
| req := make([]interface{}, 0, len(l)) |
| for _, raw := range l { |
| if raw == nil { |
| continue |
| } |
| original := raw.(map[string]interface{}) |
| transformed := make(map[string]interface{}) |
| |
| transformedNetwork, err := expandFilestoreInstanceNetworksNetwork(original["network"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedNetwork); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["network"] = transformedNetwork |
| } |
| |
| transformedModes, err := expandFilestoreInstanceNetworksModes(original["modes"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedModes); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["modes"] = transformedModes |
| } |
| |
| transformedReservedIpRange, err := expandFilestoreInstanceNetworksReservedIpRange(original["reserved_ip_range"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedReservedIpRange); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["reservedIpRange"] = transformedReservedIpRange |
| } |
| |
| transformedIpAddresses, err := expandFilestoreInstanceNetworksIpAddresses(original["ip_addresses"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedIpAddresses); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["ipAddresses"] = transformedIpAddresses |
| } |
| |
| transformedConnectMode, err := expandFilestoreInstanceNetworksConnectMode(original["connect_mode"], d, config) |
| if err != nil { |
| return nil, err |
| } else if val := reflect.ValueOf(transformedConnectMode); val.IsValid() && !tpgresource.IsEmptyValue(val) { |
| transformed["connectMode"] = transformedConnectMode |
| } |
| |
| req = append(req, transformed) |
| } |
| return req, nil |
| } |
| |
| func expandFilestoreInstanceNetworksNetwork(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceNetworksModes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceNetworksReservedIpRange(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceNetworksIpAddresses(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceNetworksConnectMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceKmsKeyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { |
| return v, nil |
| } |
| |
| func expandFilestoreInstanceEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { |
| if v == nil { |
| return map[string]string{}, nil |
| } |
| m := make(map[string]string) |
| for k, val := range v.(map[string]interface{}) { |
| m[k] = val.(string) |
| } |
| return m, nil |
| } |
| |
| func resourceFilestoreInstanceResourceV0() *schema.Resource { |
| return &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "file_shares": { |
| Type: schema.TypeList, |
| Required: true, |
| Description: `File system shares on the instance. For this version, only a |
| single file share is supported.`, |
| MaxItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "capacity_gb": { |
| Type: schema.TypeInt, |
| Required: true, |
| Description: `File share capacity in GiB. This must be at least 1024 GiB |
| for the standard tier, or 2560 GiB for the premium tier.`, |
| }, |
| "name": { |
| Type: schema.TypeString, |
| Required: true, |
| ForceNew: true, |
| Description: `The name of the fileshare (16 characters or less)`, |
| }, |
| "nfs_export_options": { |
| Type: schema.TypeList, |
| Optional: true, |
| Description: `Nfs Export Options. There is a limit of 10 export options per file share.`, |
| MaxItems: 10, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "access_mode": { |
| Type: schema.TypeString, |
| Optional: true, |
| ValidateFunc: validation.StringInSlice([]string{"READ_ONLY", "READ_WRITE", ""}, false), |
| Description: `Either READ_ONLY, for allowing only read requests on the exported directory, |
| or READ_WRITE, for allowing both read and write requests. The default is READ_WRITE. Default value: "READ_WRITE" Possible values: ["READ_ONLY", "READ_WRITE"]`, |
| Default: "READ_WRITE", |
| }, |
| "anon_gid": { |
| Type: schema.TypeInt, |
| Optional: true, |
| Description: `An integer representing the anonymous group id with a default value of 65534. |
| Anon_gid may only be set with squashMode of ROOT_SQUASH. An error will be returned |
| if this field is specified for other squashMode settings.`, |
| }, |
| "anon_uid": { |
| Type: schema.TypeInt, |
| Optional: true, |
| Description: `An integer representing the anonymous user id with a default value of 65534. |
| Anon_uid may only be set with squashMode of ROOT_SQUASH. An error will be returned |
| if this field is specified for other squashMode settings.`, |
| }, |
| "ip_ranges": { |
| Type: schema.TypeList, |
| Optional: true, |
| Description: `List of either IPv4 addresses, or ranges in CIDR notation which may mount the file share. |
| Overlapping IP ranges are not allowed, both within and across NfsExportOptions. An error will be returned. |
| The limit is 64 IP ranges/addresses for each FileShareConfig among all NfsExportOptions.`, |
| Elem: &schema.Schema{ |
| Type: schema.TypeString, |
| }, |
| }, |
| "squash_mode": { |
| Type: schema.TypeString, |
| Optional: true, |
| ValidateFunc: validation.StringInSlice([]string{"NO_ROOT_SQUASH", "ROOT_SQUASH", ""}, false), |
| Description: `Either NO_ROOT_SQUASH, for allowing root access on the exported directory, or ROOT_SQUASH, |
| for not allowing root access. The default is NO_ROOT_SQUASH. Default value: "NO_ROOT_SQUASH" Possible values: ["NO_ROOT_SQUASH", "ROOT_SQUASH"]`, |
| Default: "NO_ROOT_SQUASH", |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| "name": { |
| Type: schema.TypeString, |
| Required: true, |
| Description: `The resource name of the instance.`, |
| }, |
| "networks": { |
| Type: schema.TypeList, |
| Required: true, |
| ForceNew: true, |
| Description: `VPC networks to which the instance is connected. For this version, |
| only a single network is supported.`, |
| MinItems: 1, |
| Elem: &schema.Resource{ |
| Schema: map[string]*schema.Schema{ |
| "modes": { |
| Type: schema.TypeList, |
| Required: true, |
| ForceNew: true, |
| Description: `IP versions for which the instance has |
| IP addresses assigned. Possible values: ["ADDRESS_MODE_UNSPECIFIED", "MODE_IPV4", "MODE_IPV6"]`, |
| Elem: &schema.Schema{ |
| Type: schema.TypeString, |
| ValidateFunc: validation.StringInSlice([]string{"ADDRESS_MODE_UNSPECIFIED", "MODE_IPV4", "MODE_IPV6"}, false), |
| }, |
| }, |
| "network": { |
| Type: schema.TypeString, |
| Required: true, |
| ForceNew: true, |
| Description: `The name of the GCE VPC network to which the |
| instance is connected.`, |
| }, |
| "connect_mode": { |
| Type: schema.TypeString, |
| Optional: true, |
| ForceNew: true, |
| ValidateFunc: validation.StringInSlice([]string{"DIRECT_PEERING", "PRIVATE_SERVICE_ACCESS", ""}, false), |
| Description: `The network connect mode of the Filestore instance. |
| If not provided, the connect mode defaults to |
| DIRECT_PEERING. Default value: "DIRECT_PEERING" Possible values: ["DIRECT_PEERING", "PRIVATE_SERVICE_ACCESS"]`, |
| Default: "DIRECT_PEERING", |
| }, |
| "reserved_ip_range": { |
| Type: schema.TypeString, |
| Computed: true, |
| Optional: true, |
| Description: `A /29 CIDR block that identifies the range of IP |
| addresses reserved for this instance.`, |
| }, |
| "ip_addresses": { |
| Type: schema.TypeList, |
| Computed: true, |
| Description: `A list of IPv4 or IPv6 addresses.`, |
| Elem: &schema.Schema{ |
| Type: schema.TypeString, |
| }, |
| }, |
| }, |
| }, |
| }, |
| "tier": { |
| Type: schema.TypeString, |
| Required: true, |
| ForceNew: true, |
| ValidateFunc: validation.StringInSlice([]string{"TIER_UNSPECIFIED", "STANDARD", "PREMIUM", "BASIC_HDD", "BASIC_SSD", "HIGH_SCALE_SSD", "ZONAL"}, false), |
| Description: `The service tier of the instance. Possible values: ["TIER_UNSPECIFIED", "STANDARD", "PREMIUM", "BASIC_HDD", "BASIC_SSD", "HIGH_SCALE_SSD", "ZONAL"]`, |
| }, |
| "zone": { |
| Type: schema.TypeString, |
| Required: true, |
| ForceNew: true, |
| Description: `The name of the Filestore zone of the instance.`, |
| }, |
| "description": { |
| Type: schema.TypeString, |
| Optional: true, |
| Description: `A description of the instance.`, |
| }, |
| "labels": { |
| Type: schema.TypeMap, |
| Optional: true, |
| Description: `Resource labels to represent user-provided metadata.`, |
| Elem: &schema.Schema{Type: schema.TypeString}, |
| }, |
| "create_time": { |
| Type: schema.TypeString, |
| Computed: true, |
| Description: `Creation timestamp in RFC3339 text format.`, |
| }, |
| "etag": { |
| Type: schema.TypeString, |
| Computed: true, |
| Description: `Server-specified ETag for the instance resource to prevent |
| simultaneous updates from overwriting each other.`, |
| }, |
| "project": { |
| Type: schema.TypeString, |
| Optional: true, |
| Computed: true, |
| ForceNew: true, |
| }, |
| }, |
| } |
| } |
| |
| func ResourceFilestoreInstanceUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { |
| log.Printf("[DEBUG] Attributes before migration: %#v", rawState) |
| |
| rawState["location"] = rawState["zone"] |
| log.Printf("[DEBUG] Attributes after migration: %#v", rawState) |
| return rawState, nil |
| } |