Merge pull request #749 from navi-infra/infra-4080-jit-database-access

INFRA-4080 | Harinder | Adding database name field in JIT request from when environment is Prod and resourceType is DB
This commit is contained in:
Harinder Singh
2025-01-15 16:22:04 +05:30
committed by GitHub
6 changed files with 90 additions and 16 deletions

View File

@@ -14,7 +14,12 @@ import { FormikAutocomplete } from '../common/FormikAutocomplete';
import _, { get, set, values } from 'lodash';
import { DropDownListProps, JitRequest } from './structs';
import { useStyles } from './styles';
import { submitJustInTimeAccessRequest } from './utils';
import {
isEnvironmentProd,
isResourceTypeAWSCustom,
isResourceTypeDB,
submitJustInTimeAccessRequest,
} from './utils';
import { ReviewsComponent } from './ReviewsComponent';
import { RequestsComponent } from './RequestsComponent';
import {
@@ -32,6 +37,7 @@ const JustInTimeAccessPage = () => {
vertical: '',
environment: '',
resourceType: '',
resourceId: '',
resourceAction: '',
awsResourceType: '',
awsResourceNames: [''],
@@ -44,7 +50,9 @@ const JustInTimeAccessPage = () => {
const classes = useStyles();
let isResourceTypeAWSCustom = false;
let isResourceTypeAWSCustomVar = false;
let isResourceTypeDBVar = false;
let isEnvironmentProdVar = false;
let resourceActionList = Array<string>();
let resourceEnvironmentList = Array<string>();
let resourceVerticalList = Array<string>();
@@ -82,21 +90,23 @@ const JustInTimeAccessPage = () => {
const classes = useStyles();
const { values }: { values: any } = useFormikContext();
const resourceTypeField = 'resourceType';
const environmentField = 'environment';
if (typeof getIn(values, resourceTypeField) !== undefined && values[resourceTypeField] !== '') {
if (values[resourceTypeField] === 'AWS-CUSTOM') {
if (isResourceTypeAWSCustom(values[resourceTypeField])) {
resourceActionList = CUSTOM_RESOURCE_ACTION_LIST_MAP[values['awsResourceType']];
awsCustomResourceTypeList = AWS_CUSTOM_RESOURCE_TYPE;
isResourceTypeAWSCustom = true;
isResourceTypeAWSCustomVar = true;
} else {
isResourceTypeAWSCustom = false;
isResourceTypeAWSCustomVar = false;
}
resourceEnvironmentList =
values[resourceTypeField] === 'KAFKA' ? KAFKA_ENVIRONMENT_LIST : environmentList;
resourceVerticalList =
values[resourceTypeField] === 'KAFKA' ? KAFKA_VERTICAL_LIST : verticalList;
resourceActionList = RESOURCE_ACTION_MAP[values[resourceTypeField]];
// }
isResourceTypeDBVar = isResourceTypeDB(values[resourceTypeField]);
isEnvironmentProdVar = isEnvironmentProd(values[environmentField]);
}
return (
@@ -166,7 +176,14 @@ const JustInTimeAccessPage = () => {
list={resourceEnvironmentList}
style={classes.field}
/>
{isResourceTypeAWSCustom ? (
{isResourceTypeDBVar && isEnvironmentProdVar ? (
<FormikTextField
className={classes.field}
label="Database Name"
name="resourceId"
/>
) : null}
{isResourceTypeAWSCustomVar ? (
<DropDownList
label="AWS Resource Type"
fieldName="awsResourceType"
@@ -180,7 +197,7 @@ const JustInTimeAccessPage = () => {
list={resourceActionList}
style={classes.field}
/>
{isResourceTypeAWSCustom ? (
{isResourceTypeAWSCustomVar ? (
<FormikTextField
multiline
label="AWS Resource Names"

View File

@@ -1,10 +1,19 @@
import * as yup from 'yup';
import { isResourceTypeDB, isEnvironmentProd } from './utils';
export const justInTimeAccessValidationSchema = yup.object({
team: yup.string().required('is Required'),
vertical: yup.string().required('is Required'),
environment: yup.string().required('is Required'),
resourceType: yup.string().required('is Required'),
resourceId: yup.string().test('is required', 'is Required', (value, context) => {
const resourceType = context.parent.resourceType;
const environment = context.parent.environment;
if (isResourceTypeDB(resourceType) && isEnvironmentProd(environment) && !value) {
return false;
}
return true;
}),
resourceAction: yup.string().required('is Required'),
justification: yup.string().required('is Required'),
grantWindow: yup

View File

@@ -50,9 +50,18 @@ export const RequestsComponent = () => {
},
{
key: 'Requested For',
value: ({ resourceType, awsResourceType, resourceAction, awsResourceNames }: RequestsInfo) =>
value: ({
environment,
resourceType,
resourceId,
awsResourceType,
resourceAction,
awsResourceNames,
}: RequestsInfo) =>
renderResourceTypeAndAction(
environment,
resourceType,
resourceId,
awsResourceType,
resourceAction,
awsResourceNames,

View File

@@ -54,9 +54,18 @@ export const ReviewsComponent = () => {
},
{
key: 'Requested For',
value: ({ resourceType, awsResourceType, resourceAction, awsResourceNames }: ReviewsInfo) =>
value: ({
environment,
resourceType,
resourceId,
awsResourceType,
resourceAction,
awsResourceNames,
}: ReviewsInfo) =>
renderResourceTypeAndAction(
environment,
resourceType,
resourceId,
awsResourceType,
resourceAction,
awsResourceNames,

View File

@@ -10,6 +10,7 @@ export type JitRequest = {
vertical: string;
environment: string;
resourceType: string;
resourceId: string;
resourceAction: string;
awsResourceType: string;
awsResourceNames: Array<string>;
@@ -24,6 +25,7 @@ export type RequestsInfo = {
vertical: string;
environment: string;
resourceType: string;
resourceId: string;
awsResourceType: string;
awsResourceNames: Array<string>;
resourceAction: string;
@@ -41,6 +43,7 @@ export type ReviewsInfo = {
vertical: string;
environment: string;
resourceType: string;
resourceId: string;
awsResourceType: string;
awsResourceNames: Array<string>;
resourceAction: string;

View File

@@ -14,6 +14,17 @@ const delayedReload = () => {
}, RELOAD_INTERVAL);
};
enum Environment {
PROD = 'PROD',
DEV = 'DEV',
QA = 'QA',
}
enum ResourceType {
DB = 'DB',
AWS_CUSTOM = 'AWS-CUSTOM',
}
export const renderGrantDuration = (
grantAt: number,
grantWindow: number,
@@ -27,19 +38,35 @@ export const renderGrantDuration = (
);
};
export const isResourceTypeDB = (resourceType: string): boolean => {
return resourceType === ResourceType.DB;
};
export const isResourceTypeAWSCustom = (resourceType: string): boolean => {
return resourceType === ResourceType.AWS_CUSTOM;
};
export const isEnvironmentProd = (environment: string): boolean => {
return environment === Environment.PROD;
};
export const renderResourceTypeAndAction = (
environment: string,
resourceType: string,
resourceId: string,
awsResourceType: string,
resourceAction: string,
awsResourceNames: Array<string>,
classes: ClassNameMap,
): React.ReactElement => {
const message =
resourceType === 'AWS-CUSTOM'
? `${resourceType} - ${awsResourceType} with ${resourceAction} on ${awsResourceNames.join(
', ',
)}`
: `${resourceType} - ${resourceAction}`;
let message = `${resourceType} - ${resourceAction}`;
if (isResourceTypeAWSCustom(resourceType)) {
message = `${resourceType} - ${awsResourceType} with ${resourceAction} on ${awsResourceNames.join(
', ',
)}`;
} else if (isResourceTypeDB(resourceType) && isEnvironmentProd(environment)) {
message = `${resourceType} - ${resourceAction} on ${resourceId}`;
}
return (
<div className={classes.resourceTypeAndAction}>