diff --git a/Dockerfile b/Dockerfile index 6c02984..0ed3f5e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,6 @@ FROM 193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/node:18.15.0-alpine3.16 as build WORKDIR /app COPY . /app -RUN yarn upgrade -RUN yarn cache clean RUN yarn install RUN yarn build @@ -31,4 +29,4 @@ ENTRYPOINT ["/entrypoint.sh"] USER 4000 -CMD ["nginx", "-g", "daemon off;"] +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/src/components/manifest/Form.tsx b/src/components/manifest/Form.tsx index 4333304..1e53c3a 100644 --- a/src/components/manifest/Form.tsx +++ b/src/components/manifest/Form.tsx @@ -213,7 +213,7 @@ const Form = (props: any) => { .forEach(breached => { const path = breached.path .split('/') - .filter(part => part.length > 0 && part !== '*') + .filter(part => part.length > 0) .map(part => (isNaN(part) ? part : parseInt(part, 10))); const pathKey = breached.limitPath; diff --git a/src/components/manifest/constants.ts b/src/components/manifest/constants.ts index 2227976..d59f12b 100644 --- a/src/components/manifest/constants.ts +++ b/src/components/manifest/constants.ts @@ -46,5 +46,4 @@ export const defaultValues = { '/deployment/instance/minMemory': '512Mi', '/deployment/instance/cpu': 5, '/deployment/instance/memory': '4095Mi', - '/deployment/allowEndpoint': [], }; diff --git a/src/coreform/FormUtil.tsx b/src/coreform/FormUtil.tsx index 7c79527..9ce355c 100644 --- a/src/coreform/FormUtil.tsx +++ b/src/coreform/FormUtil.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { TabPanelProps, TabType } from './Types'; import { FormikProps } from 'formik'; import { AutoCompleteOption } from '@src/types/Types'; -import { CiliumServiceEntry, ZoneElement } from '@src/types/Deployment'; +import { ZoneElement } from '@src/types/Deployment'; import * as _m from '../models/Manifest'; import { clusterZoneMapping, @@ -110,19 +110,3 @@ export const getClusters = (environment: string) => { } return []; }; - -export const populateServiceEntriesOptions = ( - preChangedServiceEntries: CiliumServiceEntry[] | undefined, - serviceEntries: CiliumServiceEntry[], -) => { - const serviceEntriesOptionsMap = preChangedServiceEntries?.reduce((acc, serviceEntry) => { - acc[`${serviceEntry.host}:${serviceEntry.port}`] = serviceEntry?.hashedIdentifier; - return acc; - }, {}); - return serviceEntries?.map(serviceEntry => { - return { - ...serviceEntry, - hashedIdentifier: serviceEntriesOptionsMap?.[`${serviceEntry.host}:${serviceEntry.port}`], - }; - }); -}; diff --git a/src/coreform/deployment/DeploymentBasicTab.tsx b/src/coreform/deployment/DeploymentBasicTab.tsx index 36b6729..6391193 100644 --- a/src/coreform/deployment/DeploymentBasicTab.tsx +++ b/src/coreform/deployment/DeploymentBasicTab.tsx @@ -1,17 +1,17 @@ -import React, { FC } from 'react'; +import * as React from 'react'; +import { FC, useEffect, useState } from 'react'; import Grid from '@material-ui/core/Grid'; import * as _m from '../../models/Manifest'; import { FormikTextField } from '../../components/common/FormikTextField'; import { FormikAutocomplete } from '../../components/common/FormikAutocomplete'; import { populateServiceEntriesOptions, toMenuItems } from '../FormUtil'; -import { useFormikContext, Field, setIn, useField } from 'formik'; -import { makeStyles, TableCell, styled, FormControlLabel, Tooltip } from '@material-ui/core'; +import { Field, useField, useFormikContext } from 'formik'; +import { FormControlLabel, makeStyles, styled, TableCell, Tooltip } from '@material-ui/core'; import { FormikTable } from '../../components/common/FormikTable'; import HealthCheckCard from './HealthCheckCard'; import { cardStyles } from '../Styles'; import AutoscalingCard from './AutoscalingCard'; import CardLayout from '../../components/common/CardLayout'; -import { useEffect, useState } from 'react'; import { httpClient } from '../../helper/api-client'; import { FormikCheckbox } from '../../components/common/FormikCheckbox'; import { Cluster } from '../../constants/Cluster'; @@ -20,10 +20,15 @@ import { Environment } from '../../constants/Environment'; import { InfoOutlined } from '@material-ui/icons'; import WarningDialog from '../../components/common/WarningDialog'; import { Manifest } from '@src/types/Manifest'; -import { ciliumEnabledCluster } from '@src/coreform/deployment/constants'; -import { CiliumServiceEntry } from '@src/types/Deployment'; +import { + AP_SOUTH_1A, + AP_SOUTH_1B, + AP_SOUTH_1C, + ciliumEnabledCluster, +} from '@src/coreform/deployment/constants'; import { useSelector } from 'react-redux'; import { RootState } from '@src/store'; +import FormikMultiSelect from '@components/common/FormikMultiSelect'; const useStyles = makeStyles({ ...cardStyles, @@ -54,6 +59,9 @@ const useStyles = makeStyles({ infoIcon: { verticalAlign: 'middle', }, + multiSelectMarginTop: { + marginTop: 10, + }, }); const MarginedFormControlLabel = styled(FormControlLabel)({ @@ -232,17 +240,21 @@ function renderGpu(team: string) { } function renderSpotNodeCard(environment: string) { - if (spotNodeEnabledEnvironments.has(environment)) { - return ; - } else { - return <>; - } + return ; } const disablegRPCCheckbox = (values: any, i: number) => { return values.deployment.exposedPorts[i].name === 'metrics'; }; -const SpotNodeCard = () => { + +interface AdvancedDeploymentConfigurationProps { + environment: string; +} + +const AdvancedDeploymentConfigurationCard = ( + props: AdvancedDeploymentConfigurationProps, +): React.JSX.Element => { + const classes = useStyles(); const { values, setFieldValue }: { values: any; setFieldValue: any } = useFormikContext(); const [isSpotNodeEnabled, setIsSpotNodeEnabled] = React.useState( values.deployment.scheduleOnSpotNodes, @@ -262,20 +274,34 @@ const SpotNodeCard = () => { }, [isSpotNodeEnabled, gpu.value]); return ( - - - - - } - label={'Schedule workload on spot nodes'} - /> - + <> + + + {toMenuItems([AP_SOUTH_1A, AP_SOUTH_1B, AP_SOUTH_1C])} + + {spotNodeEnabledEnvironments.has(props.environment) ? ( + + + + } + label={'Schedule workload on spot nodes'} + /> + ) : ( + <> + )} + + ); }; diff --git a/src/coreform/deployment/constants.tsx b/src/coreform/deployment/constants.tsx index ef1a66a..eb5562d 100644 --- a/src/coreform/deployment/constants.tsx +++ b/src/coreform/deployment/constants.tsx @@ -98,3 +98,7 @@ export const ciliumEnabledCluster = new Set([ Cluster.LENDING_PROD, Cluster.IAPL_PROD, ]); + +export const AP_SOUTH_1A = 'ap-south-1a'; +export const AP_SOUTH_1B = 'ap-south-1b'; +export const AP_SOUTH_1C = 'ap-south-1c'; diff --git a/src/helper/ChangeRequest.ts b/src/helper/ChangeRequest.ts index 1cb8565..3f9b8b2 100644 --- a/src/helper/ChangeRequest.ts +++ b/src/helper/ChangeRequest.ts @@ -1,6 +1,5 @@ import _ from 'lodash'; import { toast } from 'react-toastify'; -import { getHashedIdentifier } from './changeRequestUtils'; interface ValueWithWeight { type: string; @@ -19,18 +18,6 @@ const isObject = input => { ); }; -export const getBreachPath = ( - manifestPath: string, - key: string, - index: number, - hasHashedIdentifier: boolean, -): string => { - if (hasHashedIdentifier) { - return `${manifestPath}/${key}/*`; - } - return `${manifestPath}/${key}/${index}`; -}; - export const parseValue = str => { const len = str.length; const unit = str.substring(len - 2, len); @@ -169,16 +156,9 @@ const safeMapAccess = (preManifestObject, key) => { return preManifestObject[key]; }; -const safeArrayAccess = (array, identifier: number | string) => { - if (!Array.isArray(array)) { - return undefined; - } - if (typeof identifier === 'number') { - return array[identifier]; - } else if (typeof identifier === 'string') { - return array?.find(obj => obj.hashedIdentifier == identifier); - } - return undefined; +const safeArrayAccess = (array, idx) => { + if (isUndefined(array)) return undefined; + return array[idx]; }; const getBreachedLimits = ( @@ -196,22 +176,17 @@ const getBreachedLimits = ( const currentManifestObj = manifestObject[key]; const currentPreManifestObj = safeMapAccess(preManifestObject, key); if (isTarget(currentLimitObj)) { - if (currentLimitObj.hasOwnProperty('forEach') && currentManifestObj?.length) { + if (currentLimitObj.hasOwnProperty('forEach') && currentManifestObj?.length !== undefined) { for (let i = 0; i < currentManifestObj.length; i++) { const obj = currentManifestObj[i]; - const hasHashedIdentifier = currentLimitObj['hasHashedIdentifier'] == true; - const isBreach = - hasHashedIdentifier || - isChangeRequestRequired( - currentLimitObj['forEach'], - obj, - currentPreManifestObj, - manifestEnv, - ); - const path = getBreachPath(manifestPath, key, i, hasHashedIdentifier); - const identifier = hasHashedIdentifier ? getHashedIdentifier(obj, key) : i; - console.log(`path:${path}, limitPath:${limitPath} key:${key} identifier:${identifier}`); - if (isBreach && !_.isEqual(obj, safeArrayAccess(currentPreManifestObj, identifier))) { + const isBreach = isChangeRequestRequired( + currentLimitObj['forEach'], + obj, + currentPreManifestObj, + manifestEnv, + ); + const path = `${manifestPath}/${key}/${i}`; + if (isBreach && !_.isEqual(obj, safeArrayAccess(currentPreManifestObj, i))) { const diffObj = { op: getOp(currentPreManifestObj), path: path, @@ -219,7 +194,7 @@ const getBreachedLimits = ( value: obj, }; if (replaceWithPreviousValue) { - manifestObject[key] = safeMapAccess(preManifestObject, key); + manifestObject[key] = safeArrayAccess(preManifestObject, key); } breaches = breaches.concat(diffObj); } @@ -233,6 +208,7 @@ const getBreachedLimits = ( ); const path = `${manifestPath}/${key}`; if (isBreach && currentManifestObj !== currentPreManifestObj) { + console.log(`${path} is changed`); const obj = { op: getOp(currentPreManifestObj), path: path, @@ -240,11 +216,12 @@ const getBreachedLimits = ( value: currentManifestObj, }; if (replaceWithPreviousValue) { - manifestObject[key] = safeMapAccess(preManifestObject, key); + manifestObject[key] = safeArrayAccess(preManifestObject, key); } breaches = breaches.concat(obj); } } + if (!isObject(currentLimitObj)) return breaches; for (const nextKey in currentLimitObj) { const nextManifestPath = `${manifestPath}/${key}`; @@ -315,7 +292,6 @@ const getBreachedValues = ( ), ); } - console.log('Breached values:', breaches); return breaches; }; diff --git a/src/helper/changeRequestUtils.ts b/src/helper/changeRequestUtils.ts deleted file mode 100644 index 7d08a2c..0000000 --- a/src/helper/changeRequestUtils.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const getHashedIdentifier = (obj, key: string): string => { - switch (key) { - case 'allowEndpoint': - return btoa(`${obj?.host}:${obj?.port}`); - default: - return ''; - } -}; diff --git a/src/models/Manifest.ts b/src/models/Manifest.ts index 010d73e..c8f14b3 100644 --- a/src/models/Manifest.ts +++ b/src/models/Manifest.ts @@ -12,6 +12,7 @@ import { DEFAULT_ELASTIC_SEARCH_VERSION } from '../constants/ElasticSearchConsta import { LATEST_EC_VERSION } from '@src/coreform/elasticcache/constant'; import { FormType } from '@components/manifest/ShowSelectedForm'; import { DefaultFlinkAlerts } from '@src/coreform/flink/DefaultAlerts'; +import { AP_SOUTH_1A, AP_SOUTH_1B, AP_SOUTH_1C } from '@src/coreform/deployment/constants'; // lodash like path for resources in the manifest object export const path = { @@ -332,6 +333,7 @@ export const addDeployment = (manifest: any) => { }, isDeployed: false, isVpaEnabled: true, + zoneAffinity: [AP_SOUTH_1A, AP_SOUTH_1B, AP_SOUTH_1C], perfUtility: { mockServer: false, postgresServer: false, @@ -425,7 +427,7 @@ export const newOutboundConnectivity = () => { }; export const newAllowEndpoint = () => { - return { host: '', port: '', hashedIdentifier: '' }; + return { host: '', port: '' }; }; export const newHpaCronJob = () => { return { name: '', schedule: '' }; diff --git a/src/models/ManifestValidationSchema.ts b/src/models/ManifestValidationSchema.ts index 82a555e..e5a6f44 100644 --- a/src/models/ManifestValidationSchema.ts +++ b/src/models/ManifestValidationSchema.ts @@ -725,15 +725,12 @@ const perfValidationSchema = yup.object({ }), }); -const allowEndpointValidationSchema = yup - .array() - .of( - yup.object({ - host: yup.string().required('is Required'), - port: yup.string().required('is Required'), - }), - ) - .unique('Host and port combination should be unique', ({ host, port }) => `${host}:${port}`); +const allowEndpointValidationSchema = yup.array().of( + yup.object({ + host: yup.string().required('is Required'), + port: yup.string().required('is Required'), + }), +); const scyllaDbValidationSchema = yup.object({ name: yup @@ -806,6 +803,7 @@ const deploymentValidationSchema = yup.object({ efs: efsValidationSchema.default(undefined), fsx: fsxValidationSchema.default(undefined), perfUtility: perfValidationSchema.default(undefined), + zoneAffinity: yup.array().of(yup.string().required('is Required')).min(1), }); const docdbValidationScheme = yup.object({ diff --git a/src/types/Deployment.d.ts b/src/types/Deployment.d.ts index 19a1a67..c764ba0 100644 --- a/src/types/Deployment.d.ts +++ b/src/types/Deployment.d.ts @@ -32,7 +32,6 @@ export interface Deployment { instance: Instance; scheduleOnSpotNodes: boolean; isVpaEnabled: boolean; - allowEndpoint?: CiliumServiceEntry[]; } export interface ZoneElement { zone: string; @@ -56,9 +55,3 @@ export type LbEndpointProps = { getHostedZone: (index: number) => AutoCompleteOption; setHostedZone: (index: number, value: string) => void; }; - -export type CiliumServiceEntry = { - host: string; - port: string; - hashedIdentifier: string; -};