From f242d443ba9710eb0ff783e6ab35698c2549c79f Mon Sep 17 00:00:00 2001 From: David Date: Tue, 19 Sep 2023 10:04:53 +0200 Subject: [PATCH] B OpenNebula/one#6154: Fix error updating template (#2733) --- src/fireedge/package-lock.json | 1 + src/fireedge/package.json | 1 + .../components/Buttons/ScheduleAction.js | 183 ++++++---- .../ImageSteps/AdvancedOptions/index.js | 17 +- .../ImageSteps/AdvancedOptions/schema.js | 40 ++- .../Vm/AttachDiskForm/ImageSteps/index.js | 1 - .../VolatileSteps/AdvancedOptions/index.js | 17 +- .../VolatileSteps/AdvancedOptions/schema.js | 40 ++- .../VolatileSteps/BasicConfiguration/index.js | 17 +- .../BasicConfiguration/schema.js | 16 +- .../Vm/AttachDiskForm/VolatileSteps/index.js | 13 +- .../Steps/AdvancedOptions/schema.js | 50 ++- .../AttachNicForm/Steps/QOSOptions/schema.js | 24 +- .../Forms/Vm/AttachNicForm/Steps/index.js | 3 + .../Forms/Vm/CreateSchedActionForm/index.js | 7 +- .../Forms/Vm/CreateSchedActionForm/schema.js | 51 ++- .../Steps/ExtraConfiguration/backup/index.js | 6 +- .../Steps/ExtraConfiguration/backup/schema.js | 15 +- .../Steps/ExtraConfiguration/booting/index.js | 9 +- .../ExtraConfiguration/booting/schema.js | 40 ++- .../context/configurationSection.js | 24 +- .../context/filesSection.js | 19 +- .../Steps/ExtraConfiguration/context/index.js | 6 +- .../context/userInputsSection.js | 23 +- .../Steps/ExtraConfiguration/index.js | 21 +- .../inputOutput/graphicsSchema.js | 25 +- .../ExtraConfiguration/inputOutput/index.js | 20 +- .../inputOutput/inputsSchema.js | 12 +- .../inputOutput/inputsSection.js | 36 +- .../inputOutput/pciDevicesSchema.js | 16 +- .../inputOutput/pciDevicesSection.js | 34 +- .../ExtraConfiguration/networking/index.js | 10 +- .../Steps/ExtraConfiguration/numa/index.js | 17 +- .../ExtraConfiguration/placement/index.js | 6 +- .../ExtraConfiguration/placement/schema.js | 18 +- .../ExtraConfiguration/scheduleAction.js | 22 +- .../Steps/ExtraConfiguration/storage/index.js | 10 +- .../CreateForm/Steps/General/index.js | 10 +- .../CreateForm/Steps/General/schema.js | 79 ++++- .../Steps/BasicConfiguration/index.js | 10 +- .../Steps/BasicConfiguration/schema.js | 44 ++- .../Steps/ExtraConfiguration/index.js | 20 +- .../VmTemplate/InstantiateForm/Steps/index.js | 21 +- .../components/Tabs/Vm/Network/Actions.js | 97 +++-- .../components/Tabs/Vm/Storage/Actions.js | 221 ++++++------ .../src/client/constants/translates.js | 2 + .../client/containers/VmTemplates/Create.js | 83 ++++- .../containers/VmTemplates/Instantiate.js | 65 +++- src/fireedge/src/client/utils/index.js | 1 + .../src/client/utils/restrictedAttributes.js | 330 ++++++++++++++++++ src/fireedge/src/client/utils/schema.js | 43 +++ 51 files changed, 1479 insertions(+), 417 deletions(-) create mode 100644 src/fireedge/src/client/utils/restrictedAttributes.js diff --git a/src/fireedge/package-lock.json b/src/fireedge/package-lock.json index 62a62d7c92..2af1524712 100644 --- a/src/fireedge/package-lock.json +++ b/src/fireedge/package-lock.json @@ -67,6 +67,7 @@ "jsonwebtoken": "8.5.1", "jwt-simple": "0.5.6", "lockfile": "1.0.4", + "lodash": "4.17.21", "lodash.get": "4.4.2", "luxon": "2.1.1", "marked": "4.0.10", diff --git a/src/fireedge/package.json b/src/fireedge/package.json index 5ab491e233..493419c4d8 100644 --- a/src/fireedge/package.json +++ b/src/fireedge/package.json @@ -101,6 +101,7 @@ "jsonwebtoken": "8.5.1", "jwt-simple": "0.5.6", "lockfile": "1.0.4", + "lodash": "4.17.21", "lodash.get": "4.4.2", "luxon": "2.1.1", "marked": "4.0.10", diff --git a/src/fireedge/src/client/components/Buttons/ScheduleAction.js b/src/fireedge/src/client/components/Buttons/ScheduleAction.js index 658f72a594..da72fde712 100644 --- a/src/fireedge/src/client/components/Buttons/ScheduleAction.js +++ b/src/fireedge/src/client/components/Buttons/ScheduleAction.js @@ -33,7 +33,7 @@ import { VM_ACTIONS, VM_ACTIONS_IN_CHARTER, } from 'client/constants' -import { sentenceCase } from 'client/utils' +import { sentenceCase, hasRestrictedAttributes } from 'client/utils' /** * Returns a button to trigger form to create a scheduled action. @@ -44,30 +44,36 @@ import { sentenceCase } from 'client/utils' * @param {function():Promise} props.onSubmit - Submit function * @returns {ReactElement} Button */ -const CreateSchedButton = memo(({ vm, relative, onSubmit }) => ( - ( + + relative + ? CreateRelativeSchedActionForm({ + stepProps: { vm, oneConfig, adminGroup }, + }) + : CreateSchedActionForm({ + stepProps: { vm, oneConfig, adminGroup }, + }), + onSubmit, }, - form: () => - relative - ? CreateRelativeSchedActionForm({ stepProps: vm }) - : CreateSchedActionForm({ stepProps: vm }), - onSubmit, - }, - ]} - /> -)) + ]} + /> + ) +) /** * Returns a button to trigger form to update a scheduled action. @@ -79,36 +85,44 @@ const CreateSchedButton = memo(({ vm, relative, onSubmit }) => ( * @param {function():Promise} props.onSubmit - Submit function * @returns {ReactElement} Button */ -const UpdateSchedButton = memo(({ vm, schedule, relative, onSubmit }) => { - const { ID, ACTION } = schedule - const titleAction = `#${ID} ${sentenceCase(ACTION)}` - const formConfig = { stepProps: vm, initialValues: schedule } +const UpdateSchedButton = memo( + ({ vm, schedule, relative, onSubmit, oneConfig, adminGroup }) => { + const { ID, ACTION } = schedule + const titleAction = `#${ID} ${sentenceCase(ACTION)}` + const formConfig = { + stepProps: { vm, oneConfig, adminGroup }, + initialValues: schedule, + } - return ( - , - tooltip: , - }} - options={[ - { - dialogProps: { - title: ( - - ), - dataCy: 'modal-sched-actions', + return ( + , + tooltip: , + }} + options={[ + { + dialogProps: { + title: ( + + ), + dataCy: 'modal-sched-actions', + }, + form: () => + relative + ? CreateRelativeSchedActionForm(formConfig) + : CreateSchedActionForm(formConfig), + onSubmit, }, - form: () => - relative - ? CreateRelativeSchedActionForm(formConfig) - : CreateSchedActionForm(formConfig), - onSubmit, - }, - ]} - /> - ) -}) + ]} + /> + ) + } +) /** * Returns a button to trigger modal to delete a scheduled action. @@ -118,32 +132,47 @@ const UpdateSchedButton = memo(({ vm, schedule, relative, onSubmit }) => { * @param {function():Promise} props.onSubmit - Submit function * @returns {ReactElement} Button */ -const DeleteSchedButton = memo(({ onSubmit, schedule }) => { - const { ID, ACTION } = schedule - const titleAction = `#${ID} ${sentenceCase(ACTION)}` +const DeleteSchedButton = memo( + ({ onSubmit, schedule, oneConfig, adminGroup }) => { + const { ID, ACTION } = schedule + const titleAction = `#${ID} ${sentenceCase(ACTION)}` - return ( - , - tooltip: , - }} - options={[ - { - isConfirmDialog: true, - dialogProps: { - title: ( - - ), - children:

{Tr(T.DoYouWantProceed)}

, + // Disable action if the nic has a restricted attribute on the template + const disabledAction = + !adminGroup && + hasRestrictedAttributes( + schedule, + 'SCHED_ACTION', + oneConfig?.VM_RESTRICTED_ATTR + ) + + return ( + , + tooltip: !disabledAction ? Tr(T.Delete) : Tr(T.DetachRestricted), + disabled: disabledAction, + }} + options={[ + { + isConfirmDialog: true, + dialogProps: { + title: ( + + ), + children:

{Tr(T.DoYouWantProceed)}

, + }, + onSubmit, }, - onSubmit, - }, - ]} - /> - ) -}) + ]} + /> + ) + } +) /** * Returns a button to trigger form to create a charter. @@ -195,6 +224,8 @@ const ButtonPropTypes = { relative: PropTypes.bool, onSubmit: PropTypes.func, schedule: PropTypes.object, + oneConfig: PropTypes.object, + adminGroup: PropTypes.bool, } CreateSchedButton.propTypes = ButtonPropTypes diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/AdvancedOptions/index.js b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/AdvancedOptions/index.js index a40c7a1713..b7eb763970 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/AdvancedOptions/index.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/AdvancedOptions/index.js @@ -27,8 +27,11 @@ import { T, HYPERVISORS } from 'client/constants' export const STEP_ID = 'advanced' -const Content = ({ hypervisor }) => { - const sections = useMemo(() => SECTIONS(hypervisor), []) +const Content = ({ hypervisor, oneConfig, adminGroup }) => { + const sections = useMemo( + () => SECTIONS(hypervisor, oneConfig, adminGroup), + [] + ) return ( { * * @param {object} props - Props * @param {HYPERVISORS} props.hypervisor - Hypervisor + * @param {object} props.oneConfig - Config of oned.conf + * @param {boolean} props.adminGroup - User is admin or not * @returns {Step} Advance options step */ -const AdvancedOptions = ({ hypervisor } = {}) => ({ +const AdvancedOptions = ({ hypervisor, oneConfig, adminGroup } = {}) => ({ id: STEP_ID, label: T.AdvancedOptions, - resolver: SCHEMA(hypervisor), + resolver: SCHEMA(hypervisor, oneConfig, adminGroup), optionsValidate: { abortEarly: false }, - content: () => Content({ hypervisor }), + content: () => Content({ hypervisor, oneConfig, adminGroup }), }) Content.propTypes = { hypervisor: PropTypes.any, data: PropTypes.any, setFormData: PropTypes.func, + oneConfig: PropTypes.object, + adminGroup: PropTypes.bool, } export default AdvancedOptions diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/AdvancedOptions/schema.js b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/AdvancedOptions/schema.js index 9138d47996..e0c49be55a 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/AdvancedOptions/schema.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/AdvancedOptions/schema.js @@ -28,6 +28,7 @@ import { Section, getObjectSchemaFromFields, filterFieldsByHypervisor, + disableFields, } from 'client/utils' const { vcenter } = HYPERVISORS @@ -47,33 +48,60 @@ const SIZE = { /** * @param {HYPERVISORS} hypervisor - Hypervisor + * @param {object} oneConfig - Config of oned.conf + * @param {boolean} adminGroup - User is admin or not * @returns {Section[]} Sections */ -const SECTIONS = (hypervisor) => [ +const SECTIONS = (hypervisor, oneConfig, adminGroup) => [ { id: 'general', legend: T.General, - fields: filterFieldsByHypervisor([SIZE, ...GENERAL_FIELDS], hypervisor), + fields: disableFields( + filterFieldsByHypervisor([SIZE, ...GENERAL_FIELDS], hypervisor), + 'DISK', + oneConfig, + adminGroup + ), }, { id: 'vcenter', legend: 'vCenter', - fields: filterFieldsByHypervisor(VCENTER_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(VCENTER_FIELDS, hypervisor), + 'DISK', + oneConfig, + adminGroup + ), }, { id: 'throttling-bytes', legend: T.ThrottlingBytes, - fields: filterFieldsByHypervisor(THROTTLING_BYTES_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(THROTTLING_BYTES_FIELDS, hypervisor), + 'DISK', + oneConfig, + adminGroup + ), }, { id: 'throttling-iops', legend: T.ThrottlingIOPS, - fields: filterFieldsByHypervisor(THROTTLING_IOPS_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(THROTTLING_IOPS_FIELDS, hypervisor), + 'DISK', + oneConfig, + adminGroup + ), }, { id: 'edge-cluster', legend: T.EdgeCluster, - fields: filterFieldsByHypervisor(EDGE_CLUSTER_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(EDGE_CLUSTER_FIELDS, hypervisor), + 'DISK', + oneConfig, + adminGroup + ), }, ] diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/index.js b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/index.js index 48b9e97482..d2168bd75b 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/index.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/ImageSteps/index.js @@ -58,7 +58,6 @@ const Steps = createSteps([ImagesTable, AdvancedOptions], { IMAGE_UID: UID, IMAGE_UNAME: UNAME, IMAGE_STATE: STATE, - ORIGINAL_SIZE: SIZE, } }, }) diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/AdvancedOptions/index.js b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/AdvancedOptions/index.js index 2b6e692c39..0330dca1cd 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/AdvancedOptions/index.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/AdvancedOptions/index.js @@ -27,8 +27,11 @@ import { T, HYPERVISORS } from 'client/constants' export const STEP_ID = 'advanced' -const Content = ({ hypervisor }) => { - const sections = useMemo(() => SECTIONS(hypervisor), []) +const Content = ({ hypervisor, oneConfig, adminGroup }) => { + const sections = useMemo( + () => SECTIONS(hypervisor, oneConfig, adminGroup), + [] + ) return ( { * * @param {object} props - Props * @param {HYPERVISORS} props.hypervisor - Hypervisor + * @param {object} props.oneConfig - Config of oned.conf + * @param {boolean} props.adminGroup - User is admin or not * @returns {Step} Advance options step */ -const AdvancedOptions = ({ hypervisor } = {}) => ({ +const AdvancedOptions = ({ hypervisor, oneConfig, adminGroup } = {}) => ({ id: STEP_ID, label: T.AdvancedOptions, - resolver: SCHEMA(hypervisor), + resolver: SCHEMA(hypervisor, oneConfig, adminGroup), optionsValidate: { abortEarly: false }, - content: () => Content({ hypervisor }), + content: () => Content({ hypervisor, oneConfig, adminGroup }), }) Content.propTypes = { hypervisor: PropTypes.any, data: PropTypes.any, setFormData: PropTypes.func, + oneConfig: PropTypes.object, + adminGroup: PropTypes.bool, } export default AdvancedOptions diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/AdvancedOptions/schema.js b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/AdvancedOptions/schema.js index 3a0d57f3d8..ce2e53ba30 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/AdvancedOptions/schema.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/AdvancedOptions/schema.js @@ -28,37 +28,65 @@ import { Section, getObjectSchemaFromFields, filterFieldsByHypervisor, + disableFields, } from 'client/utils' /** * @param {HYPERVISORS} hypervisor - Hypervisor + * @param {object} oneConfig - Config of oned.conf + * @param {boolean} adminGroup - User is admin or not * @returns {Section[]} Sections */ -const SECTIONS = (hypervisor) => [ +const SECTIONS = (hypervisor, oneConfig, adminGroup) => [ { id: 'general', legend: T.General, - fields: filterFieldsByHypervisor(GENERAL_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(GENERAL_FIELDS, hypervisor), + 'DISK', + oneConfig, + adminGroup + ), }, { id: 'vcenter', legend: 'vCenter', - fields: filterFieldsByHypervisor(VCENTER_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(VCENTER_FIELDS, hypervisor), + 'DISK', + oneConfig, + adminGroup + ), }, { id: 'throttling-bytes', legend: T.ThrottlingBytes, - fields: filterFieldsByHypervisor(THROTTLING_BYTES_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(THROTTLING_BYTES_FIELDS, hypervisor), + 'DISK', + oneConfig, + adminGroup + ), }, { id: 'throttling-iops', legend: T.ThrottlingIOPS, - fields: filterFieldsByHypervisor(THROTTLING_IOPS_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(THROTTLING_IOPS_FIELDS, hypervisor), + 'DISK', + oneConfig, + adminGroup + ), }, { id: 'edge-cluster', legend: T.EdgeCluster, - fields: filterFieldsByHypervisor(EDGE_CLUSTER_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(EDGE_CLUSTER_FIELDS, hypervisor), + 'DISK', + oneConfig, + adminGroup + ), }, ] diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/BasicConfiguration/index.js b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/BasicConfiguration/index.js index 56a05bc4a3..4cecb990cb 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/BasicConfiguration/index.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/BasicConfiguration/index.js @@ -26,8 +26,11 @@ import { T, HYPERVISORS } from 'client/constants' export const STEP_ID = 'configuration' -const Content = ({ hypervisor }) => { - const memoFields = useMemo(() => FIELDS(hypervisor), []) +const Content = ({ hypervisor, oneConfig, adminGroup }) => { + const memoFields = useMemo( + () => FIELDS(hypervisor, oneConfig, adminGroup), + [] + ) return } @@ -37,20 +40,24 @@ const Content = ({ hypervisor }) => { * * @param {object} props - Props * @param {HYPERVISORS} props.hypervisor - Hypervisor + * @param {object} props.oneConfig - Config of oned.conf + * @param {boolean} props.adminGroup - User is admin or not * @returns {Step} Basic configuration step */ -const BasicConfiguration = ({ hypervisor } = {}) => ({ +const BasicConfiguration = ({ hypervisor, oneConfig, adminGroup } = {}) => ({ id: STEP_ID, label: T.Configuration, - resolver: SCHEMA(hypervisor), + resolver: SCHEMA(hypervisor, oneConfig, adminGroup), optionsValidate: { abortEarly: false }, - content: () => Content({ hypervisor }), + content: () => Content({ hypervisor, oneConfig, adminGroup }), }) Content.propTypes = { hypervisor: PropTypes.any, data: PropTypes.any, setFormData: PropTypes.func, + oneConfig: PropTypes.object, + adminGroup: PropTypes.bool, } export default BasicConfiguration diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/BasicConfiguration/schema.js b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/BasicConfiguration/schema.js index 2a5a9a3bd7..4e1f567cc4 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/BasicConfiguration/schema.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/BasicConfiguration/schema.js @@ -20,6 +20,7 @@ import { getValidationFromFields, filterFieldsByHypervisor, arrayToOptions, + disableFields, } from 'client/utils' import { T, @@ -120,12 +121,19 @@ const FILESYSTEM = { /** * @param {HYPERVISORS} hypervisor - hypervisor + * @param {object} oneConfig - Config of oned.conf + * @param {boolean} adminGroup - User is admin or not * @returns {Field[]} List of fields */ -export const FIELDS = (hypervisor) => - filterFieldsByHypervisor( - [SIZE, SIZEUNIT, TYPE, FORMAT, FILESYSTEM], - hypervisor +export const FIELDS = (hypervisor, oneConfig, adminGroup) => + disableFields( + filterFieldsByHypervisor( + [SIZE, SIZEUNIT, TYPE, FORMAT, FILESYSTEM], + hypervisor + ), + 'DISK', + oneConfig, + adminGroup ) /** diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/index.js b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/index.js index daecb8a0d6..be47ebbd0d 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/index.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachDiskForm/VolatileSteps/index.js @@ -22,15 +22,20 @@ import AdvancedOptions, { import { mapUserInputs, createSteps, convertToMB } from 'client/utils' const Steps = createSteps([BasicConfiguration, AdvancedOptions], { - transformInitialValue: (disk = {}, schema) => ({ - ...schema.cast( + transformInitialValue: (disk = {}, schema) => { + const schemaCast = schema.cast( { [BASIC_ID]: disk, [ADVANCED_ID]: disk, }, { stripUnknown: true } - ), - }), + ) + + // #6154: Add temp id to propagate it + schemaCast[ADVANCED_ID].TEMP_ID = disk.TEMP_ID + + return schemaCast + }, transformBeforeSubmit: (formData) => { const { [BASIC_ID]: configuration = {}, [ADVANCED_ID]: advanced = {} } = formData ?? {} diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/AdvancedOptions/schema.js b/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/AdvancedOptions/schema.js index 7bbc579912..d2567f549f 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/AdvancedOptions/schema.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/AdvancedOptions/schema.js @@ -22,6 +22,7 @@ import { filterFieldsByDriver, getObjectSchemaFromFields, arrayToOptions, + disableFields, } from 'client/utils' import { T, @@ -40,8 +41,6 @@ import { transformPciToString, } from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/inputOutput/pciDevicesSchema' -import { useDisableInputByUserAndConfig } from 'client/features/Auth' - const { vcenter, firecracker, lxc } = HYPERVISORS const PCI_TYPE_NAME = 'PCI_TYPE' const DEVICE_LIST = 'DEVICE_LIST' @@ -283,7 +282,6 @@ const OVERRIDE_IPV4_FIELDS = [ label: T.MAC, tooltip: T.MACConcept, type: INPUT_TYPES.TEXT, - fieldProps: () => useDisableInputByUserAndConfig('NIC/MAC'), validation: string() .trim() .notRequired() @@ -589,6 +587,8 @@ const GUEST_FIELDS = [ * @param {VN_DRIVERS} [data.driver] - Virtual network driver * @param {HYPERVISORS} [data.hypervisor] - VM Hypervisor * @param {object} data.defaultData - VM or VM Template data + * @param {object} data.oneConfig - Config of oned.conf + * @param {boolean} data.adminGroup - User is admin or not * @returns {Section[]} Sections */ const SECTIONS = ({ @@ -596,6 +596,8 @@ const SECTIONS = ({ driver, hypervisor = HYPERVISORS.kvm, defaultData, + oneConfig, + adminGroup, } = {}) => { const filters = { driver, hypervisor } @@ -606,7 +608,12 @@ const SECTIONS = ({ { id: 'general', legend: T.General, - fields: filterByHypAndDriver(GENERAL_FIELDS({ nics }), filters), + fields: disableFields( + filterByHypAndDriver(GENERAL_FIELDS({ nics }), filters), + 'NIC', + oneConfig, + adminGroup + ), }, ] } @@ -615,27 +622,52 @@ const SECTIONS = ({ { id: 'guacamole-connections', legend: T.GuacamoleConnections, - fields: filterByHypAndDriver(GUACAMOLE_CONNECTIONS, filters), + fields: disableFields( + filterByHypAndDriver(GUACAMOLE_CONNECTIONS, filters), + 'NIC', + oneConfig, + adminGroup + ), }, { id: 'override-ipv4', legend: T.OverrideNetworkValuesIPv4, - fields: filterByHypAndDriver(OVERRIDE_IPV4_FIELDS, filters), + fields: disableFields( + filterByHypAndDriver(OVERRIDE_IPV4_FIELDS, filters), + 'NIC', + oneConfig, + adminGroup + ), }, { id: 'override-ipv6', legend: T.OverrideNetworkValuesIPv6, - fields: filterByHypAndDriver(OVERRIDE_IPV6_FIELDS, filters), + fields: disableFields( + filterByHypAndDriver(OVERRIDE_IPV6_FIELDS, filters), + 'NIC', + oneConfig, + adminGroup + ), }, { id: 'hardware', legend: T.Hardware, - fields: filterByHypAndDriver(HARDWARE_FIELDS(defaultData), filters), + fields: disableFields( + filterByHypAndDriver(HARDWARE_FIELDS(defaultData), filters), + 'NIC', + oneConfig, + adminGroup + ), }, { id: 'guest', legend: T.GuestOptions, - fields: filterByHypAndDriver(GUEST_FIELDS, filters), + fields: disableFields( + filterByHypAndDriver(GUEST_FIELDS, filters), + 'NIC', + oneConfig, + adminGroup + ), }, ]) } diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/QOSOptions/schema.js b/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/QOSOptions/schema.js index e6cbd47a07..cceaf1172c 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/QOSOptions/schema.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/QOSOptions/schema.js @@ -21,6 +21,7 @@ import { filterFieldsByHypervisor, filterFieldsByDriver, getObjectSchemaFromFields, + disableFields, } from 'client/utils' import { T, INPUT_TYPES, HYPERVISORS, VN_DRIVERS } from 'client/constants' @@ -112,21 +113,38 @@ const OVERRIDE_OUT_QOS_FIELDS = [ * @param {object} data - VM or VM Template data * @param {VN_DRIVERS} [data.driver] - Virtual network driver * @param {HYPERVISORS} [data.hypervisor] - VM Hypervisor + * @param {object} data.oneConfig - Config of oned.conf + * @param {boolean} data.adminGroup - User is admin or not * @returns {Section[]} Sections */ -const SECTIONS = ({ driver, hypervisor = HYPERVISORS.kvm } = {}) => { +const SECTIONS = ({ + driver, + hypervisor = HYPERVISORS.kvm, + oneConfig, + adminGroup, +} = {}) => { const filters = { driver, hypervisor } return [ { id: 'override-in-qos', legend: T.OverrideNetworkInboundTrafficQos, - fields: filterByHypAndDriver(OVERRIDE_IN_QOS_FIELDS, filters), + fields: disableFields( + filterByHypAndDriver(OVERRIDE_IN_QOS_FIELDS, filters), + 'NIC', + oneConfig, + adminGroup + ), }, { id: 'override-out-qos', legend: T.OverrideNetworkOutboundTrafficQos, - fields: filterByHypAndDriver(OVERRIDE_OUT_QOS_FIELDS, filters), + fields: disableFields( + filterByHypAndDriver(OVERRIDE_OUT_QOS_FIELDS, filters), + 'NIC', + oneConfig, + adminGroup + ), }, ] } diff --git a/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/index.js b/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/index.js index 936378f53e..a025ca2687 100644 --- a/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/index.js +++ b/src/fireedge/src/client/components/Forms/Vm/AttachNicForm/Steps/index.js @@ -60,6 +60,9 @@ const Steps = createSteps([NetworksTable, AdvancedOptions, QOSOptions], { { stripUnknown: true } ) + // #6154: Add temp id to propagate it + if (rest.TEMP_ID) castedValue[ADVANCED_ID].TEMP_ID = rest.TEMP_ID + return { [NETWORK_ID]: [ { diff --git a/src/fireedge/src/client/components/Forms/Vm/CreateSchedActionForm/index.js b/src/fireedge/src/client/components/Forms/Vm/CreateSchedActionForm/index.js index cc119a6f4f..f9c91fe571 100644 --- a/src/fireedge/src/client/components/Forms/Vm/CreateSchedActionForm/index.js +++ b/src/fireedge/src/client/components/Forms/Vm/CreateSchedActionForm/index.js @@ -49,10 +49,15 @@ const commonTransformInitialValue = (scheduledAction, schema, typeForm) => { } } - return schema.cast(dataToCast, { + const castSchema = schema.cast(dataToCast, { context: scheduledAction, stripUnknown: true, }) + + // #6154: Add temportal id for restricted attributes + castSchema.TEMP_ID = scheduledAction.TEMP_ID + + return castSchema } const commonTransformBeforeSubmit = (formData) => { diff --git a/src/fireedge/src/client/components/Forms/Vm/CreateSchedActionForm/schema.js b/src/fireedge/src/client/components/Forms/Vm/CreateSchedActionForm/schema.js index 87d41fae1c..feaf55f240 100644 --- a/src/fireedge/src/client/components/Forms/Vm/CreateSchedActionForm/schema.js +++ b/src/fireedge/src/client/components/Forms/Vm/CreateSchedActionForm/schema.js @@ -23,7 +23,7 @@ import { } from 'client/components/Forms/Vm/CreateSchedActionForm/fields' import { ARGS_TYPES } from 'client/constants' import { getRequiredArgsByAction } from 'client/models/Scheduler' -import { Field, getObjectSchemaFromFields } from 'client/utils' +import { Field, getObjectSchemaFromFields, disableFields } from 'client/utils' const ARG_SCHEMA = string() .trim() @@ -66,16 +66,25 @@ const COMMON_SCHEMA = object({ }) /** - * @param {object} vm - Vm resource + * @param {object} props - Props + * @param {object} props.vm - Vm resource + * @param {object} props.oneConfig - Config of oned.conf + * @param {boolean} props.adminGroup - User is admin or not * @returns {Field[]} Fields */ -export const VM_SCHED_FIELDS = (vm) => [ - PUNCTUAL_FIELDS.ACTION_FIELD(vm), - ...COMMON_FIELDS(vm, true), - PUNCTUAL_FIELDS.TIME_FIELD, - PUNCTUAL_FIELDS.END_TYPE_FIELD, - PUNCTUAL_FIELDS.END_VALUE_FIELD, -] +export const VM_SCHED_FIELDS = ({ vm, oneConfig, adminGroup }) => + disableFields( + [ + PUNCTUAL_FIELDS.ACTION_FIELD(vm), + ...COMMON_FIELDS(vm, true), + PUNCTUAL_FIELDS.TIME_FIELD, + PUNCTUAL_FIELDS.END_TYPE_FIELD, + PUNCTUAL_FIELDS.END_VALUE_FIELD, + ], + 'SCHED_ACTION', + oneConfig, + adminGroup + ) /** @type {ObjectSchema} Schema */ export const VM_SCHED_SCHEMA = COMMON_SCHEMA.concat( @@ -94,15 +103,21 @@ export const VM_SCHED_SCHEMA = COMMON_SCHEMA.concat( ) /** @type {Field[]} Fields for relative actions */ -export const TEMPLATE_SCHED_FIELDS = (vm) => [ - PUNCTUAL_FIELDS.ACTION_FIELD(vm), - ...COMMON_FIELDS(vm), - PUNCTUAL_FIELDS.TIME_FIELD, - RELATIVE_FIELDS.RELATIVE_TIME_FIELD, - RELATIVE_FIELDS.PERIOD_FIELD, - RELATIVE_FIELDS.END_TYPE_FIELD_WITHOUT_DATE, - PUNCTUAL_FIELDS.END_VALUE_FIELD, -] +export const TEMPLATE_SCHED_FIELDS = ({ vm, oneConfig, adminGroup }) => + disableFields( + [ + PUNCTUAL_FIELDS.ACTION_FIELD(vm), + ...COMMON_FIELDS(vm), + PUNCTUAL_FIELDS.TIME_FIELD, + RELATIVE_FIELDS.RELATIVE_TIME_FIELD, + RELATIVE_FIELDS.PERIOD_FIELD, + RELATIVE_FIELDS.END_TYPE_FIELD_WITHOUT_DATE, + PUNCTUAL_FIELDS.END_VALUE_FIELD, + ], + 'SCHED_ACTION', + oneConfig, + adminGroup + ) /** @type {ObjectSchema} Relative Schema */ export const TEMPLATE_SCHED_SCHEMA = COMMON_SCHEMA.concat( diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/index.js b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/index.js index 0b0d3c6bf8..070c451b4a 100644 --- a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/index.js +++ b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/index.js @@ -28,9 +28,9 @@ import { } from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/schema' import { T } from 'client/constants' -const Backup = () => ( +const Backup = ({ oneConfig, adminGroup }) => ( <> - {SECTIONS.map(({ id, ...section }) => ( + {SECTIONS(oneConfig, adminGroup).map(({ id, ...section }) => ( ( Backup.propTypes = { data: PropTypes.any, setFormData: PropTypes.func, + oneConfig: PropTypes.object, + adminGroup: PropTypes.bool, } Backup.displayName = 'Backup' diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/schema.js b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/schema.js index eb7879c596..1fa1aae5c9 100644 --- a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/schema.js +++ b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/backup/schema.js @@ -20,6 +20,7 @@ import { Section, arrayToOptions, getObjectSchemaFromFields, + disableFields, } from 'client/utils' import { T, @@ -80,15 +81,15 @@ const MODE_FIELD = { } /** @type {Section[]} Sections */ -export const SECTIONS = [ +export const SECTIONS = (oneConfig, adminGroup) => [ { id: 'backup-configuration', - fields: [ - BACKUP_VOLATILE_FIELD, - FS_FREEZE_FIELD, - KEEP_LAST_FIELD, - MODE_FIELD, - ], + fields: disableFields( + [BACKUP_VOLATILE_FIELD, FS_FREEZE_FIELD, KEEP_LAST_FIELD, MODE_FIELD], + 'BACKUP_CONFIG', + oneConfig, + adminGroup + ), }, ] diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/booting/index.js b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/booting/index.js index c22e02cbb6..ad39d57a81 100644 --- a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/booting/index.js +++ b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/booting/index.js @@ -37,8 +37,11 @@ import { T } from 'client/constants' export const TAB_ID = 'OS' -const Booting = ({ hypervisor, ...props }) => { - const sections = useMemo(() => SECTIONS(hypervisor), [hypervisor]) +const Booting = ({ hypervisor, oneConfig, adminGroup, ...props }) => { + const sections = useMemo( + () => SECTIONS(hypervisor, oneConfig, adminGroup), + [hypervisor] + ) return ( [ +const SECTIONS = (hypervisor, oneConfig, adminGroup) => [ { id: 'os-boot', legend: T.Boot, - fields: filterFieldsByHypervisor(BOOT_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(BOOT_FIELDS, hypervisor), + 'OS', + oneConfig, + adminGroup + ), }, { id: 'os-features', legend: T.Features, - fields: filterFieldsByHypervisor(FEATURES_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(FEATURES_FIELDS, hypervisor), + 'OS', + oneConfig, + adminGroup + ), }, { id: 'os-kernel', legend: T.Kernel, - fields: filterFieldsByHypervisor(KERNEL_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(KERNEL_FIELDS, hypervisor), + 'OS', + oneConfig, + adminGroup + ), }, { id: 'os-ramdisk', legend: T.Ramdisk, - fields: filterFieldsByHypervisor(RAMDISK_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(RAMDISK_FIELDS, hypervisor), + 'OS', + oneConfig, + adminGroup + ), }, { id: 'os-raw', legend: T.RawData, legendTooltip: T.RawDataConcept, - fields: filterFieldsByHypervisor(RAW_FIELDS, hypervisor), + fields: disableFields( + filterFieldsByHypervisor(RAW_FIELDS, hypervisor), + 'OS', + oneConfig, + adminGroup + ), }, ] diff --git a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/context/configurationSection.js b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/context/configurationSection.js index 02828af2bd..ef4ff16c41 100644 --- a/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/context/configurationSection.js +++ b/src/fireedge/src/client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/context/configurationSection.js @@ -22,6 +22,8 @@ import { FormWithSchema, Legend } from 'client/components/Forms' import { SSH_PUBLIC_KEY, SCRIPT_FIELDS, OTHER_FIELDS } from './schema' import { T } from 'client/constants' +import { disableFields } from 'client/utils' + const SSH_KEY_USER = '$USER[SSH_PUBLIC_KEY]' /** @@ -29,9 +31,11 @@ const SSH_KEY_USER = '$USER[SSH_PUBLIC_KEY]' * * @param {object} props - Props passed to the component * @param {string} [props.stepId] - ID of the step the section belongs to + * @param {object} props.oneConfig - Config of oned.conf + * @param {boolean} props.adminGroup - User is admin or not * @returns {ReactElement} - Configuration section */ -const ConfigurationSection = ({ stepId }) => { +const ConfigurationSection = ({ stepId, oneConfig, adminGroup }) => { const { setValue, getValues } = useFormContext() const SSH_PUBLIC_KEY_PATH = useMemo( () => [stepId, SSH_PUBLIC_KEY.name].filter(Boolean).join('.'), @@ -66,13 +70,18 @@ const ConfigurationSection = ({ stepId }) => {