Ejemplo n.º 1
0
def _PromptForProjectId(project_ids, limit_exceeded):
    """Prompt the user for a project ID, based on the list of available IDs.

  Also allows an option to create a project.

  Args:
    project_ids: list of str or None, the project IDs to prompt for. If this
      value is None, the listing was unsuccessful and we prompt the user
      free-form (and do not validate the input). If it's empty, we offer to
      create a project for the user.
    limit_exceeded: bool, whether or not the project list limit was reached. If
      this limit is reached, then user will be prompted with a choice to
      manually enter a project id, create a new project, or list all projects.

  Returns:
    str, the project ID to use, or _CREATE_PROJECT_SENTINEL (if a project should
      be created), or None
  """
    if project_ids is None:
        return console_io.PromptResponse(
            'Enter project id you would like to use:  ') or None
    elif not project_ids:
        if not console_io.PromptContinue(
                'This account has no projects.',
                prompt_string='Would you like to create one?'):
            return None
        return _CREATE_PROJECT_SENTINEL
    elif limit_exceeded:
        idx = console_io.PromptChoice(
            ['Enter a project ID', 'Create a new project', 'List projects'],
            message=(
                'This account has a lot of projects! Listing them all can '
                'take a while.'))
        if idx is None:
            return None
        elif idx == 0:
            return console_io.PromptWithValidator(
                _IsExistingProject,
                'Project ID does not exist or is not active. Please enter an '
                'existing and active Project ID.',
                'Enter an existing project id you would like to use:  ')
        elif idx == 1:
            return _CREATE_PROJECT_SENTINEL
        else:
            project_ids = _GetProjectIds()

    idx = console_io.PromptChoice(
        project_ids + ['Create a new project'],
        message='Pick cloud project to use: ',
        allow_freeform=True,
        freeform_suggester=usage_text.TextChoiceSuggester())
    if idx is None:
        return None
    elif idx == len(project_ids):
        return _CREATE_PROJECT_SENTINEL
    return project_ids[idx]
Ejemplo n.º 2
0
 def testChoiceErrors(self):
     with self.assertRaisesRegex(ValueError, r'at least one option'):
         console_io.PromptChoice([])
     with self.assertRaisesRegex(ValueError, r'at least one option'):
         console_io.PromptChoice(None)
     with self.assertRaisesRegex(
             ValueError, r'Default option \[-1\] is not a valid index '):
         console_io.PromptChoice(['a', 'b', 'c'], default=-1)
     with self.assertRaisesRegex(
             ValueError, r'Default option \[3\] is not a valid index'):
         console_io.PromptChoice(['a', 'b', 'c'], default=3)
Ejemplo n.º 3
0
    def _PickRepo(self):
        """Allows user to clone one of the projects repositories."""
        cmd = ['alpha', 'source', 'repos', 'list']
        repos = self._RunExperimentalCmd(cmd)

        if repos:
            repos = sorted(repo.name or 'default' for repo in repos)
            log.status.write(
                'This project has one or more associated git repositories.\n')
            idx = console_io.PromptChoice(
                ['[{0}]'.format(repo) for repo in repos] + ['Do not clone'],
                message='Pick repository to clone to your local machine:',
                prompt_string=None)
            if idx >= 0 and idx < len(repos):
                repo_name = repos[idx]
            else:
                return
        elif repos is None:
            log.status.write(
                'Could not retrieve list of repos via [gcloud {0}]\n'.format(
                    ' '.join(cmd)))
            log.status.write('Perhaps alpha commands are not enabled '
                             'or the repos list command failed.\n'
                             '\n')
            answer = console_io.PromptContinue(
                prompt_string=
                'Generally projects have a repository named [default]. '
                'Would you like to try clone it?')
            if not answer:
                return
            repo_name = 'default'
        else:
            return

        self._CloneRepo(repo_name)
Ejemplo n.º 4
0
 def SetProperty(name, default_value, list_command):
     """Set named compute property to default_value or get via list command."""
     if default_value:
         log.status.write(
             'Your project default compute {0} has been set to '
             '[{1}].\nYou can change it by running '
             '[gcloud config set compute/{0} NAME].\n\n'.format(
                 name, default_value['name']))
     else:
         values = self._RunCmd(list_command)
         if values is None:
             return
         values = list(values)
         idx = console_io.PromptChoice(
             ['[{0}]'.format(value['name']) for value in values] +
             ['Do not set default {0}'.format(name)],
             message=('Which compute {0} would you like '
                      'to use as project default?'.format(name)),
             prompt_string=None)
         if idx is None or idx == len(values):
             return
         default_value = values[idx]
     self._RunCmd(['config', 'set'],
                  ['compute/{0}'.format(name), default_value['name']])
     return default_value
Ejemplo n.º 5
0
def GetRegion(args, prompt=False):
    """Prompt for region if not provided.

  Region is decided in the following order:
  - region argument;
  - run/region gcloud config;
  - compute/region gcloud config;
  - prompt user.

  Args:
    args: Namespace, The args namespace.
    prompt: bool, whether to attempt to prompt.

  Returns:
    A str representing region.
  """
    if getattr(args, 'region', None):
        return args.region
    if properties.VALUES.run.region.IsExplicitlySet():
        return properties.VALUES.run.region.Get()
    if properties.VALUES.compute.region.IsExplicitlySet():
        return properties.VALUES.compute.region.Get()
    if prompt and console_io.CanPrompt():
        client = global_methods.GetServerlessClientInstance()
        all_regions = global_methods.ListRegions(client)
        idx = console_io.PromptChoice(all_regions,
                                      message='Please specify a region:\n',
                                      cancel_option=True)
        region = all_regions[idx]
        # set the region on args, so we're not embarassed the next time we call
        # GetRegion
        args.region = region
        log.status.Print('To make this the default region, run '
                         '`gcloud config set run/region {}`.\n'.format(region))
        return region
Ejemplo n.º 6
0
    def _PromptForScopeList(self, ambiguous_refs, attributes, resource_type,
                            choice_resources, raise_on_prompt_failure):
        """Prompt to resolve abiguous resources.  Either returns str or throws."""
        # targetInstances -> target instances
        resource_name = utils.CamelCaseToOutputFriendly(resource_type)
        # Resource names should be surrounded by brackets while choices should not
        names = ['[{0}]'.format(name) for name, _, _ in ambiguous_refs]
        # Print deprecation state for choices.
        choice_names = []
        choice_mapping = []
        for attribute in attributes:
            for choice_resource in choice_resources[attribute]:
                deprecated = choice_resource.deprecated
                if deprecated:
                    choice_name = '{0} ({1})'.format(choice_resource.name,
                                                     deprecated.state)
                else:
                    choice_name = choice_resource.name

                if len(attributes) > 1:
                    choice_name = '{0}: {1}'.format(attribute, choice_name)

                choice_mapping.append((attribute, choice_resource.name))
                choice_names.append(choice_name)

        title = utils.ConstructList(
            'For the following {0}:'.format(resource_name), names)
        idx = console_io.PromptChoice(options=choice_names,
                                      message='{0}choose a {1}:'.format(
                                          title, ' or '.join(attributes)))
        if idx is None:
            raise_on_prompt_failure()
        else:
            return choice_mapping[idx]
Ejemplo n.º 7
0
    def Run(self, args):
        project = properties.VALUES.core.project.GetOrFail()
        memberships = base.ListMemberships(project)
        if not memberships:
            raise exceptions.Error('No Memberships available in Hub.')
        # User should choose an existing membership if not provide one
        if not args.membership:
            index = console_io.PromptChoice(
                options=memberships,
                message=
                'Please specify a membership to delete configmanagement:\n')
            membership = memberships[index]
        else:
            membership = args.membership
            if membership not in memberships:
                raise exceptions.Error(
                    'Membership {} is not in Hub.'.format(membership))

        client = core_apis.GetClientInstance('gkehub', 'v1alpha1')
        msg = client.MESSAGES_MODULE
        applied_config = msg.ConfigManagementFeatureSpec.MembershipConfigsValue.AdditionalProperty(
            key=membership, value=msg.MembershipConfig())
        m_configs = msg.ConfigManagementFeatureSpec.MembershipConfigsValue(
            additionalProperties=[applied_config])

        self.RunCommand(
            'configmanagement_feature_spec.membership_configs',
            configmanagementFeatureSpec=msg.ConfigManagementFeatureSpec(
                membershipConfigs=m_configs))
Ejemplo n.º 8
0
  def Run(self, args):
    if not args.config_membership:
      memberships = base.ListMemberships()
      if not memberships:
        raise exceptions.Error('No Memberships available in the fleet.')
      index = console_io.PromptChoice(
          options=memberships, message='Please specify a config membership:\n')
      config_membership = memberships[index]
    else:
      # Strip to the final path component to allow short and long names.
      # Assumes long names are for the same project and global location.
      # TODO(b/192580393): Use the resource args instead of this hack.
      config_membership = os.path.basename(args.config_membership)
    config_membership = self.MembershipResourceName(config_membership)

    # MCI requires MCSD. Enablement of the fleet feature for MCSD is taken care
    # of by CLH but we need to enable the OP API before that happens. If not,
    # CLH will return an error asking for the API to be enabled.
    mcsd_api = info.Get('multiclusterservicediscovery').api
    enable_api.EnableServiceIfDisabled(self.Project(), mcsd_api)

    f = self.messages.Feature(
        spec=self.messages.CommonFeatureSpec(
            multiclusteringress=self.messages.MultiClusterIngressFeatureSpec(
                configMembership=config_membership)))
    result = self.Enable(f)

    # We only want to poll for usability if everything above succeeded.
    if result is not None:
      self.PollForUsability()
Ejemplo n.º 9
0
    def _PickAccount(self):
        """Checks if current credentials are valid, if not runs auth login.

    Returns:
      bool, True if valid credentials are setup.
    """

        auth_info = self._RunCmd(['auth', 'list'])
        if auth_info and auth_info.accounts:
            idx = console_io.PromptChoice(auth_info.accounts +
                                          ['Login with new credentials'],
                                          message='Pick credentials to use:',
                                          prompt_string=None)
            if idx is None:
                return None
            new_credentials = idx == len(auth_info.accounts)
        else:
            answer = console_io.PromptContinue(
                prompt_string=
                'To continue, you must login. Would you like to login')
            if not answer:
                return False
            new_credentials = True
        if new_credentials:
            # gcloud auth login may have user interaction, do not suppress it.
            self._RunCmd(['auth', 'login'], disable_user_output=False)
        else:
            account = auth_info.accounts[idx]
            self._RunCmd(['config', 'set'], ['account', account])

        log.status.write('\nYou are now logged in as: [{0}]\n'.format(
            properties.VALUES.core.account.Get()))
        return True
Ejemplo n.º 10
0
    def _Prompt(self, parsed_args):
        """Fallthrough to reading the cluster name from an interactive prompt.

    Only prompt for cluster name if cluster location is already defined.

    Args:
      parsed_args: Namespace, the args namespace.

    Returns:
      A cluster name string
    """
        cluster_location = (getattr(parsed_args, 'cluster_location', None)
                            or properties.VALUES.run.cluster_location.Get())

        if cluster_location:
            clusters = global_methods.ListClusters(cluster_location)
            if not clusters:
                raise exceptions.ConfigurationError(
                    'No clusters found for cluster location [{}]. '
                    'Ensure your clusters have Cloud Run on GKE enabled.'.
                    format(cluster_location))
            cluster_names = [c.name for c in clusters]
            idx = console_io.PromptChoice(cluster_names,
                                          message='GKE cluster name:',
                                          cancel_option=True)
            name = cluster_names[idx]
            log.status.Print(
                'To make this the default cluster, run '
                '`gcloud config set run/cluster {}`.\n'.format(name))
            return name
Ejemplo n.º 11
0
def PromptForWhoisPrivacy(choices):
  index = console_io.PromptChoice(
      options=choices,
      default=0,
      message='Specify WHOIS privacy setting')
  return ParseWhoisPrivacy(
      flags.WHOIS_PRIVACY_ENUM_MAPPER.GetChoiceForEnum(choices[index]))
    def Run(self, args):
        # Get fleet memberships (cluster registered with fleet) from GCP Project.
        memberships = base.ListMemberships()
        if not memberships:
            raise exceptions.Error('No Memberships available in the fleet.')

        # Acquire membership.
        membership = None
        # Prompt user for an existing fleet membership if none is provided.
        if not args.membership:
            index = 0
            if len(memberships) > 1:
                index = console_io.PromptChoice(
                    options=memberships,
                    message=
                    'Please specify a membership to delete Identity Service {}:\n'
                )
            membership = memberships[index]
            sys.stderr.write('Selecting membership [{}].\n'.format(membership))
        else:
            membership = args.membership
            if membership not in memberships:
                raise exceptions.Error(
                    'Membership {} is not in the fleet.'.format(membership))

        # Setup a patch to set the MembershipSpec to the empty proto ("delete").
        membership_key = self.MembershipResourceName(membership)
        specs = {membership_key: self.messages.MembershipFeatureSpec()}
        patch = self.messages.Feature(
            membershipSpecs=self.hubclient.ToMembershipSpecs(specs))

        self.Update(['membership_specs'], patch)
Ejemplo n.º 13
0
def _PromptForProjectId(project_ids):
    """Prompt the user for a project ID, based on the list of available IDs.

  Also allows an option to create a project.

  Args:
    project_ids: list of str or None, the project IDs to prompt for. If this
      value is None, the listing was unsuccessful and we prompt the user
      free-form (and do not validate the input). If it's empty, we offer to
      create a project for the user.

  Returns:
    str, the project ID to use, or _CREATE_PROJECT_SENTINEL (if a project should
      be created), or None
  """
    if project_ids is None:
        return console_io.PromptResponse(
            'Enter project id you would like to use:  ') or None
    elif not project_ids:
        if not console_io.PromptContinue(
                'This account has no projects.',
                prompt_string='Would you like to create one?'):
            return None
        return _CREATE_PROJECT_SENTINEL
    else:
        idx = console_io.PromptChoice(
            project_ids + ['Create a new project'],
            message='Pick cloud project to use: ',
            allow_freeform=True,
            freeform_suggester=usage_text.TextChoiceSuggester())
        if idx is None:
            return None
        elif idx == len(project_ids):
            return _CREATE_PROJECT_SENTINEL
        return project_ids[idx]
Ejemplo n.º 14
0
def PromptForOpRegion():
    """Prompt for region from list of online prediction available regions.

  This method is referenced by the declaritive iam commands as a fallthrough
  for getting the region.

  Returns:
    The region specified by the user, str

  Raises:
    RequiredArgumentException: If can not prompt a console for region.
  """

    if console_io.CanPrompt():
        all_regions = list(constants.SUPPORTED_OP_REGIONS)
        idx = console_io.PromptChoice(all_regions,
                                      message='Please specify a region:\n',
                                      cancel_option=True)
        region = all_regions[idx]
        log.status.Print('To make this the default region, run '
                         '`gcloud config set ai/region {}`.\n'.format(region))
        return region
    raise exceptions.RequiredArgumentException(
        '--region', ('Cannot prompt a console for region. Region is required. '
                     'Please specify `--region` to select a region.'))
Ejemplo n.º 15
0
def select_memberships(args):
  """Returns a list of memberships to which to apply the command, given the arguments.

  Args:
    args: object containing arguments passed as flags with the command

  Returns:
    memberships: A list of membership name strings
  """
  memberships = []
  all_memberships = base.ListMemberships()

  if args.all_memberships:
    memberships = all_memberships
  elif args.memberships:
    memberships = args.memberships.split(',')
    for membership in memberships:
      if membership not in all_memberships:
        raise exceptions.Error('Membership {} not found'.format(membership))
  else:
    index = console_io.PromptChoice(
        options=all_memberships, message='Please specify a membership:\n')
    memberships = [all_memberships[index]]

  if not memberships:
    raise exceptions.Error('A membership is required for this command.')

  return memberships
Ejemplo n.º 16
0
def _get_or_prompt_membership(args, project):
    """Retrieves the membership name from args or prompts the user.

  Args:
    args: command line args
    project: project id
  Returns:
    membership: A membership name
  Raises: Error, if specified membership could not be found
  """
    memberships = base.ListMemberships(project)
    if not memberships:
        raise exceptions.Error('No Memberships available in Hub.')
    # User should choose an existing membership if this arg wasn't provided
    if not args.membership:
        index = console_io.PromptChoice(
            options=memberships,
            message='Please specify a membership to upgrade:\n')
        membership = memberships[index]
    else:
        membership = args.membership
        if membership not in memberships:
            raise exceptions.Error(
                'Membership {} is not in Hub.'.format(membership))
    return membership
Ejemplo n.º 17
0
def CreateAppInteractively(api_client, project):
    """Interactively choose a region and create an App Engine app.

  The caller is responsible for calling this method only when the user can be
  prompted interactively.

  Example interaction:

      Which region?
        [1] us-east1      (supports standard and flexible)
        [2] europe-west   (supports standard)
        [3] us-central    (supports standard and flexible)
      Please enter your numeric choice:  1

  Args:
    api_client: The App Engine Admin API client
    project: The GCP project

  Raises:
    AppAlreadyExistsError if app already exists
  """
    all_regions = sorted(set(api_client.ListRegions()))
    idx = console_io.PromptChoice(
        all_regions,
        message=
        ('Please choose a region for your application. After choosing a region, '
         'it cannot be changed. Which region would you like to choose?\n\n'))
    region = all_regions[idx]
    CreateApp(api_client, project, region.region)
Ejemplo n.º 18
0
def CreateAppInteractively(api_client, project):
    """Interactively choose a region and create an App Engine app.

  The caller is responsible for calling this method only when the user can be
  prompted interactively.

  Example interaction:

      Which region?
        [1] us-east1      (supports standard and flexible)
        [2] europe-west   (supports standard)
        [3] us-central    (supports standard and flexible)
        [4] cancel
      Please enter your numeric choice:  1

  Args:
    api_client: The App Engine Admin API client
    project: The GCP project

  Raises:
    AppAlreadyExistsError if app already exists
  """
    log.status.Print(
        'You are creating an app for project [{}].'.format(project))
    log.warn(APP_CREATE_WARNING)

    all_regions = sorted(set(api_client.ListRegions()))
    idx = console_io.PromptChoice(
        all_regions,
        message=('Please choose the region where you want your App Engine '
                 'application located:\n\n'),
        cancel_option=True)
    region = all_regions[idx]
    CreateApp(api_client, project, region.region, suppress_warning=True)
Ejemplo n.º 19
0
def CreateAppInteractively(api_client, project):
  """Interactively choose a region and create an App Engine app.

  The caller is responsible for calling this method only when the user can be
  prompted interactively.

  Example interaction:

      Which region?
        [1] us-east1      (supports standard and flexible)
        [2] europe-west   (supports standard)
        [3] us-central    (supports standard and flexible)
        [4] cancel
      Please enter your numeric choice:  1

  Args:
    api_client: The App Engine Admin API client
    project: The GCP project

  Raises:
    AppAlreadyExistsError if app already exists
  """
  log.warn('You are creating an app for project [{project}]. Creating '
           'an app for a project is irreversible.\n'.format(project=project))
  all_regions = sorted(set(api_client.ListRegions()))
  idx = console_io.PromptChoice(all_regions,
                                message=('Please choose a region for your '
                                         'application. After choosing a '
                                         'region, you cannot change it. Which '
                                         'region would you like to choose?'
                                         '\n\n'),
                                cancel_option=True)
  region = all_regions[idx]
  CreateApp(api_client, project, region.region, suppress_warning=True)
  def _PickConfiguration(self):
    """Allows user to re-initialize, create or pick new configuration.

    Returns:
      Configuration name or None.
    """
    configs = named_configs.ConfigurationStore.AllConfigs()
    active_config = named_configs.ConfigurationStore.ActiveConfig()

    if not configs or active_config.name not in configs:
      # Listing the configs will automatically create the default config.  The
      # only way configs could be empty here is if there are no configurations
      # and the --configuration flag or env var is set to something that does
      # not exist.  If configs has items, but the active config is not in there,
      # that similarly means that hey are using the flag or the env var and that
      # config does not exist.  In either case, just create it and go with that
      # one as the one that as they have already selected it.
      named_configs.ConfigurationStore.CreateConfig(active_config.name)
      # Need to active it in the file, not just the environment.
      active_config.Activate()
      return active_config.name

    # If there is a only 1 config, it is the default, and there are no
    # properties set, assume it was auto created and that it should be
    # initialized as if it didn't exist.
    if len(configs) == 1:
      default_config = configs.get(named_configs.DEFAULT_CONFIG_NAME, None)
      if default_config and not default_config.GetProperties():
        default_config.Activate()
        return default_config.name

    choices = []
    log.status.write('Settings from your current configuration [{0}] are:\n'
                     .format(active_config.name))
    log.status.flush()
    log.status.write(yaml.dump(properties.VALUES.AllValues(),
                               default_flow_style=False))
    log.out.flush()
    log.status.write('\n')
    log.status.flush()
    choices.append(
        'Re-initialize this configuration [{0}] with new settings '.format(
            active_config.name))
    choices.append('Create a new configuration')
    config_choices = [name for name, c in sorted(configs.iteritems())
                      if not c.is_active]
    choices.extend('Switch to and re-initialize '
                   'existing configuration: [{0}]'.format(name)
                   for name in config_choices)
    idx = console_io.PromptChoice(choices, message='Pick configuration to use:')
    if idx is None:
      return None
    if idx == 0:  # If reinitialize was selected.
      self._CleanCurrentConfiguration()
      return active_config.name
    if idx == 1:  # Second option is to create new configuration.
      return self._CreateConfiguration()
    config_name = config_choices[idx - 2]
    named_configs.ConfigurationStore.ActivateConfig(config_name)
    return config_name
Ejemplo n.º 21
0
def GetPlatform():
  """Returns the platform to run on.

  If not set by the user, this prompts the user to choose a platform and sets
  the property so future calls to this method do continue to prompt.

  Raises:
    ArgumentError: if not platform is specified and prompting is not allowed.
  """
  platform = properties.VALUES.run.platform.Get()
  if platform is None:
    if console_io.CanPrompt():
      platform_descs = [_PLATFORM_SHORT_DESCRIPTIONS[k] for k in _PLATFORMS]
      index = console_io.PromptChoice(
          platform_descs,
          message='Please choose a target platform:',
          cancel_option=True)
      platform = list(_PLATFORMS.keys())[index]
      # Set platform so we don't re-prompt on future calls to this method
      # and so it's available to anyone who wants to know the platform.
      properties.VALUES.run.platform.Set(platform)
      log.status.Print(
          'To specify the platform yourself, pass `--platform {0}`. '
          'Or, to make this the default target platform, run '
          '`gcloud config set run/platform {0}`.\n'.format(platform))
    else:
      raise ArgumentError(
          'No platform specified. Pass the `--platform` flag or set '
          'the [run/platform] property to specify a target platform.\n'
          'Available platforms:\n{}'.format(
              '\n'.join(
                  ['- {}: {}'.format(k, v) for k, v in _PLATFORMS.items()])))
  return platform
Ejemplo n.º 22
0
 def testEOF(self):
     result = console_io.PromptContinue()
     self.assertTrue(result)
     result = console_io.PromptContinue(default=False)
     self.assertFalse(result)
     with self.assertRaisesRegex(console_io.UnattendedPromptError,
                                 'This prompt could not be answered'):
         result = console_io.PromptContinue(throw_if_unattended=True)
     result = console_io.PromptResponse(message='')
     self.assertEqual(result, None)
     result = console_io.PromptWithDefault(message='')
     self.assertEqual(result, None)
     result = console_io.PromptChoice(['a', 'b', 'c'])
     self.assertEqual(result, None)
     result = console_io.PromptChoice(['a', 'b', 'c'], default=2)
     self.assertEqual(result, 2)
Ejemplo n.º 23
0
    def Run(self, args):
        log.warning(
            'Are you sure you want to update your config membership? Any '
            'differences in your MCI and MCS resources between the old and '
            'new config membership can trigger load balancer updates which '
            'could cause traffic interruption.')

        console_io.PromptContinue(default=False, cancel_on_no=True)

        project = properties.VALUES.core.project.GetOrFail()
        if not args.config_membership:
            memberships = base.ListMemberships(project)
            if not memberships:
                raise exceptions.Error('No Memberships available in Hub.')
            index = console_io.PromptChoice(
                options=memberships,
                message='Please specify a config membership:\n')
            config_membership = memberships[index]
        else:
            config_membership = args.config_membership
        config_membership = (
            'projects/{0}/locations/global/memberships/{1}'.format(
                project, os.path.basename(config_membership)))

        self.RunCommand(
            'multiclusteringress_feature_spec.config_membership',
            multiclusteringressFeatureSpec=(
                base.CreateMultiClusterIngressFeatureSpec(config_membership)))
Ejemplo n.º 24
0
    def _Prompt(self, parsed_args):
        """Fallthrough to reading the cluster location from an interactive prompt.

    Only prompt for cluster location if the user-specified platform is GKE
    and if cluster name is already defined.

    Args:
      parsed_args: Namespace, the args namespace.

    Returns:
      A cluster location string
    """
        cluster_name = (getattr(parsed_args, 'cluster', None)
                        or properties.VALUES.run.cluster.Get())
        if flags.IsGKE(parsed_args) and cluster_name:
            clusters = [
                c for c in global_methods.ListClusters()
                if c.name == cluster_name
            ]
            if not clusters:
                raise exceptions.ConfigurationError(
                    'No cluster locations found for cluster [{}]. '
                    'Ensure your clusters have Cloud Run on GKE enabled.'.
                    format(cluster_name))
            cluster_locations = [c.zone for c in clusters]
            idx = console_io.PromptChoice(
                cluster_locations,
                message='GKE cluster location for [{}]:'.format(cluster_name),
                cancel_option=True)
            location = cluster_locations[idx]
            log.status.Print(
                'To make this the default cluster location, run '
                '`gcloud config set run/cluster_location {}`.\n'.format(
                    location))
            return location
Ejemplo n.º 25
0
def GetPreferredAuthForCluster(cluster, config_file, force_update=False):
  """Get preferredAuthentication value for cluster."""
  configs = file_parsers.YamlConfigFile(config_file,
                                        file_parsers.LoginConfigObject)
  cluster_config = _GetClusterConfig(configs, cluster)
  try:
    auth_method = cluster_config.GetPreferredAuth()
  except KeyError:
    auth_method = None
  except file_parsers.YamlConfigObjectFieldError:
    # gracefully quit for config versions older than v2alpha1 that
    # do not support 'preferredAuthentication' field.
    return None

  if not auth_method or force_update:
    prompt_message = ('Please select your preferred authentication option for '
                      'cluster [{}]'.format(cluster))
    override_warning = ('. Note: This will overwrite current preferred auth '
                        'method [{}] in config file.')
    if auth_method and force_update:
      prompt_message = prompt_message + override_warning.format(auth_method)
    # do the prompting
    providers = cluster_config.GetAuthProviders()
    index = console_io.PromptChoice(providers,
                                    message=prompt_message,
                                    cancel_option=True)
    auth_method = providers[index]
    log.status.Print(
        'Setting Preferred Authentication option to [{}]'.format(auth_method))
    cluster_config.SetPreferredAuth(auth_method)
    configs.WriteToDisk()
  return auth_method
    def Run(self, args):
        log.warning(
            'Are you sure you want to update your config membership? Any '
            'differences in your MCI and MCS resources between the old and '
            'new config membership can trigger load balancer updates which '
            'could cause traffic interruption.')

        console_io.PromptContinue(default=True, cancel_on_no=True)

        config_membership = args.config_membership
        if not config_membership:
            memberships = base.ListMemberships()
            if not memberships:
                raise exceptions.Error(
                    'No Memberships available in the fleet.')
            index = console_io.PromptChoice(
                options=memberships,
                message='Please specify a config membership:\n')
            config_membership = memberships[index]
        else:
            # Strip to the final path component to allow short and long names.
            # Assumes long names are for the same project and global location.
            # TODO(b/192580393): Use the resource args instead of this hack.
            config_membership = os.path.basename(args.config_membership)

        config_membership = self.MembershipResourceName(config_membership)
        f = self.messages.Feature(spec=self.messages.CommonFeatureSpec(
            multiclusteringress=self.messages.MultiClusterIngressFeatureSpec(
                configMembership=config_membership)))

        self.Update(['spec.multiclusteringress.config_membership'], f)
Ejemplo n.º 27
0
 def SetProperty(name, default_value, list_command):
   """Set named compute property to default_value or get via list command."""
   if not default_value:
     values = self._RunCmd(list_command)
     if values is None:
       return
     values = list(values)
     message = (
         'Which Google Compute Engine {0} would you like to use as project '
         'default?\n'
         'If you do not specify a {0} via a command line flag while working '
         'with Compute Engine resources, the default is assumed.').format(
             name)
     idx = console_io.PromptChoice(
         [value['name'] for value in values]
         + ['Do not set default {0}'.format(name)],
         message=message, prompt_string=None, allow_freeform=True,
         freeform_suggester=usage_text.TextChoiceSuggester())
     if idx is None or idx == len(values):
       return
     default_value = values[idx]
   properties.PersistProperty(properties.VALUES.compute.Property(name),
                              default_value['name'])
   log.status.write('Your project default Compute Engine {0} has been set '
                    'to [{1}].\nYou can change it by running '
                    '[gcloud config set compute/{0} NAME].\n\n'
                    .format(name, default_value['name']))
   return default_value
Ejemplo n.º 28
0
def GetRegion(args, prompt=False):
    """Prompt for region if not provided.

  Region is decided in the following order:
  - region argument;
  - local config file;
  - run/region gcloud config;
  - compute/region gcloud config;
  - prompt user.

  Args:
    args: Namespace, The args namespace.
    prompt: bool, whether to attempt to prompt.

  Returns:
    A str representing region.
  """
    if getattr(args, 'region', None):
        return args.region
    conf = GetLocalConfig(args)
    if conf and conf.region:
        return conf.region
    if properties.VALUES.run.region.IsExplicitlySet():
        return properties.VALUES.run.region.Get()
    if properties.VALUES.compute.region.IsExplicitlySet():
        return properties.VALUES.compute.region.Get()
    if prompt and console_io.CanPrompt():
        all_regions = global_methods.ListRegions()
        idx = console_io.PromptChoice(all_regions,
                                      message='Please specify a region:\n',
                                      cancel_option=True)
        region = all_regions[idx]
        log.status.Print('To make this the default region, run '
                         '`gcloud config set run/region {}`.\n'.format(region))
        return region
Ejemplo n.º 29
0
  def _Prompt(self, parsed_args):
    """Fallthrough to reading the cluster name from an interactive prompt.

    Only prompt for cluster name if the user-specified platform is GKE.

    Args:
      parsed_args: Namespace, the args namespace.

    Returns:
      A cluster name string
    """
    if platforms.GetPlatform() != platforms.PLATFORM_GKE:
      return

    project = properties.VALUES.core.project.Get(required=True)
    cluster_location = (
        getattr(parsed_args, 'cluster_location', None) or
        properties.VALUES.run.cluster_location.Get())
    cluster_location_msg = ' in [{}]'.format(
        cluster_location) if cluster_location else ''

    cluster_refs = global_methods.MultiTenantClustersForProject(
        project, cluster_location)
    if not cluster_refs:
      raise exceptions.ConfigurationError(
          'No compatible clusters found{}. '
          'Ensure your cluster has Cloud Run enabled.'.format(
              cluster_location_msg))

    cluster_refs_descs = [
        self._GetClusterDescription(c, cluster_location, project)
        for c in cluster_refs
    ]

    idx = console_io.PromptChoice(
        cluster_refs_descs,
        message='GKE cluster{}:'.format(cluster_location_msg),
        cancel_option=True)

    cluster_ref = cluster_refs[idx]

    if cluster_location:
      location_help_text = ''
    else:
      location_help_text = (
          ' && gcloud config set run/cluster_location {}'.format(
              cluster_ref.zone))

    cluster_name = cluster_ref.Name()

    if cluster_ref.projectId != project:
      cluster_name = cluster_ref.RelativeName()
      location_help_text = ''

    log.status.Print('To make this the default cluster, run '
                     '`gcloud config set run/cluster {cluster}'
                     '{location}`.\n'.format(
                         cluster=cluster_name, location=location_help_text))
    return cluster_ref.SelfLink()
Ejemplo n.º 30
0
    def testLongPrompt(self):
        self.SetAnswers('list', '1', 'value10', '1', '2', '3', '1', '101')

        indices = list(range(1, 101))
        values = ['value{x}'.format(x=x) for x in indices]

        options_lines = [
            ' [{index}] {value}'.format(index=index, value=value)
            for (index, value) in zip(indices, values)
        ]

        result = console_io.PromptChoice(values, allow_freeform=True)

        expected = '\n'.join(
            options_lines[:console_io.PROMPT_OPTIONS_OVERFLOW])

        remaining = len(options_lines) - console_io.PROMPT_OPTIONS_OVERFLOW

        self.assertIn(expected, self.GetErr())

        self.assertIn(('Did not print [{remaining}] options.\n'
                       'Too many options [{total}]. Enter "list" at prompt to '
                       'print choices fully.\nPlease enter numeric choice or '
                       'text value (must exactly match list \nitem):').format(
                           remaining=remaining, total=len(options_lines)),
                      self.GetErr())

        options_lines = [
            ' [{index}] {value}'.format(index=index, value=value)
            for (index, value) in zip(indices, values)
        ]

        expected = '\n'.join(options_lines)

        self.assertIn(expected, self.GetErr())

        self.assertEqual(result, 0)

        result = console_io.PromptChoice(values, allow_freeform=True)
        self.assertEqual(result, 9)

        result = console_io.PromptChoice(values, allow_freeform=True)
        self.assertEqual(result, 0)

        result = console_io.PromptChoice(values, allow_freeform=True)
        self.assertEqual(result, 1)

        result = console_io.PromptChoice(values, allow_freeform=True)
        self.assertEqual(result, 2)

        result = console_io.PromptChoice(values,
                                         allow_freeform=True,
                                         cancel_option=True)
        self.assertEqual(result, 0)

        with self.assertRaises(console_io.OperationCancelledError):
            result = console_io.PromptChoice(values,
                                             allow_freeform=True,
                                             cancel_option=True)