def add_machine(self, request):
     """Handles an incoming CatalogMachineAdditionRequest."""
     user = auth.get_current_identity().to_bytes()
     logging.info(
         'Received CatalogMachineAdditionRequest:\nUser: %s\n%s',
         user,
         request,
     )
     error = self.check_backend(request) or self.check_hostname(request)
     if error:
         return rpc_messages.CatalogManipulationResponse(
             error=error,
             machine_addition_request=request,
         )
     if request.policies.pubsub_topic:
         if not pubsub.validate_topic(request.policies.pubsub_topic):
             logging.warning(
                 'Invalid topic for Cloud Pub/Sub: %s',
                 request.policies.pubsub_topic,
             )
             return rpc_messages.CatalogManipulationResponse(
                 error=rpc_messages.CatalogManipulationRequestError.
                 INVALID_TOPIC,
                 machine_addition_request=request,
             )
         if not request.policies.pubsub_project:
             logging.info(
                 'Cloud Pub/Sub project unspecified, using default: %s',
                 PUBSUB_DEFAULT_PROJECT,
             )
             request.policies.pubsub_project = PUBSUB_DEFAULT_PROJECT
     if request.policies.pubsub_project:
         error = None
         if not pubsub.validate_project(request.policies.pubsub_project):
             logging.warning(
                 'Invalid project for Cloud Pub/Sub: %s',
                 request.policies.pubsub_project,
             )
             error = rpc_messages.CatalogManipulationRequestError.INVALID_PROJECT
         elif not request.policies.pubsub_topic:
             logging.warning(
                 'Cloud Pub/Sub project specified without specifying topic: %s',
                 request.policies.pubsub_project,
             )
             error = rpc_messages.CatalogManipulationRequestError.UNSPECIFIED_TOPIC
         if error:
             return rpc_messages.CatalogManipulationResponse(
                 error=error, machine_addition_request=request)
     return self._add_machine(request)
 def add_machine(self, request):
   """Handles an incoming CatalogMachineAdditionRequest."""
   user = auth.get_current_identity().to_bytes()
   logging.info(
       'Received CatalogMachineAdditionRequest:\nUser: %s\n%s',
       user,
       request,
   )
   error = self.check_backend(request) or self.check_hostname(request)
   if error:
     return rpc_messages.CatalogManipulationResponse(
         error=error,
         machine_addition_request=request,
     )
   if request.policies.pubsub_topic:
     if not pubsub.validate_topic(request.policies.pubsub_topic):
       logging.warning(
           'Invalid topic for Cloud Pub/Sub: %s',
           request.policies.pubsub_topic,
       )
       return rpc_messages.CatalogManipulationResponse(
           error=rpc_messages.CatalogManipulationRequestError.INVALID_TOPIC,
           machine_addition_request=request,
       )
     if not request.policies.pubsub_project:
       logging.info(
           'Cloud Pub/Sub project unspecified, using default: %s',
           PUBSUB_DEFAULT_PROJECT,
       )
       request.policies.pubsub_project = PUBSUB_DEFAULT_PROJECT
   if request.policies.pubsub_project:
     error = None
     if not pubsub.validate_project(request.policies.pubsub_project):
       logging.warning(
           'Invalid project for Cloud Pub/Sub: %s',
           request.policies.pubsub_project,
       )
       error = rpc_messages.CatalogManipulationRequestError.INVALID_PROJECT
     elif not request.policies.pubsub_topic:
       logging.warning(
           'Cloud Pub/Sub project specified without specifying topic: %s',
           request.policies.pubsub_project,
       )
       error = rpc_messages.CatalogManipulationRequestError.UNSPECIFIED_TOPIC
     if error:
       return rpc_messages.CatalogManipulationResponse(
           error=error, machine_addition_request=request)
   return self._add_machine(request)
 def lease(self, request):
   """Handles an incoming LeaseRequest."""
   # Hash the combination of client + client-generated request ID in order to
   # deduplicate responses on a per-client basis.
   user = auth.get_current_identity().to_bytes()
   request_hash = models.LeaseRequest.generate_key(user, request).id()
   logging.info(
       'Received LeaseRequest:\nUser: %s\nRequest hash: %s\n%s',
       user,
       request_hash,
       request,
   )
   if request.pubsub_topic:
     if not pubsub.validate_topic(request.pubsub_topic):
       logging.warning(
           'Invalid topic for Cloud Pub/Sub: %s',
           request.pubsub_topic,
       )
       return rpc_messages.LeaseResponse(
           error=rpc_messages.LeaseRequestError.INVALID_TOPIC,
       )
     if not request.pubsub_project:
       logging.info(
           'Cloud Pub/Sub project unspecified, using default: %s',
           PUBSUB_DEFAULT_PROJECT,
       )
       request.pubsub_project = PUBSUB_DEFAULT_PROJECT
   if request.pubsub_project:
     if not pubsub.validate_project(request.pubsub_project):
       logging.warning(
           'Invalid project for Cloud Pub/Sub: %s',
           request.pubsub_topic,
       )
       return rpc_messages.LeaseResponse(
           error=rpc_messages.LeaseRequestError.INVALID_PROJECT,
       )
     elif not request.pubsub_topic:
       logging.warning(
           'Cloud Pub/Sub project specified without specifying topic: %s',
           request.pubsub_project,
       )
       return rpc_messages.LeaseResponse(
           error=rpc_messages.LeaseRequestError.UNSPECIFIED_TOPIC,
       )
   duplicate = models.LeaseRequest.get_by_id(request_hash)
   deduplication_checksum = models.LeaseRequest.compute_deduplication_checksum(
       request,
   )
   if duplicate:
     # Found a duplicate request ID from the same user. Attempt deduplication.
     if deduplication_checksum == duplicate.deduplication_checksum:
       # The LeaseRequest RPC we just received matches the original.
       # We're safe to dedupe.
       logging.info(
           'Dropped duplicate LeaseRequest:\n%s', duplicate.response,
       )
       return duplicate.response
     else:
       logging.warning(
           'Request ID reuse:\nOriginally used for:\n%s',
           duplicate.request
       )
       return rpc_messages.LeaseResponse(
           error=rpc_messages.LeaseRequestError.REQUEST_ID_REUSE,
       )
   else:
     logging.info('Storing LeaseRequest')
     response = rpc_messages.LeaseResponse()
     response.request_hash = request_hash
     models.LeaseRequest(
         deduplication_checksum=deduplication_checksum,
         id=request_hash,
         owner=auth.get_current_identity(),
         request=request,
         response=response,
         state=models.LeaseRequestStates.UNTRIAGED,
     ).put()
     logging.info('Sending LeaseResponse:\n%s', response)
     return response
 def _lease(self, request, user, request_hash):
     """Handles an incoming LeaseRequest."""
     if request.pubsub_topic:
         if not pubsub.validate_topic(request.pubsub_topic):
             logging.warning(
                 'Invalid topic for Cloud Pub/Sub: %s',
                 request.pubsub_topic,
             )
             return rpc_messages.LeaseResponse(
                 client_request_id=request.request_id,
                 error=rpc_messages.LeaseRequestError.INVALID_TOPIC,
             )
         if not request.pubsub_project:
             logging.info(
                 'Cloud Pub/Sub project unspecified, using default: %s',
                 PUBSUB_DEFAULT_PROJECT,
             )
             request.pubsub_project = PUBSUB_DEFAULT_PROJECT
     if request.pubsub_project:
         if not pubsub.validate_project(request.pubsub_project):
             logging.warning(
                 'Invalid project for Cloud Pub/Sub: %s',
                 request.pubsub_topic,
             )
             return rpc_messages.LeaseResponse(
                 client_request_id=request.request_id,
                 error=rpc_messages.LeaseRequestError.INVALID_PROJECT,
             )
         elif not request.pubsub_topic:
             logging.warning(
                 'Cloud Pub/Sub project specified without specifying topic: %s',
                 request.pubsub_project,
             )
             return rpc_messages.LeaseResponse(
                 client_request_id=request.request_id,
                 error=rpc_messages.LeaseRequestError.UNSPECIFIED_TOPIC,
             )
     duplicate = models.LeaseRequest.get_by_id(request_hash)
     deduplication_checksum = models.LeaseRequest.compute_deduplication_checksum(
         request, )
     if duplicate:
         # Found a duplicate request ID from the same user. Attempt deduplication.
         if deduplication_checksum == duplicate.deduplication_checksum:
             # The LeaseRequest RPC we just received matches the original.
             # We're safe to dedupe.
             logging.info(
                 'Dropped duplicate LeaseRequest:\n%s',
                 duplicate.response,
             )
             return duplicate.response
         else:
             logging.warning('Request ID reuse:\nOriginally used for:\n%s',
                             duplicate.request)
             return rpc_messages.LeaseResponse(
                 client_request_id=request.request_id,
                 error=rpc_messages.LeaseRequestError.REQUEST_ID_REUSE,
             )
     else:
         logging.info('Storing LeaseRequest')
         response = rpc_messages.LeaseResponse(
             client_request_id=request.request_id,
             request_hash=request_hash,
             state=rpc_messages.LeaseRequestState.UNTRIAGED,
         )
         models.LeaseRequest(
             deduplication_checksum=deduplication_checksum,
             id=request_hash,
             owner=auth.get_current_identity(),
             request=request,
             response=response,
         ).put()
         logging.info('Sending LeaseResponse:\n%s', response)
         return response
Beispiel #5
0
    def _lease(self, request, user, request_hash):
        """Handles an incoming LeaseRequest."""
        # Arbitrary limit. Increase if necessary.
        MAX_LEASE_DURATION = 60 * 60 * 24 * 2
        now = utils.time_time()
        max_lease_expiration_ts = now + MAX_LEASE_DURATION

        metrics.lease_requests_received.increment()
        if request.duration:
            if request.lease_expiration_ts:
                return rpc_messages.LeaseResponse(
                    client_request_id=request.request_id,
                    error=rpc_messages.LeaseRequestError.
                    MUTUAL_EXCLUSION_ERROR,
                )
            if request.duration < 1:
                return rpc_messages.LeaseResponse(
                    client_request_id=request.request_id,
                    error=rpc_messages.LeaseRequestError.NONPOSITIVE_DEADLINE,
                )
            if request.duration > MAX_LEASE_DURATION:
                return rpc_messages.LeaseResponse(
                    client_request_id=request.request_id,
                    error=rpc_messages.LeaseRequestError.LEASE_TOO_LONG,
                )
        elif request.lease_expiration_ts:
            if request.lease_expiration_ts <= now:
                return rpc_messages.LeaseResponse(
                    client_request_id=request.request_id,
                    error=rpc_messages.LeaseRequestError.
                    LEASE_EXPIRATION_TS_ERROR,
                )
            if request.lease_expiration_ts > max_lease_expiration_ts:
                return rpc_messages.LeaseResponse(
                    client_request_id=request.request_id,
                    error=rpc_messages.LeaseRequestError.LEASE_TOO_LONG,
                )
        else:
            return rpc_messages.LeaseResponse(
                client_request_id=request.request_id,
                error=rpc_messages.LeaseRequestError.LEASE_LENGTH_UNSPECIFIED,
            )
        if request.pubsub_topic:
            if not pubsub.validate_topic(request.pubsub_topic):
                logging.warning(
                    'Invalid topic for Cloud Pub/Sub: %s',
                    request.pubsub_topic,
                )
                return rpc_messages.LeaseResponse(
                    client_request_id=request.request_id,
                    error=rpc_messages.LeaseRequestError.INVALID_TOPIC,
                )
            if not request.pubsub_project:
                logging.info(
                    'Cloud Pub/Sub project unspecified, using default: %s',
                    PUBSUB_DEFAULT_PROJECT,
                )
                request.pubsub_project = PUBSUB_DEFAULT_PROJECT
        if request.pubsub_project:
            if not pubsub.validate_project(request.pubsub_project):
                logging.warning(
                    'Invalid project for Cloud Pub/Sub: %s',
                    request.pubsub_topic,
                )
                return rpc_messages.LeaseResponse(
                    client_request_id=request.request_id,
                    error=rpc_messages.LeaseRequestError.INVALID_PROJECT,
                )
            elif not request.pubsub_topic:
                logging.warning(
                    'Cloud Pub/Sub project specified without specifying topic: %s',
                    request.pubsub_project,
                )
                return rpc_messages.LeaseResponse(
                    client_request_id=request.request_id,
                    error=rpc_messages.LeaseRequestError.UNSPECIFIED_TOPIC,
                )
        duplicate = models.LeaseRequest.get_by_id(request_hash)
        deduplication_checksum = models.LeaseRequest.compute_deduplication_checksum(
            request, )
        if duplicate:
            # Found a duplicate request ID from the same user. Attempt deduplication.
            if deduplication_checksum == duplicate.deduplication_checksum:
                metrics.lease_requests_deduped.increment()
                # The LeaseRequest RPC we just received matches the original.
                # We're safe to dedupe.
                logging.info(
                    'Dropped duplicate LeaseRequest:\n%s',
                    duplicate.response,
                )
                return duplicate.response
            else:
                logging.warning('Request ID reuse:\nOriginally used for:\n%s',
                                duplicate.request)
                return rpc_messages.LeaseResponse(
                    client_request_id=request.request_id,
                    error=rpc_messages.LeaseRequestError.REQUEST_ID_REUSE,
                )
        else:
            logging.info('Storing LeaseRequest')
            response = rpc_messages.LeaseResponse(
                client_request_id=request.request_id,
                request_hash=request_hash,
                state=rpc_messages.LeaseRequestState.UNTRIAGED,
            )
            models.LeaseRequest(
                deduplication_checksum=deduplication_checksum,
                id=request_hash,
                owner=auth.get_current_identity(),
                request=request,
                response=response,
            ).put()
            logging.info('Sending LeaseResponse:\n%s', response)
            return response