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 25, 2024
1 parent a7a48f3 commit 863a881
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 82 deletions.
2 changes: 0 additions & 2 deletions frontend/packages/console-dynamic-plugin-sdk/docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1203,7 +1203,6 @@ 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. |
Expand All @@ -1230,7 +1229,6 @@ 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. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,24 @@ export enum ActionType {
BeginImpersonate = 'beginImpersonate',
EndImpersonate = 'endImpersonate',
SetActiveCluster = 'setActiveCluster',
SetAdmissionWebhookWarning = 'setAdmissionWebhookWarning',
ClearAdmissionWebhookWarning = 'clearAdmissionWebhookWarning',
}

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 = (warning: string, kind: string, name: string) =>
action(ActionType.SetAdmissionWebhookWarning, { warning, kind, name });
export const clearAdmissionWebhookWarning = () =>
action(ActionType.ClearAdmissionWebhookWarning, null);
const coreActions = {
setUser,
beginImpersonate,
endImpersonate,
setAdmissionWebhookWarning,
clearAdmissionWebhookWarning,
};

export type CoreAction = Action<typeof coreActions>;
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,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 +40,20 @@ export const coreReducer = (state: CoreState = { user: {} }, action: CoreAction)
user: action.payload.userInfo,
};

case ActionType.SetAdmissionWebhookWarning:
return {
...state,
warningPolicy: {
warning: action.payload.warning,
kind: action.payload.kind,
name: action.payload.name,
},
};
case ActionType.ClearAdmissionWebhookWarning:
return {
...state,
warningPolicy: null,
};
default:
return state;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { UserInfo } from '../../../extensions';
import { ImpersonateKind, SDKStoreState } from '../../redux-types';
import { ImpersonateKind, SDKStoreState, WarningPolicy } from '../../redux-types';

type GetImpersonate = (state: SDKStoreState) => ImpersonateKind;
type GetUser = (state: SDKStoreState) => UserInfo;
type GetWarningPolicy = (state: SDKStoreState) => WarningPolicy;

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

/**
* It provides warning policy data from the redux store.
* @param state the root state
* @returns The the warningPolicy state.
*/
export const getWarningPolicy: GetWarningPolicy = (state) => state.sdkCore.warningPolicy;
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 WarningPolicy = {
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;
warningPolicy?: WarningPolicy;
};

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
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as _ from 'lodash';
import 'whatwg-fetch';
import { getUtilsConfig } from '../../app/configSetup';
import { setAdmissionWebhookWarning } from '../../app/core/actions';
import storeHandler from '../../app/storeHandler';
import { ConsoleFetchText, ConsoleFetchJSON, ConsoleFetch } from '../../extensions/console-types';
import { TimeoutError } from '../error/http-error';
import { getConsoleRequestHeaders } from './console-fetch-utils';
Expand Down Expand Up @@ -36,19 +38,32 @@ const parseData = async (response) => {
return isPlainText || !response.ok ? text : JSON.parse(text);
};

const handleAdmissionWebhookWarning = async (response) => {
const warning = response.headers.get('Warning');
// Read the response object the second time to get the entire response.
const res = await response.clone();
const data = await parseData(res);
const store = storeHandler.getStore();
store.dispatch(setAdmissionWebhookWarning(warning, data?.kind, data?.metadata?.name));
};

const consoleFetchCommon = async (
url: string,
method: string = 'GET',
options: RequestInit = {},
timeout?: number,
isEntireResponse?: boolean,
): Promise<Response | string> => {
const headers = getConsoleRequestHeaders();
// Pass headers last to let callers to override Accept.
const allOptions = _.defaultsDeep({ method }, options, { headers });
const response = await consoleFetch(url, allOptions, timeout);

return isEntireResponse ? response : parseData(response);
// If the response has a warning header, store it in the redux store.
if (response.ok && response.headers.has('Warning')) {
await handleAdmissionWebhookWarning(response);
}

return parseData(response);
};

/**
Expand All @@ -60,20 +75,13 @@ const consoleFetchCommon = async (
* @param method The HTTP method to use. Defaults to GET
* @param options The options to pass to fetch
* @param timeout The timeout in milliseconds
* @param 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.
*/
export const consoleFetchJSON: ConsoleFetchJSON = (
url,
method = 'GET',
options = {},
timeout,
isEntireResponse,
) => {
export const consoleFetchJSON: ConsoleFetchJSON = (url, method = 'GET', options = {}, timeout) => {
const allOptions = _.defaultsDeep({}, options, {
headers: { Accept: 'application/json' },
});
return consoleFetchCommon(url, method, allOptions, timeout, isEntireResponse);
return consoleFetchCommon(url, method, allOptions, timeout);
};

/**
Expand All @@ -84,16 +92,10 @@ export const consoleFetchJSON: ConsoleFetchJSON = (
* @param url The URL to fetch
* @param options The options to pass to fetch
* @param timeout The timeout in milliseconds
* @param 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.
*/
export const consoleFetchText: ConsoleFetchText = (
url,
options = {},
timeout,
isEntireResponse,
) => {
return consoleFetchCommon(url, 'GET', options, timeout, isEntireResponse);
export const consoleFetchText: ConsoleFetchText = (url, options = {}, timeout) => {
return consoleFetchCommon(url, 'GET', options, timeout);
};

const consoleFetchSendJSON = (
Expand All @@ -102,7 +104,6 @@ const consoleFetchSendJSON = (
json = null,
options: RequestInit = {},
timeout: number,
isEntireResponse?: boolean,
) => {
const allOptions: Record<string, any> = {
headers: {
Expand All @@ -116,13 +117,7 @@ const consoleFetchSendJSON = (
allOptions.body = JSON.stringify(json);
}

return consoleFetchJSON(
url,
method,
_.defaultsDeep(allOptions, options),
timeout,
isEntireResponse,
);
return consoleFetchJSON(url, method, _.defaultsDeep(allOptions, options), timeout);
};

/**
Expand All @@ -146,10 +141,9 @@ consoleFetchJSON.delete = (url, json = null, options = {}, timeout) => {
* @param json The JSON to POST the object
* @param options The options to pass to fetch
* @param timeout The timeout in milliseconds
* @param isEntireResponse The flag to control whether to return the entire content of the response or response body. The default is the response body.
*/
consoleFetchJSON.post = (url: string, json, options = {}, timeout, isEntireResponse) =>
consoleFetchSendJSON(url, 'POST', json, options, timeout, isEntireResponse);
consoleFetchJSON.post = (url: string, json, options = {}, timeout) =>
consoleFetchSendJSON(url, 'POST', json, options, timeout);

/**
* A custom PUT method of consoleFetchJSON.
Expand All @@ -158,10 +152,9 @@ consoleFetchJSON.post = (url: string, json, options = {}, timeout, isEntireRespo
* @param json The JSON to PUT the object
* @param options The options to pass to fetch
* @param timeout The timeout in milliseconds
* @param isEntireResponse The flag to control whether to return the entire content of the response or response body. The default is the response body.
*/
consoleFetchJSON.put = (url: string, json, options = {}, timeout, isEntireResponse) =>
consoleFetchSendJSON(url, 'PUT', json, options, timeout, isEntireResponse);
consoleFetchJSON.put = (url: string, json, options = {}, timeout) =>
consoleFetchSendJSON(url, 'PUT', json, options, timeout);

/**
* A custom PATCH method of consoleFetchJSON.
Expand All @@ -170,7 +163,6 @@ consoleFetchJSON.put = (url: string, json, options = {}, timeout, isEntireRespon
* @param json The JSON to PATCH the object
* @param options The options to pass to fetch
* @param timeout The timeout in milliseconds
* @param isEntireResponse The flag to control whether to return the entire content of the response or response body. The default is the response body.
*/
consoleFetchJSON.patch = (url: string, json, options = {}, timeout, isEntireResponse) =>
consoleFetchSendJSON(url, 'PATCH', json, options, timeout, isEntireResponse);
consoleFetchJSON.patch = (url: string, json, options = {}, timeout) =>
consoleFetchSendJSON(url, 'PATCH', json, options, timeout);
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ const adapterFunc: AdapterFunc = (func: Function, knownArgs: string[]) => {
* @param ns The namespace to look into, should not be specified for cluster-scoped resources.
* @param opts The options to pass
* @param requestInit The fetch init object to use. This can have request headers, method, redirect, etc.
* @param isEntireResponse The flag to cotrol whether to return full or partial response. The default is partial.
* See more at https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.requestinit.html
* @returns A promise that resolves to the response as JSON object with a resource if the name is provided
* else it returns all the resouces matching the model. In case of failure, the promise gets rejected with HTTP error response.
Expand Down Expand Up @@ -97,22 +96,19 @@ export const k8sGetResource: K8sGetResource = adapterFunc(k8sGet, [
* @param model Kubernetes model
* @param data The payload for the resource to be created.
* @param opts The options to pass.
* @param 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 of the resource created.
* In case of failure promise gets rejected with HTTP error response.
*/
export const k8sCreate = <R extends K8sResourceCommon>(
model: K8sModel,
data: R,
opts: Options = {},
isEntireResponse?: boolean,
) => {
return coFetchJSON.post(
resourceURL(model, Object.assign({ ns: data?.metadata?.namespace }, opts)),
data,
null,
null,
isEntireResponse,
);
};

Expand Down Expand Up @@ -149,7 +145,6 @@ export const k8sCreateResource: K8sCreateResource = adapterFunc(k8sCreate, [
* @param ns namespace to look into, it should not be specified for cluster-scoped resources.
* @param name resource name to be updated.
* @param opts The options to pass
* @param 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 of the resource updated.
* In case of failure promise gets rejected with HTTP error response.
*/
Expand All @@ -159,7 +154,6 @@ export const k8sUpdate = <R extends K8sResourceCommon>(
ns?: string,
name?: string,
opts?: Options,
isEntireResponse?: boolean,
): Promise<R> =>
coFetchJSON.put(
resourceURL(model, {
Expand All @@ -170,7 +164,6 @@ export const k8sUpdate = <R extends K8sResourceCommon>(
data,
null,
null,
isEntireResponse,
);

type OptionsUpdate<R> = BaseOptions & {
Expand Down Expand Up @@ -211,7 +204,6 @@ export const k8sUpdateResource: K8sUpdateResource = adapterFunc(k8sUpdate, [
* @param resource The resource to be patched
* @param data Only the data to be patched on existing resource with the operation, path, and value
* @param opts The options to pass
* @param 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 of the resource patched.
* In case of failure promise gets rejected with HTTP error response.
*/
Expand All @@ -220,7 +212,6 @@ export const k8sPatch = <R extends K8sResourceCommon>(
resource: R,
data: Patch[],
opts: Options = {},
isEntireResponse?: boolean,
) => {
const patches = _.compact(data);

Expand All @@ -242,7 +233,6 @@ export const k8sPatch = <R extends K8sResourceCommon>(
patches,
null,
null,
isEntireResponse,
);
};

Expand Down

0 comments on commit 863a881

Please sign in to comment.