diff --git a/src/fireedge/etc/sunstone/admin/vnet-tab.yaml b/src/fireedge/etc/sunstone/admin/vnet-tab.yaml index 982ce14753..977bc80f31 100644 --- a/src/fireedge/etc/sunstone/admin/vnet-tab.yaml +++ b/src/fireedge/etc/sunstone/admin/vnet-tab.yaml @@ -40,6 +40,11 @@ actions: filters: label: true + state: true + owner: true + group: true + locked: true + vn_mad: true # Info Tabs - Which info tabs are used to show extended information diff --git a/src/fireedge/src/client/components/Cards/NetworkCard.js b/src/fireedge/src/client/components/Cards/NetworkCard.js index 92de816b25..aa109e40de 100644 --- a/src/fireedge/src/client/components/Cards/NetworkCard.js +++ b/src/fireedge/src/client/components/Cards/NetworkCard.js @@ -13,57 +13,133 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ -import { memo, ReactElement } from 'react' +import { memo, useMemo, ReactElement } from 'react' import PropTypes from 'prop-types' -import { Typography } from '@mui/material' -import { User, Group, Lock, Server, Cloud } from 'iconoir-react' +import { + User, + Group, + Lock, + Server, + Cloud, + WarningCircledOutline as WarningIcon, +} from 'iconoir-react' +import { Box, Typography, Tooltip } from '@mui/material' -import { LinearProgressWithLabel } from 'client/components/Status' -import { getLeasesInfo, getTotalLeases } from 'client/models/VirtualNetwork' +import { useViews } from 'client/features/Auth' +import MultipleTags from 'client/components/MultipleTags' +import { + StatusCircle, + StatusChip, + LinearProgressWithLabel, +} from 'client/components/Status' +import { Tr } from 'client/components/HOC' import { rowStyles } from 'client/components/Tables/styles' +import { + getState, + getLeasesInfo, + getVNManager, +} from 'client/models/VirtualNetwork' +import { + getColorFromString, + getUniqueLabels, + getErrorMessage, +} from 'client/models/Helper' +import { + VirtualNetwork, + T, + ACTIONS, + RESOURCE_NAMES, + VNET_THRESHOLD, +} from 'client/constants' + const NetworkCard = memo( /** * @param {object} props - Props - * @param {object} props.network - Network resource + * @param {VirtualNetwork} props.network - Network resource * @param {object} props.rootProps - Props to root component - * @param {ReactElement} props.actions - Actions + * @param {function(string):Promise} [props.onDeleteLabel] - Callback to delete label + * @param {ReactElement} [props.actions] - Actions * @returns {ReactElement} - Card */ - ({ network, rootProps, actions }) => { + ({ network, rootProps, actions, onDeleteLabel }) => { const classes = rowStyles() + const { [RESOURCE_NAMES.VM]: vmView } = useViews() - const { ID, NAME, UNAME, GNAME, LOCK, CLUSTERS, USED_LEASES, TEMPLATE } = - network + const enableEditLabels = + vmView?.actions?.[ACTIONS.EDIT_LABELS] === true && !!onDeleteLabel - const totalLeases = getTotalLeases(network) - const { percentOfUsed, percentLabel } = getLeasesInfo(network) - const totalClusters = [CLUSTERS?.ID ?? []].flat().length || 0 - const provisionId = TEMPLATE?.PROVISION?.ID + const { + ID, + NAME, + UNAME, + GNAME, + LOCK, + CLUSTERS, + TEMPLATE: { PROVISION, LABELS } = {}, + } = network + + const provisionId = PROVISION?.ID + const { color: stateColor, name: stateName } = getState(network) + const error = useMemo(() => getErrorMessage(network), [network]) + const vnMad = useMemo(() => getVNManager(network), [network?.VN_MAD]) + const leasesInfo = useMemo(() => getLeasesInfo(network), [network]) + const { percentOfUsed, percentLabel } = leasesInfo + + const totalClusters = useMemo( + () => [CLUSTERS?.ID ?? []].flat().length || 0, + [CLUSTERS?.ID] + ) + + const labels = useMemo( + () => + getUniqueLabels(LABELS).map((label) => ({ + text: label, + stateColor: getColorFromString(label), + onDelete: enableEditLabels && onDeleteLabel, + })), + [LABELS, enableEditLabels, onDeleteLabel] + ) return (
+ {NAME} - {LOCK && } + {error && ( + {error}} + > + + + + + )} + + {vnMad && } + {LOCK && } + +
{`#${ID}`} - + {` ${UNAME}`} - + {` ${GNAME}`} - + {` ${totalClusters}`} {provisionId && ( - + {` ${provisionId}`} @@ -72,9 +148,11 @@ const NetworkCard = memo(
{actions &&
{actions}
} @@ -88,6 +166,7 @@ NetworkCard.propTypes = { rootProps: PropTypes.shape({ className: PropTypes.string, }), + onDeleteLabel: PropTypes.func, actions: PropTypes.any, } diff --git a/src/fireedge/src/client/components/Cards/VirtualMachineCard.js b/src/fireedge/src/client/components/Cards/VirtualMachineCard.js index 59212af263..4c784a70c4 100644 --- a/src/fireedge/src/client/components/Cards/VirtualMachineCard.js +++ b/src/fireedge/src/client/components/Cards/VirtualMachineCard.js @@ -33,15 +33,11 @@ import { StatusCircle, StatusChip } from 'client/components/Status' import { Tr } from 'client/components/HOC' import { rowStyles } from 'client/components/Tables/styles' -import { - getState, - getLastHistory, - getIps, - getErrorMessage, -} from 'client/models/VirtualMachine' +import { getState, getLastHistory, getIps } from 'client/models/VirtualMachine' import { timeFromMilliseconds, getUniqueLabels, + getErrorMessage, getColorFromString, } from 'client/models/Helper' import { prettyBytes } from 'client/utils' diff --git a/src/fireedge/src/client/components/Tables/VNetworks/columns.js b/src/fireedge/src/client/components/Tables/VNetworks/columns.js index 1f2736d92d..bc541a7a70 100644 --- a/src/fireedge/src/client/components/Tables/VNetworks/columns.js +++ b/src/fireedge/src/client/components/Tables/VNetworks/columns.js @@ -13,39 +13,64 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ -/* eslint-disable jsdoc/require-jsdoc */ -import * as VirtualNetworkModel from 'client/models/VirtualNetwork' +import { Column } from 'react-table' + +import { + getState, + getTotalLeases, + getVNManager, +} from 'client/models/VirtualNetwork' +import { T } from 'client/constants' const getTotalOfResources = (resources) => [resources?.ID ?? []].flat().length || 0 -export default [ - { Header: 'ID', accessor: 'ID', sortType: 'number' }, - { Header: 'Name', accessor: 'NAME' }, - { Header: 'Owner', accessor: 'UNAME' }, - { Header: 'Group', accessor: 'GNAME' }, - { Header: 'Locked', accessor: 'LOCK' }, +/** @type {Column[]} VM columns */ +const COLUMNS = [ + { Header: T.ID, id: 'id', accessor: 'ID', sortType: 'number' }, + { Header: T.Name, id: 'name', accessor: 'NAME' }, { - Header: 'Total Clusters', - id: 'CLUSTERS', + Header: T.State, + id: 'state', + accessor: (row) => getState(row)?.name, + }, + { Header: T.Owner, id: 'owner', accessor: 'UNAME' }, + { Header: T.Group, id: 'group', accessor: 'GNAME' }, + { Header: T.Locked, id: 'locked', accessor: 'LOCK' }, + { Header: T.Driver, id: 'vn_mad', accessor: getVNManager }, + { + Header: T.TotalClusters, + id: 'clusters', accessor: (row) => getTotalOfResources(row?.CLUSTERS), sortType: 'number', }, { - Header: 'Used Leases', + Header: T.UsedLeases, + id: 'used_leases', accessor: 'USED_LEASES', sortType: 'number', }, { - Header: 'Total Leases', - id: 'TOTAL_LEASES', - accessor: (row) => VirtualNetworkModel.getTotalLeases(row), + Header: T.TotalLeases, + id: 'total_leases', + accessor: getTotalLeases, sortType: 'number', }, { - Header: 'Provision ID', - id: 'PROVISION_ID', + Header: T.ProvisionId, + id: 'provision_id', accessor: (row) => row?.TEMPLATE?.PROVISION?.ID, disableSortBy: true, }, ] + +COLUMNS.noFilterIds = [ + 'id', + 'name', + 'clusters', + 'used_leases', + 'total_leases', + 'provision_id', +] + +export default COLUMNS diff --git a/src/fireedge/src/client/components/Tabs/VNetwork/Info/index.js b/src/fireedge/src/client/components/Tabs/VNetwork/Info/index.js index c593e8dbd2..8ef9bfbf8e 100644 --- a/src/fireedge/src/client/components/Tabs/VNetwork/Info/index.js +++ b/src/fireedge/src/client/components/Tabs/VNetwork/Info/index.js @@ -28,7 +28,7 @@ import { Ownership, AttributePanel, } from 'client/components/Tabs/Common' -import Information from 'client/components/Tabs/VNetworkTemplate/Info/information' +import Information from 'client/components/Tabs/VNetwork/Info/information' import { Tr } from 'client/components/HOC' import { T } from 'client/constants' @@ -42,7 +42,7 @@ import { cloneObject, set } from 'client/utils' const LXC_ATTRIBUTES_REG = /^LXC_/ const VCENTER_ATTRIBUTES_REG = /^VCENTER_/ const HIDDEN_ATTRIBUTES_REG = - /^(SECURITY_GROUPS|INBOUND_AVG_BW|INBOUND_PEAK_BW|INBOUND_PEAK_KB|OUTBOUND_AVG_BW|OUTBOUND_PEAK_BW|OUTBOUND_PEAK_KB)$/ + /^(ERROR|SECURITY_GROUPS|INBOUND_AVG_BW|INBOUND_PEAK_BW|INBOUND_PEAK_KB|OUTBOUND_AVG_BW|OUTBOUND_PEAK_BW|OUTBOUND_PEAK_KB)$/ /** * Renders mainly information tab. diff --git a/src/fireedge/src/client/components/Tabs/VNetwork/Info/information.js b/src/fireedge/src/client/components/Tabs/VNetwork/Info/information.js index ee10133678..6ba8f08869 100644 --- a/src/fireedge/src/client/components/Tabs/VNetwork/Info/information.js +++ b/src/fireedge/src/client/components/Tabs/VNetwork/Info/information.js @@ -17,8 +17,12 @@ import { ReactElement } from 'react' import PropTypes from 'prop-types' import { useRenameVNTemplateMutation } from 'client/features/OneApi/networkTemplate' + +import { StatusChip } from 'client/components/Status' import { List } from 'client/components/Tabs/Common' -import { T, VNetwork, VNET_ACTIONS } from 'client/constants' + +import { getState } from 'client/models/VirtualNetwork' +import { T, VNetwork, VN_ACTIONS } from 'client/constants' /** * Renders mainly information tab. @@ -32,6 +36,8 @@ const InformationPanel = ({ vnet = {}, actions }) => { const [rename] = useRenameVNTemplateMutation() const { ID, NAME } = vnet + const { name: stateName, color: stateColor } = getState(vnet) + const handleRename = async (_, newName) => { await rename({ id: ID, name: newName }) } @@ -42,9 +48,15 @@ const InformationPanel = ({ vnet = {}, actions }) => { name: T.Name, value: NAME, dataCy: 'name', - canEdit: actions?.includes?.(VNET_ACTIONS.RENAME), + canEdit: actions?.includes?.(VN_ACTIONS.RENAME), handleEdit: handleRename, }, + { + name: T.State, + value: ( + + ), + }, ] return ( diff --git a/src/fireedge/src/client/components/Tabs/Vm/Info/index.js b/src/fireedge/src/client/components/Tabs/Vm/Info/index.js index 446b6c0421..04cbbcd1e7 100644 --- a/src/fireedge/src/client/components/Tabs/Vm/Info/index.js +++ b/src/fireedge/src/client/components/Tabs/Vm/Info/index.js @@ -34,11 +34,12 @@ import { SubmitButton } from 'client/components/FormControl' import { Tr, Translate } from 'client/components/HOC' import { T } from 'client/constants' -import { getHypervisor, getErrorMessage } from 'client/models/VirtualMachine' +import { getHypervisor } from 'client/models/VirtualMachine' import { getActionsAvailable, filterAttributes, jsonToXml, + getErrorMessage, } from 'client/models/Helper' import { cloneObject, set } from 'client/utils' diff --git a/src/fireedge/src/client/constants/flow.js b/src/fireedge/src/client/constants/flow.js index d232102f06..8bee91834e 100644 --- a/src/fireedge/src/client/constants/flow.js +++ b/src/fireedge/src/client/constants/flow.js @@ -18,6 +18,7 @@ import COLOR from 'client/constants/color' export const APPLICATION_STATES = [ { + // 0 name: STATES.PENDING, color: COLOR.info.main, meaning: ` @@ -25,26 +26,31 @@ export const APPLICATION_STATES = [ it until the LCM decides to deploy it`, }, { + // 1 name: STATES.DEPLOYING, color: COLOR.info.main, meaning: 'Some Tiers are being deployed', }, { + // 2 name: STATES.RUNNING, color: COLOR.success.main, meaning: 'All Tiers are deployed successfully', }, { + // 3 name: STATES.UNDEPLOYING, color: COLOR.error.light, meaning: 'Some Tiers are being undeployed', }, { + // 4 name: STATES.WARNING, color: COLOR.error.light, meaning: 'A VM was found in a failure state', }, { + // 5 name: STATES.DONE, color: COLOR.error.dark, meaning: ` @@ -52,30 +58,59 @@ export const APPLICATION_STATES = [ a successful undeployment. It can be deleted`, }, { + // 6 name: STATES.FAILED_UNDEPLOYING, color: COLOR.error.dark, meaning: 'An error occurred while undeploying the Application', }, { + // 7 name: STATES.FAILED_DEPLOYING, color: COLOR.error.dark, meaning: 'An error occurred while deploying the Application', }, { + // 8 name: STATES.SCALING, color: COLOR.error.light, meaning: 'A Tier is scaling up or down', }, { + // 9 name: STATES.FAILED_SCALING, color: COLOR.error.dark, meaning: 'An error occurred while scaling the Application', }, { + // 10 name: STATES.COOLDOWN, color: COLOR.error.light, meaning: 'A Tier is in the cooldown period after a scaling operation', }, + { + // 11 + name: STATES.DEPLOYING_NETS, + color: COLOR.info.main, + meaning: '', + }, + { + // 12 + name: STATES.UNDEPLOYING_NETS, + color: COLOR.error.light, + meaning: '', + }, + { + // 13 + name: STATES.FAILED_DEPLOYING_NETS, + color: COLOR.error.dark, + meaning: '', + }, + { + // 14 + name: STATES.FAILED_UNDEPLOYING_NETS, + color: COLOR.error.dark, + meaning: '', + }, ] export const TIER_STATES = [ diff --git a/src/fireedge/src/client/constants/network.js b/src/fireedge/src/client/constants/network.js index a4fc5bc9f4..31e5eb6bec 100644 --- a/src/fireedge/src/client/constants/network.js +++ b/src/fireedge/src/client/constants/network.js @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ +import * as STATES from 'client/constants/states' +import COLOR from 'client/constants/color' // eslint-disable-next-line no-unused-vars import { Permissions, LockInfo } from 'client/constants/common' import * as ACTIONS from 'client/constants/actions' @@ -21,7 +23,7 @@ import * as ACTIONS from 'client/constants/actions' * @typedef ARLease * @property {string} [IP] - IP * @property {string} [IP6] - IP6 - * @property {string} [IP6_GLOBAL] - IP6 globa + * @property {string} [IP6_GLOBAL] - IP6 global * @property {string} [IP6_LINK] - IP6 link * @property {string} [IP6_ULA] - IP6 ULA * @property {string} MAC - MAC @@ -64,6 +66,8 @@ import * as ACTIONS from 'client/constants/actions' * @property {string} GID - Group id * @property {string} GNAME - Group name * @property {Permissions} PERMISSIONS - Permissions + * @property {string|number} STATE - Current state + * @property {string|number} PREV_STATE - Previous state * @property {LockInfo} [LOCK] - Lock information * @property {{ ID: string|string[] }} CLUSTERS - Clusters * @property {{ ID: string|string[] }} VROUTERS - Virtual routers @@ -97,6 +101,79 @@ import * as ACTIONS from 'client/constants/actions' * @property {string} [TEMPLATE.VCENTER_TEMPLATE_REF] - vCenter information */ +/** @type {STATES.StateInfo[]} Virtual Network states */ +export const VN_STATES = [ + { + // 0 + name: STATES.INIT, + color: COLOR.info.light, + meaning: 'Initialization state, the Virtual Network object was created', + }, + { + // 1 + name: STATES.READY, + color: COLOR.success.main, + meaning: 'Virtual Network is ready, can execute any action', + }, + { + // 2 + name: STATES.LOCK_CREATE, + color: COLOR.error.light, + meaning: 'The driver initialization action is in progress', + }, + { + // 3 + name: STATES.LOCK_DELETE, + color: COLOR.error.light, + meaning: 'The driver delete action is in progress', + }, + { + // 4 + name: STATES.DONE, + color: COLOR.debug.light, + meaning: 'Network driver delete successful', + }, + { + // 5 + name: STATES.ERROR, + color: COLOR.error.dark, + meaning: 'Driver action failed.', + }, +] + +/** @enum {string} Virtual network actions */ +export const VN_ACTIONS = { + CREATE_DIALOG: 'create_dialog', + DELETE: 'delete', + RECOVER: 'recover', + UPDATE: 'update', + + // INFORMATION + RENAME: ACTIONS.RENAME, + CHANGE_MODE: ACTIONS.CHANGE_MODE, + CHANGE_OWNER: ACTIONS.CHANGE_OWNER, + CHANGE_GROUP: ACTIONS.CHANGE_GROUP, +} + +/** @enum {string} Virtual network actions by state */ +export const VN_ACTIONS_BY_STATE = { + [VN_ACTIONS.DELETE]: [STATES.READY], + [VN_ACTIONS.RECOVER]: [ + STATES.INIT, + STATES.LOCK_CREATE, + STATES.LOCK_DELETE, + STATES.LOCKED, + STATES.ERROR, + ], + [VN_ACTIONS.UPDATE]: [STATES.READY], + + // INFORMATION + [VN_ACTIONS.RENAME]: [], + [VN_ACTIONS.CHANGE_MODE]: [], + [VN_ACTIONS.CHANGE_OWNER]: [], + [VN_ACTIONS.CHANGE_GROUP]: [], +} + /** @enum {string} Type of Addresses defined by this address range */ export const AR_TYPES = { NONE: 'NONE', @@ -123,14 +200,10 @@ export const VN_DRIVERS = { nodeport: 'nodeport', } -/** @enum {string} Virtual network actions */ -export const VN_ACTIONS = { - CREATE_DIALOG: 'create_dialog', - DELETE: 'delete', - - // INFORMATION - RENAME: ACTIONS.RENAME, - CHANGE_MODE: ACTIONS.CHANGE_MODE, - CHANGE_OWNER: ACTIONS.CHANGE_OWNER, - CHANGE_GROUP: ACTIONS.CHANGE_GROUP, +/** + * @enum {{ high: number, low: number }} + * Virtual Network threshold to specify the maximum and minimum of the bar range + */ +export const VNET_THRESHOLD = { + LEASES: { high: 66, low: 33 }, } diff --git a/src/fireedge/src/client/constants/states.js b/src/fireedge/src/client/constants/states.js index a015faae6f..cce43b3ee0 100644 --- a/src/fireedge/src/client/constants/states.js +++ b/src/fireedge/src/client/constants/states.js @@ -45,6 +45,7 @@ export const COOLDOWN = 'COOLDOWN' export const DELETE = 'DELETE' export const DELETING = 'DELETING' export const DEPLOYING = 'DEPLOYING' +export const DEPLOYING_NETS = 'DEPLOYING_NETS' export const DISABLED = 'DISABLED' export const DISK_RESIZE = 'DISK_RESIZE' export const DISK_RESIZE_POWEROFF = 'DISK_RESIZE_POWEROFF' @@ -69,8 +70,10 @@ export const EPILOG_UNDEPLOY_FAILURE = 'EPILOG_UNDEPLOY_FAILURE' export const ERROR = 'ERROR' export const FAILED = 'FAILED' export const FAILED_DEPLOYING = 'FAILED_DEPLOYING' +export const FAILED_DEPLOYING_NETS = 'FAILED_DEPLOYING_NETS' export const FAILED_SCALING = 'FAILED_SCALING' export const FAILED_UNDEPLOYING = 'FAILED_UNDEPLOYING' +export const FAILED_UNDEPLOYING_NETS = 'FAILED_UNDEPLOYING_NETS' export const FAILURE = 'FAILURE' export const HOLD = 'HOLD' export const HOTPLUG = 'HOTPLUG' @@ -87,6 +90,8 @@ export const HOTPLUG_SAVEAS_UNDEPLOYED = 'HOTPLUG_SAVEAS_UNDEPLOYED' export const HOTPLUG_SNAPSHOT = 'HOTPLUG_SNAPSHOT' export const INIT = 'INIT' export const LCM_INIT = 'LCM_INIT' +export const LOCK_CREATE = 'LOCK_CREATE' +export const LOCK_DELETE = 'LOCK_DELETE' export const LOCKED = 'LOCKED' export const LOCKED_USED = 'LOCKED_USED' export const LOCKED_USED_PERS = 'LOCKED_USED_PERS' @@ -123,9 +128,11 @@ export const SHUTDOWN = 'SHUTDOWN' export const SHUTDOWN_POWEROFF = 'SHUTDOWN_POWEROFF' export const SHUTDOWN_UNDEPLOY = 'SHUTDOWN_UNDEPLOY' export const STOPPED = 'STOPPED' +export const SUCCESS = 'SUCCESS' export const SUSPENDED = 'SUSPENDED' export const UNDEPLOYED = 'UNDEPLOYED' export const UNDEPLOYING = 'UNDEPLOYING' +export const UNDEPLOYING_NETS = 'UNDEPLOYING_NETS' export const UNKNOWN = 'UNKNOWN' export const USED = 'USED' export const USED_PERS = 'USED_PERS' diff --git a/src/fireedge/src/client/constants/translates.js b/src/fireedge/src/client/constants/translates.js index 09b8047cd0..c7f7b162cb 100644 --- a/src/fireedge/src/client/constants/translates.js +++ b/src/fireedge/src/client/constants/translates.js @@ -749,6 +749,7 @@ module.exports = { be unshared with the group's users. Permission changed: GROUP USE`, /* Virtual Network schema - network */ + Driver: 'Driver', IP: 'IP', IPv4Concept: 'First IP in the range in dot notation', IPv6Concept: 'First IP6 (full 128 bits) in the range', @@ -786,6 +787,9 @@ module.exports = { GuestOptions: 'Guest options', GuestMTU: 'GuestMTU', GuestMTUConcept: 'Sets the MTU for the NICs in this network', + UsedLeases: 'Used leases', + TotalLeases: 'Total leases', + TotalClusters: 'Total clusters', /* security group schema */ TCP: 'TCP', @@ -888,6 +892,10 @@ module.exports = { Can be used only if IOTHREADS > 0. If this input is disabled please first configure IOTHREADS value on OS & CPU -> Features`, + /* Provision schema */ + /* Provision - general */ + ProvisionId: 'Provision ID', + /* User inputs */ UserInputs: 'User Inputs', UserInputsConcept: ` diff --git a/src/fireedge/src/client/containers/VirtualNetworks/index.js b/src/fireedge/src/client/containers/VirtualNetworks/index.js index 78462a8b8f..2de24948f1 100644 --- a/src/fireedge/src/client/containers/VirtualNetworks/index.js +++ b/src/fireedge/src/client/containers/VirtualNetworks/index.js @@ -33,7 +33,7 @@ function VirtualNetworks() { {selectedRows?.length > 0 && ( {selectedRows?.length === 1 ? ( - + ) : ( data?.VNET ?? {}, providesTags: (_, __, { id }) => [{ type: VNET, id }], + async onQueryStarted({ id }, { dispatch, queryFulfilled }) { + try { + const { data: queryVNet } = await queryFulfilled + + dispatch( + vNetworkApi.util.updateQueryData( + 'getVNetworks', + undefined, + (draft) => { + const index = draft.findIndex(({ ID }) => +ID === +id) + index !== -1 && (draft[index] = queryVNet) + } + ) + ) + } catch { + dispatch( + vNetworkApi.util.updateQueryData( + 'getVNetworks', + undefined, + (draft) => draft.filter(({ ID }) => +ID !== +id) + ) + ) + } + }, + onCacheEntryAdded: ({ id }, baseQueryApi) => + UpdateFromSocket({ + updateQueryData: (updateFn) => + vNetworkApi.util.updateQueryData( + 'getVNetworks', + undefined, + updateFn + ), + resource: 'net', + })(id, baseQueryApi), }), allocateVnet: builder.mutation({ /** diff --git a/src/fireedge/src/client/features/OneApi/socket.js b/src/fireedge/src/client/features/OneApi/socket.js index ac3cdc5b9e..a4e8ed5a36 100644 --- a/src/fireedge/src/client/features/OneApi/socket.js +++ b/src/fireedge/src/client/features/OneApi/socket.js @@ -25,7 +25,7 @@ import { WEBSOCKET_URL, SOCKETS } from 'client/constants' /** * @typedef {object} HookStateMessage - Hook message from OpenNebula API * @property {'STATE'} HOOK_TYPE - Type of event API - * @property {('VM'|'HOST'|'IMAGE')} HOOK_OBJECT - Type name of the resource + * @property {('VM'|'HOST'|'IMAGE'|'NET')} HOOK_OBJECT - Type name of the resource * @property {string} STATE - The state that triggers the hook. * @property {string} [LCM_STATE] * - The LCM state that triggers the hook (Only for VM hooks) @@ -37,6 +37,7 @@ import { WEBSOCKET_URL, SOCKETS } from 'client/constants' * @property {object} [VM] - New data of the VM * @property {object} [HOST] - New data of the HOST * @property {object} [IMAGE] - New data of the IMAGE + * @property {object} [VNET] - New data of the VNET */ /** @@ -57,13 +58,20 @@ const createWebsocket = (path, query) => /** * @param {HookStateData} data - Event data from hook event STATE - * @returns {{name: ('vm'|'host'|'image'), value: object}} + * @returns {{name: ('vm'|'host'|'image'|'net'), value: object}} * - Name and new value of resource */ const getResourceFromEventState = (data) => { - const { HOOK_OBJECT: name, [name]: value } = data?.HOOK_MESSAGE ?? {} + const { HOOK_OBJECT: name } = data?.HOOK_MESSAGE ?? {} - return { name: String(name).toLowerCase(), value } + const ensuredValue = + data?.HOOK_MESSAGE?.[name] ?? + data?.HOOK_MESSAGE?.VM ?? + data?.HOOK_MESSAGE?.HOST ?? + data?.HOOK_MESSAGE?.IMAGE ?? + data?.HOOK_MESSAGE?.VNET + + return { name: String(name).toLowerCase(), value: ensuredValue } } /** diff --git a/src/fireedge/src/client/models/Datastore.js b/src/fireedge/src/client/models/Datastore.js index 7965c365ba..70f4d11bda 100644 --- a/src/fireedge/src/client/models/Datastore.js +++ b/src/fireedge/src/client/models/Datastore.js @@ -14,7 +14,7 @@ * limitations under the License. * * ------------------------------------------------------------------------- */ import { prettyBytes } from 'client/utils' -import { DATASTORE_STATES, DATASTORE_TYPES, StateInfo } from 'client/constants' +import { DATASTORE_STATES, DATASTORE_TYPES, STATES } from 'client/constants' /** * Returns the datastore type name. @@ -30,7 +30,7 @@ export const getType = ({ TYPE } = {}) => DATASTORE_TYPES[TYPE] * * @param {object} datastore - Datastore * @param {number} datastore.STATE - Datastore state ID - * @returns {StateInfo} - Datastore state object + * @returns {STATES.StateInfo} - Datastore state object */ export const getState = ({ STATE = 0 } = {}) => DATASTORE_STATES[STATE] diff --git a/src/fireedge/src/client/models/Helper.js b/src/fireedge/src/client/models/Helper.js index 5af6860404..157a5b18ad 100644 --- a/src/fireedge/src/client/models/Helper.js +++ b/src/fireedge/src/client/models/Helper.js @@ -531,3 +531,15 @@ export const getColorFromString = (text, options = {}) => { return `#${hex.padEnd(6, hex)}` } + +/** + * @param {object} resource - OpenNebula resource + * @returns {string} Error message from resource + */ +export const getErrorMessage = (resource) => { + const { USER_TEMPLATE, TEMPLATE } = resource ?? {} + const { ERROR, SCHED_MESSAGE } = USER_TEMPLATE ?? {} + const { ERROR: templateError } = TEMPLATE ?? {} + + return [ERROR, SCHED_MESSAGE, templateError].filter(Boolean)[0] +} diff --git a/src/fireedge/src/client/models/Host.js b/src/fireedge/src/client/models/Host.js index 55f337c4df..3e3b08111a 100644 --- a/src/fireedge/src/client/models/Host.js +++ b/src/fireedge/src/client/models/Host.js @@ -19,10 +19,10 @@ import { CUSTOM_HOST_HYPERVISOR, Host, HOST_STATES, + STATES, HYPERVISORS, NumaNode, PciDevice, - StateInfo, } from 'client/constants' import { useGetOneConfigQuery } from 'client/features/OneApi/system' @@ -30,7 +30,7 @@ import { useGetOneConfigQuery } from 'client/features/OneApi/system' * Returns information about the host state. * * @param {Host} host - Host - * @returns {StateInfo} Host state object + * @returns {STATES.StateInfo} Host state object */ export const getState = (host) => HOST_STATES[+host?.STATE ?? 0] diff --git a/src/fireedge/src/client/models/Image.js b/src/fireedge/src/client/models/Image.js index d63ac2e79c..09b58a91b1 100644 --- a/src/fireedge/src/client/models/Image.js +++ b/src/fireedge/src/client/models/Image.js @@ -17,7 +17,7 @@ import { IMAGE_TYPES, DISK_TYPES, IMAGE_STATES, - StateInfo, + STATES, Image, } from 'client/constants' import { prettyBytes } from 'client/utils' @@ -35,7 +35,7 @@ export const getType = ({ TYPE } = {}) => * Returns the image state. * * @param {Image} image - Image - * @returns {StateInfo} - Image state information + * @returns {STATES.StateInfo} - Image state information */ export const getState = ({ STATE } = {}) => IMAGE_STATES[+STATE] diff --git a/src/fireedge/src/client/models/Marketplace.js b/src/fireedge/src/client/models/Marketplace.js index 2c6003c2ba..e458e1ab24 100644 --- a/src/fireedge/src/client/models/Marketplace.js +++ b/src/fireedge/src/client/models/Marketplace.js @@ -14,13 +14,13 @@ * limitations under the License. * * ------------------------------------------------------------------------- */ import { prettyBytes } from 'client/utils' -import { MARKETPLACE_STATES, StateInfo, Marketplace } from 'client/constants' +import { MARKETPLACE_STATES, STATES, Marketplace } from 'client/constants' /** * Returns the marketplace state. * * @param {Marketplace} marketplace - Marketplace - * @returns {StateInfo} Marketplace state information + * @returns {STATES.StateInfo} Marketplace state information */ export const getState = ({ STATE } = {}) => MARKETPLACE_STATES[+STATE] diff --git a/src/fireedge/src/client/models/MarketplaceApp.js b/src/fireedge/src/client/models/MarketplaceApp.js index 07251ca574..bffb9947df 100644 --- a/src/fireedge/src/client/models/MarketplaceApp.js +++ b/src/fireedge/src/client/models/MarketplaceApp.js @@ -14,9 +14,9 @@ * limitations under the License. * * ------------------------------------------------------------------------- */ import { + STATES, MARKETPLACE_APP_STATES, MARKETPLACE_APP_TYPES, - StateInfo, } from 'client/constants' /** @@ -33,6 +33,6 @@ export const getType = ({ TYPE = 0 } = {}) => MARKETPLACE_APP_TYPES[+TYPE] * * @param {object} marketplaceApp - Marketplace app * @param {number|string} marketplaceApp.STATE - State - * @returns {StateInfo} Marketplace app state information + * @returns {STATES.StateInfo} Marketplace app state information */ export const getState = ({ STATE = 0 } = {}) => MARKETPLACE_APP_STATES[+STATE] diff --git a/src/fireedge/src/client/models/VirtualMachine.js b/src/fireedge/src/client/models/VirtualMachine.js index 02e2a5ff39..ea39d61b41 100644 --- a/src/fireedge/src/client/models/VirtualMachine.js +++ b/src/fireedge/src/client/models/VirtualMachine.js @@ -29,7 +29,6 @@ import { EXTERNAL_IP_ATTRS, HISTORY_ACTIONS, HYPERVISORS, - StateInfo, VM, Disk, Nic, @@ -97,7 +96,7 @@ export const isVCenter = (vm) => getHypervisor(vm) === HYPERVISORS.vcenter /** * @param {VM} vm - Virtual machine - * @returns {StateInfo} State information from resource + * @returns {STATES.StateInfo} State information from resource */ export const getState = (vm) => { const { STATE, LCM_STATE } = vm ?? {} @@ -106,28 +105,6 @@ export const getState = (vm) => { return state?.name === STATES.ACTIVE ? VM_LCM_STATES[+LCM_STATE] : state } -/** - * @param {VM} vm - Virtual machine - * @returns {string[]} Labels from resource - */ -export const getLabels = (vm) => { - const { USER_TEMPLATE } = vm ?? {} - const { LABELS } = USER_TEMPLATE ?? {} - - return LABELS?.split(',') ?? [] -} - -/** - * @param {VM} vm - Virtual machine - * @returns {string} Error message from resource - */ -export const getErrorMessage = (vm) => { - const { USER_TEMPLATE } = vm ?? {} - const { ERROR, SCHED_MESSAGE } = USER_TEMPLATE ?? {} - - return [ERROR, SCHED_MESSAGE].filter(Boolean)[0] -} - /** * @param {VM} vm - Virtual machine * @returns {Disk[]} List of disks from resource diff --git a/src/fireedge/src/client/models/VirtualNetwork.js b/src/fireedge/src/client/models/VirtualNetwork.js index a1c826f5de..e6fd8a08b8 100644 --- a/src/fireedge/src/client/models/VirtualNetwork.js +++ b/src/fireedge/src/client/models/VirtualNetwork.js @@ -13,7 +13,23 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ -import { VirtualNetwork } from 'client/constants' +import { VirtualNetwork, VN_STATES, STATES } from 'client/constants' + +/** + * Returns the state of the virtual network. + * + * @param {VirtualNetwork} virtualNetwork - Virtual network + * @returns {STATES.StateInfo} State information from resource + */ +export const getState = ({ STATE = 0 } = {}) => VN_STATES[+STATE] + +/** + * Returns the Virtual Network Manager name. + * + * @param {VirtualNetwork} virtualNetwork - Virtual network + * @returns {string} Virtual Network Manager + */ +export const getVNManager = (virtualNetwork) => virtualNetwork?.VN_MAD /** * Returns the total number of leases in the virtual network. diff --git a/src/fireedge/src/client/models/Zone.js b/src/fireedge/src/client/models/Zone.js index 1d429270e4..946828a521 100644 --- a/src/fireedge/src/client/models/Zone.js +++ b/src/fireedge/src/client/models/Zone.js @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * * limitations under the License. * * ------------------------------------------------------------------------- */ -import { ZONE_STATES, StateInfo } from 'client/constants' +import { STATES, ZONE_STATES } from 'client/constants' /** * Returns state information about the zone. * * @param {object} zone - Zone * @param {number|string} zone.STATE - State - * @returns {StateInfo} State information + * @returns {STATES.StateInfo} State information */ export const getState = ({ STATE = 0 } = {}) => ZONE_STATES[+STATE] diff --git a/src/fireedge/src/server/utils/constants/commands/user.js b/src/fireedge/src/server/utils/constants/commands/user.js index 707a6265ca..d0172da7a2 100644 --- a/src/fireedge/src/server/utils/constants/commands/user.js +++ b/src/fireedge/src/server/utils/constants/commands/user.js @@ -137,7 +137,7 @@ module.exports = { }, replace: { from: postBody, - default: 1, + default: 0, }, }, }, diff --git a/src/fireedge/src/server/utils/constants/defaults.js b/src/fireedge/src/server/utils/constants/defaults.js index 1cf6a04ac4..4ecab3c53e 100644 --- a/src/fireedge/src/server/utils/constants/defaults.js +++ b/src/fireedge/src/server/utils/constants/defaults.js @@ -183,6 +183,11 @@ const defaults = { 'oneprovision_optional_create_command', ], }, + + /** HOOK OBJECT NAMES */ + hookObjectNames: { + vn: 'net', + }, } module.exports = defaults diff --git a/src/fireedge/src/server/utils/opennebula.js b/src/fireedge/src/server/utils/opennebula.js index 6e8175b99b..92bb12dee3 100644 --- a/src/fireedge/src/server/utils/opennebula.js +++ b/src/fireedge/src/server/utils/opennebula.js @@ -30,6 +30,7 @@ const { defaultEmptyFunction, defaultNamespace, defaultMessageProblemOpennebula, + hookObjectNames, } = defaults const { getFireedgeConfig } = require('server/utils/yml') @@ -91,7 +92,11 @@ const fillResourceforHookConnection = ( if (!global.users[username].resourcesHooks) { global.users[username].resourcesHooks = {} } - global.users[username].resourcesHooks[match[1]] = parameters[0] + + const resourceName = match[1] + const ensuredName = hookObjectNames[resourceName] || resourceName + + global.users[username].resourcesHooks[ensuredName] = parameters[0] } } diff --git a/src/fireedge/src/server/utils/server.js b/src/fireedge/src/server/utils/server.js index f02e476418..9be39e35fa 100644 --- a/src/fireedge/src/server/utils/server.js +++ b/src/fireedge/src/server/utils/server.js @@ -204,6 +204,7 @@ const middlewareValidateResourceForHookConnection = ( next = () => undefined ) => { const { id, resource, username } = getResourceDataForRequest(server) + if ( id && resource &&