Ejemplo n.º 1
0
    def Run(self, args):
        """Executes when the user runs the describe command."""
        conn_context = connection_context.GetConnectionContext(
            args, product=connection_context.Product.EVENTS)

        trigger_ref = args.CONCEPTS.trigger.Parse()
        with eventflow_operations.Connect(conn_context) as client:
            trigger_obj = client.GetTrigger(trigger_ref)
            source_obj = None
            if trigger_obj is not None:
                source_crds = client.ListSourceCustomResourceDefinitions()
                source_obj_ref = trigger_obj.dependency
                source_crd = next((s for s in source_crds
                                   if s.source_kind == source_obj_ref.kind),
                                  None)
                if source_crd is not None:
                    source_ref = util.GetSourceRef(source_obj_ref.name,
                                                   source_obj_ref.namespace,
                                                   source_crd)
                    source_obj = client.GetSource(source_ref, source_crd)
        if not trigger_obj:
            raise exceptions.TriggerNotFound('Trigger [{}] not found.'.format(
                trigger_ref.Name()))
        if not source_obj:
            log.warning('No matching event source for trigger [{}].'.format(
                trigger_ref.Name()))
        return SerializedTriggerAndSource(
            trigger_obj.MakeSerializable(),
            source_obj.MakeSerializable() if source_obj else None)
Ejemplo n.º 2
0
    def CreateTriggerAndSource(self, trigger_obj, trigger_ref, namespace_ref,
                               source_obj, event_type, parameters, broker,
                               target_service, tracker):
        """Create a linked trigger and source pair.

    Trigger and source are linked via a dependency annotation on the trigger
    as well as the opaque knsourcetrigger field in the trigger filter and the
    source override.

    If the passed trigger_obj is not None, then a new trigger is not created,
    only a source.

    Args:
      trigger_obj: trigger.Trigger, the existing trigger or None if no trigger
        already exists.
      trigger_ref: googlecloudsdk.core.resources.Resource, trigger resource.
      namespace_ref: googlecloudsdk.core.resources.Resource, namespace resource.
      source_obj: source.Source. The source object being created.
      event_type: custom_resource_definition.EventTypeDefinition, the event
        type the source will filter by.
      parameters: dict, additional parameters to set on the source spec.
      broker: str, name of the broker to act as a sink for the source.
      target_service: str, name of the Cloud Run service to subscribe to the
        trigger.
      tracker: progress_tracker.StagedProgressTracker to update as the trigger
        is created and becomes ready.
    """
        # Create trigger if it doesn't already exist
        if trigger_obj is None:
            trigger_obj = self.CreateTrigger(trigger_ref, source_obj,
                                             event_type, target_service,
                                             broker)

        # Create source
        self.CreateSource(source_obj, event_type.crd, trigger_obj,
                          namespace_ref, broker, parameters)

        # Wait for source to be Ready == True
        source_ref = util.GetSourceRef(source_obj.name, source_obj.namespace,
                                       event_type.crd)
        source_getter = functools.partial(self.GetSource, source_ref,
                                          event_type.crd)
        poller = UnfailingConditionPoller(source_getter, tracker,
                                          stages.TriggerSourceDependencies())
        util.WaitForCondition(poller, exceptions.SourceCreationError)
        # Manually complete the stage indicating source readiness because we can't
        # track a terminal (Ready) condition in the ConditionPoller.
        tracker.CompleteStage(stages.SOURCE_READY)

        # Wait for trigger to be Ready == True
        trigger_getter = functools.partial(self.GetTrigger, trigger_ref)
        poller = UnfailingConditionPoller(trigger_getter, tracker,
                                          stages.TriggerSourceDependencies())
        util.WaitForCondition(poller, exceptions.TriggerCreationError)
Ejemplo n.º 3
0
  def Run(self, args):
    conn_context = connection_context.GetConnectionContext(
        args, product=connection_context.Product.EVENTS)
    if conn_context.supports_one_platform:
      raise exceptions.UnsupportedArgumentError(
          'Events are only available with Cloud Run for Anthos.')

    trigger_ref = args.CONCEPTS.trigger.Parse()
    namespace_ref = trigger_ref.Parent()
    with eventflow_operations.Connect(conn_context) as client:
      source_crds = client.ListSourceCustomResourceDefinitions()
      event_type = util.EventTypeFromTypeString(source_crds, args.type)
      source_obj = source.Source.New(client.client, namespace_ref.Name(),
                                     event_type.crd.source_kind,
                                     event_type.crd.source_api_category)
      source_obj.name = _SOURCE_NAME_PATTERN.format(
          trigger=trigger_ref.Name())

      trigger_obj = client.GetTrigger(trigger_ref)
      if trigger_obj is not None:
        # If trigger already exists, validate it has the attributes we're trying
        # to set right now.
        try:
          util.ValidateTrigger(trigger_obj, source_obj, event_type)
        except AssertionError:
          raise exceptions.TriggerCreationError(
              'Trigger [{}] already exists with attributes not '
              'matching this event type.'.format(trigger_obj.name))
        # If the trigger has the right attributes, check if there's already
        # a source that matches the attributes as well.
        source_ref = util.GetSourceRef(
            source_obj.name, source_obj.namespace, event_type.crd)
        if client.GetSource(source_ref, event_type.crd) is not None:
          raise exceptions.TriggerCreationError(
              'Trigger [{}] already exists.'.format(trigger_obj.name))

      parameters = events_flags.GetAndValidateParameters(args, event_type)

      # Create the trigger and source
      with progress_tracker.StagedProgressTracker(
          'Initializing trigger...',
          stages.TriggerSourceStages(),
          failure_message='Trigger creation failed') as tracker:
        client.CreateTriggerAndSource(
            trigger_obj,
            trigger_ref,
            namespace_ref,
            source_obj,
            event_type,
            parameters,
            args.broker,
            args.target_service,
            tracker
        )
Ejemplo n.º 4
0
 def PollSource(self, source_obj, event_type, tracker):
     """Wait for source to be Ready == True."""
     source_ref = util.GetSourceRef(source_obj.name, source_obj.namespace,
                                    event_type.crd, True)
     source_getter = functools.partial(self.GetSource, source_ref,
                                       event_type.crd)
     poller = SourceConditionPoller(source_getter, tracker,
                                    stages.TriggerSourceDependencies())
     util.WaitForCondition(poller, exceptions.SourceCreationError)
     # Manually complete the stage indicating source readiness because we can't
     # track the Ready condition in the ConditionPoller.
     tracker.CompleteStage(stages.SOURCE_READY)
Ejemplo n.º 5
0
    def PollSource(self, source_obj, event_type_obj, tracker):
        """Wait for source to be Ready == True."""
        source_ref = util.GetSourceRef(source_obj.name, source_obj.namespace,
                                       event_type_obj.crd, True)
        source_getter = functools.partial(self.GetSource, source_ref,
                                          event_type_obj.crd)

        # b/179156386 Increase grace period from default of 15 to 45 seconds for
        # sources, because asia-southeast1 and asia-east1's sources are unable to
        # resolve within the default grace period.
        sources_grace_period = datetime.timedelta(seconds=45)
        poller = SourceConditionPoller(
            source_getter,
            tracker,
            dependencies=stages.TriggerSourceDependencies(),
            grace_period=sources_grace_period)
        util.WaitForCondition(poller, exceptions.SourceCreationError)
        # Manually complete the stage indicating source readiness because we can't
        # track the Ready condition in the ConditionPoller.
        tracker.CompleteStage(stages.SOURCE_READY)
Ejemplo n.º 6
0
    def Run(self, args):
        conn_context = connection_context.GetConnectionContext(
            args, serverless_flags.Product.EVENTS, self.ReleaseTrack())

        trigger_ref = args.CONCEPTS.trigger.Parse()
        namespace_ref = trigger_ref.Parent()
        with eventflow_operations.Connect(conn_context) as client:
            if client.IsCluster():
                trigger_ref = resources.REGISTRY.Parse(
                    trigger_ref.RelativeName(),
                    collection=util.ANTHOS_TRIGGER_COLLECTION_NAME,
                    api_version=client.api_version)

                namespace_ref = trigger_ref.Parent()
            if args.custom_type:
                event_type = args.type
                source_obj = None
                tracker_stages = stages.TriggerStages()
            else:
                source_crds = client.ListSourceCustomResourceDefinitions()
                event_type = util.EventTypeFromTypeString(
                    source_crds, args.type, args.source)
                source_obj = source.Source.New(
                    client.client, namespace_ref.Name(),
                    event_type.crd.source_kind,
                    event_type.crd.source_api_category)
                source_obj.name = _SOURCE_NAME_PATTERN.format(
                    trigger=trigger_ref.Name())
                parameters = flags.GetAndValidateParameters(args, event_type)
                tracker_stages = stages.TriggerAndSourceStages()

            trigger_obj = client.GetTrigger(trigger_ref)
            if trigger_obj is not None:
                if args.custom_type:
                    # If custom type, no need to check idempotency since there's only
                    # a trigger to worry about.
                    raise exceptions.TriggerCreationError(
                        'Trigger [{}] already exists.'.format(
                            trigger_obj.name))
                else:
                    # If trigger already exists, validate it has the attributes we're
                    # trying to set right now to see if this is a case of idempotency.
                    try:
                        util.ValidateTrigger(trigger_obj, source_obj,
                                             event_type)
                    except AssertionError:
                        raise exceptions.TriggerCreationError(
                            'Trigger [{}] already exists with attributes not '
                            'matching this event type.'.format(
                                trigger_obj.name))
                    # If the trigger has the right attributes, check if there's already
                    # a source that matches the attributes as well.
                    source_ref = util.GetSourceRef(source_obj.name,
                                                   source_obj.namespace,
                                                   event_type.crd,
                                                   client.IsCluster())
                    if client.GetSource(source_ref,
                                        event_type.crd) is not None:
                        raise exceptions.TriggerCreationError(
                            'Trigger [{}] already exists.'.format(
                                trigger_obj.name))

            # Create the trigger and source
            with progress_tracker.StagedProgressTracker(
                    'Initializing trigger...',
                    tracker_stages,
                    failure_message='Trigger creation failed') as tracker:
                if trigger_obj is None:
                    trigger_obj = client.CreateTrigger(
                        trigger_ref, source_obj,
                        event_type if args.custom_type else event_type.type,
                        args.trigger_filters, args.target_service, args.broker)
                if not args.custom_type:
                    client.CreateSource(source_obj, event_type.crd,
                                        trigger_obj, namespace_ref,
                                        args.broker, parameters)
                    client.PollSource(source_obj, event_type, tracker)
                client.PollTrigger(trigger_ref, tracker)