# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

---
name: 'Subnetwork'
kind: 'compute#subnetwork'
description: |
  A VPC network is a virtual version of the traditional physical networks
  that exist within and between physical data centers. A VPC network
  provides connectivity for your Compute Engine virtual machine (VM)
  instances, Container Engine containers, App Engine Flex services, and
  other network-related resources.

  Each GCP project contains one or more VPC networks. Each VPC network is a
  global entity spanning all GCP regions. This global VPC network allows VM
  instances and other resources to communicate with each other via internal,
  private IP addresses.

  Each VPC network is subdivided into subnets, and each subnet is contained
  within a single region. You can have more than one subnet in a region for
  a given VPC network. Each subnet has a contiguous private RFC1918 IP
  space. You create instances, containers, and the like in these subnets.
  When you create an instance, you must create it in a subnet, and the
  instance draws its internal IP address from that subnet.

  Virtual machine (VM) instances in a VPC network can communicate with
  instances in all other subnets of the same VPC network, regardless of
  region, using their RFC1918 private IP addresses. You can isolate portions
  of the network, even entire subnets, using firewall rules.
references:
  guides:
    'Private Google Access': 'https://cloud.google.com/vpc/docs/configure-private-google-access'
    'Cloud Networking': 'https://cloud.google.com/vpc/docs/using-vpc'
  api: 'https://cloud.google.com/compute/docs/reference/rest/v1/subnetworks'
docs:
base_url: 'projects/{{project}}/regions/{{region}}/subnetworks'
has_self_link: true
immutable: true
timeouts:
  insert_minutes: 20
  update_minutes: 20
  delete_minutes: 20
async:
  actions: ['create', 'delete', 'update']
  type: 'OpAsync'
  operation:
    base_url: '{{op_id}}'
  result:
    resource_inside_response: false
collection_url_key: 'items'
iam_policy:
  allowed_iam_role: 'roles/compute.networkUser'
  parent_resource_attribute: 'subnetwork'
  iam_conditions_request_type: 'QUERY_PARAM'
  example_config_body: 'templates/terraform/iam/iam_attributes.go.tmpl'
custom_code:
  extra_schema_entry: 'templates/terraform/extra_schema_entry/subnetwork.tmpl'
  constants: 'templates/terraform/constants/subnetwork.tmpl'
  post_update: 'templates/terraform/post_update/compute_subnetwork.go.tmpl'
custom_diff:
  - 'customdiff.ForceNewIfChange("ip_cidr_range", IsShrinkageIpCidr)'
  - 'sendSecondaryIpRangeIfEmptyDiff'
sweeper:
  dependencies:
    - "google_compute_forwarding_rule"
  url_substitutions:
    - region: "us-west2"
    - region: "us-central1"
    - region: "us-east1"
    - region: "europe-west4"
    - region: "europe-west1"
    - region: "southamerica-west1"
    - region: "us-west1"
    - region: "us-south1"
examples:
  - name: 'subnetwork_basic'
    primary_resource_id: 'network-with-private-secondary-ip-ranges'
    primary_resource_name: 'fmt.Sprintf("tf-test-test-subnetwork%s", context["random_suffix"])'
    vars:
      subnetwork_name: 'test-subnetwork'
      network_name: 'test-network'
  - name: 'subnetwork_logging_config'
    primary_resource_id: 'subnet-with-logging'
    vars:
      subnetwork_name: 'log-test-subnetwork'
      network_name: 'log-test-network'
  - name: 'subnetwork_internal_l7lb'
    primary_resource_id: 'network-for-l7lb'
    min_version: 'beta'
    vars:
      subnetwork_name: 'l7lb-test-subnetwork'
      network_name: 'l7lb-test-network'
  - name: 'subnetwork_ipv6'
    primary_resource_id: 'subnetwork-ipv6'
    vars:
      subnetwork_name: 'ipv6-test-subnetwork'
      network_name: 'ipv6-test-network'
  - name: 'subnetwork_internal_ipv6'
    primary_resource_id: 'subnetwork-internal-ipv6'
    vars:
      subnetwork_name: 'internal-ipv6-test-subnetwork'
      network_name: 'internal-ipv6-test-network'
  - name: 'subnetwork_purpose_private_nat'
    primary_resource_id: 'subnetwork-purpose-private-nat'
    min_version: 'beta'
    vars:
      subnetwork_name: 'subnet-purpose-test-subnetwork'
      network_name: 'subnet-purpose-test-network'
  - name: 'subnetwork_cidr_overlap'
    primary_resource_id: 'subnetwork-cidr-overlap'
    min_version: 'beta'
    vars:
      subnetwork_name: 'subnet-cidr-overlap'
      network_name: 'net-cidr-overlap'
  - name: 'subnetwork_reserved_internal_range'
    primary_resource_id: 'subnetwork-reserved-internal-range'
    min_version: 'beta'
    vars:
      subnetwork_name: 'subnetwork-reserved-internal-range'
      network_name: 'network-reserved-internal-range'
  - name: 'subnetwork_reserved_secondary_range'
    primary_resource_id: 'subnetwork-reserved-secondary-range'
    min_version: 'beta'
    vars:
      subnetwork_name: 'subnetwork-reserved-secondary-range'
      network_name: 'network-reserved-secondary-range'
      primary_range_name: 'reserved-primary'
      secondary_range_name: 'reserved-secondary'
  - name: 'subnetwork_ipv6_only_internal'
    primary_resource_id: 'subnetwork-ipv6-only'
    exclude_docs: true
    vars:
      subnetwork_name: 'subnet-ipv6-only'
      network_name: 'network-ipv6-only'
  - name: 'subnetwork_with_subnet_mode_pdp'
    primary_resource_id: 'subnetwork-with-subnet-mode-pdp'
    exclude_docs: true
    vars:
      subnetwork_name: 'subnet-mode-pdp-subnet'
      network_name: 'network-byoipv6-external'
      ip_collection_url: '"projects/tf-static-byoip/regions/us-central1/publicDelegatedPrefixes/tf-test-subnet-mode-pdp"'
    test_vars_overrides:
      ip_collection_url: '"projects/tf-static-byoip/regions/us-central1/publicDelegatedPrefixes/tf-test-subnet-mode-pdp"'
  - name: 'subnetwork_ipv6_only_external'
    primary_resource_id: 'subnetwork-ipv6-only'
    exclude_docs: true
    vars:
      subnetwork_name: 'subnet-ipv6-only'
      network_name: 'network-ipv6-only'
virtual_fields:
  - name: 'send_secondary_ip_range_if_empty'
    description: |
      Controls the removal behavior of secondary_ip_range.
      When false, removing secondary_ip_range from config will not produce a diff as
      the provider will default to the API's value.
      When true, the provider will treat removing secondary_ip_range as sending an
      empty list of secondary IP ranges to the API.
      Defaults to false.
    type: Boolean
parameters:
properties:
  - name: 'creationTimestamp'
    type: Time
    description: 'Creation timestamp in RFC3339 text format.'
    output: true
  - name: 'description'
    type: String
    description: |
      An optional description of this resource. Provide this property when
      you create the resource. This field can be set only at resource
      creation time.
  - name: 'subnetworkId'
    type: Integer
    description: |
      The unique identifier number for the resource. This identifier is defined by the server.
    api_name: id
    output: true
  - name: 'gatewayAddress'
    type: String
    description: |
      The gateway address for default routes to reach destination addresses
      outside this subnetwork.
    output: true
  - name: 'ipCidrRange'
    type: String
    description: |
      The range of internal addresses that are owned by this subnetwork.
      Provide this property when you create the subnetwork. For example,
      10.0.0.0/8 or 192.168.0.0/16. Ranges must be unique and
      non-overlapping within a network. Only IPv4 is supported.
      Field is optional when `reserved_internal_range` is defined, otherwise required.
    required: false
    default_from_api: true
    update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}/expandIpCidrRange'
    update_verb: 'POST'
    validation:
      function: 'verify.ValidateIpCidrRange'
  - name: 'reservedInternalRange'
    type: ResourceRef
    description: |
      The ID of the reserved internal range. Must be prefixed with `networkconnectivity.googleapis.com`
      E.g. `networkconnectivity.googleapis.com/projects/{project}/locations/global/internalRanges/{rangeId}`
    resource: 'InternalRange'
    imports: 'selfLink'
  - name: 'name'
    type: String
    description: |
      The name of the resource, provided by the client when initially
      creating the resource. The name must be 1-63 characters long, and
      comply with RFC1035. Specifically, the name must be 1-63 characters
      long and match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which
      means the first character must be a lowercase letter, and all
      following characters must be a dash, lowercase letter, or digit,
      except the last character, which cannot be a dash.
    required: true
    validation:
      function: 'verify.ValidateGCEName'
  - name: 'network'
    type: ResourceRef
    description: |
      The network this subnet belongs to.
      Only networks that are in the distributed mode can have subnetworks.
    required: true
    immutable: true
    custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl'
    resource: 'Network'
    imports: 'selfLink'
  - name: 'purpose'
    type: String
    description: |
      The purpose of the resource. This field can be either `PRIVATE`, `REGIONAL_MANAGED_PROXY`, `GLOBAL_MANAGED_PROXY`, `PRIVATE_SERVICE_CONNECT`, `PEER_MIGRATION` or `PRIVATE_NAT`([Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)).
      A subnet with purpose set to `REGIONAL_MANAGED_PROXY` is a user-created subnetwork that is reserved for regional Envoy-based load balancers.
      A subnetwork in a given region with purpose set to `GLOBAL_MANAGED_PROXY` is a proxy-only subnet and is shared between all the cross-regional Envoy-based load balancers.
      A subnetwork with purpose set to `PRIVATE_SERVICE_CONNECT` reserves the subnet for hosting a Private Service Connect published service.
      A subnetwork with purpose set to `PEER_MIGRATION` is a user created subnetwork that is reserved for migrating resources from one peered network to another.
      A subnetwork with purpose set to `PRIVATE_NAT` is used as source range for Private NAT gateways.
      Note that `REGIONAL_MANAGED_PROXY` is the preferred setting for all regional Envoy load balancers.
      If unspecified, the purpose defaults to `PRIVATE`.
    default_from_api: true
    update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}'
    update_verb: 'PATCH'
    update_id: 'purpose'
    fingerprint_name: 'fingerprint'
  - name: 'role'
    type: Enum
    description: |
      The role of subnetwork.
      Currently, this field is only used when `purpose` is `REGIONAL_MANAGED_PROXY`.
      The value can be set to `ACTIVE` or `BACKUP`.
      An `ACTIVE` subnetwork is one that is currently being used for Envoy-based load balancers in a region.
      A `BACKUP` subnetwork is one that is ready to be promoted to `ACTIVE` or is currently draining.
    update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}'
    update_verb: 'PATCH'
    update_id: 'role'
    fingerprint_name: 'fingerprint'
    enum_values:
      - 'ACTIVE'
      - 'BACKUP'
  - name: 'secondaryIpRange'
    type: Array
    description: |
      An array of configurations for secondary IP ranges for VM instances
      contained in this subnetwork. The primary IP of such VM must belong
      to the primary ipCidrRange of the subnetwork. The alias IPs may belong
      to either primary or secondary ranges.

      **Note**: This field uses [attr-as-block mode](https://www.terraform.io/docs/configuration/attr-as-blocks.html) to avoid
      breaking users during the 0.12 upgrade. To explicitly send a list of zero objects,
      set `send_secondary_ip_range_if_empty = true`
    api_name: secondaryIpRanges
    unordered_list: true
    default_from_api: true
    send_empty_value: true
    update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}'
    update_verb: 'PATCH'
    update_id: 'secondaryIpRanges'
    fingerprint_name: 'fingerprint'
    item_type:
      type: NestedObject
      properties:
        - name: 'rangeName'
          type: String
          description: |
            The name associated with this subnetwork secondary range, used
            when adding an alias IP range to a VM instance. The name must
            be 1-63 characters long, and comply with RFC1035. The name
            must be unique within the subnetwork.
          required: true
          validation:
            function: 'verify.ValidateGCEName'
        - name: 'ipCidrRange'
          type: String
          description: |
            The range of IP addresses belonging to this subnetwork secondary
            range. Provide this property when you create the subnetwork.
            Ranges must be unique and non-overlapping with all primary and
            secondary IP ranges within a network. Only IPv4 is supported.
            Field is optional when `reserved_internal_range` is defined, otherwise required.
          required: false
          default_from_api: true
          validation:
            function: 'verify.ValidateIpCidrRange'
        - name: 'reservedInternalRange'
          type: ResourceRef
          description: |
            The ID of the reserved internal range. Must be prefixed with `networkconnectivity.googleapis.com`
            E.g. `networkconnectivity.googleapis.com/projects/{project}/locations/global/internalRanges/{rangeId}`
          resource: 'InternalRange'
          imports: 'selfLink'
  - name: 'privateIpGoogleAccess'
    type: Boolean
    description: |
      When enabled, VMs in this subnetwork without external IP addresses can
      access Google APIs and services by using Private Google Access.
    default_from_api: true
    update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}/setPrivateIpGoogleAccess'
    update_verb: 'POST'
  - name: 'privateIpv6GoogleAccess'
    type: String
    description: The private IPv6 google access type for the VMs in this subnet.
    default_from_api: true
    update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}'
    update_verb: 'PATCH'
    fingerprint_name: 'fingerprint'
  - name: 'region'
    type: ResourceRef
    description: |
      The GCP region for this subnetwork.
    required: false
    immutable: true
    default_from_api: true
    custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.tmpl'
    custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl'
    resource: 'Region'
    imports: 'name'
  - name: 'logConfig'
    type: NestedObject
    description: |
      This field denotes the VPC flow logging options for this subnetwork. If
      logging is enabled, logs are exported to Cloud Logging. Flow logging
      isn't supported if the subnet `purpose` field is set to subnetwork is
      `REGIONAL_MANAGED_PROXY` or `GLOBAL_MANAGED_PROXY`.
    send_empty_value: true
    update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}'
    update_verb: 'PATCH'
    update_id: 'logConfig'
    fingerprint_name: 'fingerprint'
    custom_flatten: 'templates/terraform/custom_flatten/subnetwork_log_config.go.tmpl'
    custom_expand: 'templates/terraform/custom_expand/subnetwork_log_config.go.tmpl'
    diff_suppress_func: 'subnetworkLogConfigDiffSuppress'
    properties:
      - name: 'aggregationInterval'
        type: Enum
        description: |
          Can only be specified if VPC flow logging for this subnetwork is enabled.
          Toggles the aggregation interval for collecting flow logs. Increasing the
          interval time will reduce the amount of generated flow logs for long
          lasting connections. Default is an interval of 5 seconds per connection.
        at_least_one_of:
          - 'log_config.0.aggregation_interval'
          - 'log_config.0.flow_sampling'
          - 'log_config.0.metadata'
          - 'log_config.0.filterExpr'
        default_value: "INTERVAL_5_SEC"
        enum_values:
          - 'INTERVAL_5_SEC'
          - 'INTERVAL_30_SEC'
          - 'INTERVAL_1_MIN'
          - 'INTERVAL_5_MIN'
          - 'INTERVAL_10_MIN'
          - 'INTERVAL_15_MIN'
      - name: 'flowSampling'
        type: Double
        description: |
          Can only be specified if VPC flow logging for this subnetwork is enabled.
          The value of the field must be in [0, 1]. Set the sampling rate of VPC
          flow logs within the subnetwork where 1.0 means all collected logs are
          reported and 0.0 means no logs are reported. Default is 0.5 which means
          half of all collected logs are reported.
        at_least_one_of:
          - 'log_config.0.aggregation_interval'
          - 'log_config.0.flow_sampling'
          - 'log_config.0.metadata'
          - 'log_config.0.filterExpr'
        default_value: 0.5
      - name: 'metadata'
        type: Enum
        description: |
          Can only be specified if VPC flow logging for this subnetwork is enabled.
          Configures whether metadata fields should be added to the reported VPC
          flow logs.
        at_least_one_of:
          - 'log_config.0.aggregation_interval'
          - 'log_config.0.flow_sampling'
          - 'log_config.0.metadata'
          - 'log_config.0.filterExpr'
        default_value: "INCLUDE_ALL_METADATA"
        enum_values:
          - 'EXCLUDE_ALL_METADATA'
          - 'INCLUDE_ALL_METADATA'
          - 'CUSTOM_METADATA'
      - name: 'metadataFields'
        type: Array
        description: |
          List of metadata fields that should be added to reported logs.
          Can only be specified if VPC flow logs for this subnetwork is enabled and "metadata" is set to CUSTOM_METADATA.
        is_set: true
        item_type:
          type: String
      - name: 'filterExpr'
        type: String
        description: |
          Export filter used to define which VPC flow logs should be logged, as as CEL expression. See
          https://cloud.google.com/vpc/docs/flow-logs#filtering for details on how to format this field.
          The default value is 'true', which evaluates to include everything.
        at_least_one_of:
          - 'log_config.0.aggregation_interval'
          - 'log_config.0.flow_sampling'
          - 'log_config.0.metadata'
          - 'log_config.0.filterExpr'
        default_value: "true"
  - name: 'stackType'
    type: Enum
    description: |
      The stack type for this subnet to identify whether the IPv6 feature is enabled or not.
      If not specified IPV4_ONLY will be used.
    default_from_api: true
    update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}'
    update_verb: 'PATCH'
    fingerprint_name: 'fingerprint'
    enum_values:
      - 'IPV4_ONLY'
      - 'IPV4_IPV6'
      - 'IPV6_ONLY'
  - name: 'ipv6AccessType'
    type: Enum
    description: |
      The access type of IPv6 address this subnet holds. It's immutable and can only be specified during creation
      or the first time the subnet is updated into IPV4_IPV6 dual stack. If the ipv6_type is EXTERNAL then this subnet
      cannot enable direct path.
    update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}'
    update_verb: 'PATCH'
    fingerprint_name: 'fingerprint'
    enum_values:
      - 'EXTERNAL'
      - 'INTERNAL'
  - name: 'ipv6CidrRange'
    type: String
    description: |
      The range of internal IPv6 addresses that are owned by this subnetwork.
    output: true
  - name: 'internalIpv6Prefix'
    type: String
    description: |
      The internal IPv6 address range that is assigned to this subnetwork.
    output: true
  - name: 'externalIpv6Prefix'
    type: String
    description: |
      The range of external IPv6 addresses that are owned by this subnetwork.
    default_from_api: true
  - name: 'ipCollection'
    type: String
    ignore_read: true
    description: |
      Resource reference of a PublicDelegatedPrefix. The PDP must be a sub-PDP
      in EXTERNAL_IPV6_SUBNETWORK_CREATION mode.
      Use one of the following formats to specify a sub-PDP when creating an
      IPv6 NetLB forwarding rule using BYOIP:
      Full resource URL, as in:
        * `https://www.googleapis.com/compute/v1/projects/{{projectId}}/regions/{{region}}/publicDelegatedPrefixes/{{sub-pdp-name}}`
      Partial URL, as in:
        * `projects/{{projectId}}/regions/region/publicDelegatedPrefixes/{{sub-pdp-name}}`
        * `regions/{{region}}/publicDelegatedPrefixes/{{sub-pdp-name}}`
  - name: 'ipv6GceEndpoint'
    type: Enum
    description: |
      Possible endpoints of this subnetwork. It can be one of the following:
        * VM_ONLY: The subnetwork can be used for creating instances and IPv6 addresses with VM endpoint type. Such a subnetwork
        gets external IPv6 ranges from a public delegated prefix and cannot be used to create NetLb.
        * VM_AND_FR: The subnetwork can be used for creating both VM instances and Forwarding Rules. It can also be used to reserve
        IPv6 addresses with both VM and FR endpoint types. Such a subnetwork gets its IPv6 range from Google IP Pool directly.
    output: true
    enum_values:
      - 'VM_AND_FR'
      - 'VM_ONLY'
  - name: 'allowSubnetCidrRoutesOverlap'
    type: Boolean
    description: |
      Typically packets destined to IPs within the subnetwork range that do not match
      existing resources are dropped and prevented from leaving the VPC.
      Setting this field to true will allow these packets to match dynamic routes injected
      via BGP even if their destinations match existing subnet ranges.
    min_version: 'beta'
    default_from_api: true
    send_empty_value: true
    update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}'
    update_verb: 'PATCH'
    fingerprint_name: 'fingerprint'
  - name: 'enableFlowLogs'
    type: Boolean
    description: |
      Whether to enable flow logging for this subnetwork. If this field is not explicitly set,
      it will not appear in get listings. If not set the default behavior is determined by the
      org policy, if there is no org policy specified, then it will default to disabled.
      This field isn't supported if the subnet purpose field is set to REGIONAL_MANAGED_PROXY.
    default_from_api: true
    deprecation_message: 'This field is being removed in favor of log_config. If log_config is present, flow logs are enabled.'
  - name: 'state'
    type: Enum
    description: |
     'The state of the subnetwork, which can be one of the following values:
      READY: Subnetwork is created and ready to use DRAINING: only applicable to subnetworks that have the purpose
      set to INTERNAL_HTTPS_LOAD_BALANCER and indicates that connections to the load balancer are being drained.
      A subnetwork that is draining cannot be used or modified until it reaches a status of READY'
    output: true
