Skip to content

Commit

Permalink
dispaly-warning-policy-apiserver-workloads-res
Browse files Browse the repository at this point in the history
  • Loading branch information
cyril-ui-developer committed Apr 30, 2024
1 parent a7a48f3 commit ac7fdea
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as React from 'react';
import { AlertVariant } from '@patternfly/react-core';
import { useTranslation } from 'react-i18next';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-next-line
import { useDispatch, useSelector } from 'react-redux';
import {
AdmissionWebhookWarning,
CoreState,
getAdmissionWebhookWarnings,
removeAdmissionWebhookWarning,
} from '@console/dynamic-plugin-sdk/src';
import { documentationURLs, getDocumentationURL } from '@console/internal/components/utils';
import { useToast } from '@console/shared/src';

type UseAdmissionWebhookWarnings = () => Map<string, AdmissionWebhookWarning>;
const useAdmissionWebhookWarnings: UseAdmissionWebhookWarnings = () =>
useSelector<CoreState, Map<string, AdmissionWebhookWarning>>(getAdmissionWebhookWarnings);

export const AdmissionWebhookWarningNotifications = () => {
const { t } = useTranslation();
const toastContext = useToast();
const dispatch = useDispatch();
const admissionWebhookWarnings = useAdmissionWebhookWarnings();
React.useEffect(() => {
const docURL = getDocumentationURL(documentationURLs.admissionWebhookWarning);
admissionWebhookWarnings.forEach((warning, id) => {
toastContext.addToast({
variant: AlertVariant.warning,
title: t('public~Admission Webhook Warning'),
content: t(`{{kind}} {{name}} violates policy {{warning}}`, {
kind: warning.kind,
name: warning.name,
warning: warning.warning,
}),
actions: [
{
dismiss: true,
label: t('public~Learn more'),
callback: () => {
window.open(docURL, '_blank');
},
component: 'a',
dataTest: 'admission-webhook-warning-learn-more',
},
],
timeout: true,
dismissible: true,
});
dispatch(removeAdmissionWebhookWarning(id));
});
}, [dispatch, admissionWebhookWarnings, t, toastContext]);

return null;
};
6 changes: 2 additions & 4 deletions frontend/packages/console-dynamic-plugin-sdk/docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1203,13 +1203,12 @@ A custom wrapper around `fetch` that adds console-specific headers and allows fo
| `method` | The HTTP method to use. Defaults to GET |
| `options` | The options to pass to fetch |
| `timeout` | The timeout in milliseconds |
| `isEntireResponse` | The flag to control whether to return the entire content of the response or response body. The default is the response body. |
### Returns
A promise that resolves to the response as text, response JSON object or entire content of the HTTP response.
A promise that resolves to the response as text or JSON object.
---
Expand All @@ -1230,13 +1229,12 @@ A custom wrapper around `fetch` that adds console-specific headers and allows fo
| `url` | The URL to fetch |
| `options` | The options to pass to fetch |
| `timeout` | The timeout in milliseconds |
| `isEntireResponse` | The flag to control whether to return the entire content of the response or response body. The default is the response body. |
### Returns
A promise that resolves to the response as text, response JSON object or entire content of the HTTP response.
A promise that resolves to the response as text or JSON object.
---
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import { action, ActionType as Action } from 'typesafe-actions';
import { UserInfo } from '../../../extensions';
import { AdmissionWebhookWarning } from '../../redux-types';

export enum ActionType {
SetUser = 'setUser',
BeginImpersonate = 'beginImpersonate',
EndImpersonate = 'endImpersonate',
SetActiveCluster = 'setActiveCluster',
SetAdmissionWebhookWarning = 'setAdmissionWebhookWarning',
RemoveAdmissionWebhookWarning = 'removeAdmissionWebhookWarning',
}

export const setUser = (userInfo: UserInfo) => action(ActionType.SetUser, { userInfo });
export const beginImpersonate = (kind: string, name: string, subprotocols: string[]) =>
action(ActionType.BeginImpersonate, { kind, name, subprotocols });
export const endImpersonate = () => action(ActionType.EndImpersonate);

export const setAdmissionWebhookWarning = (id: string, warning: AdmissionWebhookWarning) =>
action(ActionType.SetAdmissionWebhookWarning, { id, warning });
export const removeAdmissionWebhookWarning = (id) =>
action(ActionType.RemoveAdmissionWebhookWarning, { id });
const coreActions = {
setUser,
beginImpersonate,
endImpersonate,
setAdmissionWebhookWarning,
removeAdmissionWebhookWarning,
};

export type CoreAction = Action<typeof coreActions>;
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { CoreState } from '../../../redux-types';
import { Map as ImmutableMap } from 'immutable';
import { AdmissionWebhookWarning, CoreState } from '../../../redux-types';
import { setUser, beginImpersonate, endImpersonate } from '../../actions/core';
import { coreReducer } from '../core';
import reducerTest from './utils/reducerTest';

describe('Core Reducer', () => {
const state: CoreState = {};
const state: CoreState = {
user: {},
admissionWebhookWarnings: ImmutableMap<string, AdmissionWebhookWarning>(),
};
const mockAdmissionWebhookWarnings = ImmutableMap({});

it('set user', () => {
const mockUser = {
username: 'kube:admin',
};
reducerTest(coreReducer, state, setUser(mockUser)).expectVal({
admissionWebhookWarnings: mockAdmissionWebhookWarnings,
user: mockUser,
});
});
Expand All @@ -21,6 +27,8 @@ describe('Core Reducer', () => {
state,
beginImpersonate('User', 'developer', ['Impersonate-User.Y29uc29sZWRldmVsb3Blcg__']),
).expectVal({
user: {},
admissionWebhookWarnings: mockAdmissionWebhookWarnings,
impersonate: {
kind: 'User',
name: 'developer',
Expand All @@ -30,6 +38,9 @@ describe('Core Reducer', () => {
});

it('end Impersonate', () => {
reducerTest(coreReducer, state, endImpersonate()).expectVal({});
reducerTest(coreReducer, state, endImpersonate()).expectVal({
admissionWebhookWarnings: mockAdmissionWebhookWarnings,
user: {},
});
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CoreState } from '../../redux-types';
import { Map as ImmutableMap } from 'immutable';
import { AdmissionWebhookWarning, CoreState } from '../../redux-types';
import { ActionType, CoreAction } from '../actions/core';

/**
Expand All @@ -10,7 +11,13 @@ import { ActionType, CoreAction } from '../actions/core';
* @see CoreAction
* @returns The the updated state.
*/
export const coreReducer = (state: CoreState = { user: {} }, action: CoreAction): CoreState => {
export const coreReducer = (
state: CoreState = {
user: {},
admissionWebhookWarnings: ImmutableMap<string, AdmissionWebhookWarning>(),
},
action: CoreAction,
): CoreState => {
switch (action.type) {
case ActionType.BeginImpersonate:
return {
Expand All @@ -21,7 +28,6 @@ export const coreReducer = (state: CoreState = { user: {} }, action: CoreAction)
subprotocols: action.payload.subprotocols,
},
};

case ActionType.EndImpersonate: {
const stateKeys = Object.keys(state);
return stateKeys.reduce((acc, key) => {
Expand All @@ -41,6 +47,19 @@ export const coreReducer = (state: CoreState = { user: {} }, action: CoreAction)
user: action.payload.userInfo,
};

case ActionType.SetAdmissionWebhookWarning:
return {
...state,
admissionWebhookWarnings: state.admissionWebhookWarnings.set(
action.payload.id,
action.payload.warning,
),
};
case ActionType.RemoveAdmissionWebhookWarning:
return {
...state,
admissionWebhookWarnings: state.admissionWebhookWarnings.remove(action.payload.id),
};
default:
return state;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Map as ImmutableMap } from 'immutable';
import { UserInfo } from '../../../extensions';
import { ImpersonateKind, SDKStoreState } from '../../redux-types';
import { ImpersonateKind, SDKStoreState, AdmissionWebhookWarning } from '../../redux-types';

type GetImpersonate = (state: SDKStoreState) => ImpersonateKind;
type GetUser = (state: SDKStoreState) => UserInfo;
type GetAdmissionWebhookWarnings = (
state: SDKStoreState,
) => ImmutableMap<string, AdmissionWebhookWarning>;

/**
* It provides impersonation details from the redux store.
Expand All @@ -26,3 +30,11 @@ export const impersonateStateToProps = (state: SDKStoreState) => {
* @returns The the user state.
*/
export const getUser: GetUser = (state) => state.sdkCore.user;

/**
* It provides admission webhook warning data from the redux store.
* @param state the root state
* @returns The the admissionWebhookWarning state.
*/
export const getAdmissionWebhookWarnings: GetAdmissionWebhookWarnings = (state) =>
state.sdkCore.admissionWebhookWarnings;
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import { UserInfo } from '../extensions/console-types';

export type K8sState = ImmutableMap<string, any>;

export type AdmissionWebhookWarning = {
kind: string;
name: string;
warning: string;
};
export type ImpersonateKind = {
kind: string;
name: string;
Expand All @@ -12,6 +17,7 @@ export type ImpersonateKind = {
export type CoreState = {
user?: UserInfo;
impersonate?: ImpersonateKind;
admissionWebhookWarnings?: ImmutableMap<string, AdmissionWebhookWarning>;
};

export type SDKStoreState = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,39 +266,14 @@ export type ConsoleFetch = (
url: string,
options?: RequestInit,
timeout?: number,
isEntireResponse?: boolean,
) => Promise<Response>;

export type ConsoleFetchJSON<T = any> = {
(
url: string,
method?: string,
options?: RequestInit,
timeout?: number,
isEntireResponse?: boolean,
): Promise<T>;
(url: string, method?: string, options?: RequestInit, timeout?: number): Promise<T>;
delete(url: string, json?: any, options?: RequestInit, timeout?: number): Promise<T>;
post(
url: string,
json: any,
options?: RequestInit,
timeout?: number,
isEntireResponse?: boolean,
): Promise<T>;
put(
url: string,
json: any,
options?: RequestInit,
timeout?: number,
isEntireResponse?: boolean,
): Promise<T>;
patch(
url: string,
json: any,
options?: RequestInit,
timeout?: number,
isEntireResponse?: boolean,
): Promise<T>;
post(url: string, json: any, options?: RequestInit, timeout?: number): Promise<T>;
put(url: string, json: any, options?: RequestInit, timeout?: number): Promise<T>;
patch(url: string, json: any, options?: RequestInit, timeout?: number): Promise<T>;
};

export type ConsoleFetchText<T = any> = (...args: Parameters<ConsoleFetch>) => Promise<T>;
Expand Down

0 comments on commit ac7fdea

Please sign in to comment.