Skip to content

Commit 1a879a2

Browse files
[release-1.15] Backstage plugin docs (#6128)
* Make the event registry page a directory Signed-off-by: Ali Ok <aliok@redhat.com> * Backstage plugin installation docs Signed-off-by: Ali Ok <aliok@redhat.com> * Backstage plugin usage docs Signed-off-by: Ali Ok <aliok@redhat.com> --------- Signed-off-by: Ali Ok <aliok@redhat.com> Co-authored-by: Ali Ok <aliok@redhat.com>
1 parent 8a73b4e commit 1a879a2

8 files changed

+374
-1
lines changed

config/nav.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ nav:
8181
- Install Istio for Knative: install/installing-istio.md
8282
# Cert-manager Installation
8383
- Install cert-manager: install/installing-cert-manager.md
84+
# Backstage plugin
85+
- Install Knative Backstage plugin: install/installing-backstage-plugins.md
8486
# Vendor docs
8587
- Using a Knative-based offering: install/knative-offerings.md
8688
# Upgrading Knative
@@ -274,7 +276,9 @@ nav:
274276
- Create a ContainerSource: eventing/custom-event-source/containersource/README.md
275277
- ContainerSource Reference: eventing/custom-event-source/containersource/reference.md
276278
- Handling delivery failure: eventing/event-delivery.md
277-
- Event registry: eventing/event-registry.md
279+
- Event registry:
280+
- Using the Event registry: eventing/event-registry/README.md
281+
- Knative EventMesh Backstage Plugin: eventing/event-registry/eventmesh-backstage-plugin.md
278282
- Sugar controller: eventing/sugar/README.md
279283
- Debugging: eventing/troubleshooting/README.md
280284
- Administrator topics:
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Knative Event Mesh Backstage Plugin
2+
3+
!!! info
4+
For installation instructions, see the [plugin installation documentation](../../../install/installing-backstage-plugins).
5+
6+
The Knative Event Mesh plugin is a Backstage plugin that allows you to view and manage Knative Eventing resources. The
7+
plugin talks to a special backend that runs in the Kubernetes cluster and communicates with the Kubernetes API server.
8+
9+
[Backstage](https://backstage.io/){:target="_blank"} is a platform for building developer portals.
10+
It provides a unified way to manage and visualize the different resources that developers use in their daily work.
11+
12+
While Backstage is not designed as a next generation Kubernetes Dashboard, it can visualize and partially manage Knative
13+
resources. These resources would be read-only and focused on what's relevant to developers.
14+
15+
![Event Mesh plugin](./images/event-mesh-plugin-components-view.png)
16+
17+
![Event Mesh plugin](./images/event-mesh-plugin-apis-view.png)
18+
19+
!!! info
20+
A demo setup for this plugin is available at <https://github.com/aliok/knative-backstage-demo>.
21+
22+
## How it works
23+
24+
The plugins are the frontend part of the Backstage instance. They are responsible for rendering the UI and communicating
25+
with the backend. The backend is responsible for talking to the Kubernetes API server and providing the necessary
26+
information to the frontend.
27+
28+
This plugin leverages Backstage's [entity provider](https://backstage.io/docs/features/software-catalog/external-integrations/#custom-entity-providers){:target="_blank"} and [entity processor](https://backstage.io/docs/features/software-catalog/external-integrations/#custom-processors){:target="_blank"}
29+
concepts. The entity provider is responsible for fetching the resources from the backend and the entity processor is
30+
responsible for processing the resources and making them available to the frontend.
31+
The provider is the part that talks to the custom backend.
32+
33+
The plugin fetches Knative EventType, Broker, and Trigger resources from the backend. Instead of directly fetching the
34+
raw Kubernetes resources, it gathers a more user-friendly representation of the data. This means certain fields are
35+
excluded, some are combined for clarity, and others are transformed to be easier to understand within this interface.
36+
37+
## What is shown
38+
39+
Knative Triggers can be pointing at any [Addressable](https://knative.dev/docs/concepts/duck-typing/#addressable){:target="_blank"} or at even a URL directly. Since Backstage
40+
side won't know how to handle these, the plugin will only show the trigger's subscriber if it is already registered in
41+
Backstage. For this relation, we use the [`backstage.io/kubernetes-id`](https://backstage.io/docs/features/kubernetes/configuration#surfacing-your-kubernetes-components-as-part-of-an-entity){:target="_blank"}
42+
annotation in the Backstage entity and in the Kubernetes resource.
43+
44+
How the matching works is documented with diagrams in the [Event Mesh plugin README file](https://github.com/knative-extensions/backstage-plugins?tab=readme-ov-file#event-mesh-plugin-1){:target="_blank"}.
45+
46+
What's really cool about this integration is that Backstage's ability to show graphs. For example, you can see
47+
the relationships between EventTypes, Brokers, and Trigger subscribers in a graph.
48+
49+
![](./images/event-mesh-plugin-graph.png)
50+
*Graphs in Backstage*
51+
52+
## Security
53+
54+
![](./images/knative-backstage-security.png)
55+
*Backstage Security*
56+
[//]: # (https://drive.google.com/file/d/1qMu0yd-zGYcveUM_tLigw1yZ_0jksX9i/view?usp=drive_link)
57+
58+
Similar to other Backstage plugins, we wanted the plugin administrator to configure the plugin by setting up the
59+
necessary things like the backend URL and the token. It is a similar approach with the
60+
[Backstage Kubernetes plugin](https://backstage.io/docs/features/kubernetes/configuration#configuring-kubernetes-clusters), where the user needs to provide the URL and the token.
61+
62+
The token is stored in Backstage configuration and is passed to the backend with each request.
63+
The backend uses this token to authenticate to the Kubernetes API server.
64+
The token is a service account token that has the necessary permissions to list the Knative Eventing
65+
resources in the cluster.
66+
67+
```yaml
68+
...
69+
catalog:
70+
providers:
71+
knativeEventMesh:
72+
dev:
73+
token: '${KNATIVE_EVENT_MESH_TOKEN}'
74+
baseUrl: "http://eventmesh-backend.knative-eventing.svc:8080"
75+
schedule: # optional; same options as in TaskScheduleDefinition
76+
# supports cron, ISO duration, "human duration" as used in code
77+
frequency: { minutes: 1 }
78+
# supports ISO duration, "human duration" as used in code
79+
timeout: { minutes: 1 }
80+
```
81+
82+
The `token` is taken from the `KNATIVE_EVENT_MESH_TOKEN` environment variable. Backstage supports environment variables
83+
in the configuration files, so you can set the token as an environment variable before starting the Backstage instance.
84+
Actually, Backstage has other mechanisms, including configuration files, file includes and others.
85+
You can check the [Backstage documentation](https://backstage.io/docs/conf/writing/){:target="_blank"} for more information.
86+
87+
How to create the `ServiceAccount`, `ClusterRole`, `ClusterRoleBinding`, `Secret` and the token for that `Secret` is documented in
88+
the [plugin installation documentation](../../../install/installing-backstage-plugins).
89+
90+
## Usage
91+
92+
The plugin will show all `Broker` and `EventType` resources in the cluster. `Broker`s will be shown as Backstage
93+
[`Component`s](https://backstage.io/docs/features/software-catalog/system-model#component){:target="_blank"}
94+
and `EventType`s will be shown as Backstage [`API`s](https://backstage.io/docs/features/software-catalog/system-model#api){:target="_blank"}.
95+
96+
The subscribers of the `Trigger`s will be shown as Backstage `Component`s. However, they will be shown if:
97+
98+
- They are registered in Backstage
99+
- They have the [`backstage.io/kubernetes-id`](https://backstage.io/docs/features/kubernetes/configuration#surfacing-your-kubernetes-components-as-part-of-an-entity){:target="_blank"} annotation set to the Kubernetes resource's name
Loading
Loading
Loading
Loading
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
# Installing Knative Backstage Plugins
2+
3+
Knative community is planning to provide a set of Backstage plugins for Knative and their respective backends.
4+
Currently there is one plugin available, the Event Mesh plugin.
5+
6+
## Event Mesh plugin
7+
8+
The Event Mesh plugin is a Backstage plugin that allows you to view and manage Knative Eventing resources.
9+
10+
The Backstage plugin talks to a special backend that runs in the Kubernetes cluster and communicates with the Kubernetes
11+
API server.
12+
13+
A demo setup for this plugin is available at <https://github.com/aliok/knative-backstage-demo>.
14+
15+
The plugin has 2 distributions: static and dynamic. In this document, we will focus on the static distribution.
16+
For the dynamic distribution, please see the
17+
[Dynamic Plugin README file](https://github.com/knative-extensions/backstage-plugins/blob/main/backstage/plugins/knative-event-mesh-backend/README-dynamic.md)
18+
in the plugin repository.
19+
20+
### Installation
21+
22+
The plugin needs to be installed in the Backstage instance and the backend it talks to needs to be installed in the
23+
Kubernetes cluster.
24+
25+
#### Plugin backend controller installation
26+
27+
```shell
28+
VERSION="latest" # or a specific version like knative-v1.15.0
29+
kubectl apply -f https://github.com/knative-extensions/backstage-plugins/releases/${VERSION}/download/eventmesh.yaml
30+
```
31+
32+
This will install the backend controller in the Kubernetes cluster. The backend's responsibility is to talk to
33+
the Kubernetes API server and provide the necessary information to the plugin.
34+
35+
#### The Backstage plugin installation
36+
37+
In your Backstage directory, run the following command to install the plugin:
38+
39+
```bash
40+
VERSION="latest" # or a specific version like 1.15.0 from https://www.npmjs.com/package/@knative-extensions/plugin-knative-event-mesh-backend
41+
yarn workspace backend add @knative-extensions/plugin-knative-event-mesh-backend@${VERSION}
42+
```
43+
44+
Backstage has a legacy backend system that is being replaced with a new system. If you are using the legacy backend
45+
system, you can follow the instructions below to install the plugin.
46+
47+
To learn more about the new and the legacy backend systems, see the
48+
[Backstage documentation](https://backstage.io/docs/backend-system/building-backends/migrating/).
49+
50+
!!! info
51+
We are aware there is a `Backend` term used in both the Kubernetes controller and the Backstage backend system.
52+
Backstage backend system is different from the Kubernetes controller we've installed before.
53+
The controller is a Kubernetes controller that runs in the Kubernetes cluster and talks to the Kubernetes API server.
54+
Backstage backend system is a framework to run backend plugins that talk to data providers, such as the Kubernetes controller mentioned above.
55+
56+
#### Enabling the plugin on the new Backstage backend system
57+
58+
To install on the new backend system, add the following into the `packages/backend/index.ts` file:
59+
60+
```ts
61+
import { createBackend } from '@backstage/backend-defaults';
62+
63+
const backend = createBackend();
64+
65+
// Other plugins/modules
66+
67+
backend.add(import('@knative-extensions/plugin-knative-event-mesh-backend/alpha'));
68+
```
69+
70+
!!! warning
71+
If you have made any changes to the schedule in the `app-config.yaml` file, then restart to apply the changes.
72+
73+
#### Enabling the plugin on the legacy Backstage backend system
74+
75+
Configure the scheduler for the entity provider and enable the processor. Add the following code
76+
to `packages/backend/src/plugins/catalog.ts` file:
77+
78+
```ts
79+
import {CatalogClient} from "@backstage/catalog-client";
80+
import {
81+
KnativeEventMeshProcessor,
82+
KnativeEventMeshProvider
83+
} from '@knative-extensions/plugin-knative-event-mesh-backend';
84+
85+
export default async function createPlugin(
86+
env:PluginEnvironment,
87+
):Promise<Router> {
88+
const builder = await CatalogBuilder.create(env);
89+
90+
/* ... other processors and/or providers ... */
91+
92+
// ADD THESE
93+
builder.addEntityProvider(
94+
KnativeEventMeshProvider.fromConfig(env.config, {
95+
logger: env.logger,
96+
scheduler: env.scheduler,
97+
}),
98+
);
99+
const catalogApi = new CatalogClient({
100+
discoveryApi: env.discovery,
101+
});
102+
const knativeEventMeshProcessor = new KnativeEventMeshProcessor(catalogApi, env.logger);
103+
builder.addProcessor(knativeEventMeshProcessor);
104+
105+
/* ... other processors and/or providers ... */
106+
107+
const {processingEngine, router} = await builder.build();
108+
await processingEngine.start();
109+
return router;
110+
}
111+
```
112+
113+
### Configuration
114+
115+
!!! info
116+
**NOTE**: The backend needs to be accessible from the Backstage instance. If you are running the backend without
117+
exposing it, you can use `kubectl port-forward` to forward the port of the backend service to your local machine
118+
for testing purposes.
119+
```bash
120+
kubectl port-forward -n knative-eventing svc/eventmesh-backend 8080:8080
121+
```
122+
123+
The plugin needs to be configured to talk to the backend. It can be configured in the `app-config.yaml` file of the
124+
Backstage instance and allows configuration of one or multiple providers.
125+
126+
Use a `knativeEventMesh` marker to start configuring the `app-config.yaml` file of Backstage:
127+
128+
```yaml
129+
catalog:
130+
providers:
131+
knativeEventMesh:
132+
dev:
133+
token: '${KNATIVE_EVENT_MESH_TOKEN}' # SA token to authenticate to the backend
134+
baseUrl: '${KNATIVE_EVENT_MESH_BACKEND}' # URL of the backend installed in the cluster
135+
schedule: # optional; same options as in TaskScheduleDefinition
136+
# supports cron, ISO duration, "human duration" as used in code
137+
frequency: { minutes: 1 }
138+
# supports ISO duration, "human duration" as used in code
139+
timeout: { minutes: 1 }
140+
```
141+
142+
You can either manually change the placeholders in the `app-config.yaml` file or use environment variables to set the
143+
values. The environment variables can be set as following before starting the Backstage instance:
144+
145+
```bash
146+
export KNATIVE_EVENT_MESH_TOKEN=<your-token>
147+
export KNATIVE_EVENT_MESH_BACKEND=<backend-url>
148+
```
149+
150+
The value of `KNATIVE_EVENT_MESH_BACKEND` should be the URL of the backend service. If you are running the backend
151+
service in the same cluster as the Backstage instance, you can use the service name as the URL such as
152+
`http://eventmesh-backend.knative-eventing.svc.cluster.local`.
153+
If the Backstage instance is not running in the same cluster, you can use the external URL of the backend service.
154+
Or, if you are running the backend without exposing it for testing purposes, you can use `kubectl port-forward` as
155+
mentioned above.
156+
157+
The value of `KNATIVE_EVENT_MESH_TOKEN` should be a service account token that has the necessary permissions to list
158+
the Knative Eventing resources in the cluster. The backend will use this token to authenticate to the Kubernetes API
159+
server. This is required for security reasons as otherwise (if the backend is running with a SA token directly) the
160+
backend would have full access to the cluster will be returning all resources to anyone who can access the backend.
161+
162+
The token will require the following permissions to work properly:
163+
164+
- `get`, `list` and `watch` permissions for `eventing.knative.dev/brokers`, `eventing.knative.dev/eventtypes` and
165+
`eventing.knative.dev/triggers` resources
166+
- `get` permission for all resources to fetch subscribers for triggers
167+
168+
You can create a ClusterRole with the necessary permissions and bind it to the service account token.
169+
170+
An example configuration is as follows:
171+
172+
```yaml
173+
apiVersion: v1
174+
kind: ServiceAccount
175+
metadata:
176+
name: my-eventmesh-backend-service-account
177+
namespace: default
178+
---
179+
apiVersion: rbac.authorization.k8s.io/v1
180+
kind: ClusterRole
181+
metadata:
182+
name: my-eventmesh-backend-cluster-role
183+
rules:
184+
# permissions for eventtypes, brokers and triggers
185+
- apiGroups:
186+
- "eventing.knative.dev"
187+
resources:
188+
- brokers
189+
- eventtypes
190+
- triggers
191+
verbs:
192+
- get
193+
- list
194+
- watch
195+
# permissions to get subscribers for triggers
196+
# as subscribers can be any resource, we need to give access to all resources
197+
# we fetch subscribers one by one, we only need `get` verb
198+
- apiGroups:
199+
- "*"
200+
resources:
201+
- "*"
202+
verbs:
203+
- get
204+
---
205+
apiVersion: rbac.authorization.k8s.io/v1
206+
kind: ClusterRoleBinding
207+
metadata:
208+
name: my-eventmesh-backend-cluster-role-binding
209+
subjects:
210+
- kind: ServiceAccount
211+
name: my-eventmesh-backend-service-account
212+
namespace: default
213+
roleRef:
214+
kind: ClusterRole
215+
name: my-eventmesh-backend-cluster-role
216+
apiGroup: rbac.authorization.k8s.io
217+
---
218+
apiVersion: v1
219+
kind: Secret
220+
metadata:
221+
name: my-eventmesh-backend-secret
222+
namespace: default
223+
annotations:
224+
kubernetes.io/service-account.name: my-eventmesh-backend-service-account
225+
type: kubernetes.io/service-account-token
226+
```
227+
228+
To get the token, you can run the following command:
229+
230+
```bash
231+
kubectl get secret my-eventmesh-backend-secret -o jsonpath='{.data.token}' | base64 --decode
232+
```
233+
234+
Run a quick check to see if the token works with the Kubernetes API server:
235+
236+
```bash
237+
export KUBE_API_SERVER_URL=$(kubectl config view --minify --output jsonpath="{.clusters[*].cluster.server}") # e.g. "https://192.168.2.151:16443"
238+
export KUBE_SA_TOKEN=$(kubectl get secret my-eventmesh-backend-secret -o jsonpath='{.data.token}' | base64 --decode)
239+
curl -k -H "Authorization: Bearer $KUBE_SA_TOKEN" -X GET "${KUBE_API_SERVER_URL}/apis/eventing.knative.dev/v1/namespaces/default/brokers"
240+
# Should see the brokers, or nothing if there are no brokers
241+
# But, should not see an error
242+
```
243+
244+
Run a second quick check to see if the token works with the Backstage backend:
245+
246+
```bash
247+
export KNATIVE_EVENT_MESH_BACKEND=http://localhost:8080 # or the URL of the backend
248+
export KUBE_SA_TOKEN=$(kubectl get secret my-eventmesh-backend-secret -o jsonpath='{.data.token}' | base64 --decode)
249+
curl -k -H "Authorization: Bearer $KUBE_SA_TOKEN" -X GET "${KNATIVE_EVENT_MESH_BACKEND}"
250+
# Should see the response from the backend such as
251+
# {
252+
# "brokers" : [...],
253+
# "eventTypes" : [...]
254+
#}
255+
```
256+
257+
If these quick checks work, you can use the token in the `app-config.yaml` file as the value
258+
of `KNATIVE_EVENT_MESH_TOKEN`.
259+
260+
### Troubleshooting
261+
262+
When you start your Backstage application, you can see some log lines as follows:
263+
264+
```text
265+
[1] 2024-01-04T09:38:08.707Z knative-event-mesh-backend info Found 1 knative event mesh provider configs with ids: dev type=plugin
266+
```
267+
268+
### Usage
269+
270+
See the [plugin documentation](../../eventing/event-registry/eventmesh-backstage-plugin/) for more information about using the plugin.

0 commit comments

Comments
 (0)