Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(kiali): add corner cases, fix some issues and improve dev env #1202

Merged
merged 3 commits into from
Feb 14, 2024
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
59 changes: 14 additions & 45 deletions plugins/kiali/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The Kiali plugin has the following capabilities:
- Health by namespace
- Canary info
- Istio Config warnings
- Worklist

## For administrators

Expand All @@ -21,58 +22,22 @@ The Kiali plugin has the following capabilities:

- The following annotation is added to the entity's `catalog-info.yaml` file to identify whether an entity contains the Kubernetes resources:

```yaml
annotations:
...

backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
```

You can also add the `backstage.io/kubernetes-namespace` annotation to identify the Kubernetes resources using the defined namespace.

```yaml
annotations:
...

backstage.io/kubernetes-namespace: <RESOURCE_NS>
```

- The following annotation is added to the `catalog-info.yaml` file of entity to view the latest `PipelineRun` in the CI/CD tab of the application:

```yaml
annotations:
...

janus-idp.io/kiali-enabled : 'true'
```

- A custom label selector can be added, which Backstage uses to find the Kubernetes resources. The label selector takes precedence over the ID annotations.
For now we support kubernetes-namespace due Kiali works in namespace level. We expect to support `kubernetes-label-selector` and `kubernetes-id`

```yaml
annotations:
...

backstage.io/kubernetes-label-selector: 'app=my-app,component=front-end'
```

- The following label is added to the resources so that the Kubernetes plugin gets the Kubernetes resources from the requested entity:
- The following annotation is added to the `catalog-info.yaml` file of entity to view the latest `PipelineRun` in the CI/CD tab of the application:

```yaml
labels:
...

backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>`
janus-idp.io/kiali-enabled: 'true'
```

***

**NOTE**

When using the label selector, the mentioned labels must be present on the resource.

***

#### Setting up the OCM frontend package
#### Setting up the Kiali frontend package

1. Install the Kiali plugin using the following commands:

Expand Down Expand Up @@ -166,8 +131,8 @@ Authentication methods:
The following table describes the parameters that you can configure to enable the plugin under `catalog.providers.keycloakOrg.<ENVIRONMENT_NAME>` object in the `app-config.yaml` file:

| Name | Description | Default Value | Required |
| --------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------- | --------------------------------------- | --- |
| `url` | Location of the kIALI server, such as `https://localhost:4000` | "" | Yes | |
| --------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------- | --------------------------------------- |
| `url` | Location of the Kiali server, such as `https://localhost:4000` | "" | Yes |
| `serviceAccountToken` | Service Account Token which is used for querying data from Kiali | "" | Yes if using token based authentication |
| `skipTLSVerify` | Skip TLS certificate verification presented by the API server | false | No |
| `caData` | Base64-encoded certificate authority bundle in PEM format | "" | No |
Expand All @@ -178,20 +143,24 @@ The following table describes the parameters that you can configure to enable th

1. Open your Backstage application and select a component from the **Catalog** page.

![catalog-list](./images/catalog-list.png)
![catalog-list](./images/janus/catalog-list.png)

2. Check that you entity has the annotations.

![entity](./images/entity.png)
![entity](./images/janus/entity.png)

3. Go to the **Kiali** tab.

The **Kiali** tab displays the Overview view associated to a Servicemesh.

![overview-tab](./images/overview_tab.png)
![overview-tab](./images/janus/overview_tab.png)

There is also a **Go To Kiali Graph** option at the bottom of each card, which redirects you to the **Graph in the Kiali Standalone**.

## Red Hat Developer Hub

If you want to know more about Kiali in Red Hat Developer Hub follow [these instructions](./RHDH.md)

## Development

To develop/contribute in kiali plugin follow [these instructions](./DEVELOPMENT.md)
72 changes: 72 additions & 0 deletions plugins/kiali/RHDH.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Kiali Plugin in Red Hat Developer hub

The Kiali plugin is in the Red Hat Developer Hub for OpenShift users of Istio/OSSM. It is Technology Preview and provides early access to potential product features, enabling users to test features and provide feedback during the development process. Because this is a brand new offering, there are some things you should consider:

It is based on the new dynamic plugin-in framework.
Because it is currently a Technology Preview, we are not yet ready to provide official support, and it is not subject Red Hat production service level agreements (SLAs).
Copy link
Contributor

Choose a reason for hiding this comment

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

it is not subject to?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

well this was correct by editors in post https://medium.com/kialiproject/kiali-setup-in-red-hat-developer-hub-57502ea8b988 it's copy/paste it seems that this is right

With that said, the Kiali team hopes that the community will try out the new Kiali Plugin in Red Hat Developer Hub and provide feedback. We thank you for joining the effort to provide Kiali/Service Mesh observability features directly to the Red Hat Developer Hub.

## Install

To install Kiali we need to modify the helm chart and add these values under global > dynamic > plugins

```yaml
global:
dynamic:
includes:
- dynamic-plugins.default.yaml
plugins:
- disabled: false
integrity: <Checksum>
package: '@janus-idp/backstage-plugin-kiali@<version>'
pluginConfig:
dynamicPlugins:
frontend:
janus-idp.backstage-plugin-kiali:
appIcons:
- importName: KialiIcon
name: kialiIcon
dynamicRoutes:
- importName: KialiPage
menuItem:
icon: kialiIcon
text: Kiali
path: /kiali
- disabled: falseName of the contact in Engineering
integrity: <Checksum>
package: '@janus-idp/backstage-plugin-kiali-backend-dynamic@<version>'
pluginConfig:
catalog:
providers:
kiali:
skipTLSVerify: true
url: '${KIALI_ENDPOINT}'
serviceAccountToken: '${KIALI_SERVICE_ACCOUNT_TOKEN}'
```

_integrity: required for external packages) An integrity checksum in the format of <alg>-<digest> specific to the package. Supported algorithms include sha256, sha384, and sha512._

We can calculate the integrity with the next bash commands (Example with version 1.9.0).

```bash

npm pack @janus-idp/[email protected]
echo "sha512-$(cat janus-idp-backstage-plugin-kiali-backend-dynamic-1.9.0.tgz | openssl dgst -sha512 -binary | openssl base64 -A)"

```

_The mountPoints configuration is not available in the tech preview, we’ll use this to configure the kiali view by entity_

## Kiali Page

### Overview Page

![overview](./images/rhdh/RHDH_kiali_page_overview.png)

### Workloads List

![workloads](./images/rhdh/RHDH_kiali_page_workloads.png)

### Video Demo

[![RHDH-demo](https://img.youtube.com/vi/jCExpeXl9A8/0.jpg)](https://youtu.be/jCExpeXl9A8)
7 changes: 7 additions & 0 deletions plugins/kiali/dev/__fixtures__/general/statusError.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"verify": false,
"missingAttributes": ["serviceAccountToken"],
"message": "Attribute 'serviceAccountToken' is not in the backstage configuration",
"helper": "For more information follow the steps in https://janus-idp.io/plugins/kiali",
"authData": { "strategy": "token", "sessionInfo": {} }
}
21 changes: 17 additions & 4 deletions plugins/kiali/dev/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { KialiNoPath } from '../src/pages/Kiali';
import { KialiHeader } from '../src/pages/Kiali/Header/KialiHeader';
import { KialiHeaderEntity } from '../src/pages/Kiali/Header/KialiHeaderEntity';
import { KialiEntity } from '../src/pages/Kiali/KialiEntity';
import { KialiNoAnnotation } from '../src/pages/Kiali/KialiNoAnnotation';
import { KialiNoResources } from '../src/pages/Kiali/KialiNoResources';
import { OverviewPage } from '../src/pages/Overview/OverviewPage';
import { WorkloadListPage } from '../src/pages/WorkloadList/WorkloadListPage';
import { KialiApi, kialiApiRef } from '../src/services/Api';
Expand Down Expand Up @@ -50,7 +52,7 @@ import {
} from '../src/types/Workload';
import { filterNsByAnnotation } from '../src/utils/entityFilter';
import { kialiData } from './__fixtures__';
import { mockEntity } from './mockEntity';
import { mockEntity, mockEntityAnnotationNoNamespace } from './mockEntity';

class MockKialiClient implements KialiApi {
private entity?: Entity;
Expand Down Expand Up @@ -284,6 +286,7 @@ class MockKialiClient implements KialiApi {

interface Props {
children?: React.ReactNode;
entity?: Entity;
isEntity?: boolean;
}

Expand Down Expand Up @@ -321,7 +324,7 @@ const RoutesList = () => (

const MockProvider = (props: Props) => {
const content = (
<KialiProvider entity={mockEntity}>
<KialiProvider entity={props.entity || mockEntity}>
<BrowserRouter>
<Page themeId="tool">
{!props.isEntity && (
Expand Down Expand Up @@ -357,12 +360,22 @@ createDevApp()
.registerPlugin(kialiPlugin)
.addPage({
element: <MockProvider />,
title: 'Kiali Overview',
title: 'KialiPage',
path: '/overview',
})
.addPage({
element: <MockProvider isEntity />,
title: 'Kiali Entity',
title: 'Entity',
path: '/kiali',
})
.addPage({
element: <KialiNoResources entity={mockEntityAnnotationNoNamespace} />,
title: 'No resource',
path: '/no-resource',
})
.addPage({
element: <KialiNoAnnotation />,
title: 'No Annotation',
path: '/no-annotation',
})
.render();
35 changes: 35 additions & 0 deletions plugins/kiali/dev/mockEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,38 @@ export const mockEntity: Entity = {
owner: 'user:guest',
},
};

export const mockEntityNoAnnotation: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'backstage',
description: 'backstage.io',
annotations: {
'backstage.io/my-annotation': 'no annotation',
'backstage.io/another-annotation': 'no other annotation',
},
},
spec: {
lifecycle: 'production',
type: 'service',
owner: 'user:guest',
},
};

export const mockEntityAnnotationNoNamespace: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'backstage',
description: 'backstage.io',
annotations: {
'backstage.io/kubernetes-namespace': 'no-namespace',
},
},
spec: {
lifecycle: 'production',
type: 'service',
owner: 'user:guest',
},
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 14 additions & 29 deletions plugins/kiali/src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,15 @@ import React from 'react';
import { Route, Routes } from 'react-router-dom';

import { Entity } from '@backstage/catalog-model';
import {
Content,
MissingAnnotationEmptyState,
Page,
} from '@backstage/core-components';
import { Content, Page } from '@backstage/core-components';
import { useEntity } from '@backstage/plugin-catalog-react';

import { Button } from '@material-ui/core';

import { KialiNoPath } from './pages/Kiali';
import { KialiHeader } from './pages/Kiali/Header/KialiHeader';
import { KialiHeaderEntity } from './pages/Kiali/Header/KialiHeaderEntity';
import { KialiTabs } from './pages/Kiali/Header/KialiTabs';
import { KialiEntity } from './pages/Kiali/KialiEntity';
import { KialiNoAnnotation } from './pages/Kiali/KialiNoAnnotation';
import { OverviewPage } from './pages/Overview/OverviewPage';
import { WorkloadListPage } from './pages/WorkloadList/WorkloadListPage';
import { KialiProvider } from './store/KialiProvider';
Expand All @@ -25,14 +20,16 @@ export const KUBERNETES_NAMESPACE = 'backstage.io/kubernetes-namespace';
export const KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION =
'backstage.io/kubernetes-label-selector';

export const ANNOTATION_SUPPORTED = [KUBERNETES_NAMESPACE];

const validateAnnotation = (entity: Entity) => {
return (
Boolean(entity.metadata.annotations?.[KUBERNETES_NAMESPACE]) ||
Boolean(entity.metadata.annotations?.[KUBERNETES_ANNOTATION]) ||
Boolean(
entity.metadata.annotations?.[KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION],
)
);
let validated = false;
ANNOTATION_SUPPORTED.forEach(key => {
if (Boolean(entity.metadata.annotations?.[key])) {
validated = true;
}
});
return validated;
};

/*
Expand All @@ -41,22 +38,10 @@ const validateAnnotation = (entity: Entity) => {

export const EmbeddedRouter = () => {
const { entity } = useEntity();
if (!validateAnnotation(entity)) {
return (
<>
<MissingAnnotationEmptyState annotation={KUBERNETES_ANNOTATION} />
<h1>
Or use a label selector query, which takes precedence over the
previous annotation.
</h1>
<Button variant="contained" color="primary" href="#">
Read Kiali Plugin Docs
</Button>
</>
);
}

return (
return !validateAnnotation(entity) ? (
<KialiNoAnnotation />
) : (
<KialiProvider entity={entity}>
<KialiHeaderEntity />
<Routes>
Expand Down
22 changes: 22 additions & 0 deletions plugins/kiali/src/pages/Kiali/KialiNoAnnotation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

import {
Content,
MissingAnnotationEmptyState,
Page,
} from '@backstage/core-components';

import { ANNOTATION_SUPPORTED } from '../../Router';

export const KialiNoAnnotation = () => {
return (
<Page themeId="tool">
<Content>
<MissingAnnotationEmptyState
annotation={ANNOTATION_SUPPORTED}
readMoreUrl="https://github.com/janus-idp/backstage-plugins/blob/main/plugins/kiali/README.md"
/>
</Content>
</Page>
);
};
Loading
Loading