HEX
Server: Apache/2.4.65 (Ubuntu)
System: Linux ielts-store-v2 6.8.0-1036-gcp #38~22.04.1-Ubuntu SMP Thu Aug 14 01:19:18 UTC 2025 x86_64
User: root (0)
PHP: 7.2.34-54+ubuntu20.04.1+deb.sury.org+1
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,
Upload Files
File: //snap/google-cloud-cli/396/lib/googlecloudsdk/command_lib/bms/flags.py
# -*- coding: utf-8 -*- #
# Copyright 2022 Google LLC. All Rights Reserved.
#
# 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.
"""Flags for data-catalog commands."""

from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

import sys

from googlecloudsdk.api_lib.util import apis
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.calliope.concepts import concepts
from googlecloudsdk.command_lib.util.apis import arg_utils
from googlecloudsdk.command_lib.util.apis import yaml_data
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.command_lib.util.concepts import presentation_specs

FILTER_FLAG_NO_SORTBY_DOC = base.Argument(
    '--filter',
    metavar='EXPRESSION',
    require_coverage_in_tests=False,
    category=base.LIST_COMMAND_FLAGS,
    help="""\
    Apply a Boolean filter _EXPRESSION_ to each resource item to be listed.
    If the expression evaluates `True`, then that item is listed. For more
    details and examples of filter expressions, run $ gcloud topic filters. This
    flag interacts with other flags that are applied in this order: *--flatten*,
    *--filter*, *--limit*.""")


LIMIT_FLAG_NO_SORTBY_DOC = base.Argument(
    '--limit',
    type=arg_parsers.BoundedInt(1, sys.maxsize, unlimited=True),
    require_coverage_in_tests=False,
    category=base.LIST_COMMAND_FLAGS,
    help="""\
    Maximum number of resources to list. The default is *unlimited*.
    This flag interacts with other flags that are applied in this order:
    *--flatten*, *--filter*, *--limit*.
    """)


VOLUME_SNAPSHOT_AUTO_DELETE_BEHAVIOR_MAPPER = arg_utils.ChoiceEnumMapper(
    arg_name='--snapshot-auto-delete',
    message_enum=apis.GetMessagesModule(
        'baremetalsolution',
        'v2').Volume.SnapshotAutoDeleteBehaviorValueValuesEnum,
    custom_mappings={
        'NEWEST_FIRST': ('newest-first', 'Delete the newest snapshot first.'),
        'OLDEST_FIRST': ('oldest-first', 'Delete the oldest snapshot first.'),
        'DISABLED': ('disabled', ("Don't delete any snapshots. This disables "
                                  'new snapshot creation as long as the '
                                  'snapshot reserved space is full.')),
    },
    required=False,
    help_str='Behavior of the disk when snapshot reserved space is full.')


ASYNC_FLAG_DEFAULT_TRUE = base.Argument(
    '--async',
    action='store_true',
    dest='async_',
    default=True,
    help="""\
    Return immediately, without waiting for the operation in progress to
    complete.""")

IP_RESERVATION_SPEC = {
    'start-address': str,
    'end-address': str,
    'note': str
}

IP_RESERVATION_KEY_SPEC = {
    'start-address': str,
    'end-address': str,
}

NFS_ALLOWED_CLIENTS_HELP_TEXT = """
Adds an allowed client to the NFS share. This flag can be repeated to specify multiple allowed clients.

*network*::: The name of the network to allow.

*network-project-id*::: The project ID of the allowed client network.
If not present, the project ID of the NFS share will be used.

*cidr*::: The subnet of IP addresses permitted to access the NFS
share.

*mount-permissions*::: The mount permissions for the allowed client.
``MOUNT_PERMISSIONS'' must be one of: `READ_ONLY`, `READ_WRITE`.

*allow-dev*::: If ``yes'', allows creation of devices.

*allow-suid*::: If ``yes'', allows SUID.

*enable-root-squash*::: If ``yes'', enables root squashing which
is a special mapping of the remote superuser (root) identity when
using identity authentication .
"""


def _ValidateNFSMountPermissions(mount_permissions_input):
  """Validates NFS mount permissions field, throws exception if invalid."""
  mount_permissions = mount_permissions_input.upper()
  if mount_permissions not in NFS_MOUNT_PERMISSIONS_CHOICES:
    raise exceptions.InvalidArgumentException(
        '--allowed-client',
        'Invalid value {} for mount-permissions'.format(
            mount_permissions_input))
  return mount_permissions

NFS_ALLOWED_CLIENT_SPEC = {
    'network': str,
    'network-project-id': str,
    'cidr': str,
    'mount-permissions': _ValidateNFSMountPermissions,
    'allow-dev': arg_parsers.ArgBoolean(),
    'allow-suid': arg_parsers.ArgBoolean(),
    'enable-root-squash': arg_parsers.ArgBoolean(),
}
REQUIRED_NFS_ALLOWED_CLIENT_KEYS = [  # Only network-project-id is optional.
    'network',
    'cidr',
    'mount-permissions',
    'allow-dev',
    'allow-suid',
    'enable-root-squash',
]
NFS_MOUNT_PERMISSIONS_CHOICES = ('READ_ONLY', 'READ_WRITE')
REMOVE_NFS_ALLOWED_CLIENT_SPEC = {
    'network': str,
    'network-project-id': str,
    'cidr': str,
}
REQUIRED_REMOVE_NFS_ALLOWED_CLIENT_KEYS = [
    # Only network-project-id is optional.
    'network',
    'cidr',
]


def AddInstanceArgToParser(parser, positional=False):
  """Sets up an argument for the instance resource."""
  if positional:
    name = 'instance'
  else:
    name = '--instance'
  instance_data = yaml_data.ResourceYAMLData.FromPath(
      'bms.instance')
  resource_spec = concepts.ResourceSpec.FromYaml(instance_data.GetData())
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name,
      concept_spec=resource_spec,
      required=True,
      group_help='instance.')
  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddRegionArgToParser(parser, positional=False):
  """Parses region flag."""
  region_data = yaml_data.ResourceYAMLData.FromPath('bms.region')
  resource_spec = concepts.ResourceSpec.FromYaml(region_data.GetData())
  if positional:
    name = 'region'
  else:
    name = '--region'
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name,
      concept_spec=resource_spec,
      required=False,
      group_help='region.')
  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddVolumeArgToParser(parser, positional=False, group_help_text=None):
  """Sets up an argument for the instance resource."""
  if positional:
    name = 'volume'
  else:
    name = '--volume'
  volume_data = yaml_data.ResourceYAMLData.FromPath(
      'bms.volume')
  resource_spec = concepts.ResourceSpec.FromYaml(volume_data.GetData())
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name,
      concept_spec=resource_spec,
      required=True,
      group_help=group_help_text or 'volume.')
  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddSnapshotSchedulePolicyArgToParser(parser,
                                         positional=False,
                                         required=True,
                                         name=None,
                                         group=None):
  """Sets up an argument for the snapshot schedule policy resource."""
  if not name:
    if positional:
      name = 'snapshot_schedule_policy'
    else:
      name = '--snapshot-schedule-policy'
  policy_data = yaml_data.ResourceYAMLData.FromPath(
      'bms.snapshot_schedule_policy')
  resource_spec = concepts.ResourceSpec.FromYaml(policy_data.GetData())
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name,
      group=group,
      concept_spec=resource_spec,
      required=required,
      flag_name_overrides={'region': ''},
      group_help='snapshot_schedule_policy.')
  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddSnapshotScheduleArgListToParser(parser, required=True):
  """Sets up an argument for a snapshot schedule."""
  spec = {
      'crontab_spec': str,
      'retention_count': int,
      'prefix': str,
  }
  parser.add_argument(
      '--schedule',
      required=required,
      type=arg_parsers.ArgDict(spec=spec,
                               max_length=len(spec),
                               required_keys=spec.keys()),
      action='append',
      metavar='CRONTAB_SPEC,RETENTION_COUNT,PREFIX',
      help="""
              Adds a schedule for taking snapshots of volumes under this policy.
              This flag may be repeated to specify up to 5 schedules.

              *crontab_spec*::: Specification of the times at which snapshots
              will be taken. This should be in Crontab format:
              http://en.wikipedia.org/wiki/Cron#Overview

              *retention_count*::: The maximum number of snapshots to retain in
              this schedule.

              *prefix*::: Value to append to the name of snapshots created by
              this schedule.

           """,
      )


def AddNetworkArgToParser(parser, positional=False):
  """Sets up an argument for the network resource."""
  if positional:
    name = 'network'
  else:
    name = '--network'
  policy_data = yaml_data.ResourceYAMLData.FromPath(
      'bms.network')
  resource_spec = concepts.ResourceSpec.FromYaml(policy_data.GetData())
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name,
      concept_spec=resource_spec,
      required=True,
      group_help='network.')

  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddLunArgToParser(parser):
  """Sets up an argument for a volume snapshot policy."""
  name = 'lun'
  snapshot_data = yaml_data.ResourceYAMLData.FromPath('bms.lun')
  resource_spec = concepts.ResourceSpec.FromYaml(snapshot_data.GetData())
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name,
      concept_spec=resource_spec,
      required=True,
      group_help='lun.')
  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddVolumeSnapshotArgToParser(parser, positional=False):
  """Sets up an argument for a volume snapshot policy."""
  if positional:
    name = 'snapshot'
  else:
    name = '--snapshot'
  snapshot_data = yaml_data.ResourceYAMLData.FromPath('bms.snapshot')
  resource_spec = concepts.ResourceSpec.FromYaml(snapshot_data.GetData())
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name,
      concept_spec=resource_spec,
      required=True,
      group_help='snapshot.')
  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddVolumeSnapshotAutoDeleteBehaviorArgToParser(parser):
  """Sets up an argument for a volume snapshot auto-delete-behavior enum."""
  VOLUME_SNAPSHOT_AUTO_DELETE_BEHAVIOR_MAPPER.choice_arg.AddToParser(parser)


def AddNfsShareArgToParser(parser, positional=False):
  """Sets up an argument for an nfs-share resource."""
  if positional:
    name = 'nfs_share'
  else:
    name = '--nfs_share'
  nfs_data = yaml_data.ResourceYAMLData.FromPath(
      'bms.nfs_share')
  resource_spec = concepts.ResourceSpec.FromYaml(nfs_data.GetData())
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name,
      concept_spec=resource_spec,
      required=True,
      group_help='nfs_share.')
  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddOsImageArgToParser(parser, positional=False):
  """Sets up an argument for an os-image resource."""
  if positional:
    name = 'os_image'
  else:
    name = '--os-image'
  os_image_data = yaml_data.ResourceYAMLData.FromPath(
      'bms.os_image')
  resource_spec = concepts.ResourceSpec.FromYaml(os_image_data.GetData())
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name,
      concept_spec=resource_spec,
      required=True,
      group_help='os_image.')
  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddSerialConsoleSshKeyArgToParser(parser, positional=False, name=None):
  """Sets up an argument for the serial-console-ssh-key resource."""
  name = 'serial_console_ssh_key' if positional else '--serial-console-ssh-key'
  ssh_key_data = yaml_data.ResourceYAMLData.FromPath(
      'bms.serial_console_ssh_key'
  )
  resource_spec = concepts.ResourceSpec.FromYaml(ssh_key_data.GetData())
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name,
      concept_spec=resource_spec,
      required=True,
      flag_name_overrides={'region': ''},
      group_help='serial_console_ssh_key.',
  )
  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddProvisioningSshKeyArgToParser(
    parser, positional=False, name=None, required=True, plural=False
):
  group_parser = parser.add_mutually_exclusive_group(required=required)
  AddSshKeyArgToParser(
      group_parser,
      positional=positional,
      name=name,
      plural=plural,
      required=required,
  )
  AddClearSshKeyToParser(group_parser)


def AddSshKeyArgToParser(
    parser, positional=False, name=None, required=True, plural=False
):
  """Sets up an argument for the ssh-key resource."""
  name = 'ssh_key' if positional else '--ssh-key'
  ssh_key_data = yaml_data.ResourceYAMLData.FromPath('bms.ssh_key')
  resource_spec = concepts.ResourceSpec.FromYaml(ssh_key_data.GetData())
  presentation_spec = presentation_specs.ResourcePresentationSpec(
      name=name if not plural else f'{name}s',
      concept_spec=resource_spec,
      required=required,
      flag_name_overrides={'region': ''},
      group_help='ssh_key.',
      plural=plural,
      )
  return concept_parsers.ConceptParser([presentation_spec]).AddToParser(parser)


def AddClearSshKeyToParser(parser):
  parser.add_argument(
      '--clear-ssh-keys',
      action='store_true',
      help="""Provisions the instance without any SSH keys.""",
      required=False,
  )


def AddNewNameArgToParser(parser, obj_name):
  parser.add_argument(
      '--new-name',
      type=str,
      help="""New {name} name for renaming an already existing {name}.""".format(
          name=obj_name),
      required=True)


def AddInstanceOsImageToParser(parser, hidden, required):
  parser.add_argument(
      '--os-image',
      type=str,
      help="""
              OS image to install on the server.

              To list all OS image codes supported by BMS, run:

                  $ gcloud bms os-images list
        """,
      hidden=hidden,
      required=required,
  )


def AddInstanceEnableHyperthreadingToParser(parser, hidden):
  parser.add_argument(
      '--enable-hyperthreading',
      action=arg_parsers.StoreTrueFalseAction,
      help="""Enable hyperthreading for the server.""",
      hidden=hidden)


def AddNetworkIpReservationToParser(parser, hidden):
  """Adds the flags for network IP range reservation to parser."""
  group_arg = parser.add_mutually_exclusive_group(required=False)
  group_arg.add_argument(
      '--add-ip-range-reservation',
      type=arg_parsers.ArgDict(spec=IP_RESERVATION_SPEC),
      metavar='PROPERTY=VALUE',
      help="""
              Add a reservation of a range of IP addresses in the network.

              *start_address*::: The first address of this reservation block.
              Must be specified as a single IPv4 address, e.g. `10.1.2.2`.

              *end_address*::: The last address of this reservation block,
              inclusive. I.e., for cases when reservations are only single
              addresses, end_address and start_address will be the same.
              Must be specified as a single IPv4 address, e.g. `10.1.2.2`.

              *note*::: A note about this reservation, intended for human consumption.
            """,
      hidden=hidden)
  group_arg.add_argument(
      '--remove-ip-range-reservation',
      type=arg_parsers.ArgDict(spec=IP_RESERVATION_KEY_SPEC),
      metavar='PROPERTY=VALUE',
      help="""
              Remove a reservation of a range of IP addresses in the network.

              *start_address*::: The first address of the reservation block to remove.

              *end_address*::: The last address of the reservation block to remove.
            """,
      hidden=hidden)
  group_arg.add_argument(
      '--clear-ip-range-reservations',
      action='store_true',
      help="""Removes all IP range reservations in the network.""",
      hidden=hidden)


def AddNfsSizeGibArg(parser):
  """Adds size GiB argument for NFS."""
  parser.add_argument(
      '--size-gib',
      help='The requested size of the NFS share in GiB',
      type=int,
      required=True)


def AddNfsStorageTypeArg(parser):
  """Adds storage type argument for NFS."""
  parser.add_argument(
      '--storage-type',
      choices={
          'SSD':
              'The storage type of the underlying volume will be SSD',
          'HDD':
              'The storage type of the underlying volume will be HDD'
      },
      required=True,
      type=arg_utils.ChoiceToEnumName,
      help=('Specifies the storage type of the underlying volume which will be'
            ' created for the NFS share.'))


def AddNfsAllowedClientArg(parser):
  parser.add_argument(
      '--allowed-client',
      type=arg_parsers.ArgDict(spec=NFS_ALLOWED_CLIENT_SPEC,
                               required_keys=REQUIRED_NFS_ALLOWED_CLIENT_KEYS,
                               ),
      required=True,
      action='append',
      metavar='PROPERTY=VALUE',
      help=NFS_ALLOWED_CLIENTS_HELP_TEXT,
      )


def AddNfsUpdateAllowedClientArgs(parser, hidden):
  """Adds NFS update allowed clients arguments group."""
  group_arg = parser.add_mutually_exclusive_group(required=False, hidden=hidden)
  group_arg.add_argument(
      '--add-allowed-client',
      type=arg_parsers.ArgDict(
          spec=NFS_ALLOWED_CLIENT_SPEC,
          required_keys=REQUIRED_NFS_ALLOWED_CLIENT_KEYS,
      ),
      action='append',
      metavar='PROPERTY=VALUE',
      help=NFS_ALLOWED_CLIENTS_HELP_TEXT,
  )
  group_arg.add_argument(
      '--remove-allowed-client',
      type=arg_parsers.ArgDict(
          spec=REMOVE_NFS_ALLOWED_CLIENT_SPEC,
          required_keys=REQUIRED_REMOVE_NFS_ALLOWED_CLIENT_KEYS,
      ),
      action='append',
      metavar='PROPERTY=VALUE',
      help="""
              Removes an allowed client for the NFS share given its network name and cidr. This flag can be repeated to remove multiple allowed clients.

              *network*::: The name of the network of the allowed client to remove.

              *network-project-id*::: The project ID of the allowed client network.
              If not present, the project ID of the NFS share will be used.

              *cidr*::: The subnet of permitted IP addresses of the allowed client to remove.
            """)
  group_arg.add_argument(
      '--clear-allowed-clients',
      action='store_true',
      help="""Removes all IP range reservations in the network.""")


def AddKMSCryptoKeyVersionToParser(parser, hidden):
  parser.add_argument(
      '--kms-crypto-key-version',
      type=str,
      help="""
      Resource ID of a KMS CryptoKeyVersion used to encrypt the initial password.

      https://cloud.google.com/kms/docs/resource-hierarchy#key_versions
      """,
      hidden=hidden,
  )