diff --git a/.changeset/warm-gifts-study.md b/.changeset/warm-gifts-study.md new file mode 100644 index 0000000000..fcfee164f7 --- /dev/null +++ b/.changeset/warm-gifts-study.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kafka': minor +'@backstage/plugin-kafka-backend': minor +--- + +Created alpha version of Kafka plugin, supporting listing consumer group for a Backstage configured service. diff --git a/packages/app/package.json b/packages/app/package.json index 1488ee5505..66471b981c 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -19,7 +19,7 @@ "@backstage/plugin-gitops-profiles": "^0.2.2", "@backstage/plugin-graphiql": "^0.2.2", "@backstage/plugin-jenkins": "^0.3.4", - "@backstage/plugin-kafka": "^0.1.1", + "@backstage/plugin-kafka": "^0.1.0", "@backstage/plugin-kubernetes": "^0.3.3", "@backstage/plugin-lighthouse": "^0.2.6", "@backstage/plugin-newrelic": "^0.2.2", diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index a4d097b1d4..a1ab181211 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -63,6 +63,7 @@ import { UserProfileCard, } from '@backstage/plugin-org'; import { Router as SentryRouter } from '@backstage/plugin-sentry'; +import { Router as KafkaRouter } from '@backstage/plugin-kafka'; import { EmbeddedDocsRouter as DocsRouter } from '@backstage/plugin-techdocs'; import { Button, Grid } from '@material-ui/core'; import { @@ -243,6 +244,11 @@ const ServiceEntityPage = ({ entity }: { entity: Entity }) => ( title="Code Insights" element={} /> + } + /> ); diff --git a/packages/backend/package.json b/packages/backend/package.json index 718b008c7b..707c14e33c 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -35,6 +35,7 @@ "@backstage/plugin-catalog-backend": "^0.5.0", "@backstage/plugin-graphql-backend": "^0.1.4", "@backstage/plugin-kubernetes-backend": "^0.2.3", + "@backstage/plugin-kafka-backend": "^0.1.0", "@backstage/plugin-proxy-backend": "^0.2.3", "@backstage/plugin-rollbar-backend": "^0.1.5", "@backstage/plugin-scaffolder-backend": "^0.3.5", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 68cc170901..81d0bb96d2 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -38,6 +38,7 @@ import healthcheck from './plugins/healthcheck'; import auth from './plugins/auth'; import catalog from './plugins/catalog'; import kubernetes from './plugins/kubernetes'; +import kafka from './plugins/kafka'; import rollbar from './plugins/rollbar'; import scaffolder from './plugins/scaffolder'; import proxy from './plugins/proxy'; @@ -77,6 +78,7 @@ async function main() { const rollbarEnv = useHotMemoize(module, () => createEnv('rollbar')); const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs')); const kubernetesEnv = useHotMemoize(module, () => createEnv('kubernetes')); + const kafkaEnv = useHotMemoize(module, () => createEnv('kafka')); const graphqlEnv = useHotMemoize(module, () => createEnv('graphql')); const appEnv = useHotMemoize(module, () => createEnv('app')); @@ -87,6 +89,7 @@ async function main() { apiRouter.use('/auth', await auth(authEnv)); apiRouter.use('/techdocs', await techdocs(techdocsEnv)); apiRouter.use('/kubernetes', await kubernetes(kubernetesEnv)); + apiRouter.use('/kafka', await kafka(kafkaEnv)); apiRouter.use('/proxy', await proxy(proxyEnv)); apiRouter.use('/graphql', await graphql(graphqlEnv)); apiRouter.use(notFoundHandler()); diff --git a/packages/backend/src/plugins/kafka.ts b/packages/backend/src/plugins/kafka.ts new file mode 100644 index 0000000000..e65ce6719c --- /dev/null +++ b/packages/backend/src/plugins/kafka.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2020 Spotify AB + * + * 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. + */ + +import { createRouter } from '@backstage/plugin-kafka-backend'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin({ + logger, + config, +}: PluginEnvironment) { + return await createRouter({ logger, config }); +} diff --git a/plugins/kafka-backend/README.md b/plugins/kafka-backend/README.md new file mode 100644 index 0000000000..0f2dece2e5 --- /dev/null +++ b/plugins/kafka-backend/README.md @@ -0,0 +1,24 @@ +# Kafka Backend + +This is the backend part of the Kafka plugin. It responds to Kafka requests from the frontend. + +## Configuration + +This configures how to connect to the brokers in your Kafka cluster. + +### clientId + +The name of the client to use when connecting to the cluster. + +### brokers + +A list of the brokers' hostnames and ports to connect to. + +Example: + +```yaml +kafka: + clientId: backstage + brokers: + - localhost:9092 +``` diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index a77d7981c9..93ec810ca2 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kafka-backend", - "version": "0.1.1", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka/README.md b/plugins/kafka/README.md index 35a62758f3..52dbd16520 100644 --- a/plugins/kafka/README.md +++ b/plugins/kafka/README.md @@ -1,13 +1,87 @@ -# kafka +# Kafka Plugin -Welcome to the kafka plugin! + -_This plugin was created through the Backstage CLI_ +## Setup -## Getting started +1. Run: -Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/kafka](http://localhost:3000/kafka). +```bash +yarn add @backstage/plugin-kafka @backstage/plugin-kafka-backend +``` -You can also serve the plugin in isolation by running `yarn start` in the plugin directory. -This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. -It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. +2. Add the plugin backend: + +In a new file named `kafka.js` under `backend/src/plugins`: + +```js +import { createRouter } from '@backstage/plugin-kafka-backend'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin({ + logger, + config, +}: PluginEnvironment) { + return await createRouter({ logger, config }); +} +``` + +And then add to `packages/backend/src/index.ts`: + +```js +async function main() { + // ... + const kafkaEnv = useHotMemoize(module, () => createEnv('kafka')); + // ... + + const apiRouter = Router(); + // ... + apiRouter.use('/kafka', await kafka(kafkaEnv)); + // ... +``` + +3. Add the plugin frontend to `packages/app/src/plugin.ts`: + +```js +export { plugin as Kafka } from '@backstage/plugin-kafka'; +``` + +4. Register the plugin frontend router in `packages/app/src/components/catalog/EntityPage.tsx`: + +```jsx +import { Router as KafkaRouter } from '@backstage/plugin-kafka'; + +// Then, somewhere inside + +} +/>; +``` + +5. Add broker configs for the backend in your `app-config.yaml`: + +```yaml +kafka: + clientId: backstage + brokers: + - localhost:9092 +``` + +6. Add `kafka.apache.org/consumer-group` annotation to your services: + +```yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + # ... + annotations: + kafka.apache.org/consumer-group: consumer-group-name +spec: + type: service +``` + +## Features + +- List topics offsets and consumer group offsets for configured services. diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index ed256f51a3..62a79823bf 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kafka", - "version": "0.1.1", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,7 +34,7 @@ "@backstage/cli": "^0.4.2", "@backstage/dev-utils": "^0.1.6", "@backstage/test-utils": "^0.1.5", - "@backstage/plugin-kafka-backend": "^0.1.1", + "@backstage/plugin-kafka-backend": "^0.1.0", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/kafka/src/assets/screenshot-1.png b/plugins/kafka/src/assets/screenshot-1.png new file mode 100644 index 0000000000..0afae0b5d3 Binary files /dev/null and b/plugins/kafka/src/assets/screenshot-1.png differ diff --git a/plugins/kafka/src/constants.ts b/plugins/kafka/src/constants.ts index 652911a91f..c19651ef04 100644 --- a/plugins/kafka/src/constants.ts +++ b/plugins/kafka/src/constants.ts @@ -14,4 +14,4 @@ * limitations under the License. */ export const KAFKA_CONSUMER_GROUP_ANNOTATION = - 'kafka.apache.org/consumer-groups'; + 'kafka.apache.org/consumer-group';