- release_tracks: [ALPHA, GA]

  help_text:
    brief: |
      Create a new internal range.
    description: |
      Create a new internal range with the given name.
    examples: |
      Create an internal range with name ``my-range'' and ip-cidr-range ``192.168.0.0/25'' in
      network ``https://www.googleapis.com/compute/v1/projects/my-project/locations/global/networks/my-network'':

        $ {command} my-range
          --ip-cidr-range="192.168.0.0/25"
          --network="https://www.googleapis.com/compute/v1/projects/my-project/locations/global/networks/my-network"
          --project=my-project

      Create an internal range with name ``my-range'' and auto-allocated /25 block (prefix-length
      ``25'') in network ``my-network'':

        $ {command} my-range
          --prefix-length=25
          --network="my-network"
          --project=my-project

  arguments:
    resource:
      spec: !REF googlecloudsdk.command_lib.network_connectivity.resources:internalRange
      help_text: |
        Name of the internal range to be created.
    params:
    - arg_name: description
      api_field: internalRange.description
      help_text: |
        Description of the internal range to be created.
    - group:
        mutex: true
        required: true
        params:
        - arg_name: ip-cidr-range
          api_field: internalRange.ipCidrRange
          help_text: |
            IP range that this internal range defines.
        - group:
            params:
            - arg_name: prefix-length
              api_field: internalRange.prefixLength
              help_text: |
                An alternative to ip-cidr-range.
                Can be set when trying to create a reservation that automatically finds a free range
                of the given size.
              required: true
            - group:
                help_text: |
                  Additional options for the internal range's address auto-allocation (allowed only
                  when prefix-length is set):
                params:
                - arg_name: target-cidr-range
                  api_field: internalRange.targetCidrRange
                  help_text: |
                    Can be set to narrow down or pick a different address space while searching for
                    a free range.
                    If not set, defaults to the "10.0.0.0/8" address space. This can be used to
                    search in other rfc-1918 address spaces like "172.16.0.0/12" and
                    "192.168.0.0/16" or non-rfc-1918 address spaces used in the VPC.
                  type: arg_list
                - arg_name: exclude-cidr-ranges
                  api_field: internalRange.excludeCidrRanges
                  help_text: |
                    A list of CIDR ranges to exclude from the search for a free range.
                    This can be used to exclude specific ranges that are already intended to
                    have some other use.
                  type: arg_list
                - arg_name: allocation-strategy
                  api_field: internalRange.allocationOptions.allocationStrategy
                  help_text: |
                    Allocation strategy to be used when searching for a free range.
                  choices:
                  - arg_value: random
                    enum_value: RANDOM
                    help_text: |
                      Random strategy, the legacy algorithm, used for backwards compatibility. This
                      allocation strategy remains efficient in the case of concurrent allocation
                      requests in the same peered network space and doesn't require providing the
                      level of concurrency in an explicit parameter, but it is prone to fragmenting
                      available address space.
                  - arg_value: first-available
                    enum_value: FIRST_AVAILABLE
                    help_text: |
                      Pick the first available address range. This strategy is deterministic and the
                      result is easy to predict.
                  - arg_value: random-first-n-available
                    enum_value: RANDOM_FIRST_N_AVAILABLE
                    help_text: |
                      Pick an arbitrary range out of the first N available ones. The N will be set
                      in the first_available_ranges_lookup_size flag. This strategy should be used
                      when concurrent allocation requests are made in the same space of peered
                      networks  while the fragmentation of the addrress space is reduced.
                  - arg_value: first-smallest-fitting
                    enum_value: FIRST_SMALLEST_FITTING
                    help_text: |
                      Pick the smallest but fitting available range. This deterministic strategy
                      minimizes fragmentation of the address space.
                - arg_name: first-available-ranges-lookup-size
                  api_field: internalRange.allocationOptions.firstAvailableRangesLookupSize
                  help_text: |
                    The number of ranges to be considered when using the
                    RANDOM_FIRST_N_AVAILABLE allocation strategy. This is only allowed when
                    allocation-strategy is set to RANDOM_FIRST_N_AVAILABLE.
    - arg_name: labels
      api_field: internalRange.labels.additionalProperties
      metavar: KEY=VALUE
      help_text: |
        List of label KEY=VALUE pairs to add.
      type:
        arg_dict:
          flatten: true
          spec:
          - api_field: key
          - api_field: value
    - arg_name: network
      api_field: internalRange.network
      help_text: |
        The URL or resource ID of the network in which to reserve the internal range.
        Legacy network is not supported. This can only be specified for a global internal address.

        For example:
          - https://www.googleapis.com/compute/v1/projects/my-project/locations/global/networks/my-network
          - /projects/my-project/locations/global/networks/my-network
          - my-network
      required: true
    - arg_name: usage
      api_field: internalRange.usage
      help_text: |
        The type of usage set for the internal range.
      choices:
      - arg_value: for-vpc
        enum_value: FOR_VPC
        help_text: |
          A cloud resource can use the reserved CIDR block by associating it with the internal range
          resource if usage is set to FOR_VPC.
      - arg_value: external-to-vpc
        enum_value: EXTERNAL_TO_VPC
        help_text:  |
          Ranges created with EXTERNAL_TO_VPC cannot be associated with cloud resources and are
          meant to block out address ranges for various use cases, like for example, usage on-prem,
          with dynamic route announcements via interconnect.
      - arg_value: for-migration
        enum_value: FOR_MIGRATION
        help_text: |
          Ranges created with FOR_MIGRATION are used as locks for migrating subnetworks between
          peered VPC networks.
      default: for-vpc
    - arg_name: peering
      api_field: internalRange.peering
      help_text: |
        The type of peering set for the internal range.
      choices:
      - arg_value: for-self
        enum_value: FOR_SELF
        help_text: |
          This beharior represents the case that the internal range is intended to be used in the
          VPC on which it is created and is accessible from its peers. This implies that peers or
          peer-of-peers cannot use this range.
      - arg_value: for-peer
        enum_value: FOR_PEER
        help_text: |
          This behavior can be set when the internal range is being reserved for usage by the peers.
          This means that no resource within the VPC in which it is being created can use this to
          associate with a cloud resource, but one of the peers can. This represents "donating" a
          range for peers to use.
      - arg_value: not-shared
        enum_value: NOT_SHARED
        help_text: |
          This behavior can be set when the internal range is being reserved for usage by the VPC on
          which it is created but not shared with the peers. In a sense it is local to the VPC. This
          can be used to create internal ranges for various purposes like
          HTTP_INTERNAL_LOAD_BALANCER or for interconnect routes that are not shared with peers.
          This also implies that peers cannot use this range in a way that is visible to this VPC,
          but can re-use this range as long as it is NOT_SHARED from the peer VPC too.
      default: for-self
    - arg_name: overlaps
      api_field: internalRange.overlaps
      help_text: Overlap specifications for the range being created.
      choices:
      - arg_value: overlap-route-range
        enum_value: OVERLAP_ROUTE_RANGE
        help_text: |
          Allows for creation or existence of routes that have a more specific destination
          than the created range.
      - arg_value: overlap-existing-subnet-range
        enum_value: OVERLAP_EXISTING_SUBNET_RANGE
        help_text: |
          Allows for creation of internal ranges that overlap with existing subnets.
    - group:
        help_text: |
          Endpoints of a for-migration internal range. This is only applicable when --usage is set
          to for-migration.
          Both MIGRATION_SOURCE and MIGRATION_TARGET must either belong to the same VPC or their
          VPCs must be peered (they may then even belong to different projects).
          MIGRATION_SOURCE must belong to the VPC network specifed by the --network flag.
          MIGRATION_TARGET may name a subnetwork which does not exist yet; it must be a valid
          resource path, and parent resources (network and project) and their locations must exist.
        params:
        - arg_name: migration-source
          required: true
          api_field: internalRange.migration.source
          help_text: |
            The migration source subnetwork (of a for-migration internal range) resource URI or
            resource ID.
        - arg_name: migration-target
          required: true
          api_field: internalRange.migration.target
          help_text: |
            The migration target subnetwork (of a for-migration internal range) resource URI or
            resource ID.
    - arg_name: immutable
      api_field: internalRange.immutable
      help_text: |
        Mark the internal range as immutable. Then only non-semantic fields like description and
        labels could be modified after creation.
      type: bool

  async:
    collection: networkconnectivity.projects.locations.operations

  request: &request
    ALPHA:
      api_version: v1alpha1
      modify_request_hooks:
      - googlecloudsdk.command_lib.network_connectivity.util:ValidateMigration
    GA:
      api_version: v1
      modify_request_hooks:
      - googlecloudsdk.command_lib.network_connectivity.util:ValidateMigration
    collection: networkconnectivity.projects.locations.internalRanges
    method: create
