Exemplo 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]
Exemplo n.º 2
0
    def testPromptWithValidator(self):
        def simple_validator(s):
            return len(s) > 3

        self.SetAnswers('1', '1234')
        result = console_io.PromptWithValidator(simple_validator, 'error',
                                                'prompt', 'message')
        self.assertIn('message', self.GetErr())
        self.assertIn('prompt', self.GetErr())
        self.assertIn('error', self.GetErr())
        self.assertEqual(result, '1234')
Exemplo n.º 3
0
def PromptForWhoisContact():
    """Interactively prompts for Whois Contact information."""
    if not console_io.PromptContinue(
            'Registrant contact information not provided',
            prompt_string='Do you want to enter it interactively',
            default=False):
        return None
    messages = registrations.GetMessagesModule()
    whois_contact = messages.WhoisContact()
    whois_contact.postalAddress = messages.PostalAddress()
    # TODO(b/110077203): Improve interactive address info.
    whois_contact.postalAddress.recipients.append(
        console_io.PromptWithValidator(validator=_ValidateNonEmpty,
                                       error_message='Name must not be empty.',
                                       prompt_string=' full name:  '))
    whois_contact.postalAddress.organization = console_io.PromptResponse(
        ' organization (if applicable):  ')
    whois_contact.email = console_io.PromptWithDefault(
        message=' email', default=properties.VALUES.core.account.Get())
    whois_contact.phoneNumber = console_io.PromptWithValidator(
        validator=_ValidateNonEmpty,
        error_message='Phone number must not be empty.',
        prompt_string=' phone number:  ',
        message='Enter phone number with country code, e.g. "+1.1234567890".')
    whois_contact.postalAddress.regionCode = console_io.PromptWithValidator(
        validator=_ValidateRegionCode,
        error_message=(
            'Country code must be in ISO 3166-1 format, e.g. "US" or "PL".\n'
            'See https://support.google.com/business/answer/6270107 for a list '
            'of valid choices.'),
        prompt_string=' country code:  ',
        message='Enter two-letter country code, e.g. "US" or "PL".')
    whois_contact.postalAddress.postalCode = console_io.PromptResponse(
        ' postal code/zipcode:  ')
    whois_contact.postalAddress.administrativeArea = console_io.PromptResponse(
        ' state (if applicable):  ')
    whois_contact.postalAddress.locality = console_io.PromptResponse(
        ' city:  ')
    whois_contact.postalAddress.addressLines.append(
        console_io.PromptResponse(' street address (incl. building, apt):  '))
    return whois_contact
Exemplo n.º 4
0
def _GetLdapUserAndPass(cluster_config, auth_name, cluster):
  """Prompt User for Ldap Username and Password."""
  ldap_user = None
  ldap_pass = None
  if not cluster_config.IsLdap():
    return None, None
  # do the prompting
  user_message = ('Please enter the ldap user for '
                  '[{}] on cluster [{}]: '.format(auth_name, cluster))
  pass_message = ('Please enter the ldap password for '
                  '[{}] on cluster [{}]: '.format(auth_name, cluster))
  ldap_user = console_io.PromptWithValidator(
      validator=lambda x: len(x) > 1,
      error_message='Error: Invalid username, please try again.',
      prompt_string=user_message)
  ldap_pass = console_io.PromptPassword(
      pass_message, validation_callable=lambda x: len(x) > 1)
  return _Base64EncodeLdap(ldap_user, ldap_pass)
Exemplo n.º 5
0
def ResourceFromFreeformPrompt(name, long_name, list_func):
  """Prompts the user to select a resource.

  Args:
    name: the name of the resource. For example, "environment" or "developer".
    long_name: a longer form of `name` which the user will see in prompts.
      Should explain the context in which the resource will be used. For
      example, "the environment to be updated".
    list_func: a function that returns the names of existing resources.

  Returns:
    The resource's identifier if successful, or None if not.
  """
  resource_list = []
  try:
    resource_list = list_func()
  except errors.RequestError:
    # Organization list flakiness, no matches, etc.
    pass

  entity_names = resource_args.ENTITIES[name]
  if resource_list:
    enter_manually = "(some other %s)" % entity_names.docs_name
    choice = console_io.PromptChoice(
        resource_list + [enter_manually],
        prompt_string="Select %s:" % long_name)
    # If the user selected an option from resource_list, not the "enter
    # manually" option at the bottom...
    if choice < len(resource_list):
      return resource_list[choice]

  valid_pattern = resource_args.ValidPatternForEntity(name)
  validator = lambda response: valid_pattern.search(response) is not None
  error_str = "Doesn't match the expected format of a " + entity_names.docs_name

  prompt_message = "Enter %s: " % long_name
  return console_io.PromptWithValidator(validator, error_str, prompt_message)
Exemplo n.º 6
0
  def Run(self, args):
    """Run the deploy command."""
    if args.organization is None:
      args.organization = defaults.OrganizationFromGCPProduct()

    if console_io.CanPrompt():
      if args.organization is None:

        def _ListOrgs():
          response = apigee.OrganizationsClient.List()
          if "organizations" in response:
            return [item["organization"] for item in response["organizations"]]
          else:
            return []

        args.organization = prompts.ResourceFromFreeformPrompt(
            "organization",
            "the organization in which to create the API product", _ListOrgs)

      if args.INTERNAL_NAME is None:
        product_matcher = resource_args.ValidPatternForEntity("product")
        valid_product = lambda name: product_matcher.search(name) is not None
        args.INTERNAL_NAME = console_io.PromptWithValidator(
            valid_product, "Empty or invalid API product name.",
            "Enter an internal name for the new API product: ")

      org_identifier = {"organizationsId": args.organization}
      if args.environments is None:
        list_envs = lambda: apigee.EnvironmentsClient.List(org_identifier)
        choice = console_io.PromptChoice(
            ["Include all environments", "Choose environments to include"],
            prompt_string=("What environments should be accessible in the API "
                           "product?"))
        if choice == 0:
          args.environments = []
        else:
          args.environments = prompts.ResourceListFromPrompt(
              "environment", list_envs)

      if not args.apis and not args.resources and not args.all_proxies:
        choice = console_io.PromptChoice(
            [
                "Include all API proxies",
                "Choose API proxies and/or basepaths to include"
            ],
            prompt_string=("What API proxies should be accessible in the API "
                           "product?"))
        if choice == 0:
          args.all_proxies = True
        else:

          def _ListDeployedProxies():
            response = apigee.DeploymentsClient.List(org_identifier)
            return sorted(list(set(item["apiProxy"] for item in response)))

          args.apis = prompts.ResourceListFromPrompt(
              "api", _ListDeployedProxies, "Include all deployed API proxies")

          resource_options = [
              "Restrict proxy access by resource path",
              "Include all resource paths of the product's API proxies"
          ]
          if console_io.PromptChoice(resource_options) == 0:
            args.resources = prompts.ListFromFreeformPrompt(
                "Enter a resource path that should be included: ",
                "Include another resource path",
                "Include all resource paths of the product's API proxies")
          else:
            args.resources = []

          if not args.resources and not args.apis:
            # User explicitly chose to include all proxies and resources.
            args.all_proxies = True

      if args.access is None:
        option = console_io.PromptChoice([
            "Public - visible in the Apigee developer portal",
            ("Private - callable by external developers but not visible in the "
             "Apigee developer portal"),
            "Internal - not callable by external developers"
        ],
                                         message="Choose an access policy.")
        args.access = ["public", "private", "internal"][option]

    if args.environments is None:
      raise exceptions.OneOfArgumentsRequiredException(
          ["--environments", "--all-environments"],
          "All API products must include at least one environment.")

    if args.access is None:
      raise exceptions.OneOfArgumentsRequiredException([
          "--public-access", "--private-access", "--internal-access"
      ], "All API products must specify whether they can be publicly accessed.")

    if not args.apis and not args.resources and not args.all_proxies:
      raise exceptions.OneOfArgumentsRequiredException(
          ["--apis", "--resources", "--all-proxies"],
          "All API products must include at least one API proxy or resource.")

    quota_args_missing = [
        arg for arg in vars(args) if "quota" in arg and vars(args)[arg] is None
    ]
    if quota_args_missing:
      if len(quota_args_missing) < 3:
        raise exceptions.RequiredArgumentException(
            "--" + quota_args_missing[0].replace("_", "-"),
            "Must specify all quota arguments to use quotas.")
    else:
      args.quota = "%d" % args.quota
      args.quota_interval = "%d" % args.quota_interval

    attributes = [{"name": "access", "value": args.access}]
    if args.attributes:
      for key in args.attributes:
        attributes.append({"name": key, "value": args.attributes[key]})

    identifiers = args.CONCEPTS.internal_name.Parse().AsDict()

    if args.display_name is None:
      args.display_name = identifiers["apiproductsId"]

    product = apigee.ProductsInfo(
        name=identifiers["apiproductsId"],
        displayName=args.display_name,
        approvalType="manual" if args.manual_approval else "auto",
        attributes=attributes,
        description=args.description,
        apiResources=args.resources if args.resources else None,
        environments=args.environments if args.environments else None,
        proxies=args.apis if args.apis else None,
        quota=args.quota,
        quotaInterval=args.quota_interval,
        quotaTimeUnit=args.quota_unit,
        scopes=args.oauth_scopes)
    return apigee.ProductsClient.Create(identifiers, product)