Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat…
Browse files Browse the repository at this point in the history
…/pipeline-deploy-config-diff-revamp
  • Loading branch information
RohitRaj011 committed Oct 3, 2024
2 parents ddf54da + 161cd88 commit ddc7a98
Show file tree
Hide file tree
Showing 29 changed files with 613 additions and 721 deletions.
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,6 @@ src/components/security/SecurityPolicyEdit.tsx
src/components/security/SecurityPolicyEnvironment.tsx
src/components/security/SecurityPolicyGlobal.tsx
src/components/security/UpdateSeverityModal.tsx
src/components/security/VulnerabilityExposure.tsx
src/components/security/security.service.ts
src/components/security/security.util.tsx
src/components/terminal/TerminalWrapper.tsx
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"homepage": "/dashboard",
"dependencies": {
"@devtron-labs/devtron-fe-common-lib": "0.3.15-beta-3",
"@devtron-labs/devtron-fe-common-lib": "0.3.21",
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
"@rjsf/core": "^5.13.3",
"@rjsf/utils": "^5.13.3",
Expand Down
2 changes: 2 additions & 0 deletions src/Pages/Shared/ConfigMapSecret/ConfigMapSecret.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export const SECRET_TOAST_INFO = {
CHECK_KEY_SECRET_KEY: 'Please check key and secretKey',
BOTH_STORE_UNAVAILABLE: 'Please provide secretStore or secretStoreRef',
CHECK_KEY_NAME: 'Please check key and name',
BOTH_ESO_DATA_AND_DATA_FROM_AVAILABLE: 'Please use either esoData or esoDataFrom',
BOTH_ESO_DATA_AND_DATA_FROM_UNAVAILABLE: 'Please provide esoData or esoDataFrom',
}

export const CM_SECRET_COMPONENT_NAME = {
Expand Down
19 changes: 15 additions & 4 deletions src/Pages/Shared/ConfigMapSecret/ConfigMapSecret.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,27 @@ export const processCurrentData = (
return [{ k: '', v: '', keyError: '', valueError: '' }]
}

const getExternalSubPathValues = (configMapSecretData: CMSecretConfigData) => {
const externalSubPathValues = {
value: configMapSecretData?.data ? Object.keys(configMapSecretData.data).join(',') : '',
error: '',
}

if (!externalSubPathValues.value && configMapSecretData?.esoSubPath) {
externalSubPathValues.value = configMapSecretData.esoSubPath.join(', ')
}

return externalSubPathValues
}

export const initState = (
configMapSecretData,
componentType: CMSecretComponentType,
cmSecretStateLabel: CM_SECRET_STATE,
): ConfigMapState | ConfigMapSecretState => {
const secretInitState =
componentType === CMSecretComponentType.Secret ? getSecretInitState(configMapSecretData) : {}

const initialState = {
isFormDirty: false,
loading: false,
Expand All @@ -87,10 +101,7 @@ export const initState = (
selectedType: configMapSecretData?.type ?? 'environment',
volumeMountPath: { value: configMapSecretData?.mountPath ?? configMapSecretData?.defaultMountPath, error: '' },
isSubPathChecked: !!configMapSecretData?.subPath,
externalSubpathValues: {
value: configMapSecretData?.data ? Object.keys(configMapSecretData?.data).join(',') : '',
error: '',
},
externalSubpathValues: getExternalSubPathValues(configMapSecretData),
isFilePermissionChecked: !!configMapSecretData?.filePermission,
configName: {
value: configMapSecretData?.name ?? '',
Expand Down
8 changes: 7 additions & 1 deletion src/Pages/Shared/ConfigMapSecret/ConfigMapSecret.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
}

&.with-crud-btn {
> .main-content {
>.main-content {
height: calc(100vh - 142px);
}
}
Expand Down Expand Up @@ -104,3 +104,9 @@

white-space: pre;
}

.sub-path-checkbox {
.form__checkbox-container {
align-self: flex-start;
}
}
3 changes: 3 additions & 0 deletions src/Pages/Shared/ConfigMapSecret/ConfigMapSecret.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ export interface SecretState {
externalType: string
roleARN: ValueWithError
esoData: any
template: Record<string, any>
esoDataFrom: Record<string, any>[]
secretData: any
secretDataYaml: string
codeEditorRadio: string
Expand Down Expand Up @@ -196,6 +198,7 @@ export interface ConfigDatum {
overridden: boolean
mountPath?: string
defaultMountPath?: string
esoSubPath?: string[]
}

export interface CMSecret extends Omit<ConfigMapSecretData, 'configData'> {
Expand Down
62 changes: 40 additions & 22 deletions src/Pages/Shared/ConfigMapSecret/ConfigMapSecretForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -346,13 +346,16 @@ export const ConfigMapSecretForm = React.memo(
} else if (componentType === CMSecretComponentType.Secret && (isHashiOrAWS || isESO)) {
let isValidSecretData = false
if (isESO) {
isValidSecretData = state.esoData?.reduce(
(_isValidSecretData, s) => {
isValidSecretData = _isValidSecretData && !!s?.secretKey && !!s.key
return isValidSecretData
},
!state.secretStore !== !state.secretStoreRef && !!state.esoData?.length,
)
isValidSecretData =
!(state.esoData && state.esoDataFrom) &&
(state.esoData || state.esoDataFrom) &&
!state.secretStore !== !state.secretStoreRef
if (state.esoData && isValidSecretData) {
isValidSecretData = state.esoData.reduce(
(_isValidSecretData, s) => _isValidSecretData && !!s?.secretKey && !!s.key,
isValidSecretData,
)
}
} else {
isValidSecretData = state.secretData.reduce((_isValidSecretData, s) => {
isValidSecretData = _isValidSecretData && !!s.fileName && !!s.name
Expand All @@ -361,7 +364,13 @@ export const ConfigMapSecretForm = React.memo(
}

if (!isValidSecretData) {
secretValidationInfoToast(isESO, state.secretStore, state.secretStoreRef)
secretValidationInfoToast({
isESO,
esoData: state.esoData,
secretStore: state.secretStore,
secretStoreRef: state.secretStoreRef,
esoDataFrom: state.esoDataFrom,
})
isFormValid = false
}
}
Expand Down Expand Up @@ -395,6 +404,7 @@ export const ConfigMapSecretForm = React.memo(
mountPath: null,
subPath: null,
filePermission: null,
esoSubPath: null,
}
if (
(componentType === CMSecretComponentType.Secret && state.externalType === 'KubernetesSecret') ||
Expand All @@ -421,8 +431,14 @@ export const ConfigMapSecretForm = React.memo(
esoData: state.esoData,
secretStoreRef: state.secretStoreRef,
refreshInterval: state.refreshInterval,
// if null don't send these keys which is achieved by `undefined`
esoDataFrom: state.esoDataFrom ?? undefined,
template: state.template ?? undefined,
}
payload.roleARN = state.roleARN.value
if (state.isSubPathChecked && state.externalSubpathValues.value) {
payload.esoSubPath = state.externalSubpathValues.value.replace(/\s+/g, '').split(',')
}
}
}
if (state.selectedType === 'volume') {
Expand Down Expand Up @@ -795,18 +811,19 @@ export const ConfigMapSecretForm = React.memo(
)

const renderSubPathCheckBoxContent = (): JSX.Element => (
<span data-testid={`${CM_SECRET_COMPONENT_NAME[componentType]}-sub-path-checkbox`} className="mb-0">
Set SubPath (same as
<a
href="https://kubernetes.io/docs/concepts/storage/volumes/#using-subpath"
className="ml-5 mr-5 anchor"
target="_blank"
rel="noreferrer"
>
subPath
</a>
for volume mount)
<br />
<p data-testid={`${CM_SECRET_COMPONENT_NAME[componentType]}-sub-path-checkbox`} className="flexbox-col m-0">
<p className="m-0">
<span>Set SubPath (same as</span>
<a
href="https://kubernetes.io/docs/concepts/storage/volumes/#using-subpath"
className="ml-5 mr-5 anchor"
target="_blank"
rel="noreferrer"
>
subPath
</a>
<span>for volume mount)</span>
</p>
{state.isSubPathChecked && (
<span className="mb-0 cn-5 fs-11">
{state.external
Expand All @@ -827,22 +844,23 @@ export const ConfigMapSecretForm = React.memo(
</a>
</span>
)}
</span>
</p>
)

const renderSubPath = (): JSX.Element => (
<div className="mb-16">
<Checkbox
isChecked={state.isSubPathChecked}
onClick={stopPropagation}
rootClassName="top"
rootClassName={`${state.isSubPathChecked ? 'sub-path-checkbox' : ''}`}
disabled={!draftMode && (state.cmSecretState === CM_SECRET_STATE.INHERITED || readonlyView)}
value={CHECKBOX_VALUE.CHECKED}
onChange={toggleSubpath}
>
{renderSubPathCheckBoxContent()}
</Checkbox>
{(state.externalType === 'KubernetesSecret' ||
isESO ||
(componentType !== CMSecretComponentType.Secret && state.external)) &&
state.isSubPathChecked && (
<div className="mb-16">
Expand Down
34 changes: 30 additions & 4 deletions src/Pages/Shared/ConfigMapSecret/Secret.utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -337,10 +337,22 @@ export const hasESO = (externalType): boolean =>

export const hasProperty = (externalType): boolean => externalType === 'ESO_AWSSecretsManager'

export const secretValidationInfoToast = (isESO, secretStore, secretStoreRef) => {
export const secretValidationInfoToast = ({
isESO,
esoData,
esoDataFrom,
secretStore,
secretStoreRef,
}: {
isESO: boolean
} & Pick<SecretState, 'esoData' | 'esoDataFrom' | 'secretStore' | 'secretStoreRef'>) => {
let errorMessage = ''
if (isESO) {
if (secretStore && secretStoreRef) {
if (esoDataFrom && esoData) {
errorMessage = SECRET_TOAST_INFO.BOTH_ESO_DATA_AND_DATA_FROM_AVAILABLE
} else if (!esoDataFrom && !esoData) {
errorMessage = SECRET_TOAST_INFO.BOTH_ESO_DATA_AND_DATA_FROM_UNAVAILABLE
} else if (secretStore && secretStoreRef) {
errorMessage = SECRET_TOAST_INFO.BOTH_STORE_AVAILABLE
} else if (secretStore || secretStoreRef) {
errorMessage = SECRET_TOAST_INFO.CHECK_KEY_SECRET_KEY
Expand Down Expand Up @@ -428,10 +440,18 @@ const handleValidJson = (isESO: boolean, json, dispatch: (action: ConfigMapActio
secretStoreRef: json.secretStoreRef,
refreshInterval: json.refreshInterval,
esoData: null,
esoDataFrom: null,
template: null,
}
if (Array.isArray(json?.esoData)) {
payload.esoData = json.esoData
}
if (Array.isArray(json?.esoDataFrom)) {
payload.esoDataFrom = json.esoDataFrom
}
if (typeof json?.template === 'object' && !Array.isArray(json.template)) {
payload.template = json.template
}
dispatch({
type: ConfigMapActionTypes.multipleOptions,
payload,
Expand Down Expand Up @@ -497,18 +517,24 @@ export const getSecretInitState = (configMapSecretData): SecretState => {
}))
jsonForSecretDataYaml = transformSecretDataJSON(jsonForSecretDataYaml)
const tempEsoSecretData =
(configMapSecretData?.esoSecretData?.esoData || []).length === 0 && configMapSecretData?.defaultESOSecretData
(configMapSecretData?.esoSecretData?.esoData || []).length === 0 &&
!configMapSecretData?.esoSecretData?.template &&
!configMapSecretData?.esoSecretData?.esoDataFrom &&
configMapSecretData?.defaultESOSecretData
? configMapSecretData?.defaultESOSecretData
: configMapSecretData?.esoSecretData
const isEsoSecretData: boolean =
(tempEsoSecretData?.secretStore || tempEsoSecretData?.secretStoreRef) && tempEsoSecretData.esoData
(tempEsoSecretData?.secretStore || tempEsoSecretData?.secretStoreRef) &&
(tempEsoSecretData.esoData || tempEsoSecretData.template || tempEsoSecretData.esoDataFrom)
return {
externalType: configMapSecretData?.externalType ?? '',
roleARN: {
value: configMapSecretData?.roleARN ?? '',
error: '',
},
esoData: tempEsoSecretData?.esoData,
template: tempEsoSecretData?.template,
esoDataFrom: tempEsoSecretData?.esoDataFrom,
secretData: tempSecretData,
secretDataYaml: YAMLStringify(jsonForSecretDataYaml),
codeEditorRadio: CODE_EDITOR_RADIO_STATE.DATA,
Expand Down
4 changes: 0 additions & 4 deletions src/components/app/details/cIDetails/CIDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,6 @@ const HistoryLogs = ({
blobStorageEnabled={triggerDetails.blobStorageEnabled}
downloadArtifactUrl={downloadArtifactUrl}
isArtifactUploaded={triggerDetails.isArtifactUploaded}
isJobView={isJobView}
isJobCI={isJobCI}
imageComment={triggerDetails.imageComment}
imageReleaseTags={triggerDetails.imageReleaseTags}
Expand All @@ -579,7 +578,6 @@ const HistoryLogs = ({
tagsEditable={tagsEditable}
appReleaseTagNames={appReleaseTags}
hideImageTaggingHardDelete={hideImageTaggingHardDelete}
type={HistoryComponentType.CI}
rootClassName="pb-0-imp"
renderCIListHeader={renderCIListHeader}
/>
Expand Down Expand Up @@ -620,7 +618,6 @@ const HistoryLogs = ({
blobStorageEnabled={triggerDetails.blobStorageEnabled}
downloadArtifactUrl={downloadArtifactUrl}
isArtifactUploaded={triggerDetails.isArtifactUploaded}
isJobView={isJobView}
isJobCI={isJobCI}
imageComment={triggerDetails.imageComment}
imageReleaseTags={triggerDetails.imageReleaseTags}
Expand All @@ -629,7 +626,6 @@ const HistoryLogs = ({
tagsEditable={tagsEditable}
appReleaseTagNames={appReleaseTags}
hideImageTaggingHardDelete={hideImageTaggingHardDelete}
type={HistoryComponentType.CI}
renderCIListHeader={renderCIListHeader}
/>
</div>
Expand Down
14 changes: 14 additions & 0 deletions src/components/app/details/cdDetails/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ export const prepareConfigMapAndSecretData = (
}
if (rawData['subPath']) {
secretValues['subPath'] = { displayName: 'Set SubPath', value: 'Yes' }

if (rawData.esoSubPath) {
secretValues['subPathValues'] = { displayName: 'SubPath', value: rawData.esoSubPath.join(', ') }
} else if (
rawData.external &&
rawData.externalType === 'KubernetesSecret' &&
historyData.codeEditorValue?.resolvedValue
) {
const resolvedSecretData = JSON.parse(historyData.codeEditorValue.resolvedValue)
secretValues['subPathValues'] = {
displayName: 'SubPath',
value: Object.keys(resolvedSecretData).join(', '),
}
}
}
if (rawData['filePermission']) {
secretValues['filePermission'] = {
Expand Down
14 changes: 9 additions & 5 deletions src/components/cdPipeline/CDPipeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -663,9 +663,11 @@ export default function CDPipeline({
deploymentAppName: formData.deploymentAppName,
releaseMode: formData.releaseMode,
deploymentAppCreated: formData.deploymentAppCreated,
...(getUserApprovalConfigPayload ? {
userApprovalConfig: getUserApprovalConfigPayload(formData.userApprovalConfig)
}: {}),
...(getUserApprovalConfigPayload
? {
userApprovalConfig: getUserApprovalConfigPayload(formData.userApprovalConfig),
}
: {}),
triggerType: formData.triggerType,
environmentName: formData.environmentName,
preStageConfigMapSecretNames: _preStageConfigMapSecretNames,
Expand Down Expand Up @@ -1031,8 +1033,10 @@ export default function CDPipeline({
})
.catch((error: ServerErrors) => {
// 412 is for linked pipeline and 403 is for RBAC
// 422 is for deployment window
if (!force && error.code != 403 && error.code != 412 && error.code != 422) {
//For now we are removing check for error code 422 which is of deployment window,
// so in that case force delete modal would be shown.
// This should be done at BE and when done we will revert our changes
if (!force && error.code != 403 && error.code != 412) {
setForceDeleteDialogData(error)
setDeleteDialog(DeleteDialogType.showForceDeleteDialog)
} else {
Expand Down
Loading

0 comments on commit ddc7a98

Please sign in to comment.