Skip to content

Commit

Permalink
M #-: Schedule actions tab on services. Perform action on role. (#3206)
Browse files Browse the repository at this point in the history

Signed-off-by: dcarracedo <[email protected]>
  • Loading branch information
dcarracedo authored Aug 23, 2024
1 parent 92541b6 commit 5dff938
Show file tree
Hide file tree
Showing 14 changed files with 433 additions and 53 deletions.
9 changes: 5 additions & 4 deletions src/fireedge/etc/sunstone/admin/service-tab.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
13 changes: 7 additions & 6 deletions src/fireedge/etc/sunstone/cloud/service-tab.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
9 changes: 5 additions & 4 deletions src/fireedge/etc/sunstone/groupadmin/service-tab.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
46 changes: 46 additions & 0 deletions src/fireedge/src/client/components/Buttons/ScheduleAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -234,6 +275,8 @@ const ButtonPropTypes = {
oneConfig: PropTypes.object,
adminGroup: PropTypes.bool,
backupjobs: PropTypes.bool,
service: PropTypes.object,
roles: PropTypes.object,
}

CreateSchedButton.propTypes = ButtonPropTypes
Expand All @@ -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,
}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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 }))
Original file line number Diff line number Diff line change
Expand Up @@ -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 })

return (
<>
<Stack gap="1em" py="0.8em">
{service?.NAME}
{/* TODO: scheduler actions & form */}
</Stack>
</>
)
}

SchedulingTab.propTypes = {
tabProps: PropTypes.object,
id: PropTypes.string,
}
const CreatePerformAction = (configProps) =>
AsyncLoadForm({ formPath: 'Service/PerformAction' }, configProps)

export default SchedulingTab
export { CreatePerformAction }
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand All @@ -52,7 +51,7 @@ const ScheduleActionsSection = ({ oneConfig, adminGroup }) => {
update,
append,
} = useFieldArray({
name: `${EXTRA_ID}.${TAB_ID}`,
name: `charter.${TAB_ID}`,
keyName: 'ID',
})

Expand Down
Loading

0 comments on commit 5dff938

Please sign in to comment.