Skip to content

Commit 88bb893

Browse files
Alberto GutierrezAlberto Gutierrez
authored andcommitted
fix(kiali): remove IstioConfig extra, Fix links and add kiali control
1 parent 32d9bdf commit 88bb893

File tree

25 files changed

+302
-206
lines changed

25 files changed

+302
-206
lines changed

plugins/kiali-backend/__fixtures__/data/config/status.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"status": {
33
"Kiali commit hash": "72a2496cb4ed1545457a68e34fe3e81409b1611d",
4-
"Kiali container version": "v1.71.0-SNAPSHOT",
4+
"Kiali container version": "v1.73.0-SNAPSHOT",
55
"Kiali state": "running",
6-
"Kiali version": "v1.71.0-SNAPSHOT",
6+
"Kiali version": "v1.73.0-SNAPSHOT",
77
"Mesh name": "Istio",
88
"Mesh version": "1.17.1"
99
},

plugins/kiali-backend/src/clients/KialiAPIConnector.ts

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
import { Logger } from 'winston';
22

3+
import supported from '../kiali_supported.json';
34
import { KialiDetails } from '../service/config';
4-
import { KialiFetcher } from './fetch';
5+
import { AuthValid, KialiFetcher } from './fetch';
56

67
export type Options = {
78
logger: Logger;
89
kiali: KialiDetails;
910
};
1011

12+
const KIALI_CORE_VERSION = 'Kiali version';
13+
14+
type Status = { [K: string]: string };
15+
16+
interface StatusState {
17+
status: Status;
18+
}
19+
1120
export interface KialiApi {
1221
proxy(endpoint: string, method?: string): Promise<any>;
1322
}
@@ -21,7 +30,26 @@ export class KialiApiImpl implements KialiApi {
2130
this.kialiFetcher = new KialiFetcher(options.kiali, options.logger);
2231
}
2332

24-
async proxy(endpoint: string, method: string): Promise<any> {
33+
supportedVersion = (version: string): string | undefined => {
34+
this.logger.info('Validating kiali version');
35+
const versionSupported = supported[KIALI_CORE_VERSION].replace(
36+
/^./,
37+
'',
38+
).split('.');
39+
const versionClean = version.replace(/^./, '').split('.');
40+
this.logger.info(
41+
`Kiali Version supported ${supported[KIALI_CORE_VERSION]}`,
42+
);
43+
if (
44+
versionSupported[0] === versionClean[0] &&
45+
versionSupported[1] === versionClean[1]
46+
) {
47+
return undefined;
48+
}
49+
return `kiali version supported is ${supported[KIALI_CORE_VERSION]}, we found version ${version}`;
50+
};
51+
52+
async proxy(endpoint: string): Promise<any> {
2553
const authValid = await this.kialiFetcher.checkSession();
2654
if (authValid.verify) {
2755
this.logger.debug(
@@ -30,7 +58,7 @@ export class KialiApiImpl implements KialiApi {
3058
}`,
3159
);
3260
return this.kialiFetcher
33-
.newRequest<any>(endpoint, false, method)
61+
.newRequest<any>(endpoint, false)
3462
.then(resp => resp.data);
3563
}
3664
this.logger.debug(
@@ -45,9 +73,21 @@ export class KialiApiImpl implements KialiApi {
4573
async status(): Promise<any> {
4674
const authValid = await this.kialiFetcher.checkSession();
4775
if (authValid.verify) {
48-
return this.kialiFetcher
49-
.newRequest<any>('api/status')
50-
.then(resp => resp.data);
76+
return this.kialiFetcher.newRequest<any>('api/status').then(resp => {
77+
const st: StatusState = resp.data;
78+
const versionControl = this.supportedVersion(
79+
st.status[KIALI_CORE_VERSION],
80+
);
81+
if (versionControl) {
82+
const response: AuthValid = {
83+
verify: false,
84+
title: 'kiali version not supported',
85+
message: versionControl,
86+
};
87+
return Promise.resolve(response);
88+
}
89+
return Promise.resolve(resp.data);
90+
});
5191
}
5292
return Promise.resolve(authValid);
5393
}

plugins/kiali-backend/src/clients/fetch.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414

1515
export type AuthValid = {
1616
verify: boolean;
17+
title?: string;
1718
missingAttributes?: string[];
1819
message?: string;
1920
helper?: string;
@@ -32,13 +33,9 @@ export class KialiFetcher {
3233
this.kialiAuth = new KialiAuthentication(KD);
3334
}
3435

35-
newRequest = async <P>(
36-
endpoint: string,
37-
auth: boolean = false,
38-
method?: string,
39-
) => {
36+
newRequest = async <P>(endpoint: string, auth: boolean = false) => {
4037
this.logger.info(`Query to ${endpoint}`);
41-
return axios.request<P>(this.getRequestInit(endpoint, auth, method));
38+
return axios.request<P>(this.getRequestInit(endpoint, auth));
4239
};
4340

4441
private async getAuthInfo(): Promise<AuthInfo> {
@@ -63,6 +60,7 @@ export class KialiFetcher {
6360
this.KialiDetails.serviceAccountToken === ''
6461
) {
6562
result.verify = false;
63+
result.title = 'Authentication failed';
6664
result.message = `Attribute 'serviceAccountToken' is not in the backstage configuration`;
6765
result.helper = `For more information follow the steps in https://janus-idp.io/plugins/kiali`;
6866
result.missingAttributes = ['serviceAccountToken'];
@@ -71,6 +69,7 @@ export class KialiFetcher {
7169
}
7270
default:
7371
result.verify = false;
72+
result.title = 'Authentication failed';
7473
result.message = `Strategy ${auth.strategy} is not supported in Kiali backstage plugin yet`;
7574
break;
7675
}
@@ -107,6 +106,7 @@ export class KialiFetcher {
107106
})
108107
.catch(err => {
109108
checkAuth.verify = false;
109+
checkAuth.title = 'Authentication failed';
110110
checkAuth.message = this.handleUnsuccessfulResponse(err);
111111
});
112112
}
@@ -126,7 +126,6 @@ export class KialiFetcher {
126126
private getRequestInit = (
127127
endpoint: string,
128128
auth: boolean = false,
129-
method?: string,
130129
): AxiosRequestConfig => {
131130
const requestInit: AxiosRequestConfig = { timeout: TIMEOUT_FETCH };
132131
const headers = { 'X-Auth-Type-Kiali-UI': '1' };
@@ -141,7 +140,7 @@ export class KialiFetcher {
141140
requestInit.data = params;
142141
requestInit.method = 'post';
143142
} else {
144-
requestInit.method = method ? method : 'get';
143+
requestInit.method = 'get';
145144
requestInit.headers = {
146145
...headers,
147146
Accept: 'application/json',
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"Kiali version": "v1.73"
3+
}

plugins/kiali-backend/src/service/router.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ describe('createRouter', () => {
5454
expect(result.body).toEqual({
5555
status: {
5656
'Kiali commit hash': '72a2496cb4ed1545457a68e34fe3e81409b1611d',
57-
'Kiali container version': 'v1.71.0-SNAPSHOT',
57+
'Kiali container version': 'v1.73.0-SNAPSHOT',
5858
'Kiali state': 'running',
59-
'Kiali version': 'v1.71.0-SNAPSHOT',
59+
'Kiali version': 'v1.73.0-SNAPSHOT',
6060
'Mesh name': 'Istio',
6161
'Mesh version': '1.17.1',
6262
},

plugins/kiali-backend/src/service/router.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@ export const makeRouter = (
2222
// curl -H "Content-type: application/json" -H "Accept: application/json" -X GET localhost:7007/api/kiali/proxy --data '{"endpoint": "api/namespaces"}'
2323
router.post('/proxy', async (req, res) => {
2424
const endpoint = req.body.endpoint;
25-
const method = req.body.method;
26-
2725
logger.info(`Call to Kiali ${endpoint}`);
28-
res.json(await kialiAPI.proxy(endpoint, method));
26+
res.json(await kialiAPI.proxy(endpoint));
2927
});
3028

3129
router.post('/status', async (_, res) => {

plugins/kiali/src/components/BreadcrumbView/BreadcrumbView.tsx

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import { HistoryManager } from '../../app/History';
77
import { isMultiCluster, Paths } from '../../config';
88
import { kialiStyle, useLinkStyle } from '../../styles/StyleUtils';
99
import { dicIstioType } from '../../types/IstioConfigList';
10+
import {
11+
getJanusEntityView,
12+
getJanusObjectLink,
13+
getJanusSectionLink,
14+
} from '../../utils/janusLinks';
1015
import { FilterSelected } from '../Filters/StatefulFilters';
1116

1217
const ItemNames = {
@@ -16,7 +21,6 @@ const ItemNames = {
1621
istio: 'Istio Object',
1722
};
1823

19-
export const pluginRoot = 'kiali';
2024
const IstioName = 'Istio Config';
2125
const namespaceRegex =
2226
/kiali\/([a-z0-9-]+)\/([\w-.]+)\/([\w-.*]+)(\/([\w-.]+))?(\/([\w-.]+))?/;
@@ -45,7 +49,7 @@ const breadcrumStyle = kialiStyle({
4549
marginTop: '-20px',
4650
});
4751

48-
export const BreadcrumbView = () => {
52+
export const BreadcrumbView = (props: { entity?: boolean }) => {
4953
const capitalize = (str: string) => {
5054
return str?.charAt(0)?.toUpperCase() + str?.slice(1);
5155
};
@@ -70,11 +74,15 @@ export const BreadcrumbView = () => {
7074

7175
const getItemPage = () => {
7276
if (path) {
73-
let pathT = `/${pluginRoot}/${path?.pathItem}/${path?.namespace}/${path?.item}`;
74-
if (path?.cluster && isMultiCluster) {
75-
pathT += `?clusterName=${path.cluster}`;
76-
}
77-
return pathT;
77+
const query =
78+
path?.cluster && isMultiCluster ? `clusterName=${path.cluster}` : '';
79+
return getJanusObjectLink(
80+
path?.pathItem,
81+
path?.namespace,
82+
path?.item,
83+
undefined,
84+
query,
85+
);
7886
}
7987
return '';
8088
};
@@ -94,23 +102,37 @@ export const BreadcrumbView = () => {
94102
</Link>
95103
);
96104

97-
const linkTo = `/${pluginRoot}/${pathItem}?namespaces=${namespace}&type=${
98-
// @ts-ignore
99-
dicIstioType[path?.istioType || '']
100-
}`;
105+
const tab = `tabresources=${pathItem}`;
106+
const filterNs = `namespaces=${namespace}`;
107+
108+
const linkTo = getJanusSectionLink(
109+
pathItem,
110+
`${filterNs}&type=${
111+
// @ts-ignore
112+
dicIstioType[path?.istioType || '']
113+
}`,
114+
);
101115

102116
return (
103117
<div className={breadcrumStyle}>
104118
<Breadcrumbs>
105119
<Link
106-
to={`/${pluginRoot}/${pathItem}`}
120+
to={
121+
props.entity
122+
? getJanusEntityView(tab)
123+
: getJanusSectionLink(pathItem)
124+
}
107125
onClick={cleanFilters}
108126
className={linkStyle}
109127
>
110128
{isIstio ? IstioName : capitalize(pathItem)}
111129
</Link>
112130
<Link
113-
to={`/${pluginRoot}/${pathItem}?namespaces=${namespace}`}
131+
to={
132+
props.entity
133+
? getJanusEntityView(`${tab}&${filterNs}`)
134+
: getJanusSectionLink(pathItem, filterNs)
135+
}
114136
onClick={cleanFilters}
115137
className={linkStyle}
116138
>

plugins/kiali/src/components/Link/IstioObjectLink.tsx

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { Link as RouterLink } from 'react-router-dom';
33

44
import { Link, Tooltip } from '@material-ui/core';
55

6-
import { isMultiCluster, KialiIcon, Paths } from '../../config';
6+
import { KialiIcon } from '../../config';
77
import { kialiStyle } from '../../styles/StyleUtils';
8-
import { pluginRoot } from '../BreadcrumbView/BreadcrumbView';
8+
import { useJanusObjectLink } from '../../utils/janusLinks';
99
import { PFBadge } from '../Pf/PfBadges';
1010
import { IstioTypes } from '../VirtualList/Config';
1111

@@ -22,38 +22,19 @@ type IstioObjectProps = ReferenceIstioObjectProps & {
2222
children: React.ReactNode;
2323
};
2424

25-
export const getIstioObjectUrl = (
26-
name: string,
27-
namespace: string,
28-
type: string,
29-
cluster?: string,
30-
query?: string,
31-
): string => {
32-
const istioType = IstioTypes[type];
33-
let to = `/${pluginRoot}/${Paths.ISTIO}/${namespace}`;
34-
35-
to = `${to}/${istioType.url}/${name}`;
36-
37-
if (cluster && isMultiCluster) {
38-
to = `${to}?clusterName=${cluster}`;
39-
}
40-
41-
if (!query) {
42-
if (to.includes('?')) {
43-
to = `${to}&${query}`;
44-
} else {
45-
to = `${to}?${query}`;
46-
}
47-
}
48-
49-
return to;
50-
};
51-
5225
export const IstioObjectLink: React.FC<IstioObjectProps> = (
5326
props: IstioObjectProps,
5427
) => {
5528
const { name, namespace, type, cluster, query } = props;
56-
const href = getIstioObjectUrl(name, namespace, type, cluster, query);
29+
const istioType = IstioTypes[type];
30+
const href = useJanusObjectLink(
31+
'istio',
32+
namespace,
33+
name,
34+
istioType.url,
35+
cluster,
36+
query,
37+
);
5738

5839
return (
5940
<Link

0 commit comments

Comments
 (0)