Skip to content

Commit

Permalink
fix(kiali): add corner cases, fix some issues and improve dev env (#1202
Browse files Browse the repository at this point in the history
)

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

* Fix error loading and docs

* remove console
  • Loading branch information
aljesusg authored Feb 14, 2024
1 parent c6e2663 commit fd9a8aa
Show file tree
Hide file tree
Showing 17 changed files with 252 additions and 82 deletions.
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).
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',
},
};
File renamed without changes
File renamed without changes
File renamed without changes
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

0 comments on commit fd9a8aa

Please sign in to comment.