예제 #1
0
def AssertInstanceGroupManagerExists(igm_ref, project, messages, compute, http,
                                     batch_url):
    """Makes sure the given Instance Group Manager exists.

  Args:
    igm_ref: reference to the Instance Group Manager.
    project: project owning resources.
    messages: module containing message classes.
    compute: module representing compute api.
    http: communication channel.
    batch_url: batch url.
  """
    request = messages.ComputeInstanceGroupManagersGetRequest(project=project)
    request.zone = igm_ref.zone
    request.instanceGroupManager = igm_ref.Name()

    errors = []
    # Run throught the generator to actually make the requests and get potential
    # errors.
    igm_details = list(
        request_helper.MakeRequests(
            requests=[(compute.instanceGroupManagers, 'Get', request)],
            http=http,
            batch_url=batch_url,
            errors=errors,
            custom_get_requests=None,
        ))

    if errors or len(igm_details) != 1:
        utils.RaiseException(errors,
                             ResourceNotFoundException,
                             error_message='Could not fetch resource:')
예제 #2
0
  def ProcessEditedResource(self, file_contents, args):
    """Returns an updated resource that was edited by the user."""

    # It's very important that we replace the characters of comment
    # lines with spaces instead of removing the comment lines
    # entirely. JSON and YAML deserialization give error messages
    # containing line, column, and the character offset of where the
    # error occurred. If the deserialization fails; we want to make
    # sure those numbers map back to what the user actually had in
    # front of him or her otherwise the errors will not be very
    # useful.
    non_comment_lines = '\n'.join(
        ' ' * len(line) if line.startswith('#') else line
        for line in file_contents.splitlines())

    modified_record = _DeserializeValue(non_comment_lines,
                                        args.format or BaseEdit.DEFAULT_FORMAT)

    # Normalizes all of the fields that refer to other
    # resource. (i.e., translates short names to URIs)
    reference_normalizer = property_selector.PropertySelector(
        transformations=self.reference_normalizers)
    modified_record = reference_normalizer.Apply(modified_record)

    if self.modifiable_record == modified_record:
      new_object = None

    else:
      modified_record['name'] = self.original_record['name']
      fingerprint = self.original_record.get('fingerprint')
      if fingerprint:
        modified_record['fingerprint'] = fingerprint

      new_object = encoding.DictToMessage(
          modified_record, self._resource_spec.message_class)

    # If existing object is equal to the proposed object or if
    # there is no new object, then there is no work to be done, so we
    # return the original object.
    if not new_object or self.original_object == new_object:
      return [self.original_object]

    errors = []
    resources = list(request_helper.MakeRequests(
        requests=[self.GetSetRequest(args, new_object, self.original_object)],
        http=self.http,
        batch_url=self.batch_url,
        errors=errors,
        custom_get_requests=None))
    if errors:
      utils.RaiseToolException(
          errors,
          error_message='Could not update resource:')

    return resources
예제 #3
0
def _GetResources(service, project, scopes, scope_name, filter_expr, http,
                  batch_url, errors):
    """Helper for the Get{Zonal,Regional,Global}Resources functions."""
    requests = FormatListRequests(service, project, scopes, scope_name,
                                  filter_expr)

    return request_helper.MakeRequests(requests=requests,
                                       http=http,
                                       batch_url=batch_url,
                                       errors=errors,
                                       custom_get_requests=None)
예제 #4
0
  def GetResources(self, args, errors):
    """Yields regional and/or global resources."""
    # This is true if the user provided no flags indicating scope
    no_scope_flags = args.regions is None and not getattr(args, 'global')

    requests = []
    filter_expr = self.GetFilterExpr(args)
    max_results = constants.MAX_RESULTS_PER_PAGE
    project = self.project

    # If --global is present OR no scope flags are present then we have to fetch
    # the global resources.
    if getattr(args, 'global'):
      requests.append(
          (self.global_service,
           'List',
           self.global_service.GetRequestType('List')(
               filter=filter_expr,
               maxResults=max_results,
               project=project)))

    # If --regions is present with no arguments OR no scope flags are present
    # then we have to do an aggregated list
    # pylint:disable=g-explicit-bool-comparison
    if args.regions == [] or no_scope_flags:
      requests.append(
          (self.regional_service,
           'AggregatedList',
           self.regional_service.GetRequestType('AggregatedList')(
               filter=filter_expr,
               maxResults=max_results,
               project=project)))
    # Else if some regions were provided then only list within them
    elif args.regions:
      region_names = set(
          self.CreateGlobalReference(region, resource_type='regions').Name()
          for region in args.regions)
      for region_name in sorted(region_names):
        requests.append(
            (self.regional_service,
             'List',
             self.regional_service.GetRequestType('List')(
                 filter=filter_expr,
                 maxResults=max_results,
                 region=region_name,
                 project=project)))

    return request_helper.MakeRequests(
        requests=requests,
        http=self.http,
        batch_url=self.batch_url,
        errors=errors,
        custom_get_requests=None)
  def _GetResources(self, args):
    """Retrieves response with named ports."""
    group_ref = self.CreateZonalReference(args.name, args.zone)
    request = self.service.GetRequestType('Get')(
        instanceGroup=group_ref.Name(),
        zone=group_ref.zone,
        project=self.project)

    errors = []
    results = list(request_helper.MakeRequests(
        requests=[(self.service, 'Get', request)],
        http=self.http,
        batch_url=self.batch_url,
        errors=errors,
        custom_get_requests=None))

    return results, errors
예제 #6
0
 def GetImage(self, image_ref):
   """Returns the image resource corresponding to the given reference."""
   errors = []
   res = list(request_helper.MakeRequests(
       requests=[(self.compute.images,
                  'Get',
                  self.messages.ComputeImagesGetRequest(
                      image=image_ref.Name(),
                      project=image_ref.project))],
       http=self.http,
       batch_url=self.batch_url,
       errors=errors,
       custom_get_requests=None))
   if errors:
     utils.RaiseToolException(
         errors,
         error_message='Could not fetch image resource:')
   return res[0]
예제 #7
0
 def GetProject(self):
     """Returns the project object."""
     errors = []
     objects = list(
         request_helper.MakeRequests(requests=[
             (self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(
                  project=properties.VALUES.core.project.Get(
                      required=True), ))
         ],
                                     http=self.http,
                                     batch_url=self.batch_url,
                                     errors=errors,
                                     custom_get_requests=None))
     if errors:
         utils.RaiseToolException(
             errors, error_message='Could not fetch project resource:')
     return objects[0]
예제 #8
0
    def GetInstanceExternalIpAddress(self, instance_ref):
        """Returns the external ip address for the given instance."""
        request = (self.compute.instances, 'Get',
                   self.messages.ComputeInstancesGetRequest(
                       instance=instance_ref.Name(),
                       project=self.project,
                       zone=instance_ref.zone))

        errors = []
        objects = list(
            request_helper.MakeRequests(requests=[request],
                                        http=self.http,
                                        batch_url=self.batch_url,
                                        errors=errors,
                                        custom_get_requests=None))
        if errors:
            utils.RaiseToolException(errors,
                                     error_message='Could not fetch instance:')
        return GetExternalIPAddress(objects[0])
예제 #9
0
 def GetAddress(self, address_ref):
   """Returns the address resource corresponding to the given reference."""
   errors = []
   res = list(request_helper.MakeRequests(
       requests=[(self.compute.addresses,
                  'Get',
                  self.messages.ComputeAddressesGetRequest(
                      address=address_ref.Name(),
                      project=address_ref.project,
                      region=address_ref.region))],
       http=self.http,
       batch_url=self.batch_url,
       errors=errors,
       custom_get_requests=None))
   if errors:
     utils.RaiseToolException(
         errors,
         error_message='Could not fetch address resource:')
   return res[0]
예제 #10
0
    def SetProjectMetadata(self, new_metadata):
        """Sets the project metadata to the new metadata."""
        compute = self.compute

        errors = []
        list(
            request_helper.MakeRequests(requests=[
                (compute.projects, 'SetCommonInstanceMetadata',
                 self.messages.ComputeProjectsSetCommonInstanceMetadataRequest(
                     metadata=new_metadata,
                     project=properties.VALUES.core.project.Get(required=True),
                 ))
            ],
                                        http=self.http,
                                        batch_url=self.batch_url,
                                        errors=errors,
                                        custom_get_requests=None))
        if errors:
            utils.RaiseToolException(
                errors,
                error_message='Could not add SSH key to project metadata:')
예제 #11
0
    def LookupUsers(self, users):
        """Makes a get request for each user in users and returns results."""
        requests = []
        for user in users:
            request = (self.clouduseraccounts.users, 'Get',
                       self.clouduseraccounts.MESSAGES_MODULE.
                       ClouduseraccountsUsersGetRequest(project=self.project,
                                                        user=user))
            requests.append(request)

        errors = []
        res = list(
            request_helper.MakeRequests(requests=requests,
                                        http=self.http,
                                        batch_url=self.batch_url,
                                        errors=errors,
                                        custom_get_requests=None))
        if errors:
            utils.RaiseException(errors,
                                 UserException,
                                 error_message='Could not fetch some users:')
        return res
예제 #12
0
    def RemovePublicKey(self, user, fingerprint):
        """Removes a public key from a user."""
        request = (self.clouduseraccounts.users, 'RemovePublicKey',
                   self.clouduseraccounts.MESSAGES_MODULE.
                   ClouduseraccountsUsersRemovePublicKeyRequest(
                       project=self.project,
                       fingerprint=fingerprint,
                       user=user))

        requests = [request]

        errors = []
        res = list(
            request_helper.MakeRequests(requests=requests,
                                        http=self.http,
                                        batch_url=self.batch_url,
                                        errors=errors,
                                        custom_get_requests=None))
        if errors:
            utils.RaiseException(errors,
                                 UserException,
                                 error_message='Could not remove public key:')
        return res
예제 #13
0
  def Run(self, args, request_protobufs=None, service=None):
    if request_protobufs is None:
      request_protobufs = self.CreateRequests(args)
    if service is None:
      service = self.service
    requests = []
    # If a method is not passed as part of a tuple then use the self.method
    # default
    for request in request_protobufs:
      if isinstance(request, tuple):
        method = request[0]
        proto = request[1]
      else:
        method = self.method
        proto = request
      requests.append((service, method, proto))

    errors = []
    # We want to run through the generator that MakeRequests returns in order to
    # actually make the requests, since these requests mutate resources.
    resources = list(request_helper.MakeRequests(
        requests=requests,
        http=self.http,
        batch_url=self.batch_url,
        errors=errors,
        custom_get_requests=self.custom_get_requests))

    resources = lister.ProcessResults(
        resources=resources,
        field_selector=property_selector.PropertySelector(
            properties=None,
            transformations=self.transformations))

    if errors:
      utils.RaiseToolException(errors)

    return resources
예제 #14
0
    def GetZones(self, resource_refs):
        """Fetches zone resources."""
        errors = []
        requests = []
        zone_names = set()
        for resource_ref in resource_refs:
            if resource_ref.zone not in zone_names:
                zone_names.add(resource_ref.zone)
                requests.append((self.compute.zones, 'Get',
                                 self.messages.ComputeZonesGetRequest(
                                     project=self.project,
                                     zone=resource_ref.zone)))

        res = list(
            request_helper.MakeRequests(requests=requests,
                                        http=self.http,
                                        batch_url=self.batch_url,
                                        errors=errors,
                                        custom_get_requests=None))

        if errors:
            return None
        else:
            return res
예제 #15
0
  def GetMatchingImages(self, image, alias, errors):
    """Yields images from a public image project and the user's project."""
    service = self.compute.images
    requests = [
        (service,
         'List',
         self.messages.ComputeImagesListRequest(
             filter='name eq ^{0}(-.+)*-v.+'.format(alias.name_prefix),
             maxResults=constants.MAX_RESULTS_PER_PAGE,
             project=alias.project)),
        (service,
         'List',
         self.messages.ComputeImagesListRequest(
             filter='name eq ^{0}$'.format(image),
             maxResults=constants.MAX_RESULTS_PER_PAGE,
             project=self.project)),
    ]

    return request_helper.MakeRequests(
        requests=requests,
        http=self.http,
        batch_url=self.batch_url,
        errors=errors,
        custom_get_requests=None)
  def _GetGroupFingerprint(self, name, zone):
    """Gets fingerprint of given instance group."""
    get_request = self.messages.ComputeInstanceGroupsGetRequest(
        instanceGroup=name,
        zone=zone,
        project=self.project)

    errors = []
    resources = list(request_helper.MakeRequests(
        requests=[(
            self.compute.instanceGroups,
            'Get',
            get_request)],
        http=self.http,
        batch_url=self.batch_url,
        errors=errors,
        custom_get_requests=None))

    if errors:
      utils.RaiseException(
          errors,
          FingerprintFetchException,
          error_message='Could not set named ports for resource:')
    return resources[0].fingerprint
예제 #17
0
  def Run(self, args):
    self.ref = self.CreateReference(args)
    get_request = self.GetGetRequest(args)

    errors = []
    objects = list(request_helper.MakeRequests(
        requests=[get_request],
        http=self.http,
        batch_url=self.batch_url,
        errors=errors,
        custom_get_requests=None))
    if errors:
      utils.RaiseToolException(
          errors,
          error_message='Could not fetch resource:')

    self.original_object = objects[0]
    self.original_record = encoding.MessageToDict(self.original_object)

    # Selects only the fields that can be modified.
    field_selector = property_selector.PropertySelector(
        properties=self._resource_spec.editables)
    self.modifiable_record = field_selector.Apply(self.original_record)

    buf = cStringIO.StringIO()
    for line in _HELP.splitlines():
      buf.write('#')
      if line:
        buf.write(' ')
      buf.write(line)
      buf.write('\n')

    buf.write('\n')
    buf.write(_SerializeDict(self.modifiable_record,
                             args.format or BaseEdit.DEFAULT_FORMAT))
    buf.write('\n')

    example = _SerializeDict(
        encoding.MessageToDict(self.example_resource),
        args.format or BaseEdit.DEFAULT_FORMAT)
    _WriteResourceInCommentBlock(example, 'Example resource:', buf)

    buf.write('#\n')

    original = _SerializeDict(self.original_record,
                              args.format or BaseEdit.DEFAULT_FORMAT)
    _WriteResourceInCommentBlock(original, 'Original resource:', buf)

    file_contents = buf.getvalue()
    while True:
      try:
        file_contents = edit.OnlineEdit(file_contents)
      except edit.NoSaveException:
        raise calliope_exceptions.ToolException('Edit aborted by user.')
      try:
        resources = self.ProcessEditedResource(file_contents, args)
        break
      except (ValueError, yaml.error.YAMLError,
              protorpc.messages.ValidationError,
              calliope_exceptions.ToolException) as e:
        if isinstance(e, ValueError):
          message = e.message
        else:
          message = str(e)

        if isinstance(e, calliope_exceptions.ToolException):
          problem_type = 'applying'
        else:
          problem_type = 'parsing'

        message = ('There was a problem {0} your changes: {1}'
                   .format(problem_type, message))
        if not console_io.PromptContinue(
            message=message,
            prompt_string='Would you like to edit the resource again?'):
          raise calliope_exceptions.ToolException('Edit aborted by user.')

    resources = lister.ProcessResults(
        resources=resources,
        field_selector=property_selector.PropertySelector(
            properties=None,
            transformations=self.transformations))
    for resource in resources:
      yield resource