Skip to content

Commit 70ab7c3

Browse files
authored
Merge pull request #34707 from abrennan89/SRVKE-652
SRVKE-652: Container source docs
2 parents 0f221c1 + bc45f3a commit 70ab7c3

File tree

6 files changed

+267
-1
lines changed

6 files changed

+267
-1
lines changed

_topic_map.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3163,5 +3163,7 @@ Topics:
31633163
File: kn-flags-reference
31643164
- Name: Knative Serving CLI commands
31653165
File: kn-serving-ref
3166+
- Name: Knative Eventing CLI commands
3167+
File: kn-eventing-ref
31663168
- Name: kn func
31673169
File: kn-func-ref

modules/apiserversource-kn.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[id="apiserversource-kn_context"]
1+
[id="apiserversource-kn_{context}"]
22
= Creating an API server source by using the Knative CLI
33

44
This section describes the steps required to create an API server source using `kn` commands.
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
[id="serverless-containersource-custom-sources_{context}"]
2+
= Creating custom event sources by using a container source
3+
4+
You can use a container source to create and manage a container for your custom event source image.
5+
6+
To implement a custom event source by using a container source, you must first create a container image of your event source, and then create a container source that specifies the correct configuration, including the container image URI.
7+
8+
== Guidelines for creating a container image
9+
10+
* A container image can be developed using any language, and can be built and published with any tool that you prefer.
11+
12+
* The main process of the container image must accept parameters from arguments and environment variables.
13+
14+
* Two environment variables are injected by the container source controller: `K_SINK` and `K_CE_OVERRIDES`. These variables are resolved from the `sink` and `ceOverrides` spec, respectively.
15+
16+
* Event messages are sent to the sink URI specified in the `K_SINK` environment variable. The event message can be in any format; however, using the link:https://cloudevents.io/[`CloudEvent`] spec is recommended.
17+
18+
== Example container images
19+
20+
The following is an example of a heartbeats container image:
21+
22+
[source,go]
23+
----
24+
package main
25+
26+
import (
27+
"context"
28+
"encoding/json"
29+
"flag"
30+
"fmt"
31+
"log"
32+
"os"
33+
"strconv"
34+
"time"
35+
36+
duckv1 "knative.dev/pkg/apis/duck/v1"
37+
38+
cloudevents "github.com/cloudevents/sdk-go/v2"
39+
"github.com/kelseyhightower/envconfig"
40+
)
41+
42+
type Heartbeat struct {
43+
Sequence int `json:"id"`
44+
Label string `json:"label"`
45+
}
46+
47+
var (
48+
eventSource string
49+
eventType string
50+
sink string
51+
label string
52+
periodStr string
53+
)
54+
55+
func init() {
56+
flag.StringVar(&eventSource, "eventSource", "", "the event-source (CloudEvents)")
57+
flag.StringVar(&eventType, "eventType", "dev.knative.eventing.samples.heartbeat", "the event-type (CloudEvents)")
58+
flag.StringVar(&sink, "sink", "", "the host url to heartbeat to")
59+
flag.StringVar(&label, "label", "", "a special label")
60+
flag.StringVar(&periodStr, "period", "5", "the number of seconds between heartbeats")
61+
}
62+
63+
type envConfig struct {
64+
// Sink URL where to send heartbeat cloud events
65+
Sink string `envconfig:"K_SINK"`
66+
67+
// CEOverrides are the CloudEvents overrides to be applied to the outbound event.
68+
CEOverrides string `envconfig:"K_CE_OVERRIDES"`
69+
70+
// Name of this pod.
71+
Name string `envconfig:"POD_NAME" required:"true"`
72+
73+
// Namespace this pod exists in.
74+
Namespace string `envconfig:"POD_NAMESPACE" required:"true"`
75+
76+
// Whether to run continuously or exit.
77+
OneShot bool `envconfig:"ONE_SHOT" default:"false"`
78+
}
79+
80+
func main() {
81+
flag.Parse()
82+
83+
var env envConfig
84+
if err := envconfig.Process("", &env); err != nil {
85+
log.Printf("[ERROR] Failed to process env var: %s", err)
86+
os.Exit(1)
87+
}
88+
89+
if env.Sink != "" {
90+
sink = env.Sink
91+
}
92+
93+
var ceOverrides *duckv1.CloudEventOverrides
94+
if len(env.CEOverrides) > 0 {
95+
overrides := duckv1.CloudEventOverrides{}
96+
err := json.Unmarshal([]byte(env.CEOverrides), &overrides)
97+
if err != nil {
98+
log.Printf("[ERROR] Unparseable CloudEvents overrides %s: %v", env.CEOverrides, err)
99+
os.Exit(1)
100+
}
101+
ceOverrides = &overrides
102+
}
103+
104+
p, err := cloudevents.NewHTTP(cloudevents.WithTarget(sink))
105+
if err != nil {
106+
log.Fatalf("failed to create http protocol: %s", err.Error())
107+
}
108+
109+
c, err := cloudevents.NewClient(p, cloudevents.WithUUIDs(), cloudevents.WithTimeNow())
110+
if err != nil {
111+
log.Fatalf("failed to create client: %s", err.Error())
112+
}
113+
114+
var period time.Duration
115+
if p, err := strconv.Atoi(periodStr); err != nil {
116+
period = time.Duration(5) * time.Second
117+
} else {
118+
period = time.Duration(p) * time.Second
119+
}
120+
121+
if eventSource == "" {
122+
eventSource = fmt.Sprintf("https://knative.dev/eventing-contrib/cmd/heartbeats/#%s/%s", env.Namespace, env.Name)
123+
log.Printf("Heartbeats Source: %s", eventSource)
124+
}
125+
126+
if len(label) > 0 && label[0] == '"' {
127+
label, _ = strconv.Unquote(label)
128+
}
129+
hb := &Heartbeat{
130+
Sequence: 0,
131+
Label: label,
132+
}
133+
ticker := time.NewTicker(period)
134+
for {
135+
hb.Sequence++
136+
137+
event := cloudevents.NewEvent("1.0")
138+
event.SetType(eventType)
139+
event.SetSource(eventSource)
140+
event.SetExtension("the", 42)
141+
event.SetExtension("heart", "yes")
142+
event.SetExtension("beats", true)
143+
144+
if ceOverrides != nil && ceOverrides.Extensions != nil {
145+
for n, v := range ceOverrides.Extensions {
146+
event.SetExtension(n, v)
147+
}
148+
}
149+
150+
if err := event.SetData(cloudevents.ApplicationJSON, hb); err != nil {
151+
log.Printf("failed to set cloudevents data: %s", err.Error())
152+
}
153+
154+
log.Printf("sending cloudevent to %s", sink)
155+
if res := c.Send(context.Background(), event); !cloudevents.IsACK(res) {
156+
log.Printf("failed to send cloudevent: %v", res)
157+
}
158+
159+
if env.OneShot {
160+
return
161+
}
162+
163+
// Wait for next tick
164+
<-ticker.C
165+
}
166+
}
167+
----
168+
169+
The following is an example of a container source that references the previous heartbeats container image:
170+
171+
[source,yaml]
172+
----
173+
apiVersion: sources.knative.dev/v1
174+
kind: ContainerSource
175+
metadata:
176+
name: test-heartbeats
177+
spec:
178+
template:
179+
spec:
180+
containers:
181+
# This corresponds to a heartbeats image URI that you have built and published
182+
- image: gcr.io/knative-releases/knative.dev/eventing/cmd/heartbeats
183+
name: heartbeats
184+
args:
185+
- --period=1
186+
env:
187+
- name: POD_NAME
188+
value: "example-pod"
189+
- name: POD_NAMESPACE
190+
value: "event-test"
191+
sink:
192+
ref:
193+
apiVersion: serving.knative.dev/v1
194+
kind: Service
195+
name: example-service
196+
...
197+
----
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[id="serverless-kn-containersource_{context}"]
2+
= Creating and managing container sources by using the Knative CLI
3+
4+
You can use the following `kn` commands to create and manage container sources:
5+
6+
.Create a container source
7+
[source,terminal]
8+
----
9+
$ kn source container create <container_source_name> --image <image_uri> --sink <sink>
10+
----
11+
12+
.Delete a container source
13+
[source,terminal]
14+
----
15+
$ kn source container delete <container_source_name>
16+
----
17+
18+
.Describe a container source
19+
[source,terminal]
20+
----
21+
$ kn source container describe <container_source_name>
22+
----
23+
24+
.List existing container sources
25+
[source,terminal]
26+
----
27+
$ kn source container list
28+
----
29+
30+
.List existing container sources in YAML format
31+
[source,terminal]
32+
----
33+
$ kn source container list -o yaml
34+
----
35+
36+
.Update a container source
37+
38+
This command updates the image URI for an existing container source:
39+
40+
[source,terminal]
41+
----
42+
$ kn source container update <container_source_name> --image <image_uri>
43+
----
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
include::modules/serverless-document-attributes.adoc[]
2+
[id="kn-eventing-ref"]
3+
= Knative Eventing CLI commands
4+
:context: kn-eventing-ref
5+
include::modules/common-attributes.adoc[]
6+
7+
toc::[]
8+
9+
You can use the following `kn` CLI commands to complete Knative Eventing tasks on the cluster.
10+
11+
[id="kn-eventing-ref-kn-sources"]
12+
== kn source commands
13+
14+
You can use the following commands to list, create, and manage Knative event sources.
15+
16+
include::modules/serverless-list-source-types-kn.adoc[leveloffset=+2]
17+
include::modules/serverless-kn-containersource.adoc[leveloffset=+2]
18+
include::modules/apiserversource-kn.adoc[leveloffset=+2]
19+
include::modules/apiserversource-kn-delete.adoc[leveloffset=+2]
20+
include::modules/serverless-pingsource-kn.adoc[leveloffset=+2]
21+
include::modules/deleting-pingsource-kn.adoc[leveloffset=+2]
22+
include::modules/serverless-kafka-source-kn.adoc[leveloffset=+2]

serverless/event_sources/serverless-containersource.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ toc::[]
88

99
Container sources create a container image that generates events and sends events to a sink. You can use a container source to create a custom event source.
1010

11+
include::modules/serverless-containersource-custom-sources.adoc[leveloffset=+1]
12+
include::modules/serverless-kn-containersource.adoc[leveloffset=+1]
1113
include::modules/serverless-odc-create-containersource.adoc[leveloffset=+1]

0 commit comments

Comments
 (0)