Skip to content

Commit c91bcc3

Browse files
authored
feat(kiali): add KialiPage Component (#1180)
* feat(kiali): add KialiPage Component * Set grid in overview cards for other namespaces
1 parent c2fe940 commit c91bcc3

22 files changed

+555
-262
lines changed

plugins/kiali/DEVELOPMENT.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ async function main() {
7979
apiRouter.use('/kiali', await kiali(kialiEnv));
8080
```
8181

82-
6. Configure you `app-config.yaml` with kiali configuration
82+
6. Configure you `app-config.local.yaml` with kiali configuration
8383

8484
```yaml
8585
catalog:
@@ -103,7 +103,7 @@ catalog:
103103

104104
7. Add catalog
105105

106-
Add to locations in `app-config.yaml`
106+
Add to locations in `app-config.local.yaml`
107107

108108
```yaml
109109
locations:
@@ -116,7 +116,7 @@ locations:
116116

117117
### Token authentication
118118

119-
1. Set the parameters in app-config.yaml
119+
1. Set the parameters in app-config.local.yaml
120120

121121
```yaml
122122
catalog:

plugins/kiali/README.md

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,53 @@ The Kiali plugin has the following capabilities:
7272
7373
***
7474
75-
#### Procedure
75+
#### Setting up the OCM frontend package
7676
7777
1. Install the Kiali plugin using the following commands:
7878
7979
```console
8080
yarn workspace app add @janus-idp/backstage-plugin-kiali
8181
```
8282
83-
2. Enable the **Kiali** tab on the entity view page using the `packages/app/src/components/catalog/EntityPage.tsx` file:
83+
2. Select the components that you want to use, such as:
84+
85+
- `KialiPage`: This is a standalone page or dashboard displaying all namespaces in the mesh. You can add `KialiPage` to `packages/app/src/App.tsx` file as follows:
86+
87+
```tsx title="packages/app/src/App.tsx"
88+
/* highlight-add-next-line */
89+
import { KialiPage } from '@janus-idp/backstage-plugin-kiali';
90+
91+
const routes = (
92+
<FlatRoutes>
93+
{/* ... */}
94+
{/* highlight-add-next-line */}
95+
<Route path="/kiali" element={<KialiPage />} />
96+
</FlatRoutes>
97+
);
98+
```
99+
100+
You can also update navigation in `packages/app/src/components/Root/Root.tsx` as follows:
101+
102+
```tsx title="packages/app/src/components/Root/Root.tsx"
103+
/* highlight-add-next-line */
104+
import { KialiIcon } from '@janus-idp/backstage-plugin-kiali';
105+
106+
export const Root = ({ children }: PropsWithChildren<{}>) => (
107+
<SidebarPage>
108+
<Sidebar>
109+
<SidebarGroup label="Menu" icon={<MenuIcon />}>
110+
{/* ... */}
111+
{/* highlight-add-next-line */}
112+
<SidebarItem icon={KialiIcon} to="kiali" text="Kiali" />
113+
</SidebarGroup>
114+
{/* ... */}
115+
</Sidebar>
116+
{children}
117+
</SidebarPage>
118+
);
119+
```
120+
121+
- `EntityKialiContent`: This component is a React context provided for Kiali data, which is related to the current entity. The `EntityKialiContent` component is used to display any data on the React components mentioned in `packages/app/src/components/catalog/EntityPage.tsx`:
84122

85123
```tsx title="packages/app/src/components/catalog/EntityPage.tsx"
86124
/* highlight-add-next-line */
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
dynamicPlugins:
2+
frontend:
3+
janus-idp.backstage-plugin-kiali:
4+
appIcons:
5+
- name: kialiIcon
6+
importName: KialiIcon
7+
dynamicRoutes:
8+
- path: /kiali
9+
importName: KialiPage
10+
menuItem:
11+
icon: kialiIcon
12+
text: Kiali
13+
mountPoints:
14+
- config:
15+
layout:
16+
gridColumn: '1 / -1'
17+
height: 75vh
18+
if:
19+
anyOf:
20+
- hasAnnotation: backstage.io/kubernetes-namespace
21+
importName: EntityKialiContent
22+
mountPoint: entity.page.kiali/cards

plugins/kiali/dev/index.tsx

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import React from 'react';
22

33
import { Entity } from '@backstage/catalog-model';
4+
import { Content, Page } from '@backstage/core-components';
45
import { createDevApp } from '@backstage/dev-utils';
56
import { EntityProvider } from '@backstage/plugin-catalog-react';
67
import { TestApiProvider } from '@backstage/test-utils';
78

8-
import { KialiPage, kialiPlugin } from '../src/plugin';
9+
import { KialiHeader } from '../src/pages/Kiali/Header/KialiHeader';
10+
import { KialiHeaderEntity } from '../src/pages/Kiali/Header/KialiHeaderEntity';
11+
import { KialiEntity } from '../src/pages/Kiali/KialiEntity';
12+
import { OverviewPage } from '../src/pages/Overview/OverviewPage';
13+
import { kialiPlugin } from '../src/plugin';
914
import { KialiApi, kialiApiRef } from '../src/services/Api';
1015
import { KialiProvider } from '../src/store/KialiProvider';
1116
import { AuthInfo } from '../src/types/Auth';
@@ -237,24 +242,54 @@ class MockKialiClient implements KialiApi {
237242
return true;
238243
}
239244
}
240-
// @ts-expect-error
241-
const MockProvider = ({ children }) => (
242-
<TestApiProvider apis={[[kialiApiRef, new MockKialiClient()]]}>
243-
<EntityProvider entity={mockEntity}>
244-
<KialiProvider>{children}</KialiProvider>
245-
</EntityProvider>
246-
</TestApiProvider>
247-
);
245+
246+
interface Props {
247+
children: React.ReactNode;
248+
isEntity?: boolean;
249+
}
250+
251+
const MockProvider = (props: Props) => {
252+
const content = (
253+
<KialiProvider entity={mockEntity}>
254+
<Page themeId="tool">
255+
{!props.isEntity && <KialiHeader />}
256+
<Content>
257+
{props.isEntity && <KialiHeaderEntity />}
258+
{props.children}
259+
</Content>
260+
</Page>
261+
</KialiProvider>
262+
);
263+
264+
const viewIfEntity = props.isEntity && (
265+
<EntityProvider entity={mockEntity}>{content}</EntityProvider>
266+
);
267+
268+
return (
269+
<TestApiProvider apis={[[kialiApiRef, new MockKialiClient()]]}>
270+
{viewIfEntity || content}
271+
</TestApiProvider>
272+
);
273+
};
248274

249275
createDevApp()
250276
.registerPlugin(kialiPlugin)
251277
.addPage({
252278
element: (
253279
<MockProvider>
254-
<KialiPage />
280+
<OverviewPage />
281+
</MockProvider>
282+
),
283+
title: 'Kiali Overview',
284+
path: '/overview',
285+
})
286+
.addPage({
287+
element: (
288+
<MockProvider isEntity>
289+
<KialiEntity />
255290
</MockProvider>
256291
),
257-
title: 'Overview Page',
258-
path: '/kiali/overview',
292+
title: 'Kiali Entity',
293+
path: '/kiali',
259294
})
260295
.render();

plugins/kiali/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"@material-ui/core": "^4.9.13",
3535
"@material-ui/icons": "^4.11.3",
3636
"@material-ui/lab": "^4.0.0-alpha.45",
37+
"@mui/icons-material": "^5.15.8",
3738
"@patternfly/patternfly": "^5.1.0",
3839
"@patternfly/react-charts": "^7.1.1",
3940
"@patternfly/react-core": "^5.1.1",

plugins/kiali/src/Router.tsx

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,63 +2,82 @@ import React from 'react';
22
import { Route, Routes } from 'react-router-dom';
33

44
import { Entity } from '@backstage/catalog-model';
5-
import { MissingAnnotationEmptyState } from '@backstage/core-components';
5+
import {
6+
Content,
7+
MissingAnnotationEmptyState,
8+
Page,
9+
} from '@backstage/core-components';
610
import { useEntity } from '@backstage/plugin-catalog-react';
711

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

10-
import { KialiNoPath, KialiPage } from './pages/Kiali';
14+
import { KialiNoPath } from './pages/Kiali';
15+
import { KialiHeader } from './pages/Kiali/Header/KialiHeader';
16+
import { KialiHeaderEntity } from './pages/Kiali/Header/KialiHeaderEntity';
17+
import { KialiEntity } from './pages/Kiali/KialiEntity';
18+
import { OverviewPage } from './pages/Overview/OverviewPage';
1119
import { KialiProvider } from './store/KialiProvider';
1220

1321
export const KUBERNETES_ANNOTATION = 'backstage.io/kubernetes-id';
1422
export const KUBERNETES_NAMESPACE = 'backstage.io/kubernetes-namespace';
15-
1623
export const KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION =
1724
'backstage.io/kubernetes-label-selector';
1825

19-
export const isKubernetesAvailable = (entity: Entity) =>
20-
Boolean(entity.metadata.annotations?.[KUBERNETES_ANNOTATION]) ||
21-
Boolean(
22-
entity.metadata.annotations?.[KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION],
26+
const validateAnnotation = (entity: Entity) => {
27+
return (
28+
Boolean(entity.metadata.annotations?.[KUBERNETES_NAMESPACE]) ||
29+
Boolean(entity.metadata.annotations?.[KUBERNETES_ANNOTATION]) ||
30+
Boolean(
31+
entity.metadata.annotations?.[KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION],
32+
)
2333
);
34+
};
2435

25-
export const Router = () => {
26-
const { entity } = useEntity();
27-
const kubernetesAnnotationValue =
28-
entity.metadata.annotations?.[KUBERNETES_ANNOTATION];
29-
30-
const kubernetesNamespaceValue =
31-
entity.metadata.annotations?.[KUBERNETES_NAMESPACE];
32-
33-
const kubernetesLabelSelectorQueryAnnotationValue =
34-
entity.metadata.annotations?.[KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION];
36+
/*
37+
Router for entity
38+
*/
3539

36-
if (
37-
kubernetesAnnotationValue ||
38-
kubernetesNamespaceValue ||
39-
kubernetesLabelSelectorQueryAnnotationValue
40-
) {
40+
export const EmbeddedRouter = () => {
41+
const { entity } = useEntity();
42+
if (!validateAnnotation(entity)) {
4143
return (
42-
<KialiProvider>
43-
<Routes>
44-
<Route path="/" element={<KialiPage />} />
45-
<Route path="/overview" element={<KialiPage />} />
46-
<Route path="*" element={<KialiNoPath />} />
47-
</Routes>
48-
</KialiProvider>
44+
<>
45+
<MissingAnnotationEmptyState annotation={KUBERNETES_ANNOTATION} />
46+
<h1>
47+
Or use a label selector query, which takes precedence over the
48+
previous annotation.
49+
</h1>
50+
<Button variant="contained" color="primary" href="#">
51+
Read Kiali Plugin Docs
52+
</Button>
53+
</>
4954
);
5055
}
5156

5257
return (
53-
<>
54-
<MissingAnnotationEmptyState annotation={KUBERNETES_ANNOTATION} />
55-
<h1>
56-
Or use a label selector query, which takes precedence over the previous
57-
annotation.
58-
</h1>
59-
<Button variant="contained" color="primary" href="#">
60-
Read Kiali Plugin Docs
61-
</Button>
62-
</>
58+
<KialiProvider entity={entity}>
59+
<KialiHeaderEntity />
60+
<Routes>
61+
<Route path="/" element={<KialiEntity />} />
62+
<Route path="*" element={<KialiNoPath />} />
63+
</Routes>
64+
</KialiProvider>
65+
);
66+
};
67+
68+
export const Router = () => {
69+
return (
70+
<KialiProvider>
71+
<Page themeId="tool">
72+
<KialiHeader />
73+
<Content>
74+
<Routes>
75+
<Route path="/" element={<OverviewPage />} />
76+
<Route path="/overview" element={<OverviewPage />} />
77+
<Route path="*" element={<KialiNoPath />} />
78+
</Routes>
79+
</Content>
80+
</Page>
81+
</KialiProvider>
6382
);
6483
};

plugins/kiali/src/components/About/AboutUIModal.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,14 @@ export const AboutUIModal = (props: AboutUIModalProps) => {
8282
: `${externalService.name} URL`;
8383
const additionalInfo = additionalComponentInfoContent(externalService);
8484
return (
85-
<div key={`component_${name}`}>
86-
<Grid item xs={4}>
85+
<>
86+
<Grid item xs={8} key={`component_${name}`}>
8787
{name}
8888
</Grid>
89-
<Grid item xs={8}>
89+
<Grid item xs={4} key={`component_version_${name}`}>
9090
{additionalInfo}
9191
</Grid>
92-
</div>
92+
</>
9393
);
9494
};
9595

plugins/kiali/src/components/DebugInformation/DebugInformation.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ export const DebugInformation = (props: DebugInformationProps) => {
209209
);
210210

211211
const kialiConfigCard = (
212-
<CardTab label="Kiali Config" key="kialiConfig">
212+
<CardTab label="Kiali Config" value="kialiConfig">
213213
{copyClip}
214214
</CardTab>
215215
);

plugins/kiali/src/components/MessageCenter/MessageCenter.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const calculateMessageStatus = (state: KialiAppState) => {
7474
);
7575
};
7676

77-
export const MessageCenter = () => {
77+
export const MessageCenter = (props: { color?: string }) => {
7878
const kialiState = React.useContext(KialiContext) as KialiAppState;
7979
const [isOpen, toggleDrawer] = React.useState(false);
8080
const messageCenterStatus = calculateMessageStatus(kialiState);
@@ -99,7 +99,7 @@ export const MessageCenter = () => {
9999
}
100100
color={messageCenterStatus.badgeDanger ? 'error' : 'primary'}
101101
>
102-
<KialiIcon.Bell className={bell} />
102+
<KialiIcon.Bell className={bell} color={`${props.color}`} />
103103
</Badge>
104104
</Button>
105105
<Drawer anchor="right" open={isOpen} onClose={() => toggleDrawer(false)}>

plugins/kiali/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
export { kialiPlugin, EntityKialiContent } from './plugin';
1+
export { kialiPlugin, EntityKialiContent, KialiPage } from './plugin';
2+
3+
export { default as KialiIcon } from '@mui/icons-material/Troubleshoot';

0 commit comments

Comments
 (0)