knative/func

Provide `func subscribe` for creating Triggers and subscribing to events from the Knative Broker

Closed this issue · 2 comments

Func Subscribe

Feature focused on subscribing to events from a broker, for consumption by the Function.

func subscribe com.foo.bar [--source my-broker]

While the func is an abstraction from direct Knative manifest interaction, the above however would creates a Knative Trigger resource for the given com.foo.bar CloudEvent Type, which will be consumed from the given broker. If the --source is not present, the assumption is to use the default broker.

The func generated Trigger resource for the example above would look like:

apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: my-kn-function-com.foo.bar-trigger
  namespace: default
  ownerReferences:
  - apiVersion: serving.knative.dev/v1
    blockOwnerDeletion: true
    controller: true
    kind: Service
    name: my-kn-function
spec:
  broker: my-broker
  filter:
    attributes:
      type: com.foo.bar
  subscriber:
    ref:
      apiVersion: serving.knative.dev/v1
      kind: Service
      name: my-kn-function

The generated Trigger resource has a ownerReference to the subscribing Service. When the service is being deleted the Trigger will be removed as well, this prevents floating Triggers in the system`.

NOTE: The initial implementation will just focus on the type of the CloudEvent, and will ignore other attributes and custom extensions. This will be added in a later iteration.

Subscribe to all events

Besides subscribing to specific events, it should be possible to subscribe to all events. This is especially nice in the development phase and generally for debugging purposes:

func subscribe --event-all [--source my-broker]

The above invocation would generate a Trigger that has no specific filter, and hence will subscribe to all events, which is especially nice in the development phase, for debugging purposes:

apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: my-kn-function-all-trigger
  namespace: default
  ownerReferences:
  - apiVersion: serving.knative.dev/v1
    blockOwnerDeletion: true
    controller: true
    kind: Service
    name: my-kn-function
spec:
  broker: my-broker
  subscriber:
    ref:
      apiVersion: serving.knative.dev/v1
      kind: Service
      name: my-kn-function

Conflicts with kn CLI

While the func CLI is for a different persona (developers) than the kn CLI (SREs or Admins),it is possible to use the func as a plugin itself on kn.

Creating a Trigger with the kn client goes like:

kn trigger create NAME --sink SINK [options]  

This does create a Trigger resource, for a given sink. While the func would not need the given sink, as the context for the invocation is the function itself, defined in the func.yaml file.

Perhaps the func tool itself (when used as a kn plugin) could leverage the above?

Bind a Function to Event Types for consumption

In order to allow a Knative Function (aka a Knative Serving Service) to consume events for a given set of event types, a Trigger manifest is needed, like:

apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: <trigger-name>
spec:
  broker: <broker-name>
  filter:
    attributes:
      type: <some event type>
  subscriber:
    ref:
      apiVersion: serving.knative.dev/v1
      kind: Service
      name: <my-function>

Unfortunately, this needs to be either created by hand (using yaml) or the kn CLI:

kn trigger create <trigger-name> --sink ksvc:<my-function> --broker <broker-name> --filter type=<some event type>

Func subscribe command

Instead of forcing func users to either create the Trigger manually or with the kn tool, which requires a decent amount of Knative specifics, it would be desirable to have a kn func subscribe command.

The explicit invocation

The easiest way is to call the func subscribe the the events and from flag:

kn func subscribe --events <list of event types> --from/source <broker>

The arguments:

  • events: A list of Event Types
  • from/source: the name of the broker

This would register the some hook to func.yaml, so that func deploy knows it needs to create one or more Triggers, for the function being developed, where the ownerReferences is provided, being the Knative Serving Service.

NOTE: The subscribe command would use the Golang library of the kn CLI, in order to create the Trigger`

Interactive Command

If not all arguments are provided some interactive support is offered.

Interactive Events argument

kn func subscribe

This would give us an interactive command, where we would be presented a list of EventType resources that are available on the namespace:

NAME                           TYPE                       SOURCE          REFERENCE NAME   REFERENCE KIND
com.custom.event.orders        com.custom.event.orders   /system/id/$ID               
com.custom.event.orders-xyz    com.custom.event.orders   /system/id/007   prod-broker      Broker
com.custom.event.orders-UUID   com.custom.event.orders   /system/id/999   test-broker      Broker
com.custom.event.orders-SOME   com.custom.event.orders   /system/id/123   test-broker      Broker

It would basically give a simplified view of k get eventtypes... (or kn eventype list)

The developer than can select a number of event types

Interactive From argument

Similar to the above, for the from (or source) we would list the available Brokers on the namespace:

kn broker list
NAME        URL                                                                          AGE   CONDITIONS   READY   REASON
my-broker   http://broker-ingress.knative-eventing.svc.cluster.local/default/my-broker   79s   6 OK / 6     True    

The developer than can select the desired broker

Alternative we could also assume the usage of the default broker, if no --from is specified.

TBD / Not defined:

  • Fully EventType discocery of what other CloudEvent attrributes and extensions are available

Related to this: knative/eventing#7265

This issue is stale because it has been open for 90 days with no
activity. It will automatically close after 30 more days of
inactivity. Reopen the issue with /reopen. Mark the issue as
fresh by adding the comment /remove-lifecycle stale.