Skip to content

fix(kiali): remove IstioConfig extra, Fix links and add kiali control #1452

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

Merged
merged 5 commits into from
May 2, 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
4 changes: 2 additions & 2 deletions plugins/kiali-backend/__fixtures__/data/config/status.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"status": {
"Kiali commit hash": "72a2496cb4ed1545457a68e34fe3e81409b1611d",
"Kiali container version": "v1.71.0-SNAPSHOT",
"Kiali container version": "v1.73.0-SNAPSHOT",
"Kiali state": "running",
"Kiali version": "v1.71.0-SNAPSHOT",
"Kiali version": "v1.73.0-SNAPSHOT",
"Mesh name": "Istio",
"Mesh version": "1.17.1"
},
Expand Down
34 changes: 34 additions & 0 deletions plugins/kiali-backend/src/clients/KialiAPIConnector.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { createLogger, transports } from 'winston';

import supported from '../kiali_supported.json';
import { KIALI_CORE_VERSION, KialiApiImpl } from './KialiAPIConnector';

const logger = createLogger({
transports: [new transports.Console({ silent: true })],
});

const kialiApi = new KialiApiImpl({
logger: logger,
kiali: { url: 'https://localhost:4000' },
});

describe('kiali Api Connector', () => {
describe('Validate suported version', () => {
it('Plugin support the version', () => {
const versionsToTest = ['v1.73', 'v1.73.6'];
versionsToTest.forEach(version => {
const support = kialiApi.supportedVersion(version);
expect(support).toBeUndefined();
});
});

it('Plugin not support version', () => {
const versionToTest = 'v1.70';
const support = kialiApi.supportedVersion(versionToTest);
const kialiSupported = supported[KIALI_CORE_VERSION];
expect(support).toBe(
`Kiali version supported is ${kialiSupported}, we found version ${versionToTest}`,
);
});
});
});
59 changes: 50 additions & 9 deletions plugins/kiali-backend/src/clients/KialiAPIConnector.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import { Logger } from 'winston';

import supported from '../kiali_supported.json';
import { KialiDetails } from '../service/config';
import { KialiFetcher } from './fetch';
import { KialiFetcher, KialiValidations, ValidationCategory } from './fetch';

export type Options = {
logger: Logger;
kiali: KialiDetails;
};

export const KIALI_CORE_VERSION = 'Kiali version';

type Status = { [K: string]: string };

interface StatusState {
status: Status;
}

export interface KialiApi {
proxy(endpoint: string, method?: string): Promise<any>;
}
Expand All @@ -21,7 +30,26 @@ export class KialiApiImpl implements KialiApi {
this.kialiFetcher = new KialiFetcher(options.kiali, options.logger);
}

async proxy(endpoint: string, method: string): Promise<any> {
supportedVersion = (version: string): string | undefined => {
this.logger.info('Validating kiali version');
const versionSupported = supported[KIALI_CORE_VERSION].replace(
/^./,
'',
).split('.');
const versionClean = version.replace(/^./, '').split('.');
this.logger.info(
`Kiali Version supported ${supported[KIALI_CORE_VERSION]}`,
);
if (
versionSupported[0] === versionClean[0] &&
versionSupported[1] === versionClean[1]
) {
return undefined;
}
return `Kiali version supported is ${supported[KIALI_CORE_VERSION]}, we found version ${version}`;
};

async proxy(endpoint: string): Promise<any> {
const authValid = await this.kialiFetcher.checkSession();
if (authValid.verify) {
this.logger.debug(
Expand All @@ -30,7 +58,7 @@ export class KialiApiImpl implements KialiApi {
}`,
);
return this.kialiFetcher
.newRequest<any>(endpoint, false, method)
.newRequest<any>(endpoint, false)
.then(resp => resp.data);
}
this.logger.debug(
Expand All @@ -43,12 +71,25 @@ export class KialiApiImpl implements KialiApi {
}

async status(): Promise<any> {
const authValid = await this.kialiFetcher.checkSession();
if (authValid.verify) {
return this.kialiFetcher
.newRequest<any>('api/status')
.then(resp => resp.data);
const validations = await this.kialiFetcher.checkSession();
if (validations.verify) {
return this.kialiFetcher.newRequest<any>('api/status').then(resp => {
const st: StatusState = resp.data;
const versionControl = this.supportedVersion(
st.status[KIALI_CORE_VERSION],
);
if (versionControl) {
const response: KialiValidations = {
verify: false,
category: ValidationCategory.versionSupported,
title: 'kiali version not supported',
message: versionControl,
};
return Promise.resolve(response);
}
return Promise.resolve(resp.data);
});
}
return Promise.resolve(authValid);
return Promise.resolve(validations);
}
}
23 changes: 22 additions & 1 deletion plugins/kiali-backend/src/clients/fetch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AxiosError } from 'axios';
import { createLogger, transports } from 'winston';

import { AuthStrategy } from './Auth';
import { KialiFetcher } from './fetch';
import { KialiFetcher, ValidationCategory } from './fetch';

const logger = createLogger({
transports: [new transports.Console({ silent: true })],
Expand All @@ -22,6 +22,7 @@ describe('kiali Fetch', () => {
});

expect(result.verify).toBeTruthy();
expect(result.category).toBe(ValidationCategory.unknown);
expect(result.message).toBeUndefined();
expect(result.missingAttributes).toBeUndefined();
expect(result.helper).toBeUndefined();
Expand All @@ -39,6 +40,7 @@ describe('kiali Fetch', () => {
});

expect(result.verify).toBeFalsy();
expect(result.category).toBe(ValidationCategory.configuration);
expect(result.message).toBeDefined();
expect(result.message).toStrictEqual(
"Attribute 'serviceAccountToken' is not in the backstage configuration",
Expand All @@ -60,6 +62,7 @@ describe('kiali Fetch', () => {
});

expect(result.verify).toBeTruthy();
expect(result.category).toBe(ValidationCategory.unknown);
expect(result.message).toBeUndefined();
expect(result.missingAttributes).toBeUndefined();
expect(result.helper).toBeUndefined();
Expand All @@ -78,6 +81,7 @@ describe('kiali Fetch', () => {
});

expect(result.verify).toBeFalsy();
expect(result.category).toBe(ValidationCategory.configuration);
expect(result.message).toBeDefined();
expect(result.message).toStrictEqual(
`Strategy ${AuthStrategy.openid} is not supported in Kiali backstage plugin yet`,
Expand Down Expand Up @@ -127,6 +131,23 @@ describe('kiali Fetch', () => {
});
});

describe('Return networking error in checkSession', () => {
it('Respond with verify category to network', async () => {
const kialiFetch = new KialiFetcher(
{ url: 'https://localhost:4000' },
logger,
);

jest.mock('./fetch', () => ({
getAuthInfo: Promise.reject({}),
}));
const validations = await kialiFetch.checkSession();
expect(validations).toBeDefined();
expect(validations.title).toBe('Error reaching Kiali');
expect(validations.category).toBe(ValidationCategory.networking);
});
});

describe('Handle Unsuccessful Response', () => {
it('Respond with a readable message with endpoint', () => {
const kialiFetch = new KialiFetcher(
Expand Down
74 changes: 50 additions & 24 deletions plugins/kiali-backend/src/clients/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,18 @@ import {
SessionInfo,
} from './Auth';

export type AuthValid = {
export enum ValidationCategory {
configuration = 'configuration',
authentication = 'authentication',
versionSupported = 'versionSupported',
networking = 'networking',
unknown = 'unknown',
}

export type KialiValidations = {
verify: boolean;
category: ValidationCategory;
title?: string;
missingAttributes?: string[];
message?: string;
helper?: string;
Expand All @@ -32,13 +42,9 @@ export class KialiFetcher {
this.kialiAuth = new KialiAuthentication(KD);
}

newRequest = async <P>(
endpoint: string,
auth: boolean = false,
method?: string,
) => {
newRequest = async <P>(endpoint: string, auth: boolean = false) => {
this.logger.info(`Query to ${endpoint}`);
return axios.request<P>(this.getRequestInit(endpoint, auth, method));
return axios.request<P>(this.getRequestInit(endpoint, auth));
};

private async getAuthInfo(): Promise<AuthInfo> {
Expand All @@ -49,9 +55,10 @@ export class KialiFetcher {
return this.kialiAuth.getSession();
}

private validateConfiguration = (auth: AuthInfo): AuthValid => {
const result: AuthValid = {
private validateConfiguration = (auth: AuthInfo): KialiValidations => {
const result: KialiValidations = {
verify: true,
category: ValidationCategory.unknown,
authData: auth,
};
switch (auth.strategy) {
Expand All @@ -63,6 +70,8 @@ export class KialiFetcher {
this.KialiDetails.serviceAccountToken === ''
) {
result.verify = false;
result.title = 'Authentication failed. Missing Configuration';
result.category = ValidationCategory.configuration;
result.message = `Attribute 'serviceAccountToken' is not in the backstage configuration`;
result.helper = `For more information follow the steps in https://janus-idp.io/plugins/kiali`;
result.missingAttributes = ['serviceAccountToken'];
Expand All @@ -71,30 +80,46 @@ export class KialiFetcher {
}
default:
result.verify = false;
result.category = ValidationCategory.configuration;
result.title = 'Authentication failed. Not supported';
result.message = `Strategy ${auth.strategy} is not supported in Kiali backstage plugin yet`;
break;
}

return result;
};

async checkSession(): Promise<AuthValid> {
let checkAuth: AuthValid = { verify: true };
async checkSession(): Promise<KialiValidations> {
let checkValidations: KialiValidations = {
verify: true,
category: ValidationCategory.unknown,
};
/*
* Get/Update AuthInformation from /api/auth/info
*/

const auth = await this.getAuthInfo();
this.kialiAuth.setAuthInfo(auth);
this.logger.info(`AuthInfo: ${JSON.stringify(auth)}`);
/*
* Check Configuration
*/
checkAuth = this.validateConfiguration(auth);
try {
const auth = await this.getAuthInfo();
this.kialiAuth.setAuthInfo(auth);
this.logger.info(`AuthInfo: ${JSON.stringify(auth)}`);
/*
* Check Configuration
*/
checkValidations = this.validateConfiguration(auth);
} catch (error: any) {
return {
verify: false,
category: ValidationCategory.networking,
title: 'Error reaching Kiali',
message: error.message || '',
helper: `Check if ${this.KialiDetails.url} works`,
};
}

/*
* Check if the actual cookie/session is valid and if the configuration is right
*/
if (checkAuth.verify && this.kialiAuth.shouldRelogin()) {
if (checkValidations.verify && this.kialiAuth.shouldRelogin()) {
this.logger.info(`User must relogin`);
await this.newRequest<AuthInfo>('api/authenticate', true)
.then(resp => {
Expand All @@ -106,11 +131,13 @@ export class KialiFetcher {
this.logger.info(`User ${session.username} logged in kiali plugin`);
})
.catch(err => {
checkAuth.verify = false;
checkAuth.message = this.handleUnsuccessfulResponse(err);
checkValidations.verify = false;
checkValidations.category = ValidationCategory.authentication;
checkValidations.title = 'Authentication failed';
checkValidations.message = this.handleUnsuccessfulResponse(err);
});
}
return checkAuth;
return checkValidations;
}

private bufferFromFileOrString(file?: string, data?: string): Buffer | null {
Expand All @@ -126,7 +153,6 @@ export class KialiFetcher {
private getRequestInit = (
endpoint: string,
auth: boolean = false,
method?: string,
): AxiosRequestConfig => {
const requestInit: AxiosRequestConfig = { timeout: TIMEOUT_FETCH };
const headers = { 'X-Auth-Type-Kiali-UI': '1' };
Expand All @@ -141,7 +167,7 @@ export class KialiFetcher {
requestInit.data = params;
requestInit.method = 'post';
} else {
requestInit.method = method ? method : 'get';
requestInit.method = 'get';
requestInit.headers = {
...headers,
Accept: 'application/json',
Expand Down
3 changes: 3 additions & 0 deletions plugins/kiali-backend/src/kiali_supported.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"Kiali version": "v1.73"
}
4 changes: 2 additions & 2 deletions plugins/kiali-backend/src/service/router.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ describe('createRouter', () => {
expect(result.body).toEqual({
status: {
'Kiali commit hash': '72a2496cb4ed1545457a68e34fe3e81409b1611d',
'Kiali container version': 'v1.71.0-SNAPSHOT',
'Kiali container version': 'v1.73.0-SNAPSHOT',
'Kiali state': 'running',
'Kiali version': 'v1.71.0-SNAPSHOT',
'Kiali version': 'v1.73.0-SNAPSHOT',
'Mesh name': 'Istio',
'Mesh version': '1.17.1',
},
Expand Down
4 changes: 1 addition & 3 deletions plugins/kiali-backend/src/service/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ export const makeRouter = (
// curl -H "Content-type: application/json" -H "Accept: application/json" -X GET localhost:7007/api/kiali/proxy --data '{"endpoint": "api/namespaces"}'
router.post('/proxy', async (req, res) => {
const endpoint = req.body.endpoint;
const method = req.body.method;

logger.info(`Call to Kiali ${endpoint}`);
res.json(await kialiAPI.proxy(endpoint, method));
res.json(await kialiAPI.proxy(endpoint));
});

router.post('/status', async (_, res) => {
Expand Down
Loading