Skip to content

Commit

Permalink
[PLAT-14668] - Move YSQL/YCQL configuration RBAC check to universe ac…
Browse files Browse the repository at this point in the history
…tions level and integrate RBAC for PG Compatibility

Summary:
  - RBAC check for EDIT YSQL/YCQL configuration was already handled in UI at the modal level but due to customer request moving check at universe actions level.
  - Integrate RBAC for PG Compatibility

Test Plan: Tested manullay

Reviewers: kkannan, sagarg

Reviewed By: kkannan

Subscribers: ui, yugaware

Differential Revision: https://phorge.dev.yugabyte.com/D36572
  • Loading branch information
Lingeshwar committed Jul 16, 2024
1 parent 3996f55 commit 6ec058d
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ import { RuntimeConfigKey, UNIVERSE_TASKS } from '../../../redesign/helpers/cons
import { isActionFrozen } from '../../../redesign/helpers/utils';
import {
getCurrentVersion,
isVerionPGSupported
isVersionPGSupported
} from '../../../redesign/features/universe/universe-form/utils/helpers';

//icons
Expand Down Expand Up @@ -504,7 +504,7 @@ class UniverseDetail extends Component {
const isDeleteUniverseDisabled =
isActionFrozen(allowedTasks, UNIVERSE_TASKS.DELETE_UNIVERSE) || isK8ActionsDisabled;

const isPGCompatibilitySupported = isVerionPGSupported(
const isPGCompatibilitySupported = isVersionPGSupported(
getCurrentVersion(currentUniverse.data.universeDetails)
);

Expand Down Expand Up @@ -1123,11 +1123,18 @@ class UniverseDetail extends Component {
<RbacValidator
accessRequiredOn={{
onResource: uuid,
...ApiPermissionMap.GET_UNIVERSES_BY_ID
...ApiPermissionMap.UPGRADE_UNIVERSE_GFLAGS
}}
isControl
>
<YBMenuItem onClick={showPGCompatibilityModal}>
<YBMenuItem
disabled={isEditGFlagsDisabled}
onClick={showPGCompatibilityModal}
availability={getFeatureState(
currentCustomer.data.features,
'universes.details.overview.editGFlags'
)}
>
<YBLabelWithIcon icon="fa fa-retweet fa-fw">
Edit Postgres Compatibility
</YBLabelWithIcon>
Expand All @@ -1138,11 +1145,18 @@ class UniverseDetail extends Component {
<RbacValidator
accessRequiredOn={{
onResource: uuid,
...ApiPermissionMap.GET_UNIVERSES_BY_ID
...ApiPermissionMap.UNIVERSE_CONFIGURE_YSQL
}}
isControl
>
<YBMenuItem disabled={isYSQLConfigDisabled} onClick={showEnableYSQLModal}>
<YBMenuItem
disabled={isYSQLConfigDisabled}
onClick={showEnableYSQLModal}
availability={getFeatureState(
currentCustomer.data.features,
'universes.details.overview.editUniverse'
)}
>
<YBLabelWithIcon icon="fa fa-database fa-fw">
Edit YSQL Configuration
</YBLabelWithIcon>
Expand All @@ -1153,11 +1167,18 @@ class UniverseDetail extends Component {
<RbacValidator
accessRequiredOn={{
onResource: uuid,
...ApiPermissionMap.GET_UNIVERSES_BY_ID
...ApiPermissionMap.UNIVERSE_CONFIGURE_YCQL
}}
isControl
>
<YBMenuItem disabled={isYCQLConfigDisabled} onClick={showEnableYCQLModal}>
<YBMenuItem
disabled={isYCQLConfigDisabled}
onClick={showEnableYCQLModal}
availability={getFeatureState(
currentCustomer.data.features,
'universes.details.overview.editUniverse'
)}
>
<YBLabelWithIcon icon="fa fa-database fa-fw">
Edit YCQL Configuration
</YBLabelWithIcon>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export const EditGflagsModal: FC<EditGflagsModalProps> = ({
if (primaryCluster && !_.isEmpty(primaryCluster)) {
const { masterGFlags, tserverGFlags } = transformFlagArrayToObject(gFlags);
primaryCluster.userIntent.specificGFlags = {
...primaryCluster.userIntent.specificGFlags,
inheritFromPrimary: false,
perProcessFlags: {
value: {
Expand All @@ -160,12 +161,14 @@ export const EditGflagsModal: FC<EditGflagsModalProps> = ({
if (asyncCluster && !_.isEmpty(asyncCluster)) {
if (inheritFlagsFromPrimary) {
asyncCluster.userIntent.specificGFlags = {
...asyncCluster.userIntent.specificGFlags,
inheritFromPrimary: true,
perProcessFlags: {}
};
} else {
const { tserverGFlags } = transformFlagArrayToObject(asyncGflags);
asyncCluster.userIntent.specificGFlags = {
...asyncCluster.userIntent.specificGFlags,
inheritFromPrimary: false,
perProcessFlags: {
value: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FC } from 'react';
import _ from 'lodash';
import { get, cloneDeep } from 'lodash';
import { toast } from 'react-toastify';
import { useForm } from 'react-hook-form';
import { useMutation } from 'react-query';
Expand All @@ -15,6 +15,9 @@ import {
import { api } from '../../universe-form/utils/api';
import { EditGflagPayload, UpgradeOptions } from '../edit-gflags/GflagHelper';
import { isPGEnabledFromIntent } from '../../universe-form/utils/helpers';
import { RBAC_ERR_MSG_NO_PERM } from '../../../rbac/common/validator/ValidatorUtils';
import { hasNecessaryPerm } from '../../../rbac/common/RbacApiPermValidator';
import { ApiPermissionMap } from '../../../rbac/ApiAndUserPermMapping';
import { Universe } from '../../universe-form/utils/dto';
import { DEFAULT_SLEEP_INTERVAL_IN_MS } from '../../universe-form/utils/constants';
import { GFLAG_GROUPS } from '../../../../helpers/constants';
Expand Down Expand Up @@ -93,11 +96,10 @@ export const EditPGCompatibilityModal: FC<PGCompatibilityModalProps> = ({
const classes = useStyles();
const { universeDetails, universeUUID } = universeData;
const { nodePrefix } = universeDetails;
let primaryCluster = _.cloneDeep(getPrimaryCluster(universeDetails));
const universeName = _.get(primaryCluster, 'userIntent.universeName');
let primaryCluster = cloneDeep(getPrimaryCluster(universeDetails));
const universeName = get(primaryCluster, 'userIntent.universeName');
const isPGEnabled = primaryCluster ? isPGEnabledFromIntent(primaryCluster?.userIntent) : false;

console.log(universeDetails);
const { control, handleSubmit, watch } = useForm<PGFormValues>({
defaultValues: {
enablePGCompatibitilty: isPGEnabled ? true : false
Expand All @@ -110,7 +112,6 @@ export const EditPGCompatibilityModal: FC<PGCompatibilityModalProps> = ({
},
{
onSuccess: () => {
toast.success('Upgrade Gflags in progress');
onClose();
},
onError: (error) => {
Expand All @@ -127,12 +128,12 @@ export const EditPGCompatibilityModal: FC<PGCompatibilityModalProps> = ({
const payload: EditGflagPayload = {
nodePrefix,
universeUUID,
sleepAfterMasterRestartMillis: _.get(
sleepAfterMasterRestartMillis: get(
universeDetails,
'sleepAfterMasterRestartMillis',
DEFAULT_SLEEP_INTERVAL_IN_MS
),
sleepAfterTServerRestartMillis: _.get(
sleepAfterTServerRestartMillis: get(
universeDetails,
'sleepAfterTServerRestartMillis',
DEFAULT_SLEEP_INTERVAL_IN_MS
Expand Down Expand Up @@ -165,6 +166,11 @@ export const EditPGCompatibilityModal: FC<PGCompatibilityModalProps> = ({
}
});

const canEditGFlags = hasNecessaryPerm({
onResource: universeUUID,
...ApiPermissionMap.UPGRADE_UNIVERSE_GFLAGS
});

return (
<YBModal
open={open}
Expand All @@ -177,6 +183,12 @@ export const EditPGCompatibilityModal: FC<PGCompatibilityModalProps> = ({
overrideWidth={'600px'}
submitTestId="EditPGCompatibilityModal-Submit"
cancelTestId="EditPGCompatibilityModal-Cancel"
buttonProps={{
primary: {
disabled: !canEditGFlags
}
}}
submitButtonTooltip={!canEditGFlags ? RBAC_ERR_MSG_NO_PERM : ''}
>
<Box
display="flex"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { FC } from 'react';
import { useUpdateEffect } from 'react-use';
import { useTranslation, Trans } from 'react-i18next';
import { Box, makeStyles, Typography, Link } from '@material-ui/core';
import { useFormContext, useWatch } from 'react-hook-form';
import { YBToggleField, YBLabel, YBTooltip } from '../../../../../../components';
import { isVerionPGSupported } from '../../../utils/helpers';
import { isVersionPGSupported } from '../../../utils/helpers';
import { UniverseFormData } from '../../../utils/dto';
import { PG_COMPATIBILITY_FIELD, SOFTWARE_VERSION_FIELD } from '../../../utils/constants';

Expand Down Expand Up @@ -39,14 +40,19 @@ const useStyles = makeStyles((theme) => ({
}));

export const PGCompatibiltyField: FC<PGCompatibiltyFieldProps> = ({ disabled }) => {
const { control } = useFormContext<UniverseFormData>();
const { control, setValue } = useFormContext<UniverseFormData>();
const classes = useStyles();
const { t } = useTranslation();

//watchers
const dbVersionValue = useWatch({ name: SOFTWARE_VERSION_FIELD });

const isPGSupported = isVerionPGSupported(dbVersionValue);
const isPGSupported = isVersionPGSupported(dbVersionValue);

useUpdateEffect(() => {
//set toggle to false if unsupported db version is selected
if (!isVersionPGSupported(dbVersionValue)) setValue(PG_COMPATIBILITY_FIELD, false);
}, [dbVersionValue]);

return (
<Box display="flex" width="100%" data-testid="PGCompatibiltyField-Container">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ export const createUniverse = async ({
//patch - end

// now everything is ready to create universe
console.log(finalPayload, 'Final');
const response = await api.createUniverse(finalPayload);

//redirect to task page
Expand Down Expand Up @@ -511,7 +510,7 @@ export const getKubernetesDiffClusterData = (
};
};

export const isVerionPGSupported = (dbVersion: string) => {
export const isVersionPGSupported = (dbVersion: string) => {
return (
compareYBSoftwareVersions({
versionA: dbVersion,
Expand Down

0 comments on commit 6ec058d

Please sign in to comment.