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 17, 2024
1 parent 5a66e79 commit 47b291a
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,26 @@ export enum ActionType {
BeginImpersonate = 'beginImpersonate',
EndImpersonate = 'endImpersonate',
SetActiveCluster = 'setActiveCluster',
SetResponseHeaders = 'setResponseHeaders',
}

// export type WarningPolicy = {
// headers: Headers;
// data: ---
// };

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 setResponseHeaders = (responseHeaders: any) =>
action(ActionType.SetResponseHeaders, { responseHeaders });

const coreActions = {
setUser,
beginImpersonate,
endImpersonate,
setResponseHeaders,
};

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

case ActionType.SetResponseHeaders:
return {
...state,
responseHeaders: {
resp: action.payload.responseHeaders,
},
};
case ActionType.EndImpersonate: {
const stateKeys = Object.keys(state);
return stateKeys.reduce((acc, key) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,10 @@ export const impersonateStateToProps = (state: SDKStoreState) => {
* @returns The the user state.
*/
export const getUser: GetUser = (state) => state.sdkCore.user;

/**
* It provides user details from the redux store.
* @param state the root state
* @returns The the responseHeaders state.
*/
export const getResponseHeaders: any = (state) => state.sdkCore.responseHeaders;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type ImpersonateKind = {
export type CoreState = {
user?: UserInfo;
impersonate?: ImpersonateKind;
responseHeaders?: any;
};

export type SDKStoreState = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as _ from 'lodash';
import 'whatwg-fetch';
import { K8sResourceCommon } from '@console/internal/module/k8s';
import { getUtilsConfig } from '../../app/configSetup';
import { setResponseHeaders } 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,6 +39,15 @@ const parseData = async (response) => {
return isPlainText || !response.ok ? text : JSON.parse(text);
};

const getConsoleResponseDetails = async <R extends K8sResourceCommon>(
response: Response,
): Promise<{ data: R; headers: Headers; status: number }> => {
const res = await response.clone();
const data = await parseData(res);
const { headers, status } = res;
return { data, headers, status };
};

const consoleFetchCommon = async (
url: string,
method: string = 'GET',
Expand All @@ -48,6 +60,12 @@ const consoleFetchCommon = async (
const allOptions = _.defaultsDeep({ method }, options, { headers });
const response = await consoleFetch(url, allOptions, timeout);

if (response.ok && response.headers.has('Warning')) {
const entireResponse = await getConsoleResponseDetails(response);
const data = storeHandler.getStore();
data.dispatch(setResponseHeaders(entireResponse));
}

return isEntireResponse ? response : parseData(response);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { K8sResourceCommon } from '@console/internal/module/k8s';

const parseData = async (response) => {
const text = await response.text();
const isPlainText = response.headers.get('Content-Type') === 'text/plain';
if (!text) {
return isPlainText ? '' : {};
}
return isPlainText || !response.ok ? text : JSON.parse(text);
};

/**
* This function takes a response object, converts the response to JSON or text, and then returns the data, headers, and status.
* @param {Response} response - The response object to process.
* @return {Promise<{ data: R, headers: Headers, status: number }>} - A promise that resolves to an object containing the data, headers, and status of the response.
*/
export const getConsoleResponseDetails = async <R extends K8sResourceCommon>(
response: Response,
): Promise<{ data: R; headers: Headers; status: number }> => {
const res = await response;
const data = await parseData(res);
const { headers, status } = res;
return { data, headers, status };
};
44 changes: 44 additions & 0 deletions frontend/public/components/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
AppInitSDK,
getUser,
useActivePerspective,
getResponseHeaders,
} from '@console/dynamic-plugin-sdk';
import { initConsolePlugins } from '@console/dynamic-plugin-sdk/src/runtime/plugin-init';
import { GuidedTour } from '@console/app/src/components/tour';
Expand All @@ -48,8 +49,11 @@ import { ModalProvider } from '@console/dynamic-plugin-sdk/src/app/modal-support
import { settleAllPromises } from '@console/dynamic-plugin-sdk/src/utils/promise';
import ToastProvider from '@console/shared/src/components/toast/ToastProvider';
import { useToast } from '@console/shared/src/components/toast';
//import { getConsoleResponseDetails } from '@console/shared/src/utils/get-console-response-details';
import { documentationURLs, getDocumentationURL } from '@console/internal/components/utils';
import { useTelemetry } from '@console/shared/src/hooks/useTelemetry';
import { useDebounceCallback } from '@console/shared/src/hooks/debounce';
//import { useWarningPolicy } from '@console/shared/src/hooks/useWarningPolicy';
import { LOGIN_ERROR_PATH } from '@console/internal/module/auth';
import { URL_POLL_DEFAULT_DELAY } from '@console/internal/components/utils/url-poll-hook';
import { ThemeProvider } from './ThemeProvider';
Expand Down Expand Up @@ -337,6 +341,45 @@ const CaptureTelemetry = React.memo(function CaptureTelemetry() {
return null;
});

const WarningPolicyAlert = React.memo(function WarningPolicyAlert() {
const { t } = useTranslation();
const toastContext = useToast();
const response = useSelector(getResponseHeaders);

const headers = React.useMemo(() => Object.fromEntries(response?.resp?.headers || []), [
response?.resp?.headers,
]);

React.useEffect(() => {
if (headers?.warning) {
const docURL = getDocumentationURL(documentationURLs.warningPolicy);
toastContext.addToast({
variant: AlertVariant.warning,
title: t('public~Warning Policy'),
content: t(`The {{kind}} {{ name }} violates policy {{warning}}`, {
kind: response?.resp?.data?.kind,
name: response?.resp?.data?.metadata?.name,
warning: headers.warning,
}),
actions: [
{
dismiss: true,
label: t('public~Learn more'),
callback: () => {
window.open(docURL, '_blank');
},
component: 'a',
},
],
timeout: true,
dismissible: true,
});
}
}, [headers, t, toastContext]);

return null;
});

const PollConsoleUpdates = React.memo(function PollConsoleUpdates() {
const toastContext = useToast();
const { t } = useTranslation();
Expand Down Expand Up @@ -597,6 +640,7 @@ graphQLReady.onReady(() => {
>
<ToastProvider>
<PollConsoleUpdates />
<WarningPolicyAlert />
<AppRouter />
</ToastProvider>
</AppInitSDK>
Expand Down
4 changes: 4 additions & 0 deletions frontend/public/components/utils/documentation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ export const documentationURLs: documentationURLsType = {
downstream: 'html/building_applications/deployments',
upstream: 'applications/deployments/what-deployments-are.html',
},
warningPolicy: {
downstream: '',
upstream: 'operators/understanding/olm/olm-webhooks.html',
},
};

export const isUpstream = () => window.SERVER_FLAGS.branding === 'okd';
Expand Down
4 changes: 3 additions & 1 deletion frontend/public/locales/en/public.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
"Details": "Details",
"Schema": "Schema",
"Instances": "Instances",
"Warning Policy": "Warning Policy",
"The {{kind}} {{ name }} violates policy {{warning}}": "The {{kind}} {{ name }} violates policy {{warning}}",
"Learn more": "Learn more",
"Web console update is available": "Web console update is available",
"There has been an update to the web console. Ensure any changes have been saved and refresh your browser to access the latest version.": "There has been an update to the web console. Ensure any changes have been saved and refresh your browser to access the latest version.",
"Refresh web console": "Refresh web console",
Expand Down Expand Up @@ -823,7 +826,6 @@
"Partial cluster update": "Partial cluster update",
"Pause {{worker}} or custom pool {{resource}} updates to accommodate your maintenance schedule.": "Pause {{worker}} or custom pool {{resource}} updates to accommodate your maintenance schedule.",
"You must resume updates within 60 days to avoid failures.": "You must resume updates within 60 days to avoid failures.",
"Learn more": "Learn more",
"Update": "Update",
"Selected columns will appear in the table.": "Selected columns will appear in the table.",
"You can select up to {{MAX_VIEW_COLS}} columns": "You can select up to {{MAX_VIEW_COLS}} columns",
Expand Down
1 change: 0 additions & 1 deletion frontend/public/reducers/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ export default (state: UIState, action: UIAction): UIState => {
return state.setIn(['utilizationDuration', 'selectedKey'], action.payload.key);
case ActionType.SetUtilizationDurationEndTime:
return state.setIn(['utilizationDuration', 'endTime'], action.payload.endTime);

case ActionType.SetShowOperandsInAllNamespaces:
return state.set('showOperandsInAllNamespaces', action.payload.value);
default:
Expand Down

0 comments on commit 47b291a

Please sign in to comment.