mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-16 22:50:10 +03:00
M #-: Schedule actions tab on services. Perform action on role. (#3206)
Signed-off-by: dcarracedo <dcarracedo@opennebula.io>
This commit is contained in:
parent
92541b6da6
commit
5dff9383fa
@ -53,13 +53,14 @@ info-tabs:
|
||||
log:
|
||||
enabled: true
|
||||
|
||||
scheduler_actions:
|
||||
sched_actions:
|
||||
enabled: true
|
||||
actions:
|
||||
sched_action_create: true
|
||||
sched_action_update: true
|
||||
sched_action_delete: true
|
||||
sched-add: true
|
||||
sched-update: false
|
||||
sched-delete: false
|
||||
charter_create: true
|
||||
perform_action: true
|
||||
|
||||
# Dialogs
|
||||
|
||||
|
@ -54,13 +54,14 @@ info-tabs:
|
||||
log:
|
||||
enabled: true
|
||||
|
||||
scheduler_actions:
|
||||
enabled: false
|
||||
sched_actions:
|
||||
enabled: true
|
||||
actions:
|
||||
sched_action_create: false
|
||||
sched_action_update: false
|
||||
sched_action_delete: false
|
||||
charter_create: false
|
||||
sched-add: true
|
||||
sched-update: false
|
||||
sched-delete: false
|
||||
charter_create: true
|
||||
perform_action: true
|
||||
|
||||
# Dialogs
|
||||
|
||||
|
@ -54,13 +54,14 @@ info-tabs:
|
||||
log:
|
||||
enabled: true
|
||||
|
||||
scheduler_actions:
|
||||
sched_actions:
|
||||
enabled: true
|
||||
actions:
|
||||
sched_action_create: true
|
||||
sched_action_update: true
|
||||
sched_action_delete: true
|
||||
sched-add: true
|
||||
sched-update: false
|
||||
sched-delete: false
|
||||
charter_create: true
|
||||
perform_action: true
|
||||
|
||||
# Dialogs
|
||||
|
||||
|
@ -26,6 +26,8 @@ import {
|
||||
CreateSchedActionForm,
|
||||
} from 'client/components/Forms/Vm'
|
||||
|
||||
import { CreatePerformAction } from 'client/components/Forms/Service'
|
||||
|
||||
import { Tr, Translate } from 'client/components/HOC'
|
||||
import {
|
||||
SERVER_CONFIG,
|
||||
@ -226,6 +228,45 @@ const CharterButton = memo(({ relative, onSubmit }) => {
|
||||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* Returns a button to trigger form to perform an action.
|
||||
*
|
||||
* @param {object} props - Props
|
||||
* @param {object} props.service - Service resource
|
||||
* @param {boolean} [props.relative] - Applies to the form relative format
|
||||
* @param {function():Promise} props.onSubmit - Submit function
|
||||
* @returns {ReactElement} Button
|
||||
*/
|
||||
const PerformActionButton = memo(
|
||||
({ service, onSubmit, oneConfig, adminGroup, roles }) => {
|
||||
const formConfig = {
|
||||
stepProps: { service, oneConfig, adminGroup, roles },
|
||||
}
|
||||
|
||||
return (
|
||||
<ButtonToTriggerForm
|
||||
buttonProps={{
|
||||
color: 'secondary',
|
||||
'data-cy': VM_ACTIONS.PERFORM_ACTION,
|
||||
label: T.PerformAction,
|
||||
variant: 'outlined',
|
||||
}}
|
||||
options={[
|
||||
{
|
||||
name: T.PerformAction,
|
||||
dialogProps: {
|
||||
title: T.PerformAction,
|
||||
dataCy: 'modal-perform-action',
|
||||
},
|
||||
form: () => CreatePerformAction(formConfig),
|
||||
onSubmit,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
const ButtonPropTypes = {
|
||||
vm: PropTypes.object,
|
||||
relative: PropTypes.bool,
|
||||
@ -234,6 +275,8 @@ const ButtonPropTypes = {
|
||||
oneConfig: PropTypes.object,
|
||||
adminGroup: PropTypes.bool,
|
||||
backupjobs: PropTypes.bool,
|
||||
service: PropTypes.object,
|
||||
roles: PropTypes.object,
|
||||
}
|
||||
|
||||
CreateSchedButton.propTypes = ButtonPropTypes
|
||||
@ -244,10 +287,13 @@ DeleteSchedButton.propTypes = ButtonPropTypes
|
||||
DeleteSchedButton.displayName = 'DeleteSchedButton'
|
||||
CharterButton.propTypes = ButtonPropTypes
|
||||
CharterButton.displayName = 'CharterButton'
|
||||
PerformActionButton.propTypes = ButtonPropTypes
|
||||
PerformActionButton.displayName = 'PerformActionButton'
|
||||
|
||||
export {
|
||||
CharterButton,
|
||||
CreateSchedButton,
|
||||
DeleteSchedButton,
|
||||
UpdateSchedButton,
|
||||
PerformActionButton,
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* Copyright 2002-2024, OpenNebula Project, OpenNebula Systems *
|
||||
* *
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
|
||||
* not use this file except in compliance with the License. You may obtain *
|
||||
* a copy of the License at *
|
||||
* *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 *
|
||||
* *
|
||||
* Unless required by applicable law or agreed to in writing, software *
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, *
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { createForm } from 'client/utils'
|
||||
|
||||
import {
|
||||
FIELDS,
|
||||
SCHEMA,
|
||||
} from 'client/components/Forms/Service/PerformAction/schema'
|
||||
|
||||
const PerformActionForm = createForm(SCHEMA, FIELDS, {
|
||||
transformBeforeSubmit: (formData) => {
|
||||
// Transform args for an action that needs some arguments
|
||||
if (formData?.ARGS) {
|
||||
if (formData?.ARGS?.NAME) {
|
||||
formData.ARGS = formData.ARGS.NAME
|
||||
} else if (formData?.ARGS?.SNAPSHOT_ID) {
|
||||
formData.ARGS = formData.ARGS.SNAPSHOT_ID
|
||||
}
|
||||
}
|
||||
|
||||
return formData
|
||||
},
|
||||
})
|
||||
|
||||
export default PerformActionForm
|
@ -0,0 +1,132 @@
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* Copyright 2002-2024, OpenNebula Project, OpenNebula Systems *
|
||||
* *
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
|
||||
* not use this file except in compliance with the License. You may obtain *
|
||||
* a copy of the License at *
|
||||
* *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 *
|
||||
* *
|
||||
* Unless required by applicable law or agreed to in writing, software *
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, *
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { ObjectSchema, string } from 'yup'
|
||||
import { getObjectSchemaFromFields, arrayToOptions, Field } from 'client/utils'
|
||||
import {
|
||||
INPUT_TYPES,
|
||||
T,
|
||||
VM_ACTIONS_WITH_SCHEDULE,
|
||||
VM_ACTIONS,
|
||||
ARGS_TYPES,
|
||||
} from 'client/constants'
|
||||
|
||||
import { getRequiredArgsByAction } from 'client/models/Scheduler'
|
||||
|
||||
/**
|
||||
* @returns {Field} Action name field
|
||||
*/
|
||||
const ACTION_FIELD = {
|
||||
name: 'ACTION',
|
||||
label: T.Action,
|
||||
type: INPUT_TYPES.AUTOCOMPLETE,
|
||||
optionsOnly: true,
|
||||
values: () => {
|
||||
const validActions = {
|
||||
...VM_ACTIONS_WITH_SCHEDULE,
|
||||
}
|
||||
|
||||
/**
|
||||
* BACKUP: Not supported by oneflow api
|
||||
*/
|
||||
delete validActions[VM_ACTIONS.BACKUP]
|
||||
|
||||
return arrayToOptions(
|
||||
Object.entries({
|
||||
...validActions,
|
||||
}),
|
||||
{
|
||||
addEmpty: false,
|
||||
getText: ([, text]) => text,
|
||||
getValue: ([value]) => value,
|
||||
}
|
||||
)
|
||||
},
|
||||
validation: string().trim().required(),
|
||||
grid: { xs: 12 },
|
||||
}
|
||||
|
||||
export const ACTION_FIELD_NAME = 'ACTION'
|
||||
|
||||
const createArgField = (argName, htmlType) => ({
|
||||
name: `ARGS.${argName}`,
|
||||
dependOf: ACTION_FIELD_NAME,
|
||||
htmlType: (action) => {
|
||||
const prueba = getRequiredArgsByAction(action)
|
||||
console.log(argName, prueba.includes(argName))
|
||||
|
||||
return !getRequiredArgsByAction(action)?.includes(argName)
|
||||
? INPUT_TYPES.HIDDEN
|
||||
: htmlType
|
||||
},
|
||||
})
|
||||
|
||||
/** @type {Field} Snapshot name field */
|
||||
const ARGS_NAME_FIELD = {
|
||||
...createArgField(ARGS_TYPES.NAME),
|
||||
label: T.SnapshotName,
|
||||
type: INPUT_TYPES.TEXT,
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Field} Snapshot id field
|
||||
*/
|
||||
const ARGS_SNAPSHOT_ID_FIELD = {
|
||||
...createArgField(ARGS_TYPES.SNAPSHOT_ID),
|
||||
label: T.Snapshot + ' ' + T.ID,
|
||||
type: INPUT_TYPES.TEXT,
|
||||
}
|
||||
|
||||
const ROLE_FIELD = (roles) => ({
|
||||
name: 'ROLE',
|
||||
label: T.Role,
|
||||
type: INPUT_TYPES.AUTOCOMPLETE,
|
||||
optionsOnly: true,
|
||||
values: () => {
|
||||
const rolesWithAll = roles.map((role) => ({
|
||||
name: role.name,
|
||||
value: role.name,
|
||||
}))
|
||||
|
||||
rolesWithAll.push({
|
||||
name: T.All,
|
||||
value: 'ALL',
|
||||
})
|
||||
|
||||
return arrayToOptions(rolesWithAll, {
|
||||
addEmpty: false,
|
||||
getText: (role) => role.name,
|
||||
getValue: (role) => role.value,
|
||||
})
|
||||
},
|
||||
validation: string().trim().required(),
|
||||
grid: { xs: 12 },
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {object} props - Properties of the form
|
||||
* @param {object} props.roles - Roles of the service
|
||||
* @returns {Array} - List of fields
|
||||
*/
|
||||
export const FIELDS = ({ roles }) => [
|
||||
ACTION_FIELD,
|
||||
ROLE_FIELD(roles),
|
||||
ARGS_NAME_FIELD,
|
||||
ARGS_SNAPSHOT_ID_FIELD,
|
||||
]
|
||||
|
||||
/** @type {ObjectSchema} Schema */
|
||||
export const SCHEMA = ({ roles }) =>
|
||||
getObjectSchemaFromFields(FIELDS({ roles }))
|
@ -14,37 +14,14 @@
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { ReactElement } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Stack } from '@mui/material'
|
||||
|
||||
import { useGetServiceQuery } from 'client/features/OneApi/service'
|
||||
// import ScheduleActionCard from 'client/components/Cards/ScheduleActionCard'
|
||||
import { AsyncLoadForm, ConfigurationProps } from 'client/components/HOC'
|
||||
import { CreateStepsCallback } from 'client/utils/schema'
|
||||
|
||||
/**
|
||||
* Renders the list of schedule actions from a Service.
|
||||
*
|
||||
* @param {object} props - Props
|
||||
* @param {string} props.id - Service id
|
||||
* @param {object|boolean} props.tabProps - Tab properties
|
||||
* @param {object} [props.tabProps.actions] - Actions from user view yaml
|
||||
* @returns {ReactElement} Schedule actions tab
|
||||
* @param {ConfigurationProps} configProps - Configuration
|
||||
* @returns {ReactElement|CreateStepsCallback} Asynchronous loaded form
|
||||
*/
|
||||
const SchedulingTab = ({ id, tabProps: { actions } = {} }) => {
|
||||
const { data: service = {} } = useGetServiceQuery({ id })
|
||||
const CreatePerformAction = (configProps) =>
|
||||
AsyncLoadForm({ formPath: 'Service/PerformAction' }, configProps)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack gap="1em" py="0.8em">
|
||||
{service?.NAME}
|
||||
{/* TODO: scheduler actions & form */}
|
||||
</Stack>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
SchedulingTab.propTypes = {
|
||||
tabProps: PropTypes.object,
|
||||
id: PropTypes.string,
|
||||
}
|
||||
|
||||
export default SchedulingTab
|
||||
export { CreatePerformAction }
|
@ -31,7 +31,6 @@ import { Tr } from 'client/components/HOC'
|
||||
import { Legend } from 'client/components/Forms'
|
||||
|
||||
import { mapNameByIndex } from 'client/components/Forms/VmTemplate/CreateForm/Steps/ExtraConfiguration/schema'
|
||||
import { STEP_ID as EXTRA_ID } from 'client/components/Forms/ServiceTemplate/CreateForm/Steps/Extra'
|
||||
|
||||
import { Component, useMemo } from 'react'
|
||||
|
||||
@ -52,7 +51,7 @@ const ScheduleActionsSection = ({ oneConfig, adminGroup }) => {
|
||||
update,
|
||||
append,
|
||||
} = useFieldArray({
|
||||
name: `${EXTRA_ID}.${TAB_ID}`,
|
||||
name: `charter.${TAB_ID}`,
|
||||
keyName: 'ID',
|
||||
})
|
||||
|
||||
|
@ -48,14 +48,41 @@ const Steps = createSteps([General, UserInputs, Network, Charter], {
|
||||
}
|
||||
)
|
||||
|
||||
// Get schedule actions from vm template contents
|
||||
const schedActions = parseVmTemplateContents(
|
||||
ServiceTemplate?.TEMPLATE?.BODY?.roles[0]?.vm_template_contents,
|
||||
true
|
||||
)?.schedActions
|
||||
|
||||
const knownTemplate = schema.cast({
|
||||
[GENERAL_ID]: {},
|
||||
[USERINPUTS_ID]: {},
|
||||
[NETWORK_ID]: { NETWORKS: networks },
|
||||
[CHARTER_ID]: {},
|
||||
[CHARTER_ID]: { SCHED_ACTION: schedActions },
|
||||
})
|
||||
|
||||
return { ...knownTemplate, roles: roles }
|
||||
const newRoles = roles.map((role) => {
|
||||
// Parse vm template content
|
||||
const roleTemplateContent = parseVmTemplateContents(
|
||||
role.vm_template_contents,
|
||||
true
|
||||
)
|
||||
|
||||
// Delete schedule actions
|
||||
delete roleTemplateContent.schedActions
|
||||
|
||||
// Parse content without sched actions
|
||||
const roleTemplateWithoutSchedActions = parseVmTemplateContents(
|
||||
roleTemplateContent,
|
||||
false
|
||||
)
|
||||
role.vm_template_contents = roleTemplateWithoutSchedActions
|
||||
|
||||
// Return content
|
||||
return role
|
||||
})
|
||||
|
||||
return { ...knownTemplate, roles: newRoles }
|
||||
},
|
||||
|
||||
transformBeforeSubmit: (formData) => {
|
||||
@ -86,12 +113,12 @@ const Steps = createSteps([General, UserInputs, Network, Charter], {
|
||||
{
|
||||
vmTemplateContents: role?.vm_template_contents,
|
||||
customAttrsValues: userInputsData,
|
||||
schedActions: charterData.SCHED_ACTION,
|
||||
},
|
||||
false,
|
||||
true
|
||||
),
|
||||
})),
|
||||
...(!!charterData?.SCHED_ACTION?.length && { ...charterData }),
|
||||
name: generalData?.NAME,
|
||||
}
|
||||
|
||||
|
148
src/fireedge/src/client/components/Tabs/Service/SchedActions.js
Normal file
148
src/fireedge/src/client/components/Tabs/Service/SchedActions.js
Normal file
@ -0,0 +1,148 @@
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* Copyright 2002-2024, OpenNebula Project, OpenNebula Systems *
|
||||
* *
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
|
||||
* not use this file except in compliance with the License. You may obtain *
|
||||
* a copy of the License at *
|
||||
* *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 *
|
||||
* *
|
||||
* Unless required by applicable law or agreed to in writing, software *
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, *
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { ReactElement, useMemo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Stack } from '@mui/material'
|
||||
|
||||
import { parseVmTemplateContents } from 'client/utils'
|
||||
|
||||
import {
|
||||
useGetServiceQuery,
|
||||
useServiceRoleActionMutation,
|
||||
useServiceAddActionMutation,
|
||||
} from 'client/features/OneApi/service'
|
||||
import {} from 'client/features/OneApi/vm'
|
||||
|
||||
import ScheduleActionCard from 'client/components/Cards/ScheduleActionCard'
|
||||
import { PerformActionButton } from 'client/components/Buttons/ScheduleAction'
|
||||
|
||||
import { getScheduleActions } from 'client/models/VirtualMachine'
|
||||
|
||||
import { VM_ACTIONS, T } from 'client/constants'
|
||||
|
||||
import { useGeneralApi } from 'client/features/General'
|
||||
|
||||
const { PERFORM_ACTION } = VM_ACTIONS
|
||||
|
||||
/**
|
||||
* Renders the list of schedule actions from a Service.
|
||||
*
|
||||
* @param {object} props - Props
|
||||
* @param {string} props.id - Service id
|
||||
* @param {object|boolean} props.tabProps - Tab properties
|
||||
* @param {object} [props.tabProps.actions] - Actions from user view yaml
|
||||
* @returns {ReactElement} Schedule actions tab
|
||||
*/
|
||||
const SchedulingTab = ({ id, tabProps: { actions } = {} }) => {
|
||||
const { enqueueError, enqueueSuccess, enqueueInfo } = useGeneralApi()
|
||||
|
||||
// Get service info
|
||||
const { data: service = {} } = useGetServiceQuery({ id })
|
||||
|
||||
// Functions to manage sched actions
|
||||
const [useServiceAddAction] = useServiceAddActionMutation()
|
||||
const [serviceRoleAction] = useServiceRoleActionMutation()
|
||||
|
||||
// Check actions and roles
|
||||
const [scheduling, actionsAvailable, roles] = useMemo(() => {
|
||||
const schedActions = {
|
||||
TEMPLATE: {
|
||||
SCHED_ACTION: parseVmTemplateContents(
|
||||
service?.TEMPLATE?.BODY?.roles[0]?.vm_template_contents,
|
||||
true
|
||||
)?.schedActions,
|
||||
},
|
||||
}
|
||||
|
||||
const updatedRoles = service?.TEMPLATE?.BODY?.roles
|
||||
|
||||
return [getScheduleActions(schedActions), actions, updatedRoles]
|
||||
}, [service])
|
||||
|
||||
const isPerformActionEnabled = actionsAvailable[PERFORM_ACTION]
|
||||
|
||||
/**
|
||||
* Add new schedule action to VM.
|
||||
*
|
||||
* @param {object} formData - New schedule action
|
||||
* @returns {Promise} - Add schedule action and refetch VM data
|
||||
*/
|
||||
const handlePerformAction = async (formData) => {
|
||||
enqueueInfo(T.InfoServiceActionRole, [formData.ACTION, formData.ROLE])
|
||||
|
||||
try {
|
||||
if (formData.ROLE === 'ALL') {
|
||||
await useServiceAddAction({
|
||||
id,
|
||||
perform: formData.ACTION,
|
||||
params: {
|
||||
args: formData.ARGS,
|
||||
},
|
||||
})
|
||||
enqueueSuccess(T.SuccessRoleActionCompleted, [
|
||||
formData.ACTION,
|
||||
formData.ROLE,
|
||||
])
|
||||
} else {
|
||||
await serviceRoleAction({
|
||||
id,
|
||||
role: formData.ROLE,
|
||||
perform: formData.ACTION,
|
||||
params: {
|
||||
args: formData.ARGS,
|
||||
},
|
||||
})
|
||||
enqueueSuccess(T.SuccessRoleActionCompleted, [
|
||||
formData.ACTION,
|
||||
formData.ROLE,
|
||||
])
|
||||
}
|
||||
} catch (error) {
|
||||
enqueueError(T.ErrorServiceActionRole, [
|
||||
formData?.ACTION,
|
||||
formData?.ROLE,
|
||||
error,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{isPerformActionEnabled && (
|
||||
<Stack flexDirection="row" gap="1em">
|
||||
{isPerformActionEnabled && (
|
||||
<PerformActionButton onSubmit={handlePerformAction} roles={roles} />
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
<Stack gap="1em" py="0.8em">
|
||||
{scheduling.map((schedule) => {
|
||||
const { ID, NAME } = schedule
|
||||
|
||||
return <ScheduleActionCard key={ID ?? NAME} schedule={schedule} />
|
||||
})}
|
||||
</Stack>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
SchedulingTab.propTypes = {
|
||||
tabProps: PropTypes.object,
|
||||
id: PropTypes.string,
|
||||
}
|
||||
|
||||
export default SchedulingTab
|
@ -23,7 +23,7 @@ import { useGetServiceQuery } from 'client/features/OneApi/service'
|
||||
import { getAvailableInfoTabs } from 'client/models/Helper'
|
||||
|
||||
import Tabs from 'client/components/Tabs'
|
||||
import Actions from 'client/components/Tabs/Service/Actions'
|
||||
import Actions from 'client/components/Tabs/Service/SchedActions'
|
||||
import Info from 'client/components/Tabs/Service/Info'
|
||||
import Log from 'client/components/Tabs/Service/Log'
|
||||
import Roles from 'client/components/Tabs/Service/Roles'
|
||||
@ -33,7 +33,7 @@ const getTabComponent = (tabName) =>
|
||||
info: Info,
|
||||
roles: Roles,
|
||||
log: Log,
|
||||
schedulerAction: Actions,
|
||||
sched_actions: Actions,
|
||||
}[tabName])
|
||||
|
||||
const ServiceTabs = memo(({ id }) => {
|
||||
|
@ -151,6 +151,8 @@ module.exports = {
|
||||
Migrate: 'Migrate',
|
||||
MigrateLive: 'Migrate live',
|
||||
Offline: 'Offline',
|
||||
PerformAction: 'Perform action',
|
||||
AllRoles: 'All roles',
|
||||
Pin: 'Pin',
|
||||
Poweroff: 'Poweroff',
|
||||
PoweroffHard: 'Poweroff hard',
|
||||
@ -1515,6 +1517,8 @@ module.exports = {
|
||||
RoleManageApps: 'Manage multi-VM applications efficiently.',
|
||||
/* Service Template - configuration */
|
||||
RoleConfiguration: 'Role Configuration',
|
||||
/* Service Template - schedule actions */
|
||||
ServiceSheduleActionCreated: 'Shedule action added to service',
|
||||
|
||||
/* VMGroups - Role definition */
|
||||
NewRole: 'New Role',
|
||||
|
@ -804,6 +804,7 @@ export const VM_ACTIONS = {
|
||||
SCHED_ACTION_UPDATE: 'sched-update',
|
||||
SCHED_ACTION_DELETE: 'sched-delete',
|
||||
CHARTER_CREATE: 'charter_create',
|
||||
PERFORM_ACTION: 'perform_action',
|
||||
|
||||
// CONFIGURATION
|
||||
UPDATE_CONF: 'update_configuration',
|
||||
|
@ -102,7 +102,7 @@ const extractPropertiesToArray = (content) => {
|
||||
}
|
||||
|
||||
const formatInstantiate = (contents) => {
|
||||
const { vmTemplateContents, customAttrsValues } = contents
|
||||
const { vmTemplateContents, customAttrsValues, schedActions } = contents
|
||||
|
||||
const sections = extractSections(vmTemplateContents)
|
||||
.map(parseSection)
|
||||
@ -139,7 +139,12 @@ const formatInstantiate = (contents) => {
|
||||
...filteredProperties,
|
||||
]
|
||||
|
||||
const formattedTemplate = combinedContent.join('\n') + '\n'
|
||||
const formattedActions = schedActions?.map((action, index) =>
|
||||
formatSchedActions({ ...action, ID: index })
|
||||
)
|
||||
|
||||
const formattedTemplate =
|
||||
combinedContent.join('\n') + formattedActions.join('\n') + '\n'
|
||||
|
||||
return formattedTemplate
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user