Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions config/200-source-observer-clusterrole.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2019 The Knative Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Use this aggregated ClusterRole when you need to read "Sources".
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: source-observer
Comment thread
vaikas marked this conversation as resolved.
labels:
eventing.knative.dev/release: devel
aggregationRule:
clusterRoleSelectors:
- matchLabels:
duck.knative.dev/source: "true"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be duck.knative.dev/sourceObserver? In case we ever need a distinct ClusterRole in the future. Or just to differentiate from the label that is on sources themselves.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how I have been thinking about it: the duck is a source; the role is source observer.

rules: [] # Rules are automatically filled in by the controller manager.

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: eventing-sources-source-observer
labels:
eventing.knative.dev/release: devel
duck.knative.dev/source: "true"
# Do not use this role directly. These rules will be added to the "source-observer" role.
rules:
- apiGroups:
- sources.eventing.knative.dev
resources:
Comment thread
n3wscott marked this conversation as resolved.
- containersources
- cronjobsources
- apiserversources
verbs:
- get
- list
- watch
1 change: 1 addition & 0 deletions config/300-apiserversource.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ metadata:
labels:
eventing.knative.dev/release: devel
eventing.knative.dev/source: "true"
duck.knative.dev/source: "true"
knative.dev/crd-install: "true"
name: apiserversources.sources.eventing.knative.dev
spec:
Expand Down
1 change: 1 addition & 0 deletions config/300-containersource.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ metadata:
labels:
eventing.knative.dev/release: devel
eventing.knative.dev/source: "true"
duck.knative.dev/source: "true"
knative.dev/crd-install: "true"
name: containersources.sources.eventing.knative.dev
spec:
Expand Down
1 change: 1 addition & 0 deletions config/300-cronjobsource.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ metadata:
labels:
eventing.knative.dev/release: devel
eventing.knative.dev/source: "true"
duck.knative.dev/source: "true"
knative.dev/crd-install: "true"
name: cronjobsources.sources.eventing.knative.dev
spec:
Expand Down
5 changes: 2 additions & 3 deletions docs/spec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ Docs in this directory:
- [Object model specification](spec.md)
- [Channel specification](channel.md) and
[older channel (0.6.0) spec](channel_060.md)

<!-- TODO(n3wscott): * [Error conditions and reporting](errors.md) -->
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might just reference https://knative.dev/docs/serving/spec/knative-api-specification-1.0/#error-signalling for the general error pattern, rather than needing to write your own.

<!-- TODO(n3wscott): * [Sample API usage](normative_examples.md) -->
- [Sources specification](sources.md)
- [Error conditions and reporting](https://knative.dev/docs/serving/spec/knative-api-specification-1.0/#error-signalling)

See the
[Knative Eventing Docs Architecture](https://www.knative.dev/docs/eventing/#architecture)
Expand Down
288 changes: 288 additions & 0 deletions docs/spec/sources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
# Sources

A **Source** is any Kubernetes object that generates or imports an event and
relays that event to another endpoint on the cluster via
[CloudEvents](https://cloudevents.io). Sourcing events is critical to developing
a distributed system that reacts to events.

A **Sink** is an [_addressable_](./interfaces.md#addressable) resource that
takes responsibility for the event. A **Sink** could be a consumer of events, or
middleware. A **Sink** will respond with 2xx when it has accepted and processed
the event.

A Source:

- Represents an off- or on-cluster system, service or application that produces
events to be consumed by a **Sink**.
- Produces or imports CloudEvents.
- Sends CloudEvents to the configured **Sink**.

In practice, sources are an abstract concept that allow us to create declarative
configurations through the usage of Custom Resource Definitions (CRDs) extending
Kubernetes. Source systems are configured by creating an instance of the
resource described by the CRD. It is up to the implementation of the source
author to understand the best way to realize the source application. This could
be as 1:1 deployments inside of Kubernetes per resource, as a single
multi-tenant application, or even an off-cluster implementation; or all
combinations in-between.

For operators of a Kubernetes cluster, there are two states to sources:

1. A Source CRD and controller (if required) have been installed into the
cluster.

A cluster with a source CRD installed allows the developers in the cluster to
find and discover what is possible to source events from. This topic is
expanded upon in the [Source CRDs](#source-crds) section.

1. A Source custom object has been created in the cluster.

Once a developer creates an instance of a source and provides the necessary
parameters, the source controller will realize this into whatever is required
for that source for the current situation. While this resource is running, a
cluster operator would like to inspect the resource without needing to be
fully aware of the implementation. This is done by conforming to the
[Source]() ducktype. This topic is expanded upon in the
[Source Custom Objects](#source-custom-objects) section.

The goal of requiring CRD labels and running resource shapes is to enable
discovery and understanding of potential sources that could be leveraged in the
cluster. This structure also aids in understanding sources that exist and are
running in the cluster.

## Source CRDs

Sources are more useful if they are discoverable. Knative Sources MUST use a
standardized label to allow controllers and operators the ability to find which
CRDs are considered to be adhering to the
[Source](https://godoc.org/github.com/knative/pkg/apis/duck/v1#Source) ducktype.

CRDs that are to be understood as a `source` MUST be labeled:
Comment thread
n3wscott marked this conversation as resolved.

```yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
labels:
duck.knative.dev/source: "true" # <-- required to be a source.
```

Labeling sources in this way allows for developers to filter the list of CRDs:

```shell
kubectl get crds -l duck.knative.dev/source=true
```

CRDs SHOULD be added to the `sources` category:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose that the to yaml should make one file, this section is confusing to me.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actutally do appreciate the breakdown of the different sections. This is a spec - not a tutorial.


```yaml
spec:
Comment thread
vaikas marked this conversation as resolved.
names:
categories:
- sources
Comment thread
n3wscott marked this conversation as resolved.
```

Comment thread
vaikas marked this conversation as resolved.
By adding to the sources category, we give an easy way to list running sources
in the cluster with:

```shell
kubectl get sources
```

Source CRDs SHOULD provide additional printer columns to provide useful feedback
to cluster operators. For example, if the resource is long-lived, it would be a
good choice to show the `Ready` status and `Reason`, as well as the `Age` of the
resource.

```yaml
additionalPrinterColumns:
- name: Ready
type: string
JSONPath: '.status.conditions[?(@.type=="Ready")].status'
- name: Reason
type: string
JSONPath: '.status.conditions[?(@.type=="Ready")].reason'
- name: Age
type: date
JSONPath: .metadata.creationTimestamp
```

### Source Validation

Sources MUST implement conditions with a `Ready` condition for long lived
sources, and `Succeeded` for batch style sources.

Sources MUST propagate the `sinkUri` to their status to signal to the cluster
where their events are being sent.

Knative has standardized on the following minimum OpenAPI definition of `status`
for Source CRDs:

```yaml
validation:
openAPIV3Schema:
properties:
status:
type: object
properties:
conditions:
type: array
items:
type: object
properties:
lastTransitionTime:
type: string
message:
type: string
reason:
type: string
severity:
type: string
status:
type: string
type:
type: string
required:
- type
- status
sinkUri:
type: string
```

Please see
[SourceStatus](https://godoc.org/github.com/knative/pkg/apis/duck/v1#SourceStatus)
and [Condition](https://godoc.org/github.com/knative/pkg/apis/#Condition) for
more details.

Sources SHOULD provide OpenAPI validation for the `spec` field. At minimum
sources SHOULD have the following,

```yaml
validation:
openAPIV3Schema:
properties:
spec:
type: object
required:
- sink
properties:
sink:
type: object
description:
"Reference to an object that will resolve to a domain name to use
as the sink."
ceOverrides:
type: object
description:
"Defines overrides to control modifications of the event sent to
the sink."
properties:
extensions:
type: object
description:
"Extensions specify what attributes are added or overridden on
the outbound event. Each `Extensions` key-value pair are set
on the event as an extension attribute independently."
```

<!-- TOOD(#1550): Follow-up with a registry implementation. -->

## Source RBAC

Sources are expected to be extensions onto Kubernetes. To prevent cluster
operators from duplicating RBAC for all accounts that will interact with
sources, cluster operators should leverage aggregated RBAC roles to dynamically
update the rights of controllers that are using common service accounts provided
by Knative. This allows Eventing controllers to check the status of source type
resources without being aware of the exact source type or implementation at
compile time.

The
[`source-observer` ClusterRole](../../config/200-source-observer-clusterrole.yaml)
looks like:

```yaml
# Use this aggregated ClusterRole when you need read "Sources".
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: source-observer
aggregationRule:
clusterRoleSelectors:
- matchLabels:
duck.knative.dev/source: "true" # Matched by source-observer ClusterRole
rules: [] # Rules are automatically filled in by the controller manager.
```

And new sources MUST include a ClusterRole as part of installing themselves into
a cluster:

```yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: foos-source-observer
labels:
duck.knative.dev/source: "true"
Comment thread
n3wscott marked this conversation as resolved.
rules:
- apiGroups:
- example.com
resources:
- foos
verbs:
- get
- list
- watch
```

## Source Custom Objects

All Source custom objects MUST implement the
[Source](https://godoc.org/github.com/knative/pkg/apis/duck/v1#Source) ducktype.
Additional data in spec and status is explicitly permitted.

### duck.Spec

The `spec` field is expected to have the following minimum shape:

```go
type SourceSpec struct {
// Sink is a reference to an object that will resolve to a domain name or a
// URI directly to use as the sink.
Sink apisv1alpha1.Destination `json:"sink,omitempty"`

// CloudEventOverrides defines overrides to control the output format and
// modifications of the event sent to the sink.
// +optional
CloudEventOverrides *CloudEventOverrides `json:"ceOverrides,omitempty"`
Comment thread
n3wscott marked this conversation as resolved.
}
```

For a golang structure definition of `Sink` and `CloudEventsOverrides`, please
see [Destination](https://godoc.org/knative.dev/pkg/apis/v1alpha1#Destination),
and
[CloudEventOverrides](https://godoc.org/github.com/knative/pkg/apis/duck/v1#CloudEventOverrides).

### duck.Status

The `status` field is expected to have the following minimum shape:

```go
type SourceStatus struct {
// inherits duck/v1 Status, which currently provides:
// * ObservedGeneration - the 'Generation' of the Service that was last
// processed by the controller.
// * Conditions - the latest available observations of a resource's current
// state.
Status `json:",inline"`
Comment thread
vaikas marked this conversation as resolved.

// SinkURI is the current active sink URI that has been configured for the
// Source.
// +optional
SinkURI *apis.URL `json:"sinkUri,omitempty"`
}
```

For a full definition of `Status` and `SinkURI`, please see
[Status](https://godoc.org/github.com/knative/pkg/apis/duck/v1#Status), and
[URL](https://godoc.org/knative.dev/pkg/apis#URL).
6 changes: 3 additions & 3 deletions docs/spec/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ Trigger._

#### Spec

| Field | Type | Description | Constraints |
| --------------- | ----------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------ |
| channelTemplate | ChannelSpec | The template used to create Channels internal to the Broker. Defaults to to the default Channel for the namespace. | Only Provisioner and Arguments may be specified. |
| Field | Type | Description | Constraints |
| --------------- | ----------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| channelTemplate | ChannelSpec | The template used to create Channels internal to the Broker. Defaults to the default Channel for the namespace. | Only Provisioner and Arguments may be specified. |

#### Status

Expand Down