예제 #1
0
    def PromptForScope(self, ambiguous_refs, attribute, service, resource_type,
                       flag_name, prefix_filter):
        """Prompts the user to resolve abiguous resources."""
        # 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]
        choice_resources = self.FetchChoiceResources(attribute, service,
                                                     flag_name, prefix_filter)
        # Print deprecation state for choices.
        choice_names = []
        for choice_resource in choice_resources:
            deprecated = choice_resource.deprecated
            if deprecated:
                choice_name = '{0} ({1})'.format(choice_resource.name,
                                                 deprecated.state)
            else:
                choice_name = 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, attribute))
        if idx is None:
            raise exceptions.ToolException(
                'Unable to prompt. Specify the [{0}] flag.'.format(flag_name))
        choice_resource = choice_resources[idx]
        for _, resource_ref in ambiguous_refs:
            setattr(resource_ref, attribute, choice_resource.name)
예제 #2
0
    def _PromptForScopeList(self, ambiguous_refs, attribute, 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 = []
        for choice_resource in choice_resources:
            deprecated = choice_resource.deprecated
            if deprecated:
                choice_name = '{0} ({1})'.format(choice_resource.name,
                                                 deprecated.state)
            else:
                choice_name = 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, attribute))
        if idx is None:
            raise_on_prompt_failure()
        else:
            return choice_resources[idx].name
예제 #3
0
    def PromptIfDisksWithoutAutoDeleteWillBeDeleted(self, args,
                                                    disks_to_warn_for):
        """Prompts if disks with False autoDelete will be deleted."""
        if not disks_to_warn_for:
            return

        prompt_list = []
        disk_refs = self.CreateZonalReferences(disks_to_warn_for,
                                               args.zone,
                                               resource_type='disks')
        for ref in disk_refs:
            prompt_list.append('[{0}] in [{1}]'.format(ref.Name(), ref.zone))
            prompt_message = utils.ConstructList(
                'The following disks are not configured to be automatically deleted '
                'with instance deletion, but they will be deleted as a result of '
                'this operation if they are not attached to any other instances:',
                prompt_list)
        if not console_io.PromptContinue(message=prompt_message):
            raise exceptions.ToolException('Deletion aborted by user.')
예제 #4
0
def MakeRequests(requests, http, batch_url, errors, custom_get_requests=None):
  """Makes one or more requests to the API.

  Each request can be either a synchronous API call or an asynchronous
  one. For synchronous calls (e.g., get and list), the result from the
  server is yielded immediately. For asynchronous calls (e.g., calls
  that return operations like insert), this function waits until the
  operation reaches the DONE state and fetches the corresponding
  object and yields that object (nothing is yielded for deletions).

  Currently, a heterogenous set of synchronous calls can be made
  (e.g., get request to fetch a disk and instance), however, the
  asynchronous requests must be homogenous (e.g., they must all be the
  same verb on the same collection). In the future, heterogenous
  asynchronous requests will be supported. For now, it is up to the
  client to ensure that the asynchronous requests are
  homogenous. Synchronous and asynchronous requests can be mixed.

  Args:
    requests: A list of requests to make. Each element must be a 3-element
      tuple where the first element is the service, the second element is
      the string name of the method on the service, and the last element
      is a protocol buffer representing the request.
    http: An httplib2.Http-like object.
    batch_url: The handler for making batch requests.
    errors: A list for capturing errors. If any response contains an error,
      it is added to this list.
    custom_get_requests: A mapping of resource names to requests. If
      this is provided, when an operation is DONE, instead of performing
      a get on the targetLink, this function will consult custom_get_requests
      and perform the request dictated by custom_get_requests.

  Yields:
    A response for each request. For deletion requests, no corresponding
    responses are returned.
  """
  if _RequestsAreListRequests(requests):
    for item in _List(
        requests=requests, http=http, batch_url=batch_url, errors=errors):
      yield item
    return

  responses, new_errors = batch_helper.MakeRequests(
      requests=requests, http=http, batch_url=batch_url)
  errors.extend(new_errors)

  operation_service = None
  resource_service = None
  project = None

  # Collects all operation objects in a list so they can be waited on
  # and yields all non-operation objects since non-operation responses
  # cannot be waited on.
  operations = []

  for request, response in zip(requests, responses):
    if response is None:
      continue

    service, _, request_body = request
    if (isinstance(response, service.client.MESSAGES_MODULE.Operation) and
        service.__class__.__name__ not in (
            'GlobalOperationsService',
            'RegionOperationsService',
            'ZoneOperationsService')):

      operations.append(response)

      if not operation_service:
        resource_service = service
        project = request_body.project

        if response.zone:
          operation_service = service.client.zoneOperations
        elif response.region:
          operation_service = service.client.regionOperations
        else:
          operation_service = service.client.globalOperations

    else:
      yield response

  if operations:
    warnings = []
    for response in waiters.WaitForOperations(
        operations=operations,
        project=project,
        operation_service=operation_service,
        resource_service=resource_service,
        http=http,
        batch_url=batch_url,
        custom_get_requests=custom_get_requests,
        warnings=warnings or [],
        errors=errors):
      yield response

    if warnings:
      log.warn(utils.ConstructList('Some requests generated warnings:',
                                   warnings))
예제 #5
0
    def WarnForZonalCreation(self, resource_refs):
        """Warns the user if a zone has upcoming maintanence or deprecation."""
        zones = self.GetZones(resource_refs)
        if not zones:
            return

        prompts = []
        zones_with_upcoming_maintenance = []
        zones_with_deprecated = []
        for zone in zones:
            if zone.maintenanceWindows:
                zones_with_upcoming_maintenance.append(zone)
            if zone.deprecated:
                zones_with_deprecated.append(zone)

        if not zones_with_upcoming_maintenance and not zones_with_deprecated:
            return

        if zones_with_upcoming_maintenance:
            phrases = []
            if len(zones_with_upcoming_maintenance) == 1:
                phrases = ('a zone', 'window is')
            else:
                phrases = ('zones', 'windows are')
            title = ('You have selected {0} with upcoming '
                     'maintenance. During maintenance, resources are '
                     'temporarily unavailible. The next scheduled '
                     '{1} as follows:'.format(phrases[0], phrases[1]))
            printable_maintenance_zones = []
            for zone in zones_with_upcoming_maintenance:
                next_event = min(zone.maintenanceWindows,
                                 key=lambda x: x.beginTime)
                window = '[{0}]: {1} -- {2}'.format(zone.name,
                                                    next_event.beginTime,
                                                    next_event.endTime)
                printable_maintenance_zones.append(window)
            prompts.append(
                utils.ConstructList(title, printable_maintenance_zones))

        if zones_with_deprecated:
            phrases = []
            if len(zones_with_deprecated) == 1:
                phrases = ('zone is', 'this zone', 'the')
            else:
                phrases = ('zones are', 'these zones', 'their')
            title = ('\n'
                     'WARNING: The following selected {0} deprecated.'
                     ' All resources in {1} will be deleted after'
                     ' {2} turndown date.'.format(phrases[0], phrases[1],
                                                  phrases[2]))
            printable_deprecated_zones = []
            for zone in zones_with_deprecated:
                if zone.deprecated.deleted:
                    printable_deprecated_zones.append(
                        ('[{0}] {1}').format(zone.name,
                                             zone.deprecated.deleted))
                else:
                    printable_deprecated_zones.append('[{0}]'.format(
                        zone.name))
            prompts.append(
                utils.ConstructList(title, printable_deprecated_zones))

        final_message = ' '.join(prompts)
        if not console_io.PromptContinue(message=final_message):
            raise calliope_exceptions.ToolException(
                'Creation aborted by user.')