Ejemplo n.º 1
0
def _GetSource(source_arg):
    """Parse the source bucket and object from the --source flag."""
    if not source_arg:
        raise exceptions.FunctionsError(SOURCE_ERROR_MESSAGE)

    source_match = SOURCE_REGEX.match(source_arg)
    if not source_match:
        raise exceptions.FunctionsError(SOURCE_ERROR_MESSAGE)

    return (source_match.group(1), source_match.group(2))
Ejemplo n.º 2
0
def _GetRetry(args, messages, event_trigger):
    """Constructs an RetryPolicy enum from --(no-)retry flag.

  Args:
    args: argparse.Namespace, arguments that this command was invoked with
    messages: messages module, the GCFv2 message stubs
    event_trigger: cloudfunctions_v2alpha_messages.EventTrigger, used to request
      events sent from another service

  Returns:
    EventTrigger.RetryPolicyValueValuesEnum(
      'RETRY_POLICY_RETRY' | 'RETRY_POLICY_DO_NOT_RETRY')
    frozenset, set of update mask fields
  """

    if event_trigger is None:
        raise exceptions.FunctionsError(_INVALID_RETRY_FLAG_ERROR_MESSAGE)

    if args.retry:
        return messages.EventTrigger.RetryPolicyValueValuesEnum(
            'RETRY_POLICY_RETRY'), frozenset(['eventTrigger.retryPolicy'])
    else:
        # explicitly using --no-retry flag
        return messages.EventTrigger.RetryPolicyValueValuesEnum(
            'RETRY_POLICY_DO_NOT_RETRY'), frozenset(
                ['eventTrigger.retryPolicy'])
Ejemplo n.º 3
0
def _GetSourceCSR(messages, source):
    """Constructs a `Source` message from a Cloud Source Repository reference.

  Args:
    messages: messages module, the GCFv2 message stubs
    source: str, the Cloud Source Repository reference

  Returns:
    function_source: cloud.functions.v2main.Source
  """
    match = _CSR_SOURCE_REGEX.match(source)

    if match is None:
        raise exceptions.FunctionsError(_CSR_SOURCE_ERROR_MESSAGE)

    repo_source = messages.RepoSource(
        projectId=match.group('project_id'),
        repoName=match.group('repo_name'),
        dir=match.group('path'),  # Optional
    )

    # Optional oneof revision field
    commit = match.group('commit')
    branch = match.group('branch')
    tag = match.group('tag')

    if commit:
        repo_source.commitSha = commit
    elif tag:
        repo_source.tagName = tag
    else:
        # Default to 'master' branch if no revision/alias provided.
        repo_source.branchName = branch or 'master'

    return messages.Source(repoSource=repo_source)
Ejemplo n.º 4
0
def WaitForOperation(client,
                     messages,
                     operation,
                     description,
                     extra_stages=None):
    """Wait for a long-running operation (LRO) to complete.

  Args:
    client: The GCFv2 API client.
    messages: The GCFv2 message stubs.
    operation: The operation message response.
    description: str, the description of the waited operation.
    extra_stages: List[progress_tracker.Stage]|None, list of optional stages for
      the progress tracker to watch. The GCF 2nd api returns unexpected stages
      in the case of rollbacks.
  """
    request = messages.CloudfunctionsProjectsLocationsOperationsGetRequest(
        name=operation.name)
    # Wait for stages to be loaded.
    with progress_tracker.ProgressTracker('Preparing function') as tracker:
        retryer = retry.Retryer(max_wait_ms=MAX_WAIT_MS)
        try:
            # List[progress_tracker.Stage]
            stages = retryer.RetryOnResult(_GetStages,
                                           args=[client, request, messages],
                                           should_retry_if=None,
                                           sleep_ms=SLEEP_MS)
        except retry.WaitException:
            raise exceptions.FunctionsError(
                'Operation {0} is taking too long'.format(request.name))

    if extra_stages is not None:
        stages += extra_stages

    # Wait for LRO to complete.
    description += '...'
    with progress_tracker.StagedProgressTracker(description,
                                                stages) as tracker:
        retryer = retry.Retryer(max_wait_ms=MAX_WAIT_MS)
        try:
            retryer.RetryOnResult(_GetOperationStatus,
                                  args=[client, request, tracker, messages],
                                  should_retry_if=False,
                                  sleep_ms=SLEEP_MS)
        except retry.WaitException:
            raise exceptions.FunctionsError(
                'Operation {0} is taking too long'.format(request.name))
Ejemplo n.º 5
0
def _GetOperationStatus(client, request, tracker):
  """Returns a Boolean indicating whether the request has completed."""
  if tracker:
    tracker.Tick()
  op = client.projects_locations_operations.Get(request)
  if op.error:
    raise exceptions.FunctionsError(op)
  return op.done
Ejemplo n.º 6
0
def _GetSourceGCS(messages, source):
    """Constructs a `Source` message from a Cloud Storage object.

  Args:
    messages: messages module, the GCFv2 message stubs
    source: str, the Cloud Storage URL

  Returns:
    function_source: cloud.functions.v2main.Source
  """
    match = _GCS_SOURCE_REGEX.match(source)
    if not match:
        raise exceptions.FunctionsError(_GCS_SOURCE_ERROR_MESSAGE)

    return messages.Source(storageSource=messages.StorageSource(
        bucket=match.group(1), object=match.group(2)))
Ejemplo n.º 7
0
def Run(args, release_track):
    """Delete a Google Cloud Function."""
    client = api_util.GetClientInstance(release_track=release_track)
    messages = api_util.GetMessagesModule(release_track=release_track)

    function_ref = args.CONCEPTS.name.Parse()
    function_relative_name = function_ref.RelativeName()

    prompt_message = 'Function [{0}] will be deleted.'.format(
        function_relative_name)
    if not console_io.PromptContinue(message=prompt_message):
        raise exceptions.FunctionsError('Deletion aborted by user.')

    operation = client.projects_locations_functions.Delete(
        messages.CloudfunctionsProjectsLocationsFunctionsDeleteRequest(
            name=function_relative_name))
    api_util.WaitForOperation(client, messages, operation, 'Deleting function')

    log.DeletedResource(function_relative_name)
Ejemplo n.º 8
0
def _UploadToGeneratedUrl(zip_file_path, url):
    """Uploads a ZIP file to a signed Cloud Storage URL.

  Args:
    zip_file_path: str, the path to the ZIP file
    url: str, the signed Cloud Storage URL
  """
    upload = transfer.Upload.FromFile(zip_file_path, mime_type=_ZIP_MIME_TYPE)
    try:
        request = http_wrapper.Request(
            url, http_method='PUT', headers={'content-type': upload.mime_type})
        request.body = upload.stream.read()
        upload.stream.close()
        response = http_wrapper.MakeRequest(transports.GetApitoolsTransport(),
                                            request)
    finally:
        upload.stream.close()
    if response.status_code // 100 != 2:
        raise exceptions.FunctionsError(_SIGNED_URL_UPLOAD_ERROR_MESSSAGE)
Ejemplo n.º 9
0
def WaitForOperation(client, messages, operation, description):
    """Wait for a long-running operation (LRO) to complete."""
    request = messages.CloudfunctionsProjectsLocationsOperationsGetRequest(
        name=operation.name)

    with progress_tracker.ProgressTracker(description,
                                          autotick=False) as tracker:
        # This is actually linear retryer.
        retryer = retry.Retryer(exponential_sleep_multiplier=1,
                                max_wait_ms=MAX_WAIT_MS,
                                wait_ceiling_ms=WAIT_CEILING_MS)
        try:
            retryer.RetryOnResult(_GetOperationStatus,
                                  args=[client, request, tracker],
                                  should_retry_if=False,
                                  sleep_ms=SLEEP_MS)
        except retry.WaitException:
            raise exceptions.FunctionsError(
                'Operation {0} is taking too long'.format(request.name))
Ejemplo n.º 10
0
def _ValidateLegacyV1Flags(args):
    for flag_variable, flag_name in LEGACY_V1_FLAGS:
        if args.IsSpecified(flag_variable):
            raise exceptions.FunctionsError(LEGACY_V1_FLAG_ERROR % flag_name)
Ejemplo n.º 11
0
def _ValidateUnsupportedV2Flags(args):
    for flag_variable, flag_name in _UNSUPPORTED_V2_FLAGS:
        if args.IsSpecified(flag_variable):
            raise exceptions.FunctionsError(_UNSUPPORTED_V2_FLAG_ERROR %
                                            flag_name)
Ejemplo n.º 12
0
def _Run(args, release_track):
    """Display log entries produced by Google Cloud Functions."""
    if args.execution_id:
        raise exceptions.FunctionsError(EXECUTION_ID_NOT_SUPPORTED)

    region = properties.VALUES.functions.region.GetOrFail()
    log_filter = [
        'resource.type="cloud_run_revision"',
        'resource.labels.location="%s"' % region,
        'logName:"run.googleapis.com"'
    ]

    if args.name:
        log_filter.append('resource.labels.service_name="%s"' % args.name)
    if args.min_log_level:
        log_filter.append('severity>=%s' % args.min_log_level.upper())

    log_filter.append('timestamp>="%s"' % logging_util.FormatTimestamp(
        args.start_time
        or datetime.datetime.utcnow() - datetime.timedelta(days=7)))

    if args.end_time:
        log_filter.append('timestamp<="%s"' %
                          logging_util.FormatTimestamp(args.end_time))

    log_filter = ' '.join(log_filter)

    entries = list(
        logging_common.FetchLogs(log_filter, order_by='DESC',
                                 limit=args.limit))

    if args.name and not entries:
        # Check if the function even exists in the given region.
        try:
            client = api_util.GetClientInstance(release_track=release_track)
            messages = api_util.GetMessagesModule(release_track=release_track)
            client.projects_locations_functions.Get(
                messages.CloudfunctionsProjectsLocationsFunctionsGetRequest(
                    name='projects/%s/locations/%s/functions/%s' %
                    (properties.VALUES.core.project.GetOrFail(), region,
                     args.name)))
        except (HttpForbiddenError, HttpNotFoundError):
            # The function doesn't exist in the given region.
            log.warning(
                'There is no function named `%s` in region `%s`. Perhaps you '
                'meant to specify `--region` or update the `functions/region` '
                'configuration property?' % (args.name, region))

    for entry in entries:
        message = entry.textPayload
        if entry.jsonPayload:
            props = [
                prop.value for prop in entry.jsonPayload.additionalProperties
                if prop.key == 'message'
            ]
            if len(props) == 1 and hasattr(props[0], 'string_value'):
                message = props[0].string_value
        row = {'log': message}
        if entry.severity:
            severity = six.text_type(entry.severity)
            if severity in flags.SEVERITIES:
                # Use short form (first letter) for expected severities.
                row['level'] = severity[0]
            else:
                # Print full form of unexpected severities.
                row['level'] = severity
        if entry.resource and entry.resource.labels:
            for label in entry.resource.labels.additionalProperties:
                if label.key == 'service_name':
                    row['name'] = label.value
        if entry.timestamp:
            row['time_utc'] = api_util.FormatTimestamp(entry.timestamp)
        yield row