@@ -87,23 +80,27 @@ const TotalProviders = ({ isLoading }) => {
[classes, chartData]
)
- return useMemo(
- () =>
- !totalProviders && isLoading ? (
-
- ) : (
-
- {title}
-
- {chart}
- {legend}
-
-
- ),
- [classes, chart, totalProviders, isLoading]
+ return (
+
+
+
+ {isLoading ? (
+
+ ) : (
+
+ )}
+ {T.Providers}
+
+ {T.InTotal}
+
+
+ {chart}
+ {legend}
+
+
)
}
diff --git a/src/fireedge/src/client/components/Widgets/TotalProvisionInfrastructures.js b/src/fireedge/src/client/components/Widgets/TotalProvisionInfrastructures.js
deleted file mode 100644
index 648f87c2e8..0000000000
--- a/src/fireedge/src/client/components/Widgets/TotalProvisionInfrastructures.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useMemo } from 'react'
-
-import {
- Server as ClusterIcon,
- HardDrive as HostIcon,
- Folder as DatastoreIcon,
- NetworkAlt as NetworkIcon,
-} from 'iconoir-react'
-import { Skeleton, Grid } from '@mui/material'
-
-import { useProvision } from 'client/features/One'
-import NumberEasing from 'client/components/NumberEasing'
-import { WavesCard } from 'client/components/Cards'
-import { get } from 'client/utils'
-import { T } from 'client/constants'
-
-const TOTAL_WIDGETS = 4
-const breakpoints = { xs: 12, sm: 6, md: 3 }
-
-const TotalProvisionInfrastructures = ({ isLoading }) => {
- const provisions = useProvision()
-
- const provisionsByProvider = useMemo(
- () =>
- provisions?.map((provision) => ({
- provider: get(provision, 'TEMPLATE.BODY.provider'),
- clusters: get(
- provision,
- 'TEMPLATE.BODY.provision.infrastructure.clusters',
- []
- ).length,
- hosts: get(
- provision,
- 'TEMPLATE.BODY.provision.infrastructure.hosts',
- []
- ).length,
- networks: get(
- provision,
- 'TEMPLATE.BODY.provision.infrastructure.networks',
- []
- ).length,
- datastores: get(
- provision,
- 'TEMPLATE.BODY.provision.infrastructure.datastores',
- []
- ).length,
- })),
- [provisions]
- )
-
- const totals = useMemo(
- () =>
- provisionsByProvider?.reduce(
- (total, { clusters, hosts, datastores, networks }) => ({
- clusters: clusters + total.clusters,
- hosts: hosts + total.hosts,
- datastores: datastores + total.datastores,
- networks: networks + total.networks,
- }),
- { clusters: 0, hosts: 0, datastores: 0, networks: 0 }
- ),
- [provisionsByProvider]
- )
-
- return useMemo(
- () => (
-
- {!totals?.clusters?.length && isLoading ? (
- Array.from(Array(TOTAL_WIDGETS)).map((_, index) => (
-
-
-
- ))
- ) : (
- <>
-
- }
- bgColor="#fa7892"
- icon={ClusterIcon}
- />
-
-
- }
- bgColor="#b25aff"
- icon={HostIcon}
- />
-
-
- }
- bgColor="#1fbbc6"
- icon={DatastoreIcon}
- />
-
-
- }
- bgColor="#f09d42"
- icon={NetworkIcon}
- />
-
- >
- )}
-
- ),
- [totals?.clusters, isLoading]
- )
-}
-
-TotalProvisionInfrastructures.displayName = 'TotalProvisionInfrastructures'
-
-export default TotalProvisionInfrastructures
diff --git a/src/fireedge/src/client/components/Widgets/TotalProvisionsByState/index.js b/src/fireedge/src/client/components/Widgets/TotalProvisionsByState/index.js
index 2d2b4a1767..90fee95814 100644
--- a/src/fireedge/src/client/components/Widgets/TotalProvisionsByState/index.js
+++ b/src/fireedge/src/client/components/Widgets/TotalProvisionsByState/index.js
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useMemo } from 'react'
+import { useMemo, ReactElement } from 'react'
-import { Skeleton, Paper, Typography } from '@mui/material'
+import { Paper, Typography, CircularProgress } from '@mui/material'
-import { useProvision } from 'client/features/One'
+import { useGetProvisionsQuery } from 'client/features/OneApi/provision'
import { SingleBar } from 'client/components/Charts'
import NumberEasing from 'client/components/NumberEasing'
import { groupBy } from 'client/utils'
@@ -26,9 +25,14 @@ import { T, PROVISIONS_STATES } from 'client/constants'
import useStyles from 'client/components/Widgets/TotalProvisionsByState/styles'
-const TotalProvisionsByState = ({ isLoading }) => {
+/**
+ * Renders a widget to display the provisions grouped by state.
+ *
+ * @returns {ReactElement} Total provisions by state
+ */
+const TotalProvisionsByState = () => {
const classes = useStyles()
- const provisions = useProvision()
+ const { data: provisions = [], isLoading } = useGetProvisionsQuery()
const totalProvisions = provisions?.length
const chartData = useMemo(() => {
@@ -39,39 +43,30 @@ const TotalProvisionsByState = ({ isLoading }) => {
)
}, [totalProvisions])
- const title = useMemo(
- () => (
+ return (
+
-
+ {isLoading ? (
+
+ ) : (
+
+ )}
{T.Provisions}
{T.InTotal}
- ),
- [classes, totalProvisions]
- )
-
- return useMemo(
- () =>
- !totalProvisions && isLoading ? (
-
- ) : (
-
- {title}
-
-
-
-
- ),
- [classes, chartData, totalProvisions, isLoading]
+
+
+
+
)
}
diff --git a/src/fireedge/src/client/components/Widgets/TotalSunstoneResources.js b/src/fireedge/src/client/components/Widgets/TotalSunstoneResources.js
deleted file mode 100644
index 23e15c1181..0000000000
--- a/src/fireedge/src/client/components/Widgets/TotalSunstoneResources.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useMemo } from 'react'
-
-import {
- User as UserIcon,
- Group as GroupIcon,
- Archive as ImageIcon,
- NetworkAlt as NetworkIcon,
-} from 'iconoir-react'
-import { Skeleton, Grid } from '@mui/material'
-
-import { useUser, useGroup, useImage, useVNetwork } from 'client/features/One'
-import NumberEasing from 'client/components/NumberEasing'
-import { WavesCard } from 'client/components/Cards'
-import { T } from 'client/constants'
-
-const TOTAL_WIDGETS = 4
-const breakpoints = { xs: 12, sm: 6, md: 3 }
-
-const TotalProvisionInfrastructures = ({ isLoading }) => {
- const users = useUser()
- const groups = useGroup()
- const images = useImage()
- const vNetworks = useVNetwork()
-
- return useMemo(
- () => (
-
- {!users?.length && isLoading ? (
- Array.from(Array(TOTAL_WIDGETS)).map((_, index) => (
-
-
-
- ))
- ) : (
- <>
-
- }
- bgColor="#fa7892"
- icon={UserIcon}
- />
-
-
- }
- bgColor="#b25aff"
- icon={GroupIcon}
- />
-
-
- }
- bgColor="#1fbbc6"
- icon={ImageIcon}
- />
-
-
- }
- bgColor="#f09d42"
- icon={NetworkIcon}
- />
-
- >
- )}
-
- ),
- [users?.length, isLoading]
- )
-}
-
-TotalProvisionInfrastructures.displayName = 'TotalProvisionInfrastructures'
-
-export default TotalProvisionInfrastructures
diff --git a/src/fireedge/src/client/components/Widgets/index.js b/src/fireedge/src/client/components/Widgets/index.js
index 50f5af8d83..50b3d3bb67 100644
--- a/src/fireedge/src/client/components/Widgets/index.js
+++ b/src/fireedge/src/client/components/Widgets/index.js
@@ -15,12 +15,5 @@
* ------------------------------------------------------------------------- */
import TotalProviders from 'client/components/Widgets/TotalProviders'
import TotalProvisionsByState from 'client/components/Widgets/TotalProvisionsByState'
-import TotalProvisionInfrastructures from 'client/components/Widgets/TotalProvisionInfrastructures'
-import TotalSunstoneResources from 'client/components/Widgets/TotalSunstoneResources'
-export {
- TotalProviders,
- TotalProvisionInfrastructures,
- TotalProvisionsByState,
- TotalSunstoneResources,
-}
+export { TotalProviders, TotalProvisionsByState }
diff --git a/src/fireedge/src/client/constants/cluster.js b/src/fireedge/src/client/constants/cluster.js
index 555f6f9873..5f2c25ff6c 100644
--- a/src/fireedge/src/client/constants/cluster.js
+++ b/src/fireedge/src/client/constants/cluster.js
@@ -15,6 +15,18 @@
* ------------------------------------------------------------------------- */
import * as ACTIONS from 'client/constants/actions'
+/**
+ * @typedef Cluster
+ * @property {string} ID - Id
+ * @property {string} NAME - Name
+ * @property {{ ID: string|string[] }} HOSTS - Hosts
+ * @property {{ ID: string|string[] }} DATASTORES - Datastores
+ * @property {{ ID: string|string[] }} VNETS - Virtual networks
+ * @property {object} TEMPLATE - Template
+ * @property {string} [TEMPLATE.RESERVED_MEM] - Reserved memory
+ * @property {string} [TEMPLATE.RESERVED_CPU] - Reserved CPU
+ */
+
/** @enum {string} Cluster actions */
export const CLUSTER_ACTIONS = {
CREATE_DIALOG: 'create_dialog',
diff --git a/src/fireedge/src/client/constants/common.js b/src/fireedge/src/client/constants/common.js
new file mode 100644
index 0000000000..fa559f4d54
--- /dev/null
+++ b/src/fireedge/src/client/constants/common.js
@@ -0,0 +1,58 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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. *
+ * ------------------------------------------------------------------------- */
+
+/**
+ * @typedef {'1'|'2'|'3'|'4'} LockLevel
+ * - `USE` (1): locks Admin, Manage and Use actions.
+ * - `MANAGE` (2): locks Manage and Use actions.
+ * - `ADMIN` (3): locks only Admin actions.
+ * - `ALL` (4): locks all actions.
+ */
+
+/**
+ * @typedef {object} LockInfo
+ * @property {'0'|'1'} LOCKED - If `1` is locked
+ * @property {string|number} OWNER - Owner
+ * @property {string|number} TIME - Time
+ * @property {string|number} REQ_ID - Request id
+ */
+
+/**
+ * @typedef {number|'-4'|'-3'|'-2'|'-1'} FilterFlag
+ * - `-4`: Resources belonging to the user’s primary group
+ * - `-3`: Resources belonging to the user
+ * - `-2`: All resources
+ * - `-1`: Resources belonging to the user and any of his groups
+ * - `>= 0`: UID User’s Resources
+ */
+
+/** @typedef {'0'|'1'} Permission */
+
+/**
+ * @typedef {object} Permissions
+ * @property {Permission} OWNER_U - Owner use
+ * @property {Permission} OWNER_M - Owner manage
+ * @property {Permission} OWNER_A - Owner administrator
+ * @property {Permission} GROUP_U - Group use
+ * @property {Permission} GROUP_M - Group manage
+ * @property {Permission} GROUP_A - Group administrator
+ * @property {Permission} OTHER_U - Other use
+ * @property {Permission} OTHER_M - Other manage
+ * @property {Permission} OTHER_A - Other administrator
+ */
+
+export const YES_VALUE = 'YES'
+export const NO_VALUE = 'NO'
diff --git a/src/fireedge/src/client/constants/datastore.js b/src/fireedge/src/client/constants/datastore.js
index c83d716aa0..56aebb7418 100644
--- a/src/fireedge/src/client/constants/datastore.js
+++ b/src/fireedge/src/client/constants/datastore.js
@@ -13,8 +13,45 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
+import * as ACTIONS from 'client/constants/actions'
import * as STATES from 'client/constants/states'
import COLOR from 'client/constants/color'
+// eslint-disable-next-line no-unused-vars
+import { DISK_TYPES_STR } from 'client/constants/image'
+// eslint-disable-next-line no-unused-vars
+import { Permissions } from 'client/constants/common'
+
+/**
+ * @typedef Datastore
+ * @property {string|number} ID - Id
+ * @property {string} NAME - Name
+ * @property {string|number} UID - User id
+ * @property {string} UNAME - User name
+ * @property {string|number} GID - Group id
+ * @property {string} GNAME - Group name
+ * @property {0|1} STATE - Possible STATE values are 0 (READY) and 1 (DISABLE)
+ * @property {Permissions} [PERMISSIONS] - Permissions
+ * @property {string} DS_MAD - Datastore driver name
+ * @property {string} TM_MAD - Transfer driver name
+ * @property {string} BASE_PATH - Datastore directory
+ * @property {DATASTORE_TYPES} TYPE - Type
+ * @property {DISK_TYPES_STR} DISK_TYPE - Disk type
+ * @property {{ ID: string[] }} CLUSTERS - Clusters
+ * @property {{ ID: string[] }} IMAGES - Images
+ * @property {string|number} TOTAL_MB - Total capacity
+ * @property {string|number} FREE_MB - Free capacity
+ * @property {string|number} USED_MB - Used capacity
+ * @property {object} TEMPLATE - Template
+ * @property {string} [TEMPLATE.RESTRICTED_DIRS] - Paths that cannot be used to register images. A space separated list of paths.
+ * @property {string} [TEMPLATE.SAFE_DIRS] - If you need to allow a directory listed under RESTRICTED_DIRS. A space separated list of paths.
+ * @property {string} [TEMPLATE.ALLOW_ORPHANS] - Safe directories
+ * @property {string} [TEMPLATE.VCENTER_DC_NAME] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_DC_REF] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_DS_NAME] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_DS_REF] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_HOST] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_INSTANCE_ID] - vCenter information
+ */
/** @type {string[]} Datastore type information */
export const DATASTORE_TYPES = ['IMAGE', 'SYSTEM', 'FILE']
@@ -32,3 +69,15 @@ export const DATASTORE_STATES = [
color: COLOR.error.dark,
},
]
+
+/** @enum {string} Datastore actions */
+export const DATASTORE_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,
+}
diff --git a/src/fireedge/src/client/constants/group.js b/src/fireedge/src/client/constants/group.js
new file mode 100644
index 0000000000..3e33bdeb41
--- /dev/null
+++ b/src/fireedge/src/client/constants/group.js
@@ -0,0 +1,46 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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. *
+ * ------------------------------------------------------------------------- */
+// eslint-disable-next-line prettier/prettier, no-unused-vars
+import { VmQuota, NetworkQuota, DatastoreQuota, ImageQuota } from 'client/constants/quota'
+import * as ACTIONS from 'client/constants/actions'
+
+/**
+ * @typedef Group
+ * @property {string|number} ID - Id
+ * @property {string} NAME - Name
+ * @property {{ ID: string[] }} [USERS] - List of user ids
+ * @property {{ ID: string[] }} [ADMINS] - List of admin ids
+ * @property {string|number} TEMPLATE - Template
+ * @property {{ DATASTORE: DatastoreQuota|DatastoreQuota[] }} [DATASTORE_QUOTA] - Datastore quotas
+ * @property {{ NETWORK: NetworkQuota|NetworkQuota[] }} [NETWORK_QUOTA] - Network quotas
+ * @property {{ VM: VmQuota }} [VM_QUOTA] - VM quotas
+ * @property {{ IMAGE: ImageQuota|ImageQuota[] }} [IMAGE_QUOTA] - Image quotas
+ * @property {{
+ * DATASTORE: DatastoreQuota|DatastoreQuota[],
+ * NETWORK: NetworkQuota|NetworkQuota[],
+ * VM: VmQuota,
+ * IMAGE: ImageQuota|ImageQuota[]
+ * }} [DEFAULT_GROUP_QUOTAS] - Default quotas
+ */
+
+export const GROUP_ACTIONS = {
+ REFRESH: ACTIONS.REFRESH,
+ CREATE_DIALOG: 'create_dialog',
+ UPDATE_DIALOG: 'update_dialog',
+ QUOTAS_DIALOG: 'quotas_dialog',
+ DELETE: 'delete',
+ EDIT_ADMINS: 'edit_admins',
+}
diff --git a/src/fireedge/src/client/constants/host.js b/src/fireedge/src/client/constants/host.js
index f1a3b702c8..d52e0d2705 100644
--- a/src/fireedge/src/client/constants/host.js
+++ b/src/fireedge/src/client/constants/host.js
@@ -19,18 +19,108 @@ import COLOR from 'client/constants/color'
/**
* @typedef {object} PciDevice - PCI device
- * @property {string} DOMAIN - PCI address domain
- * @property {string} BUS - PCI address bus
- * @property {string} SLOT - PCI address slot
- * @property {string} FUNCTION - PCI address function
- * @property {string} ADDRESS - PCI address, bus, slot and function
- * @property {string} DEVICE - Id of PCI device
+ * @property {string} ADDRESS - Address, bus, slot and function
+ * @property {string} BUS - Address bus
* @property {string} CLASS - Id of PCI device class
- * @property {string} VENDOR - Id of PCI device vendor
- * @property {string} VMID - Id using this device, -1 if free
- * @property {string} [DEVICE_NAME] - Name of PCI device
- * @property {string} [VENDOR_NAME] - Name of PCI device vendor
* @property {string} [CLASS_NAME] - Name of PCI device class
+ * @property {string} DEVICE - Id of PCI device
+ * @property {string} [DEVICE_NAME] - Name of PCI device
+ * @property {string} DOMAIN - Address domain
+ * @property {string} FUNCTION - Address function
+ * @property {string} NUMA_NODE - Numa node
+ * @property {string} SHORT_ADDRESS - Short address
+ * @property {string} SLOT - Address slot
+ * @property {string} TYPE - Type
+ * @property {string} VENDOR - Id of PCI device vendor
+ * @property {string} [VENDOR_NAME] - Name of PCI device vendor
+ * @property {string|number} VMID - Id using this device, -1 if free
+ */
+
+/**
+ * @typedef {object} Core - Core
+ * @property {string} ID -
+ * @property {string} CPUS -
+ * @property {string} DEDICATED -
+ * @property {string} FREE -
+ */
+
+/**
+ * @typedef {object} HugePage - HugePage
+ * @property {string} FREE -
+ * @property {string} SIZE -
+ * @property {string} USAGE -
+ * @property {string} DEDICATED -
+ */
+
+/**
+ * @typedef {object} NumaNode - Numa node
+ * @property {string|number} NODE_ID -
+ * @property {Core|Core[]} CORE -
+ * @property {HugePage|HugePage[]} HUGEPAGE -
+ * @property {object} MEMORY -
+ * @property {string} MEMORY.DISTANCE -
+ * @property {string|number} MEMORY.FREE -
+ * @property {string|number} MEMORY.TOTAL -
+ * @property {string|number} MEMORY.USAGE -
+ * @property {string|number} MEMORY.USED -
+ */
+
+/**
+ * @typedef Host
+ * @property {string|number} ID - Id
+ * @property {string} NAME - Name
+ * @property {string|number} STATE - State
+ * @property {string|number} PREV_STATE - Previously state
+ * @property {string} IM_MAD - Name of the Information Manager
+ * @property {string} VM_MAD - Name of the VM Manager
+ * @property {string|number} CLUSTER_ID - Cluster id
+ * @property {string} CLUSTER - Cluster name
+ * @property {object} HOST_SHARE - Host shared information
+ * @property {string|number} HOST_SHARE.MEM_USAGE - Memory used by all VMs running in the host
+ * @property {string|number} HOST_SHARE.CPU_USAGE - CPU used by all VMs running in the host
+ * @property {string|number} HOST_SHARE.TOTAL_MEM - Maximum memory that could be used for VMs
+ * @property {string|number} HOST_SHARE.TOTAL_CPU - Number of CPU’s multiplied by 100. For example, a 16 cores machine will have a value of 1600
+ * @property {string|number} HOST_SHARE.MAX_MEM - Total memory in the host
+ * @property {string|number} HOST_SHARE.MAX_CPU - Percentage, Total CPU in the host (cores * 100)
+ * @property {string|number} HOST_SHARE.RUNNING_VMS - Running VMs
+ * @property {string|number} HOST_SHARE.VMS_THREAD - Thread VMs
+ * @property {object} HOST_SHARE.DATASTORES - Datastores information
+ * @property {string|number} HOST_SHARE.DATASTORES.DISK_USAGE - Disk used by all datastores
+ * @property {string|number} HOST_SHARE.DATASTORES.FREE_DISK - Free disk in the datastores
+ * @property {string|number} HOST_SHARE.DATASTORES.MAX_DISK - Maximum of disk in the datastores
+ * @property {string|number} HOST_SHARE.DATASTORES.USED_DISK - Used disk
+ * @property {{ PCI: PciDevice|PciDevice[] }} HOST_SHARE.PCI_DEVICES - List of PCI devices
+ * @property {{ NODE: NumaNode|NumaNode[] }} HOST_SHARE.NUMA_NODES - List of NUMA nodes
+ * @property {{ ID: string|string[] }} VMS - List of VM ids
+ * @property {object} TEMPLATE - Host template
+ * @property {string} [TEMPLATE.ARCH] - Architecture
+ * @property {string} [TEMPLATE.CPUSPEED] - CPU speed
+ * @property {string} [TEMPLATE.HOSTNAME] - Host name
+ * @property {string} [TEMPLATE.HYPERVISOR] - Hypervisor name
+ * @property {string} [TEMPLATE.IM_MAD] - Information manager
+ * @property {string} [TEMPLATE.VM_MAD] - VM manager
+ * @property {string} [TEMPLATE.KVM_CPU_MODEL] - KVM CPU model
+ * @property {string} [TEMPLATE.KVM_CPU_MODELS] - KVM CPU models
+ * @property {string} [TEMPLATE.VCENTER_CCR_REF] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_DS_REF] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_HOST] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_INSTANCE_ID] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_NAME] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_PASSWORD] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_RESOURCE_POOL_INFO] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_USER] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_VERSION] - vCenter information
+ * @property {string} [TEMPLATE.VERSION] - Version
+ * @property {object} MONITORING - Monitoring information
+ * @property {string} [MONITORING.TIMESTAMP] - Timestamp
+ * @property {object} [MONITORING.CAPACITY] - Capacity information
+ * @property {string} [MONITORING.CAPACITY.FREE_CPU] - Percentage, Free CPU as returned by the probes
+ * @property {string} [MONITORING.CAPACITY.FREE_MEMORY] - Free MEMORY returned by the probes
+ * @property {string} [MONITORING.CAPACITY.USED_CPU] - Percentage of CPU used by all host processes (including VMs) over a total of (cores * 100)
+ * @property {string} [MONITORING.CAPACITY.USED_MEMORY] - Memory used by all host processes (including VMs) over a total of MAX_MEM
+ * @property {object} [MONITORING.SYSTEM] - System information
+ * @property {object} [MONITORING.SYSTEM.NETRX] - Received bytes from the network
+ * @property {object} [MONITORING.SYSTEM.NETTX] - Sent bytes to the network
*/
/** @type {STATES.StateInfo[]} Host states */
@@ -87,7 +177,7 @@ export const HOST_ACTIONS = {
REFRESH: ACTIONS.REFRESH,
CREATE_DIALOG: 'create_dialog',
RENAME: ACTIONS.RENAME,
- ADD_TO_CLUSTER: 'addtocluster',
+ CHANGE_CLUSTER: 'change_cluster',
ENABLE: 'enable',
DISABLE: 'disable',
OFFLINE: 'offline',
diff --git a/src/fireedge/src/client/constants/image.js b/src/fireedge/src/client/constants/image.js
index cbcfc882d6..d79b7196c2 100644
--- a/src/fireedge/src/client/constants/image.js
+++ b/src/fireedge/src/client/constants/image.js
@@ -14,7 +14,46 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
import * as STATES from 'client/constants/states'
+import * as ACTIONS from 'client/constants/actions'
import COLOR from 'client/constants/color'
+// eslint-disable-next-line no-unused-vars
+import { Permissions, LockInfo } from 'client/constants/common'
+// eslint-disable-next-line no-unused-vars
+import { DiskSnapshots } from 'client/constants/vm'
+
+/**
+ * @typedef Image
+ * @property {string} ID - Id
+ * @property {string} NAME - Name
+ * @property {string} UID - User id
+ * @property {string} UNAME - User name
+ * @property {string} GID - Group id
+ * @property {string} GNAME - Group name
+ * @property {string} STATE - State
+ * @property {string} PREV_STATE - Previous state
+ * @property {Permissions} PERMISSIONS - Permissions
+ * @property {LockInfo} [LOCK] - Lock information
+ * @property {IMAGE_TYPES_STR} TYPE - Type
+ * @property {DISK_TYPES_STR} DISK_TYPE - Disk type
+ * @property {string} PERSISTENT - Persistent
+ * @property {string} REGTIME - Registration time
+ * @property {string} SOURCE - Source
+ * @property {string} PATH - Path
+ * @property {string} FORMAT - Format
+ * @property {string} FS - Filesystem
+ * @property {string} SIZE - Size
+ * @property {string} RUNNING_VMS - Running VMs
+ * @property {string} CLONING_OPS - Cloning OPs
+ * @property {string} CLONING_ID - Cloning id
+ * @property {string} TARGET_SNAPSHOT - Target snapshot
+ * @property {string} DATASTORE_ID - Datastore id
+ * @property {string} DATASTORE - Datastore
+ * @property {{ ID: string|string[] }} VMS - VMs
+ * @property {{ ID: string|string[] }} CLONES - Clones
+ * @property {{ ID: string|string[] }} APP_CLONES - App clones
+ * @property {object} TEMPLATE - Template
+ * @property {DiskSnapshots} SNAPSHOTS - Snapshots information
+ */
/** @enum {string} Image type */
export const IMAGE_TYPES_STR = {
@@ -121,3 +160,17 @@ export const IMAGE_STATES = [
color: COLOR.error.light,
},
]
+
+/** @enum {string} Image actions */
+export const IMAGE_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,
+ CHANGE_TYPE: 'chtype',
+ CHANGE_PERS: 'persistent',
+}
diff --git a/src/fireedge/src/client/constants/index.js b/src/fireedge/src/client/constants/index.js
index 18f8b9c1b7..71edd034f3 100644
--- a/src/fireedge/src/client/constants/index.js
+++ b/src/fireedge/src/client/constants/index.js
@@ -113,12 +113,19 @@ export const RESOURCE_NAMES = {
export * as T from 'client/constants/translates'
export * as ACTIONS from 'client/constants/actions'
export * as STATES from 'client/constants/states'
+export * from 'client/constants/common'
+export * from 'client/constants/quota'
+export * from 'client/constants/scheduler'
export * from 'client/constants/userInput'
export * from 'client/constants/flow'
export * from 'client/constants/provision'
+export * from 'client/constants/user'
+export * from 'client/constants/group'
export * from 'client/constants/cluster'
export * from 'client/constants/vm'
export * from 'client/constants/vmTemplate'
+export * from 'client/constants/network'
+export * from 'client/constants/networkTemplate'
export * from 'client/constants/host'
export * from 'client/constants/image'
export * from 'client/constants/marketplace'
diff --git a/src/fireedge/src/client/constants/marketplace.js b/src/fireedge/src/client/constants/marketplace.js
index 16922987eb..0d71ec1105 100644
--- a/src/fireedge/src/client/constants/marketplace.js
+++ b/src/fireedge/src/client/constants/marketplace.js
@@ -13,8 +13,35 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
+import * as ACTIONS from 'client/constants/actions'
import * as STATES from 'client/constants/states'
import COLOR from 'client/constants/color'
+// eslint-disable-next-line no-unused-vars
+import { Permissions } from 'client/constants/common'
+
+/**
+ * @typedef Marketplace
+ * @property {string} ID - Id
+ * @property {string} NAME - Name
+ * @property {string} UID - User id
+ * @property {string} UNAME - User name
+ * @property {string} GID - Group id
+ * @property {string} GNAME - Group name
+ * @property {0|1} STATE - Possible STATE values are 0 (ENABLE) and 1 (DISABLE)
+ * @property {Permissions} PERMISSIONS - Permissions
+ * @property {string} MARKET_MAD - Market manager
+ * @property {string} ZONE_ID - Zone id
+ * @property {string} TOTAL_MB - Total capacity
+ * @property {string} FREE_MB - Free capacity
+ * @property {string} USED_MB - Used capacity
+ * @property {{ ID: string|string[] }} MARKETPLACEAPPS - Marketplace apps
+ * @property {object} TEMPLATE - Template information
+ * @property {string} [TEMPLATE.RESTRICTED_DIRS] - Restricted directory
+ * @property {string} [TEMPLATE.SAFE_DIRS] - Safe directory
+ * @property {string} [TEMPLATE.SHARED] - `YES` if it's shared
+ * @property {string} [TEMPLATE.TYPE] - Type
+ * @property {string} [TEMPLATE.TM_MAD] - TM manager
+ */
/** @type {STATES.StateInfo[]} Marketplace states */
export const MARKETPLACE_STATES = [
@@ -73,3 +100,15 @@ export const MARKETPLACE_APP_STATES = [
color: COLOR.debug.light,
},
]
+
+/** @enum {string} Datastore actions */
+export const MARKETPLACE_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,
+}
diff --git a/src/fireedge/src/client/constants/marketplaceApp.js b/src/fireedge/src/client/constants/marketplaceApp.js
index 5e9d247941..04314a8d69 100644
--- a/src/fireedge/src/client/constants/marketplaceApp.js
+++ b/src/fireedge/src/client/constants/marketplaceApp.js
@@ -13,9 +13,44 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
+// eslint-disable-next-line no-unused-vars
+import { Permissions, LockInfo } from 'client/constants/common'
+import * as ACTIONS from 'client/constants/actions'
+
+/**
+ * @typedef MarketplaceApp
+ * @property {string|number} ID - Id
+ * @property {string} NAME - Name
+ * @property {string} DESCRIPTION - Description
+ * @property {string} UID - User id
+ * @property {string|number} GID - Group id
+ * @property {string} GNAME - Group name
+ * @property {string} UNAME - User name
+ * @property {string} STATE - State
+ * @property {Permissions} PERMISSIONS - Permissions
+ * @property {string|number} TYPE - Type
+ * @property {LockInfo} [LOCK] - Lock information
+ * @property {string} MARKETPLACE_ID - Marketplace id
+ * @property {string} MARKETPLACE - Marketplace name
+ * @property {string} SIZE - Size
+ * @property {string} REGTIME - Registration time
+ * @property {string} ZONE_ID - Zone id
+ * @property {string} ORIGIN_ID - Origin id
+ * @property {string} SOURCE - Source
+ * @property {string} MD5 - MD5
+ * @property {string} VERSION - Version
+ * @property {string} FORMAT - Format
+ * @property {object} TEMPLATE - Template information
+ * @property {string} [TEMPLATE.PUBLISHER] - Publisher
+ * @property {string} [TEMPLATE.TAGS] - Tags
+ * @property {string} [TEMPLATE.LINK] - Link
+ * @property {string} APPTEMPLATE64 - App template in base64
+ */
+
+/** @enum {string} Marketplace App actions */
export const MARKETPLACE_APP_ACTIONS = {
- REFRESH: 'refresh',
+ REFRESH: ACTIONS.REFRESH,
CREATE_DIALOG: 'create_dialog',
- RENAME: 'rename',
+ RENAME: ACTIONS.RENAME,
EXPORT: 'export',
}
diff --git a/src/fireedge/src/client/constants/network.js b/src/fireedge/src/client/constants/network.js
new file mode 100644
index 0000000000..22acab2e93
--- /dev/null
+++ b/src/fireedge/src/client/constants/network.js
@@ -0,0 +1,121 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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. *
+ * ------------------------------------------------------------------------- */
+// eslint-disable-next-line no-unused-vars
+import { Permissions, LockInfo } from 'client/constants/common'
+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_LINK] - IP6 link
+ * @property {string} [IP6_ULA] - IP6 ULA
+ * @property {string} MAC - MAC
+ * @property {string} [VM] - Virtual machine id
+ * @property {string} [VNET] - Virtual network id
+ * @property {string} [VROUTER] - Virtual router id
+ */
+
+/**
+ * @typedef AddressRange
+ * @property {string} AR_ID - Address range id
+ * @property {string} [IP] - IP
+ * @property {string} MAC - MAC
+ * @property {string} SIZE - Size
+ * @property {AR_TYPES} TYPE - Type
+ * @property {string} USED_LEASES - Used leases
+ * @property {{ LEASE: ARLease|ARLease[] }} [LEASES] - Leases information
+ * @property {string} [GLOBAL_PREFIX] -Global prefix
+ * @property {string} [PARENT_NETWORK_AR_ID] - Parent address range id
+ * @property {string} [ULA_PREFIX] - ULA prefix
+ * @property {string} [VN_MAD] - Virtual network manager
+ * @property {string} [MAC_END] - MAC end
+ * @property {string} [IP_END] - IP end
+ * @property {string} [IP6_ULA] - IP6 ULA
+ * @property {string} [IP6_ULA_END] - IP6 ULA end
+ * @property {string} [IP6_GLOBAL] - IP6 global
+ * @property {string} [IP6_GLOBAL_END] - IP6 global end
+ * @property {string} [IP6] - IP6
+ * @property {string} [IP6_END] - IP6 end
+ * @property {string} [PORT_START] - Port start
+ * @property {string} [PORT_SIZE] - Port size
+ */
+
+/**
+ * @typedef VirtualNetwork
+ * @property {string} ID - Id
+ * @property {string} NAME - Name
+ * @property {string} UID - User id
+ * @property {string} UNAME - User name
+ * @property {string} GID - Group id
+ * @property {string} GNAME - Group name
+ * @property {Permissions} PERMISSIONS - Permissions
+ * @property {LockInfo} [LOCK] - Lock information
+ * @property {{ ID: string|string[] }} CLUSTERS - Clusters
+ * @property {{ ID: string|string[] }} VROUTERS - Virtual routers
+ * @property {string} BRIDGE - Bridge
+ * @property {string} [BRIDGE_TYPE] - Bridge type
+ * @property {string} PARENT_NETWORK_ID - Parent network id
+ * @property {string} VN_MAD - Virtual network manager
+ * @property {string} PHYDEV - Physical dev
+ * @property {string} [VLAN_ID] - VLAN id
+ * @property {string} [OUTER_VLAN_ID] - Outer VLAN id
+ * @property {string} VLAN_ID_AUTOMATIC - VLAN id automatic
+ * @property {string} OUTER_VLAN_ID_AUTOMATIC - Outer VLAN id automatic
+ * @property {string} USED_LEASES - Used leases
+ * @property {{ AR: AddressRange|AddressRange[] }} AR_POOL - Address range information
+ * @property {object} TEMPLATE - Template
+ * @property {string} [TEMPLATE.DNS] - DNS
+ * @property {string} [TEMPLATE.GATEWAY] - Gateway
+ * @property {string} [TEMPLATE.GATEWAY6] - Gateway6
+ * @property {string} [TEMPLATE.GUEST_MTU] - Guest MTU
+ * @property {string} [TEMPLATE.IP6_METHOD] - IP6 method
+ * @property {string} [TEMPLATE.IP6_METRIC] - IP6 metric
+ * @property {string} [TEMPLATE.METHOD] - Method
+ * @property {string} [TEMPLATE.METRIC] - Metric
+ * @property {string} [TEMPLATE.NETWORK_ADDRESS] - Network address
+ * @property {string} [TEMPLATE.NETWORK_MASK] - Network mask
+ * @property {string} [TEMPLATE.SEARCH_DOMAIN] - Domain
+ * @property {string} [TEMPLATE.VCENTER_FROM_WILD] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_INSTANCE_ID] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_NET_REF] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_PORTGROUP_TYPE] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_TEMPLATE_REF] - vCenter information
+ */
+
+/** @enum {string} Type of Addresses defined by this address range */
+export const AR_TYPES = {
+ NONE: 'NONE',
+ ETHER: 'ETHER',
+ IP4: 'IP4',
+ IP6: 'IP6',
+ IP6_STATIC: 'IP6_STATIC',
+ IP4_6: 'IP4_6',
+ IP4_6_STATIC: 'IP4_6_STATIC',
+}
+
+/** @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,
+}
diff --git a/src/fireedge/src/client/components/Tabs/Vm/Snapshot/List.js b/src/fireedge/src/client/constants/networkTemplate.js
similarity index 54%
rename from src/fireedge/src/client/components/Tabs/Vm/Snapshot/List.js
rename to src/fireedge/src/client/constants/networkTemplate.js
index f2869fb728..4f38c26a69 100644
--- a/src/fireedge/src/client/components/Tabs/Vm/Snapshot/List.js
+++ b/src/fireedge/src/client/constants/networkTemplate.js
@@ -13,24 +13,33 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import PropTypes from 'prop-types'
+// eslint-disable-next-line no-unused-vars
+import { Permissions, LockInfo } from 'client/constants/common'
+import * as ACTIONS from 'client/constants/actions'
-import SnapshotItem from 'client/components/Tabs/Vm/Snapshot/Item'
+/**
+ * @typedef VNetworkTemplate
+ * @property {string} ID - Id
+ * @property {string} NAME - Name
+ * @property {string} UID - User id
+ * @property {string} UNAME - User name
+ * @property {string} GID - Group id
+ * @property {string} GNAME - Group name
+ * @property {string} REGTIME - Registration time
+ * @property {Permissions} PERMISSIONS - Permissions
+ * @property {LockInfo} [LOCK] - Lock information
+ * @property {object} TEMPLATE - Template
+ * @property {string} [TEMPLATE.VN_MAD] - Virtual network manager
+ */
-const SnapshotList = ({ snapshots, actions }) => (
-
- {snapshots.map((snapshot, idx) => (
-
- ))}
-
-)
+/** @enum {string} Virtual network template actions */
+export const VN_TEMPLATE_ACTIONS = {
+ CREATE_DIALOG: 'create_dialog',
+ DELETE: 'delete',
-SnapshotList.propTypes = {
- snapshots: PropTypes.array,
- actions: PropTypes.arrayOf(PropTypes.string),
+ // INFORMATION
+ RENAME: ACTIONS.RENAME,
+ CHANGE_MODE: ACTIONS.CHANGE_MODE,
+ CHANGE_OWNER: ACTIONS.CHANGE_OWNER,
+ CHANGE_GROUP: ACTIONS.CHANGE_GROUP,
}
-
-SnapshotList.displayName = 'SnapshotList'
-
-export default SnapshotList
diff --git a/src/fireedge/src/client/constants/quota.js b/src/fireedge/src/client/constants/quota.js
new file mode 100644
index 0000000000..95d3351cb0
--- /dev/null
+++ b/src/fireedge/src/client/constants/quota.js
@@ -0,0 +1,70 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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. *
+ * ------------------------------------------------------------------------- */
+
+/**
+ * @typedef {number|'-1'|'-2'} Quota
+ * - For each quota, there are two special limits
+ * ``-1``: the default quota will be used.
+ * ``-2``: Unlimited.
+ */
+
+/**
+ * @typedef DatastoreQuota
+ * @property {Quota} ID - ID of the Datastore to set the quota for
+ * @property {Quota} IMAGES -Maximum number of images that can be created in the datastore
+ * @property {Quota} IMAGES_USED - {@link DatastoreQuota.IMAGES}
+ * @property {Quota} SIZE - Maximum size in MB that can be used in the datastore
+ * @property {Quota} SIZE_USED - {@link DatastoreQuota.SIZE}
+ */
+
+/**
+ * @typedef NetworkQuota
+ * @property {Quota} ID - ID of the Network to set the quota for
+ * @property {Quota} LEASES - Maximum IPs that can be leased from the Network
+ * @property {Quota} LEASES_USED - {@link NetworkQuota.LEASES}
+ */
+
+/**
+ * @typedef VmQuota
+ * @description Running quotas will be increased or decreased depending
+ * on the state of the Virtual Machine. The states in which the machine
+ * is counted as “Running” are `ACTIVE` , `HOLD`, `PENDING` and `CLONING`.
+ * @property {Quota} VMS - Maximum number of VMs that can be created
+ * @property {Quota} VMS_USED - {@link VmQuota.VMS}
+ * @property {Quota} RUNNING_VMS - Maximum number of VMs that can be running
+ * @property {Quota} RUNNING_VMS_USED - {@link VmQuota.RUNNING_VMS}
+ * @property {Quota} MEMORY - Maximum memory in MB that can be requested by user/group VMs
+ * @property {Quota} MEMORY_USED - {@link VmQuota.MEMORY}
+ * @property {Quota} RUNNING_MEMORY - Maximum memory in MB that can be running by user/group VMs
+ * @property {Quota} RUNNING_MEMORY_USED - {@link VmQuota.RUNNING_MEMORY}
+ * @property {Quota} CPU - Maximum CPU capacity that can be requested by user/group VMs
+ * @property {Quota} CPU_USED - {@link VmQuota.CPU}
+ * @property {Quota} RUNNING_CPU - Maximum CPU capacity that can be running by user/group VMs
+ * @property {Quota} RUNNING_CPU_USED - {@link VmQuota.RUNNING_CPU}
+ * @property {Quota} SYSTEM_DISK_SIZE - Maximum size (in MB) of system disks that can be requested by user/group VMs
+ * @property {Quota} SYSTEM_DISK_SIZE_USED - {@link VmQuota.SYSTEM_DISK_SIZE}
+ */
+
+/**
+ * @typedef ImageQuota
+ * @type {object}
+ * @property {Quota} ID - ID of the Image to set the quota for
+ * @property {Quota} RVMS - Maximum VMs that can used this image at the same time
+ * @property {Quota} RVMS_USED - {@link ImageQuota.RVMS}
+ */
+
+export const QUOTA_LIMIT_DEFAULT = '-1'
+export const QUOTA_LIMIT_UNLIMITED = '-2'
diff --git a/src/fireedge/src/client/constants/scheduler.js b/src/fireedge/src/client/constants/scheduler.js
new file mode 100644
index 0000000000..5808f8cef3
--- /dev/null
+++ b/src/fireedge/src/client/constants/scheduler.js
@@ -0,0 +1,79 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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. *
+ * ------------------------------------------------------------------------- */
+
+/**
+ * @typedef ScheduleAction
+ * @property {string} ACTION - Action to execute
+ * @property {string} ID - Id
+ * @property {string} TIME - Time
+ * @property {string} [WARNING] - Warning time
+ * @property {string} [ARGS] - Arguments separated by comma
+ * @property {string} [DAYS] - Days that the users wants execute the action.
+ * List separated by comma. Depend of {@link REPEAT}:
+ * - weekly: 0 (Sunday) to 6 (Saturday)
+ * - monthly: 1 to 31
+ * - yearly: 1 to 365
+ * - hourly: each ‘x’ hours
+ * @property {'0'|'1'|'2'} [END_TYPE] - Way to end the repetition:
+ * - `0`: never
+ * - `1`: repetition
+ * - `2`: date
+ * @property {string} [END_VALUE] - End value
+ * @property {'0'|'1'|'2'|'3'} [REPEAT] - Type of repetition:
+ * - `0`: weekly
+ * - `1`: monthly
+ * - `2`: yearly
+ * - `3`: hourly
+ */
+
+/**
+ * @typedef CharterOptions
+ * @property {boolean} [edit] - If `true`, the charter can be edited in form
+ * @property {number|string} execute_after_days - Days to execute the action
+ * @property {number|string} warn_before_days - Alert a time before the action (in days)
+ */
+
+/** @enum {string} Values to end an action */
+export const END_TYPE_VALUES = {
+ NEVER: '0',
+ REPETITION: '1',
+ DATE: '2',
+}
+
+/** @enum {string} Values to repeat an action */
+export const REPEAT_VALUES = {
+ WEEKLY: '0',
+ MONTHLY: '1',
+ YEARLY: '2',
+ HOURLY: '3',
+}
+
+/** @enum {string} Argument attributes */
+export const ARGS_TYPES = {
+ DISK_ID: 'DISK_ID',
+ NAME: 'NAME',
+ SNAPSHOT_ID: 'SNAPSHOT_ID',
+}
+
+/** @enum {string} Period type */
+export const PERIOD_TYPES = {
+ YEARS: 'years',
+ MONTHS: 'months',
+ WEEKS: 'weeks',
+ DAYS: 'days',
+ HOURS: 'hours',
+ MINUTES: 'minutes',
+}
diff --git a/src/fireedge/src/client/constants/securityGroup.js b/src/fireedge/src/client/constants/securityGroup.js
index 84e93c0778..35c5c9a70a 100644
--- a/src/fireedge/src/client/constants/securityGroup.js
+++ b/src/fireedge/src/client/constants/securityGroup.js
@@ -15,6 +15,21 @@
* ------------------------------------------------------------------------- */
import { T } from 'client/constants'
+/**
+ * @typedef {object} SecurityGroupRule
+ * @property {number|string} SECURITY_GROUP_ID - ID
+ * @property {string} SECURITY_GROUP_NAME - Name
+ * @property {string} PROTOCOL - Protocol
+ * @property {string} RULE_TYPE - Rule type
+ * @property {number|string} ICMP_TYPE - ICMP type
+ * @property {number|string} [ICMPv6_TYPE] - ICMP v6 type
+ * @property {number|string} [RANGE] - Range
+ * @property {number|string} [NETWORK_ID] - Network id
+ * @property {number|string} [SIZE] - Network size
+ * @property {string} [IP] - Network IP
+ * @property {string} [MAC] - Network MAC
+ */
+
/**
* ICMP Codes for each ICMP type as in:
* http://www.iana.org/assignments/icmp-parameters/
diff --git a/src/fireedge/src/client/constants/translates.js b/src/fireedge/src/client/constants/translates.js
index a9eb94af2c..f40ff0cbd5 100644
--- a/src/fireedge/src/client/constants/translates.js
+++ b/src/fireedge/src/client/constants/translates.js
@@ -58,7 +58,7 @@ module.exports = {
CurrentGroup: 'Current group: %s',
CurrentOwner: 'Current owner: %s',
Delete: 'Delete',
- DeleteScheduledAction: 'Delete scheduled action: %s',
+ DeleteScheduleAction: 'Delete schedule action: %s',
DeleteSomething: 'Delete: %s',
Deploy: 'Deploy',
Detach: 'Detach',
@@ -102,6 +102,7 @@ module.exports = {
Select: 'Select',
SelectDatastore: 'Select a Datastore to store the resource',
SelectDockerHubTag: 'Select DockerHub image tag (default latest)',
+ SelectYourActiveGroup: 'Select your active group',
SelectGroup: 'Select a group',
SelectHost: 'Select a host',
SelectMarketplace: 'Select Marketplace',
@@ -128,7 +129,7 @@ module.exports = {
UnReschedule: 'Un-Reschedule',
Unshare: 'Unshare',
Update: 'Update',
- UpdateScheduledAction: 'Update scheduled action: %s',
+ UpdateScheduleAction: 'Update schedule action: %s',
/* questions */
Yes: 'Yes',
@@ -137,7 +138,7 @@ module.exports = {
/* Scheduling */
Action: 'Action',
- ScheduledAction: 'Scheduled action',
+ ScheduleAction: 'Schedule action',
Charter: 'Charter',
PunctualAction: 'Punctual action',
RelativeAction: 'Relative action',
@@ -228,6 +229,7 @@ module.exports = {
ProviderTemplate: 'Provider template',
ProvisionTemplate: 'Provision template',
ConfigureInputs: 'Configure inputs',
+ Log: 'Log',
AddIP: 'Add IP',
AddHost: 'Add Host',
Cleanup: 'Cleanup',
@@ -632,6 +634,15 @@ module.exports = {
ExportAssociateApp: 'Export associated VM templates/images',
ImportAssociateApp: 'Import associated VM templates/images',
+ /* Image schema */
+ Limit: 'Limit',
+ BasePath: 'Base path',
+
+ /* Image schema */
+ FileSystemType: 'Filesystem type',
+ Persistent: 'Persistent',
+ RunningVMs: 'Running VMs',
+
/* User inputs */
UserInputs: 'User Inputs',
UserInputsConcept: `
diff --git a/src/fireedge/src/client/constants/user.js b/src/fireedge/src/client/constants/user.js
new file mode 100644
index 0000000000..89156157d7
--- /dev/null
+++ b/src/fireedge/src/client/constants/user.js
@@ -0,0 +1,66 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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. *
+ * ------------------------------------------------------------------------- */
+// eslint-disable-next-line prettier/prettier, no-unused-vars
+import { VmQuota, NetworkQuota, DatastoreQuota, ImageQuota } from 'client/constants/quota'
+import * as ACTIONS from 'client/constants/actions'
+
+/**
+ * @typedef LoginToken
+ * @property {string} TOKEN - Token
+ * @property {string|number} EXPIRATION_TIME - Expiration time
+ * @property {string} EGID - ??
+ */
+
+/**
+ * @typedef User
+ * @property {string|number} ID - Id
+ * @property {string} NAME - Name
+ * @property {string|number} GID - Group id
+ * @property {string} GNAME - Group name
+ * @property {{ ID: string[] }} GROUPS - List of group ids
+ * @property {string} PASSWORD - Password
+ * @property {string} AUTH_DRIVER - Driver to authenticate
+ * @property {'0'|'1'} ENABLED - If `0` the user is enabled
+ * @property {LoginToken|LoginToken[]} [LOGIN_TOKEN] - Token to login
+ * @property {object} TEMPLATE - Template
+ * @property {string} [TEMPLATE.TOKEN_PASSWORD] - Password token
+ * @property {{ DATASTORE: DatastoreQuota|DatastoreQuota[] }} [DATASTORE_QUOTA] - Datastore quotas
+ * @property {{ NETWORK: NetworkQuota|NetworkQuota[] }} [NETWORK_QUOTA] - Network quotas
+ * @property {{ VM: VmQuota }} [VM_QUOTA] - VM quotas
+ * @property {{ IMAGE: ImageQuota|ImageQuota[] }} [IMAGE_QUOTA] - Image quotas
+ * @property {{
+ * DATASTORE: DatastoreQuota|DatastoreQuota[],
+ * NETWORK: NetworkQuota|NetworkQuota[],
+ * VM: VmQuota,
+ * IMAGE: ImageQuota|ImageQuota[]
+ * }} [DEFAULT_USER_QUOTAS] - Default quotas
+ */
+
+export const USER_ACTIONS = {
+ REFRESH: ACTIONS.REFRESH,
+ CREATE_DIALOG: 'create_dialog',
+ QUOTAS_DIALOG: 'quotas_dialog',
+ GROUPS_DIALOG: 'groups_dialog',
+ UPDATE_PASSWORD: 'update_password',
+ DELETE: 'delete',
+ EDIT_ADMINS: 'edit_admins',
+ LOGIN_TOKEN: 'login_token',
+ TFA: 'two_factor_auth',
+ CHANGE_GROUP: ACTIONS.CHANGE_GROUP,
+ CHANGE_AUTH: 'change_authentication',
+ ENABLE: 'enable',
+ DISABLE: 'disable',
+}
diff --git a/src/fireedge/src/client/constants/vm.js b/src/fireedge/src/client/constants/vm.js
index adb379f8ec..81d3471b3f 100644
--- a/src/fireedge/src/client/constants/vm.js
+++ b/src/fireedge/src/client/constants/vm.js
@@ -16,6 +16,205 @@
import * as STATES from 'client/constants/states'
import * as ACTIONS from 'client/constants/actions'
import COLOR from 'client/constants/color'
+// eslint-disable-next-line no-unused-vars
+import { Permissions, LockInfo } from 'client/constants/common'
+// eslint-disable-next-line no-unused-vars
+import { ScheduleAction } from 'client/constants/scheduler'
+
+/**
+ * @typedef {object} Disk
+ * @property {string} [VCENTER_DS_REF] -
+ * @property {string} [VCENTER_INSTANCE_ID] -
+ */
+
+/**
+ * @typedef {object} Nic
+ * @property {string} [VCENTER_INSTANCE_ID] -
+ * @property {string} [VCENTER_NET_REF] -
+ * @property {string} [VCENTER_PORTGROUP_TYPE] -
+ */
+
+/**
+ * @typedef {object} NicAlias
+ * @property {string} ALIAS_ID -
+ * @property {string} PARENT -
+ * @property {string} PARENT_ID -
+ * @property {string} [VCENTER_INSTANCE_ID] -
+ * @property {string} [VCENTER_NET_REF] -
+ * @property {string} [VCENTER_PORTGROUP_TYPE] -
+ */
+
+/**
+ * @typedef {object} DiskSize
+ * @property {string|number} ID -
+ * @property {string|number} SIZE -
+ */
+
+/**
+ * @typedef {object} Graphics
+ * @property {string|number} LISTEN -
+ * @property {string} RANDOM_PASSW -
+ * @property {string} TYPE -
+ */
+
+/**
+ * @typedef {object} HistoryRecord
+ * @property {string|number} OID -
+ * @property {string|number} SEQ -
+ * @property {string} HOSTNAME -
+ * @property {string|number} HID -
+ * @property {string|number} CID -
+ * @property {string|number} STIME -
+ * @property {string|number} ETIME -
+ * @property {string} VM_MAD -
+ * @property {string} TM_MAD -
+ * @property {string|number} DS_ID -
+ * @property {string|number} PSTIME -
+ * @property {string|number} PETIME -
+ * @property {string|number} RSTIME -
+ * @property {string|number} RETIME -
+ * @property {string|number} ESTIME -
+ * @property {string|number} EETIME -
+ * @property {VM_ACTIONS} ACTION -
+ * @property {string|number} UID -
+ * @property {string|number} GID -
+ * @property {string|number} REQUEST_ID -
+ */
+
+/**
+ * @typedef {object} HistoryShortRecord
+ * @property {string|number} OID -
+ * @property {string|number} SEQ -
+ * @property {string} HOSTNAME -
+ * @property {string|number} HID -
+ * @property {string|number} CID -
+ * @property {string|number} DS_ID -
+ * @property {VM_ACTIONS} ACTION -
+ */
+
+/**
+ * @typedef {object} DiskSnapshots
+ * @property {string|number} ALLOW_ORPHANS -
+ * @property {string|number} CURRENT_BASE -
+ * @property {string|number} DISK_ID -
+ * @property {string|number} NEXT_SNAPSHOT -
+ * @property {DiskSnapshot|DiskSnapshot[]} [SNAPSHOT] -
+ */
+
+/**
+ * @typedef {object} DiskSnapshot
+ * @property {string|number} ID -
+ * @property {string|number} DATE -
+ * @property {string|number} PARENT -
+ * @property {string|number} SIZE -
+ * @property {string} [NAME] -
+ * @property {string} [ACTIVE] -
+ * @property {string} [CHILDREN] -
+ */
+
+/**
+ * @typedef {object} Snapshot
+ * @property {string} SNAPSHOT_ID -
+ * @property {string} NAME -
+ * @property {string} TIME -
+ * @property {string} HYPERVISOR_ID -
+ * @property {string} SYSTEM_DISK_SIZE -
+ * @property {string} [ACTIVE] -
+ * @property {string} [ACTION] -
+ */
+
+/**
+ * @typedef {object} VM
+ * @property {string|number} ID - Id
+ * @property {string} NAME - Name
+ * @property {string|number} UID - User id
+ * @property {string|number} GID - Group id
+ * @property {string} UNAME - User name
+ * @property {string} GNAME - Group name
+ * @property {Permissions} PERMISSIONS - Permissions
+ * @property {string|number} LAST_POLL - Last poll
+ * @property {string|number} STATE - Current state
+ * @property {string|number} LCM_STATE - Current LCM state
+ * @property {string|number} PREV_STATE - Previous state
+ * @property {string|number} PREV_LCM_STATE - Previous LCM state
+ * @property {string|number} STIME - Start time
+ * @property {string|number} ETIME - End time
+ * @property {string|number} DEPLOY_ID - Deploy id
+ * @property {LockInfo} [LOCK] - Lock information
+ * @property {object} MONITORING - Monitoring information
+ * @property {number} [MONITORING.CPU] - Percentage of 1 CPU consumed (two fully consumed cpu is 2.0)
+ * @property {number} [MONITORING.DISKRDBYTES] - Amount of bytes read from disk
+ * @property {number} [MONITORING.DISKRDIOPS] - Number of IO read operations
+ * @property {number} [MONITORING.DISKWRBYTES] - Amount of bytes written to disk
+ * @property {number} [MONITORING.DISKWRIOPS] - Number of IO write operations
+ * @property {DiskSize|DiskSize[]} [MONITORING.DISK_SIZE] - Disk size details
+ * @property {number} [MONITORING.ID] - ID of the VM
+ * @property {number} [MONITORING.MEMORY] - Consumption in kilobytes
+ * @property {number} [MONITORING.NETRX] - Received bytes from the network
+ * @property {number} [MONITORING.NETTX] - Sent bytes to the network
+ * @property {number} [MONITORING.TIMESTAMP] - Exact time when monitoring info were retrieved
+ * @property {string} [MONITORING.VCENTER_ESX_HOST] - vCenter information
+ * @property {string} [MONITORING.VCENTER_GUEST_STATE] - vCenter information
+ * @property {string} [MONITORING.VCENTER_RP_NAME] - vCenter information
+ * @property {string} [MONITORING.VCENTER_VMWARETOOLS_RUNNING_STATUS] - vCenter information
+ * @property {string} [MONITORING.VCENTER_VMWARETOOLS_VERSION] - vCenter information
+ * @property {string} [MONITORING.VCENTER_VMWARETOOLS_VERSION_STATUS] - vCenter information
+ * @property {string} [MONITORING.VCENTER_VM_NAME] - vCenter information
+ * @property {object} TEMPLATE - Template information
+ * @property {string} [TEMPLATE.AUTOMATIC_DS_REQUIREMENTS] -
+ * @property {string} [TEMPLATE.AUTOMATIC_NIC_REQUIREMENTS] -
+ * @property {string} [TEMPLATE.AUTOMATIC_REQUIREMENTS] -
+ * @property {string} [TEMPLATE.CLONING_TEMPLATE_ID] -
+ * @property {string} [TEMPLATE.CONTEXT] -
+ * @property {string} [TEMPLATE.CPU] -
+ * @property {string} [TEMPLATE.CPU_COST] -
+ * @property {Disk|Disk[]} [TEMPLATE.DISK] -
+ * @property {string} [TEMPLATE.DISK_COST] -
+ * @property {string} [TEMPLATE.EMULATOR] -
+ * @property {any} [TEMPLATE.FEATURES] -
+ * @property {any} [TEMPLATE.HYPERV_OPTIONS] -
+ * @property {Graphics} [TEMPLATE.GRAPHICS] -
+ * @property {string} [TEMPLATE.IMPORTED] -
+ * @property {any} [TEMPLATE.INPUT] -
+ * @property {string} [TEMPLATE.MEMORY] -
+ * @property {string} [TEMPLATE.MEMORY_COST] -
+ * @property {string} [TEMPLATE.MEMORY_MAX] -
+ * @property {string} [TEMPLATE.MEMORY_SLOTS] -
+ * @property {Nic|Nic[]} [TEMPLATE.NIC] -
+ * @property {NicAlias|NicAlias[]} [TEMPLATE.NIC_ALIAS] -
+ * @property {any} [TEMPLATE.NIC_DEFAULT] -
+ * @property {any} [TEMPLATE.NUMA_NODE] -
+ * @property {any} [TEMPLATE.OS] -
+ * @property {any} [TEMPLATE.PCI] -
+ * @property {any} [TEMPLATE.RAW] -
+ * @property {ScheduleAction|ScheduleAction[]} [TEMPLATE.SCHED_ACTION] -
+ * @property {Snapshot|Snapshot[]} [TEMPLATE.SNAPSHOT] -
+ * @property {any} [TEMPLATE.SECURITY_GROUP_RULE] -
+ * @property {any} [TEMPLATE.SPICE_OPTIONS] -
+ * @property {string} [TEMPLATE.SUBMIT_ON_HOLD] -
+ * @property {string} [TEMPLATE.TEMPLATE_ID] -
+ * @property {string} TEMPLATE.TM_MAD_SYSTEM -
+ * @property {any} [TEMPLATE.TOPOLOGY] -
+ * @property {string} [TEMPLATE.VCPU] -
+ * @property {string} [TEMPLATE.VCPU_MAX] -
+ * @property {object|object[]} [TEMPLATE.VMGROUP] -
+ * @property {string} TEMPLATE.VMID -
+ * @property {string} [TEMPLATE.VROUTER_ID] -
+ * @property {string} [TEMPLATE.VROUTER_KEEPALIVED_ID] -
+ * @property {string} [TEMPLATE.VROUTER_KEEPALIVED_PASSWORD] -
+ * @property {object} USER_TEMPLATE -
+ * @property {string} [USER_TEMPLATE.ERROR] -
+ * @property {string} [USER_TEMPLATE.HYPERVISOR] -
+ * @property {string} [USER_TEMPLATE.LOGO] -
+ * @property {string} [USER_TEMPLATE.INFO] -
+ * @property {string} [USER_TEMPLATE.SCHED_REQUIREMENTS] -
+ * @property {string} [USER_TEMPLATE.VCENTER_CCR_REF] -
+ * @property {string} [USER_TEMPLATE.VCENTER_DS_REF] -
+ * @property {string} [USER_TEMPLATE.VCENTER_INSTANCE_ID] -
+ * @property {object} HISTORY_RECORDS - History
+ * @property {HistoryRecord|HistoryRecord[]} [HISTORY_RECORDS.HISTORY] - History Records
+ * @property {DiskSnapshots|DiskSnapshots[]} [SNAPSHOTS] -
+ */
/** @type {STATES.StateInfo[]} Virtual machine states */
export const VM_STATES = [
diff --git a/src/fireedge/src/client/constants/vmTemplate.js b/src/fireedge/src/client/constants/vmTemplate.js
index d6b465af42..522b21835a 100644
--- a/src/fireedge/src/client/constants/vmTemplate.js
+++ b/src/fireedge/src/client/constants/vmTemplate.js
@@ -14,6 +14,26 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
import * as ACTIONS from 'client/constants/actions'
+// eslint-disable-next-line no-unused-vars
+import { Permissions, LockInfo } from 'client/constants/common'
+
+/**
+ * @typedef {object} VmTemplate
+ * @property {string|number} ID - Id
+ * @property {string} NAME - Name
+ * @property {string|number} UID - User id
+ * @property {string|number} GID - Group id
+ * @property {string} UNAME - User name
+ * @property {string} GNAME - Group name
+ * @property {Permissions} PERMISSIONS - Permissions
+ * @property {LockInfo} [LOCK] - Lock information
+ * @property {string|number} REGTIME - Registration time
+ * @property {object} TEMPLATE - Template information
+ * @property {string} [TEMPLATE.CONTEXT] - Context
+ * @property {string} [TEMPLATE.VCENTER_CCR_REF] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_INSTANCE_ID] - vCenter information
+ * @property {string} [TEMPLATE.VCENTER_TEMPLATE_REF] - vCenter information
+ */
export const VM_TEMPLATE_ACTIONS = {
REFRESH: ACTIONS.REFRESH,
diff --git a/src/fireedge/src/client/constants/zone.js b/src/fireedge/src/client/constants/zone.js
index c4039a24eb..9df60ddb66 100644
--- a/src/fireedge/src/client/constants/zone.js
+++ b/src/fireedge/src/client/constants/zone.js
@@ -13,9 +13,33 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
+import * as ACTIONS from 'client/constants/actions'
import * as STATES from 'client/constants/states'
import COLOR from 'client/constants/color'
+/**
+ * @typedef ZoneServer
+ * @property {string} ID - Id
+ * @property {string} NAME - Name
+ * @property {string} ENDPOINT - RPC endpoint
+ * @property {string} [STATE] - State
+ * @property {string} [TERM] - Term
+ * @property {string} [VOTEDFOR] - Voted for
+ * @property {string} [COMMIT] - Commit
+ * @property {string} [LOG_INDEX] - Log index
+ * @property {string} [FEDLOG_INDEX] - Federation log index
+ */
+
+/**
+ * @typedef Zone
+ * @property {string} ID - Id
+ * @property {string} NAME - Name
+ * @property {0|1} STATE - Possible STATE values are 0 (ENABLED) and 1 (DISABLED)
+ * @property {object} TEMPLATE - Template
+ * @property {string} TEMPLATE.ENDPOINT - Endpoint
+ * @property {{ SERVER: ZoneServer|ZoneServer[] }} SERVER_POOL - Server pool information
+ */
+
/** @type {STATES.StateInfo[]} Zone states */
export const ZONE_STATES = [
{
@@ -29,3 +53,11 @@ export const ZONE_STATES = [
color: COLOR.debug.main,
},
]
+
+/** @enum {string} Zone actions */
+export const ZONE_ACTIONS = {
+ CREATE_DIALOG: 'create_dialog',
+ DELETE: 'delete',
+
+ RENAME: ACTIONS.RENAME,
+}
diff --git a/src/fireedge/src/client/containers/ApplicationsInstances/DialogInfo/dialog.js b/src/fireedge/src/client/containers/ApplicationsInstances/DialogInfo/dialog.js
index 28746025b6..bcc8cd7d80 100644
--- a/src/fireedge/src/client/containers/ApplicationsInstances/DialogInfo/dialog.js
+++ b/src/fireedge/src/client/containers/ApplicationsInstances/DialogInfo/dialog.js
@@ -39,7 +39,7 @@ const CustomDialog = ({ title, handleClose, children }) => {
maxWidth="xl"
scroll="paper"
PaperProps={{
- style: {
+ sx: {
height: isMobile ? '100%' : '90%',
width: isMobile ? '100%' : '90%',
},
@@ -48,7 +48,7 @@ const CustomDialog = ({ title, handleClose, children }) => {
{title}
{
- fetchRequest()
- }, [])
-
- // const list = useMemo(() => (
- // applications.length > 0
- // ? applications?.filter(({ TEMPLATE: { BODY: { state } } }) =>
- // APPLICATION_STATES[state]?.name !== DONE
- // )
- // : applications
- // ), [applications])
+ const {
+ data: applications = [],
+ refetch,
+ error,
+ isLoading,
+ } = useGetServicesQuery()
return (
@@ -55,8 +41,8 @@ function ApplicationsInstances() {
hasReloadButton
reloadButtonProps={{
'data-cy': 'refresh-application-list',
- onClick: () => fetchRequest(undefined, { reload: true, delay: 500 }),
- isSubmitting: Boolean(loading || reloading),
+ onClick: () => refetch(),
+ isSubmitting: isLoading,
}}
/>
@@ -65,7 +51,6 @@ function ApplicationsInstances() {
) : (
({
diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Clusters/index.js b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Clusters/index.js
index 6a954586bb..406fbedd09 100644
--- a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Clusters/index.js
+++ b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Clusters/index.js
@@ -14,10 +14,10 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-import { useEffect, useCallback } from 'react'
+import { useCallback } from 'react'
-import { useListForm, useFetch } from 'client/hooks'
-import { useCluster, useClusterApi } from 'client/features/One'
+import { useListForm } from 'client/hooks'
+import { useGetClustersQuery } from 'client/features/OneApi/cluster'
import { ListCards } from 'client/components/List'
import { ClusterCard, EmptyCard } from 'client/components/Cards'
@@ -31,24 +31,17 @@ const Clusters = () => ({
label: T.WhereWillItRun,
resolver: STEP_FORM_SCHEMA,
content: useCallback(({ data, setFormData }) => {
- const clusters = useCluster()
- const { getClusters } = useClusterApi()
-
- const { fetchRequest, loading } = useFetch(getClusters)
+ const { data: clusters = [], isLoading } = useGetClustersQuery()
const { handleSelect, handleUnselect } = useListForm({
key: STEP_ID,
setList: setFormData,
})
- useEffect(() => {
- fetchRequest()
- }, [])
-
return (
}
CardComponent={ClusterCard}
cardsProps={({ value: { ID } }) => {
diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Networking/index.js b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Networking/index.js
index 2008b8d633..2a4589c383 100644
--- a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Networking/index.js
+++ b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Networking/index.js
@@ -14,13 +14,10 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-import { useState, useEffect, useCallback } from 'react'
-
+import { useState, useCallback } from 'react'
import { useWatch } from 'react-hook-form'
import { useListForm } from 'client/hooks'
-import { useVNetworkApi, useVNetworkTemplateApi } from 'client/features/One'
-
import FormWithSchema from 'client/components/Forms/FormWithSchema'
import { ListCards } from 'client/components/List'
import { DialogForm } from 'client/components/Dialogs'
@@ -40,9 +37,6 @@ const Networks = () => ({
const form = useWatch({})
const [showDialog, setShowDialog] = useState(false)
- const { getVNetworks } = useVNetworkApi()
- const { getVNetworkTemplates } = useVNetworkTemplateApi()
-
const { editingData, handleSave, handleEdit, handleClone, handleRemove } =
useListForm({
key: STEP_ID,
@@ -51,11 +45,6 @@ const Networks = () => ({
defaultValue: NETWORK_FORM_SCHEMA.default(),
})
- useEffect(() => {
- getVNetworks()
- getVNetworkTemplates()
- }, [])
-
return (
<>
{
- const vNetworks = useVNetwork()
- const vNetworksTemplates = useVNetworkTemplate()
+ const { data: vNetworks = [] } = useGetVNetworksQuery()
+ const { data: vNetworksTemplates = [] } = useGetVNTemplatesQuery()
const values = isNetworkSelector(dependValue)
? vNetworks
diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Steps/Policies/index.js b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Steps/Policies/index.js
index be8fb724e2..dd06ccd2c3 100644
--- a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Steps/Policies/index.js
+++ b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Steps/Policies/index.js
@@ -139,7 +139,7 @@ const Policies = () => ({
diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Steps/Template/List/MarketApps.js b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Steps/Template/List/MarketApps.js
index ae8dec0326..302235fbe8 100644
--- a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Steps/Template/List/MarketApps.js
+++ b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/Steps/Tiers/Steps/Template/List/MarketApps.js
@@ -14,22 +14,16 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-import { useEffect } from 'react'
import PropTypes from 'prop-types'
-import { useMarketplaceApp, useMarketplaceAppApi } from 'client/features/One'
+import { useGetMarketplaceAppsQuery } from 'client/features/OneApi/marketplaceApp'
import Search from 'client/components/Search'
import { SelectCard } from 'client/components/Cards'
const sortByID = (a, b) => a.ID - b.ID
const ListMarketApp = ({ backButton, currentValue, handleSetData }) => {
- const apps = useMarketplaceApp()
- const { getMarketplaceApps } = useMarketplaceAppApi()
-
- useEffect(() => {
- getMarketplaceApps()
- }, [])
+ const { data: apps = [] } = useGetMarketplaceAppsQuery()
return (
a.ID - b.ID
const ListTemplates = ({ backButton, currentValue, handleSetData }) => {
- const templates = useVmTemplate()
- const { getTemplates } = useVmTemplateApi()
-
- useEffect(() => {
- getTemplates()
- }, [])
+ const { data: templates = [] } = useGetTemplatesQuery()
return (
,
+ button: ,
content: ListTemplates,
},
{
id: 'app',
- button: ,
+ button: ,
content: ListMarketApps,
},
{
diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/index.js b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/index.js
index 9fbf599199..dbd79b49f5 100644
--- a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/index.js
+++ b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Create/index.js
@@ -14,7 +14,7 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-import { useEffect } from 'react'
+/* import { useEffect } from 'react'
import { Redirect, useHistory, useParams } from 'react-router-dom'
import { LinearProgress, Container } from '@mui/material'
@@ -25,12 +25,11 @@ import FormStepper from 'client/components/FormStepper'
import Steps from 'client/containers/ApplicationsTemplates/Form/Create/Steps'
import { PATH } from 'client/apps/sunstone/routesFlow'
-import { useFetch } from 'client/hooks'
-import { useApplicationTemplateApi } from 'client/features/One'
-import { parseApplicationToForm, parseFormToApplication } from 'client/utils'
+import { useGetServiceTemplateQuery } from 'client/features/OneApi/serviceTemplate'
+import { parseApplicationToForm, parseFormToApplication } from 'client/utils' */
function ApplicationsTemplatesCreateForm() {
- const history = useHistory()
+ /* const history = useHistory()
const { id } = useParams()
const { steps, defaultValues, resolvers } = Steps()
@@ -83,13 +82,14 @@ function ApplicationsTemplatesCreateForm() {
) : (
- )
+ ) */
+ return <>{'Create service template form WIP'}>
}
export default ApplicationsTemplatesCreateForm
diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/Steps/Networking/index.js b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/Steps/Networking/index.js
index a5080f7cc2..a767605729 100644
--- a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/Steps/Networking/index.js
+++ b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/Steps/Networking/index.js
@@ -14,11 +14,9 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-import { useEffect, useCallback } from 'react'
-
+import { useCallback } from 'react'
import { Divider, Paper, Typography } from '@mui/material'
-import { useVNetworkApi, useVNetworkTemplateApi } from 'client/features/One'
import FormWithSchema from 'client/components/Forms/FormWithSchema'
import { T } from 'client/constants'
@@ -31,32 +29,28 @@ const Networks = () => ({
label: T.ConfigureNetworking,
resolver: STEP_FORM_SCHEMA,
optionsValidate: { abortEarly: false },
- content: useCallback(({ data }) => {
- const { getVNetworks } = useVNetworkApi()
- const { getVNetworkTemplates } = useVNetworkTemplateApi()
-
- useEffect(() => {
- getVNetworks()
- getVNetworkTemplates()
- }, [])
-
- return data?.map(({ id, name, description }, index) => (
-
- {name}
- {description && {description}}
-
-
-
- ))
- }, []),
+ content: useCallback(
+ ({ data }) =>
+ data?.map(({ id, name, description }, index) => (
+
+ {name}
+ {description && (
+ {description}
+ )}
+
+
+
+ )),
+ []
+ ),
})
export default Networks
diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/Steps/Networking/schema.js b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/Steps/Networking/schema.js
index 6ad464aad7..84c14d7386 100644
--- a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/Steps/Networking/schema.js
+++ b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/Steps/Networking/schema.js
@@ -15,7 +15,8 @@
* ------------------------------------------------------------------------- */
import * as yup from 'yup'
import { INPUT_TYPES } from 'client/constants'
-import { useVNetwork, useVNetworkTemplate } from 'client/features/One'
+import { useGetVNetworksQuery } from 'client/features/OneApi/network'
+import { useGetVNTemplatesQuery } from 'client/features/OneApi/networkTemplate'
import { getValidationFromFields } from 'client/utils'
const SELECT = {
@@ -50,8 +51,8 @@ const ID_VNET = {
type: INPUT_TYPES.AUTOCOMPLETE,
dependOf: TYPE.name,
values: (dependValue) => {
- const vNetworks = useVNetwork()
- const vNetworksTemplates = useVNetworkTemplate()
+ const { data: vNetworks = [] } = useGetVNetworksQuery()
+ const { data: vNetworksTemplates = [] } = useGetVNTemplatesQuery()
const type = TYPES_NETWORKS.find(({ value }) => value === dependValue)
diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/index.js b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/index.js
index 4fec24fcc1..c63a0c49e1 100644
--- a/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/index.js
+++ b/src/fireedge/src/client/containers/ApplicationsTemplates/Form/Deploy/index.js
@@ -14,15 +14,15 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-import { useEffect, useMemo, useState } from 'react'
+/* import { useEffect, useMemo, useState } from 'react'
import PropTypes from 'prop-types'
import { CircularProgress, Backdrop } from '@mui/material'
import makeStyles from '@mui/styles/makeStyles'
import { useFetchAll } from 'client/hooks'
-import { useApplicationTemplateApi } from 'client/features/One'
import { useGeneralApi } from 'client/features/General'
+import { } from 'client/features/OneApi/serviceTemplate'
import { DialogForm } from 'client/components/Dialogs'
import FormStepper from 'client/components/FormStepper'
@@ -37,10 +37,12 @@ const useStyles = makeStyles((theme) => ({
zIndex: theme.zIndex.appBar,
color: theme.palette.common.white,
},
-}))
+})) */
-const DeployForm = ({ applicationTemplate, handleCancel }) => {
- const classes = useStyles()
+const DeployForm = () => (
+ // const DeployForm = ({ applicationTemplate, handleCancel }) => (
+
+ /* const classes = useStyles()
const [vmTemplates, setVmTemplates] = useState([])
const { enqueueInfo } = useGeneralApi()
@@ -110,10 +112,12 @@ const DeployForm = ({ applicationTemplate, handleCancel }) => {
>
- )
-}
+ ) */
-DeployForm.propTypes = {
+ <>{'Deploy service template form WIP'}>
+)
+
+/* DeployForm.propTypes = {
applicationTemplate: PropTypes.object.isRequired,
handleCancel: PropTypes.func,
}
@@ -121,6 +125,6 @@ DeployForm.propTypes = {
DeployForm.defaultProps = {
applicationTemplate: undefined,
handleCancel: undefined,
-}
+} */
export default DeployForm
diff --git a/src/fireedge/src/client/containers/ApplicationsTemplates/index.js b/src/fireedge/src/client/containers/ApplicationsTemplates/index.js
index 877bd668eb..5fbf4e9632 100644
--- a/src/fireedge/src/client/containers/ApplicationsTemplates/index.js
+++ b/src/fireedge/src/client/containers/ApplicationsTemplates/index.js
@@ -14,21 +14,15 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-import { useEffect, useState } from 'react'
-
+import { useState } from 'react'
import { useHistory, generatePath } from 'react-router-dom'
import { Container, Box } from '@mui/material'
import { PATH } from 'client/apps/sunstone/routesFlow'
-import { useFetch } from 'client/hooks'
-import {
- useApplicationTemplate,
- useApplicationTemplateApi,
-} from 'client/features/One'
-
+import { useGetServiceTemplatesQuery } from 'client/features/OneApi/serviceTemplate'
import DeployForm from 'client/containers/ApplicationsTemplates/Form/Deploy'
-import { ListHeader, ListCards } from 'client/components/List'
import AlertError from 'client/components/Alerts/Error'
+import { ListHeader, ListCards } from 'client/components/List'
import { ApplicationTemplateCard } from 'client/components/Cards'
import { T } from 'client/constants'
@@ -36,16 +30,12 @@ function ApplicationsTemplates() {
const history = useHistory()
const [showDialog, setShowDialog] = useState(false)
- const applicationsTemplates = useApplicationTemplate()
- const { getApplicationsTemplates } = useApplicationTemplateApi()
-
- const { error, fetchRequest, loading, reloading } = useFetch(
- getApplicationsTemplates
- )
-
- useEffect(() => {
- fetchRequest()
- }, [])
+ const {
+ data: applicationsTemplates = [],
+ refetch,
+ error,
+ isLoading,
+ } = useGetServiceTemplatesQuery()
return (
@@ -54,8 +44,8 @@ function ApplicationsTemplates() {
hasReloadButton
reloadButtonProps={{
'data-cy': 'refresh-application-template-list',
- onClick: () => fetchRequest(undefined, { reload: true, delay: 500 }),
- isSubmitting: Boolean(loading || reloading),
+ onClick: () => refetch(),
+ isSubmitting: isLoading,
}}
addButtonProps={{
'data-cy': 'create-application-template',
@@ -68,7 +58,6 @@ function ApplicationsTemplates() {
) : (
({
diff --git a/src/fireedge/src/client/containers/Dashboard/Provision/index.js b/src/fireedge/src/client/containers/Dashboard/Provision/index.js
index 98b239c6b0..061d136fb3 100644
--- a/src/fireedge/src/client/containers/Dashboard/Provision/index.js
+++ b/src/fireedge/src/client/containers/Dashboard/Provision/index.js
@@ -13,29 +13,32 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { useEffect, JSXElementConstructor } from 'react'
-import { Container, Box, Grid } from '@mui/material'
+import { memo, ReactElement } from 'react'
+import PropTypes from 'prop-types'
+import { Container, Box, Grid, CircularProgress } from '@mui/material'
+import {
+ Server as ClusterIcon,
+ HardDrive as HostIcon,
+ Folder as DatastoreIcon,
+ NetworkAlt as NetworkIcon,
+} from 'iconoir-react'
import { useAuth } from 'client/features/Auth'
-import { useFetchAll } from 'client/hooks'
-import { useProvisionApi, useProviderApi } from 'client/features/One'
-import * as Widgets from 'client/components/Widgets'
+import { useGetResourceQuery } from 'client/features/OneApi/provision'
+
+import {
+ TotalProviders,
+ TotalProvisionsByState,
+} from 'client/components/Widgets'
+import NumberEasing from 'client/components/NumberEasing'
+import WavesCard from 'client/components/Cards/WavesCard'
import { stringToBoolean } from 'client/models/Helper'
+import { T } from 'client/constants'
-/** @returns {JSXElementConstructor} Provision dashboard container */
+/** @returns {ReactElement} Provision dashboard container */
function ProvisionDashboard() {
- const { status, fetchRequestAll, STATUS } = useFetchAll()
- const { INIT, PENDING } = STATUS
-
- const { getProvisions } = useProvisionApi()
- const { getProviders } = useProviderApi()
-
const { settings: { disableanimations } = {} } = useAuth()
- useEffect(() => {
- fetchRequestAll([getProviders(), getProvisions()])
- }, [])
-
return (
-
-
+
+
+
+
-
+
-
+
@@ -70,4 +90,33 @@ function ProvisionDashboard() {
)
}
+const ResourceWidget = memo(({ resource, ...props }) => {
+ const { data, isLoading } = useGetResourceQuery({ resource })
+ const total = `${data?.length ?? 0}`
+
+ return (
+
+
+ ) : (
+
+ )
+ }
+ {...props}
+ />
+
+ )
+})
+
+ResourceWidget.displayName = 'ResourceWidget'
+
+ResourceWidget.propTypes = {
+ resource: PropTypes.string,
+ text: PropTypes.string,
+ bgColor: PropTypes.string,
+ icon: PropTypes.any,
+}
+
export default ProvisionDashboard
diff --git a/src/fireedge/src/client/containers/Dashboard/Sunstone/index.js b/src/fireedge/src/client/containers/Dashboard/Sunstone/index.js
index 7e8d1fc7e1..7199dc04fa 100644
--- a/src/fireedge/src/client/containers/Dashboard/Sunstone/index.js
+++ b/src/fireedge/src/client/containers/Dashboard/Sunstone/index.js
@@ -13,36 +13,30 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { useEffect, JSXElementConstructor } from 'react'
-import { Container, Box, Grid } from '@mui/material'
+import { memo, ReactElement } from 'react'
+import PropTypes from 'prop-types'
+import { Container, Box, CircularProgress, Grid } from '@mui/material'
+import {
+ User as UserIcon,
+ Group as GroupIcon,
+ Archive as ImageIcon,
+ NetworkAlt as NetworkIcon,
+} from 'iconoir-react'
import { useAuth } from 'client/features/Auth'
-import { useFetchAll } from 'client/hooks'
-import {
- useUserApi,
- useImageApi,
- useVNetworkApi,
- useDatastoreApi,
-} from 'client/features/One'
-import * as Widgets from 'client/components/Widgets'
+import { useGetUsersQuery } from 'client/features/OneApi/user'
+import { useGetGroupsQuery } from 'client/features/OneApi/group'
+import { useGetImagesQuery } from 'client/features/OneApi/image'
+import { useGetVNetworksQuery } from 'client/features/OneApi/network'
+import NumberEasing from 'client/components/NumberEasing'
+import WavesCard from 'client/components/Cards/WavesCard'
import { stringToBoolean } from 'client/models/Helper'
+import { T } from 'client/constants'
-/** @returns {JSXElementConstructor} Sunstone dashboard container */
+/** @returns {ReactElement} Sunstone dashboard container */
function SunstoneDashboard() {
- const { status, fetchRequestAll, STATUS } = useFetchAll()
- const { INIT, PENDING } = STATUS
-
- const { getUsers } = useUserApi()
- const { getImages } = useImageApi()
- const { getVNetworks } = useVNetworkApi()
- const { getDatastores } = useDatastoreApi()
-
const { settings: { disableanimations } = {} } = useAuth()
- useEffect(() => {
- fetchRequestAll([getUsers(), getImages(), getVNetworks(), getDatastores()])
- }, [])
-
return (
-
-
-
-
+
+
+
+
+
)
}
+const ResourceWidget = memo(({ query, ...props }) => {
+ const { data, isLoading } = query()
+ const total = `${data?.length ?? 0}`
+
+ return (
+
+
+ ) : (
+
+ )
+ }
+ {...props}
+ />
+
+ )
+})
+
+ResourceWidget.displayName = 'ResourceWidget'
+
+ResourceWidget.propTypes = {
+ query: PropTypes.func,
+ text: PropTypes.string,
+ bgColor: PropTypes.string,
+ icon: PropTypes.any,
+}
+
export default SunstoneDashboard
diff --git a/src/fireedge/src/client/containers/Datastores/index.js b/src/fireedge/src/client/containers/Datastores/index.js
index 018022cb66..975fbe5c4b 100644
--- a/src/fireedge/src/client/containers/Datastores/index.js
+++ b/src/fireedge/src/client/containers/Datastores/index.js
@@ -14,23 +14,52 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-
-import { Container, Box } from '@mui/material'
+import { useState } from 'react'
+import { Container, Stack, Chip } from '@mui/material'
import { DatastoresTable } from 'client/components/Tables'
+import DatastoreTabs from 'client/components/Tabs/Datastore'
+import SplitPane from 'client/components/SplitPane'
+import MultipleTags from 'client/components/MultipleTags'
function Datastores() {
+ const [selectedRows, onSelectedRowsChange] = useState(() => [])
+
return (
-
-
-
+
+
+
+
+ {selectedRows?.length > 0 && (
+
+ {selectedRows?.length === 1 ? (
+
+ ) : (
+
+ (
+ toggleRowSelected(false)}
+ />
+ )
+ )}
+ />
+
+ )}
+
+ )}
+
+
)
}
diff --git a/src/fireedge/src/client/containers/Groups/index.js b/src/fireedge/src/client/containers/Groups/index.js
index f330170379..4311f0252d 100644
--- a/src/fireedge/src/client/containers/Groups/index.js
+++ b/src/fireedge/src/client/containers/Groups/index.js
@@ -14,23 +14,52 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-
-import { Container, Box } from '@mui/material'
+import { useState } from 'react'
+import { Container, Stack, Chip } from '@mui/material'
import { GroupsTable } from 'client/components/Tables'
+import GroupTabs from 'client/components/Tabs/Group'
+import SplitPane from 'client/components/SplitPane'
+import MultipleTags from 'client/components/MultipleTags'
function Groups() {
+ const [selectedRows, onSelectedRowsChange] = useState(() => [])
+
return (
-
-
-
+
+
+
+
+ {selectedRows?.length > 0 && (
+
+ {selectedRows?.length === 1 ? (
+
+ ) : (
+
+ (
+ toggleRowSelected(false)}
+ />
+ )
+ )}
+ />
+
+ )}
+
+ )}
+
+
)
}
diff --git a/src/fireedge/src/client/containers/Images/index.js b/src/fireedge/src/client/containers/Images/index.js
index df41ce6b3e..552a92c677 100644
--- a/src/fireedge/src/client/containers/Images/index.js
+++ b/src/fireedge/src/client/containers/Images/index.js
@@ -18,7 +18,7 @@ import { useState } from 'react'
import { Container, Stack, Chip } from '@mui/material'
import { ImagesTable } from 'client/components/Tables'
-import Detail from 'client/components/Tables/Images/detail'
+import ImageTabs from 'client/components/Tabs/Image'
import SplitPane from 'client/components/SplitPane'
import MultipleTags from 'client/components/MultipleTags'
@@ -33,7 +33,7 @@ function Images() {
{selectedRows?.length > 0 && (
{selectedRows?.length === 1 ? (
-
+
) : (
{
const { user, groups } = useAuth()
diff --git a/src/fireedge/src/client/containers/MarketplaceApps/Create.js b/src/fireedge/src/client/containers/MarketplaceApps/Create.js
index af954d2875..4f06dea3df 100644
--- a/src/fireedge/src/client/containers/MarketplaceApps/Create.js
+++ b/src/fireedge/src/client/containers/MarketplaceApps/Create.js
@@ -13,21 +13,23 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { useMemo, JSXElementConstructor } from 'react'
+import { useMemo, ReactElement } from 'react'
import { useHistory, useLocation } from 'react-router'
import { Container } from '@mui/material'
import { useGeneralApi } from 'client/features/General'
-import { useMarketplaceAppApi } from 'client/features/One'
+import {
+ useAllocateAppMutation,
+ useImportAppMutation,
+} from 'client/features/OneApi/marketplaceApp'
import { CreateForm } from 'client/components/Forms/MarketplaceApp'
import { jsonToXml } from 'client/models/Helper'
-import { isDevelopment } from 'client/utils'
import { RESOURCE_NAMES } from 'client/constants'
/**
* Displays the creation or modification form to a Marketplace App.
*
- * @returns {JSXElementConstructor} Marketplace App form
+ * @returns {ReactElement} Marketplace App form
*/
function CreateMarketplaceApp() {
const history = useHistory()
@@ -35,7 +37,8 @@ function CreateMarketplaceApp() {
const initialValues = useMemo(() => ({ type: resourceName, id: ID }), [])
const { enqueueSuccess } = useGeneralApi()
- const { create, importVm, importVmTemplate } = useMarketplaceAppApi()
+ const [create] = useAllocateAppMutation()
+ const [importApp] = useImportAppMutation()
const onSubmit = async ({ type, ...formData }) => {
try {
@@ -44,30 +47,22 @@ function CreateMarketplaceApp() {
const { id: imageId, marketId, name, image } = formData
const xml = jsonToXml({ ORIGIN_ID: imageId, NAME: name, ...image })
- return await create(marketId, xml)
- },
- [RESOURCE_NAMES.VM]: async () => {
- const { id: vmId, ...data } = formData
-
- return await importVm(vmId, data)
- },
- [RESOURCE_NAMES.VM_TEMPLATE]: async () => {
- const { id: templateId, ...data } = formData
-
- return await importVmTemplate(templateId, data)
+ return await create({ id: marketId, template: xml })
},
+ [RESOURCE_NAMES.VM]: async () =>
+ await importApp({ resource: 'vm', ...formData }),
+ [RESOURCE_NAMES.VM_TEMPLATE]: async () =>
+ await importApp({ resource: 'vm-template', ...formData }),
}[String(type).toLowerCase()]
- const response = await createApp?.()
+ const response = await createApp?.()?.unwrap?.()
response && enqueueSuccess(`Marketplace App created: ${response}`)
history.goBack()
- } catch (err) {
- isDevelopment() && console.error(err)
- }
+ } catch {}
}
return (
-
+
)
diff --git a/src/fireedge/src/client/containers/Marketplaces/index.js b/src/fireedge/src/client/containers/Marketplaces/index.js
index c1ea8a2178..695a3443ce 100644
--- a/src/fireedge/src/client/containers/Marketplaces/index.js
+++ b/src/fireedge/src/client/containers/Marketplaces/index.js
@@ -14,23 +14,52 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-
-import { Container, Box } from '@mui/material'
+import { useState } from 'react'
+import { Container, Stack, Chip } from '@mui/material'
import { MarketplacesTable } from 'client/components/Tables'
+import MarketplaceTabs from 'client/components/Tabs/Marketplace'
+import SplitPane from 'client/components/SplitPane'
+import MultipleTags from 'client/components/MultipleTags'
function Marketplaces() {
+ const [selectedRows, onSelectedRowsChange] = useState(() => [])
+
return (
-
-
-
+
+
+
+
+ {selectedRows?.length > 0 && (
+
+ {selectedRows?.length === 1 ? (
+
+ ) : (
+
+ (
+ toggleRowSelected(false)}
+ />
+ )
+ )}
+ />
+
+ )}
+
+ )}
+
+
)
}
diff --git a/src/fireedge/src/client/containers/Providers/Create.js b/src/fireedge/src/client/containers/Providers/Create.js
index fec743bf99..1f2c805a32 100644
--- a/src/fireedge/src/client/containers/Providers/Create.js
+++ b/src/fireedge/src/client/containers/Providers/Create.js
@@ -17,26 +17,30 @@
import { useParams, useHistory } from 'react-router'
import { Container } from '@mui/material'
-import { useAuth } from 'client/features/Auth'
import { useGeneralApi } from 'client/features/General'
-import { useProviderApi } from 'client/features/One'
+import {
+ useGetProviderConfigQuery,
+ useCreateProviderMutation,
+ useUpdateProviderMutation,
+} from 'client/features/OneApi/provider'
+
import { CreateForm } from 'client/components/Forms/Provider'
import { isValidProviderTemplate } from 'client/models/ProviderTemplate'
import { PATH } from 'client/apps/provision/routes'
-import { isDevelopment } from 'client/utils'
function ProviderCreateForm() {
const history = useHistory()
const { id } = useParams()
-
- const { providerConfig } = useAuth()
const { enqueueSuccess, enqueueError } = useGeneralApi()
- const { createProvider, updateProvider } = useProviderApi()
+
+ const { data: providerConfig } = useGetProviderConfigQuery()
+ const [createProvider] = useCreateProviderMutation()
+ const [updateProvider] = useUpdateProviderMutation()
const onSubmit = async (formData) => {
try {
if (id !== undefined) {
- await updateProvider(id, formData)
+ await updateProvider({ id, data: formData })
enqueueSuccess(`Provider updated - ID: ${id}`)
} else {
if (!isValidProviderTemplate(formData, providerConfig)) {
@@ -46,18 +50,16 @@ function ProviderCreateForm() {
history.push(PATH.PROVIDERS.LIST)
}
- const responseId = await createProvider(formData)
+ const responseId = await createProvider({ data: formData }).unwrap()
enqueueSuccess(`Provider created - ID: ${responseId}`)
}
history.push(PATH.PROVIDERS.LIST)
- } catch (err) {
- isDevelopment() && console.error(err)
- }
+ } catch {}
}
return (
-
+
)
diff --git a/src/fireedge/src/client/containers/Providers/Sections/info.js b/src/fireedge/src/client/containers/Providers/Sections/info.js
index 486cbc1b3b..44b29e5451 100644
--- a/src/fireedge/src/client/containers/Providers/Sections/info.js
+++ b/src/fireedge/src/client/containers/Providers/Sections/info.js
@@ -24,25 +24,25 @@ import {
EyeEmpty as EyeIcon,
} from 'iconoir-react'
-import { useFetch } from 'client/hooks'
-import { useProviderApi } from 'client/features/One'
+import {
+ useLazyGetProviderConnectionQuery,
+ useGetProviderQuery,
+} from 'client/features/OneApi/provider'
import { SubmitButton } from 'client/components/FormControl'
import { Tr } from 'client/components/HOC'
import { T } from 'client/constants'
import useStyles from 'client/containers/Providers/Sections/styles'
-const Info = memo(({ fetchProps }) => {
+const Info = memo(({ id }) => {
const classes = useStyles()
- const { getProviderConnection } = useProviderApi()
+ const [
+ getConnection,
+ { data: decryptConnection, isLoading: noConnectionYet },
+ ] = useLazyGetProviderConnectionQuery()
+ const { data: provider } = useGetProviderQuery(id)
- const {
- data: showConnection,
- fetchRequest,
- loading,
- } = useFetch(getProviderConnection)
-
- const { ID, NAME, GNAME, UNAME, PERMISSIONS, TEMPLATE } = fetchProps?.data
+ const { NAME, GNAME, UNAME, PERMISSIONS, TEMPLATE } = provider
const {
connection,
description,
@@ -66,7 +66,7 @@ const Info = memo(({ fetchProps }) => {
{'ID'}
- {ID}
+ {id}
{Tr(T.Name)}
@@ -93,13 +93,13 @@ const Info = memo(({ fetchProps }) => {
{Tr(T.Credentials)}
- {!showConnection && (
+ {!decryptConnection && (
}
- onClick={() => fetchRequest(ID)}
- isSubmitting={loading}
+ onClick={async () => await getConnection(id)}
+ isSubmitting={noConnectionYet}
/>
)}
@@ -111,7 +111,7 @@ const Info = memo(({ fetchProps }) => {
{key}
- {showConnection?.[key] ?? value}
+ {decryptConnection?.[key] ?? value}
)
@@ -171,18 +171,7 @@ const Info = memo(({ fetchProps }) => {
)
})
-Info.propTypes = {
- fetchProps: PropTypes.shape({
- data: PropTypes.object.isRequired,
- }).isRequired,
-}
-
-Info.defaultProps = {
- fetchProps: {
- data: {},
- },
-}
-
+Info.propTypes = { id: PropTypes.string.isRequired }
Info.displayName = 'Info'
export default Info
diff --git a/src/fireedge/src/client/containers/Providers/index.js b/src/fireedge/src/client/containers/Providers/index.js
index 02beabb595..154ab7c0d6 100644
--- a/src/fireedge/src/client/containers/Providers/index.js
+++ b/src/fireedge/src/client/containers/Providers/index.js
@@ -13,121 +13,178 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useState, useEffect } from 'react'
+import { memo, ReactElement, useEffect } from 'react'
+import PropTypes from 'prop-types'
import { useHistory, generatePath } from 'react-router-dom'
-import { Container, Box } from '@mui/material'
+import { Container, Box, Backdrop, CircularProgress } from '@mui/material'
import { Trash as DeleteIcon, Settings as EditIcon } from 'iconoir-react'
-import { PATH } from 'client/apps/provision/routes'
-import { useProvider, useProviderApi } from 'client/features/One'
+import {
+ useGetProviderConfigQuery,
+ useGetProvidersQuery,
+ useDeleteProviderMutation,
+ useGetProviderQuery,
+} from 'client/features/OneApi/provider'
import { useGeneralApi } from 'client/features/General'
-import { useFetch, useSearch } from 'client/hooks'
-import { useAuth } from 'client/features/Auth'
+import { useSearch, useDialog } from 'client/hooks'
import { ListHeader, ListCards } from 'client/components/List'
import AlertError from 'client/components/Alerts/Error'
import { ProvisionCard } from 'client/components/Cards'
-import { DialogRequest } from 'client/components/Dialogs'
+import { DialogConfirmation } from 'client/components/Dialogs'
+import { Translate } from 'client/components/HOC'
import Information from 'client/containers/Providers/Sections/info'
+import { PATH } from 'client/apps/provision/routes'
import { T } from 'client/constants'
+/**
+ * Renders a list of available providers.
+ *
+ * @returns {ReactElement} List of providers
+ */
function Providers() {
const history = useHistory()
- const [showDialog, setShowDialog] = useState(false)
+ const { display, show, hide, values: dialogProps } = useDialog()
- const { providerConfig } = useAuth()
- const providers = useProvider()
- const { getProviders, getProvider, deleteProvider } = useProviderApi()
const { enqueueSuccess } = useGeneralApi()
+ const { data: providerConfig } = useGetProviderConfigQuery()
+ const [deleteProvider, { isLoading: isDeleting }] =
+ useDeleteProviderMutation()
- const { error, fetchRequest, loading, reloading } = useFetch(getProviders)
+ const {
+ refetch,
+ data: providers = [],
+ isFetching,
+ error,
+ } = useGetProvidersQuery()
const { result, handleChange } = useSearch({
list: providers,
listOptions: { shouldSort: true, keys: ['ID', 'NAME'] },
})
- useEffect(() => {
- fetchRequest()
- }, [])
-
- const handleCancel = () => setShowDialog(false)
+ const handleDelete = async (id) => {
+ try {
+ hide()
+ await deleteProvider({ id })
+ enqueueSuccess(`Provider deleted - ID: ${id}`)
+ } catch {}
+ }
return (
-
- fetchRequest(undefined, { reload: true }),
- isSubmitting: Boolean(loading || reloading),
- }}
- addButtonProps={{
- 'data-cy': 'create-provider',
- onClick: () => history.push(PATH.PROVIDERS.CREATE),
- }}
- searchProps={{ handleChange }}
- />
-
- {error ? (
- {T.CannotConnectOneProvision}
- ) : (
- ({
- image: providerConfig[TEMPLATE?.PLAIN?.provider]?.image,
- isProvider: true,
- handleClick: () =>
- setShowDialog({
- id: ID,
- title: `#${ID} ${NAME}`,
- }),
- actions: [
- {
- handleClick: () =>
- history.push(generatePath(PATH.PROVIDERS.EDIT, { id: ID })),
- icon: ,
- cy: 'provider-edit',
- },
- {
- handleClick: () =>
- setShowDialog({
- id: ID,
- title: `DELETE | #${ID} ${NAME}`,
- handleAccept: () => {
- setShowDialog(false)
-
- return deleteProvider(ID)
- .then(() =>
- enqueueSuccess(`Provider deleted - ID: ${ID}`)
- )
- .then(() => fetchRequest(undefined, { reload: true }))
- },
- }),
- icon: ,
- color: 'error',
- cy: 'provider-delete',
- },
- ],
- })}
- />
- )}
-
- {showDialog !== false && (
- getProvider(showDialog.id)}
- dialogProps={{ fixedWidth: true, handleCancel, ...showDialog }}
- >
- {(fetchProps) => }
-
+ <>
+
+ refetch(),
+ isSubmitting: isFetching,
+ }}
+ addButtonProps={{
+ 'data-cy': 'create-provider',
+ onClick: () => history.push(PATH.PROVIDERS.CREATE),
+ }}
+ searchProps={{ handleChange }}
+ />
+
+ {error ? (
+ {T.CannotConnectOneProvision}
+ ) : (
+ ({
+ image: providerConfig[TEMPLATE?.PLAIN?.provider]?.image,
+ isProvider: true,
+ handleClick: () => show({ id: ID, title: `#${ID} ${NAME}` }),
+ actions: [
+ {
+ handleClick: () =>
+ history.push(
+ generatePath(PATH.PROVIDERS.EDIT, { id: ID })
+ ),
+ icon: ,
+ cy: 'provider-edit',
+ },
+ {
+ handleClick: () =>
+ show({
+ id: ID,
+ title: (
+
+ ),
+ handleAccept: () => handleDelete(ID),
+ }),
+ icon: ,
+ isSubmitting: isDeleting,
+ color: 'error',
+ cy: 'provider-delete',
+ },
+ ],
+ })}
+ />
+ )}
+
+
+ {display && dialogProps?.id && (
+
)}
-
+ >
)
}
+const DialogProvider = memo(
+ ({ id, hide, dialogProps }) => {
+ const {
+ currentData: providerDetail,
+ isLoading: providerIsLoading,
+ error: providerError,
+ } = useGetProviderQuery(id)
+
+ useEffect(() => {
+ providerError && hide()
+ }, [providerError])
+
+ return providerDetail?.ID !== id || providerIsLoading ? (
+ theme.zIndex.drawer + 1,
+ color: (theme) => theme.palette.common.white,
+ }}
+ >
+
+
+ ) : (
+
+
+
+ )
+ },
+ (prev, next) => prev.id === next.id
+)
+
+DialogProvider.propTypes = {
+ id: PropTypes.string,
+ hide: PropTypes.func,
+ dialogProps: PropTypes.object,
+}
+
+DialogProvider.displayName = 'DialogProvider'
+
export default Providers
diff --git a/src/fireedge/src/client/containers/Provisions/Create.js b/src/fireedge/src/client/containers/Provisions/Create.js
index 147657dc43..35020d72c6 100644
--- a/src/fireedge/src/client/containers/Provisions/Create.js
+++ b/src/fireedge/src/client/containers/Provisions/Create.js
@@ -14,7 +14,7 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-import { useEffect, useState, memo } from 'react'
+import { useState, memo } from 'react'
import { Redirect, useHistory } from 'react-router'
import { NavArrowLeft as ArrowBackIcon } from 'iconoir-react'
@@ -26,14 +26,14 @@ import {
} from '@mui/material'
import makeStyles from '@mui/styles/makeStyles'
-import { useFetch, useSocket } from 'client/hooks'
+import { useSocket } from 'client/hooks'
import { useGeneralApi } from 'client/features/General'
-import { useProviderApi, useProvisionApi } from 'client/features/One'
+import { useCreateProvisionMutation } from 'client/features/OneApi/provision'
+import { useGetProvidersQuery } from 'client/features/OneApi/provider'
import DebugLog from 'client/components/DebugLog'
import { CreateForm } from 'client/components/Forms/Provision'
import { PATH } from 'client/apps/provision/routes'
import { Translate } from 'client/components/HOC'
-import { isDevelopment } from 'client/utils'
import { T } from 'client/constants'
const useStyles = makeStyles({
@@ -55,25 +55,18 @@ function ProvisionCreateForm() {
const { getProvisionSocket: socket } = useSocket()
const { enqueueInfo } = useGeneralApi()
- const { createProvision } = useProvisionApi()
- const { getProviders } = useProviderApi()
- const { data, fetchRequest, loading, error } = useFetch(getProviders)
+ const [createProvision] = useCreateProvisionMutation()
+ const { data, isLoading, error } = useGetProvidersQuery()
const onSubmit = async (formData) => {
try {
- const response = await createProvision(formData)
+ const response = await createProvision({ data: formData }).unwrap()
enqueueInfo('Creating provision')
response && setUuid(response)
- } catch (err) {
- isDevelopment() && console.error(err)
- }
+ } catch {}
}
- useEffect(() => {
- fetchRequest()
- }, [])
-
if (uuid) {
return }} />
}
@@ -82,7 +75,7 @@ function ProvisionCreateForm() {
return
}
- return !data || loading ? (
+ return !data || isLoading ? (
) : (
diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/datastores.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/datastores.js
index 57657d0ed0..992c301aa2 100644
--- a/src/fireedge/src/client/containers/Provisions/DialogInfo/datastores.js
+++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/datastores.js
@@ -13,60 +13,74 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { memo, useEffect } from 'react'
+import { memo } from 'react'
import PropTypes from 'prop-types'
import { Trash as DeleteIcon } from 'iconoir-react'
-import { useFetchAll } from 'client/hooks'
-import { useDatastoreApi, useProvisionApi } from 'client/features/One'
+import {
+ useGetProvisionQuery,
+ useGetResourceQuery,
+ useRemoveResourceMutation,
+} from 'client/features/OneApi/provision'
import { useGeneralApi } from 'client/features/General'
-import { ListCards } from 'client/components/List'
+
+import { DatastoresTable } from 'client/components/Tables'
import { DatastoreCard } from 'client/components/Cards'
+import { SubmitButton } from 'client/components/FormControl'
const Datastores = memo(
- ({ hidden, data, reloading, refetchProvision, disableAllActions }) => {
- const { datastores = [] } = data?.TEMPLATE?.BODY?.provision?.infrastructure
-
+ ({ id }) => {
const { enqueueSuccess } = useGeneralApi()
- const { deleteDatastore } = useProvisionApi()
- const { getDatastore } = useDatastoreApi()
- const { data: list, fetchRequestAll, loading } = useFetchAll()
- const fetchDatastores = () =>
- fetchRequestAll(datastores?.map(({ id }) => getDatastore(id)))
+ const [removeResource, { isLoading: loadingRemove }] =
+ useRemoveResourceMutation()
+ const { data } = useGetProvisionQuery(id)
- useEffect(() => {
- !hidden && !list && fetchDatastores()
- }, [hidden])
-
- useEffect(() => {
- !reloading && !loading && fetchDatastores()
- }, [reloading])
+ const provisionDatastores =
+ data?.TEMPLATE?.BODY?.provision?.infrastructure?.datastores?.map(
+ (datastore) => +datastore.id
+ ) ?? []
return (
-
- !disableAllActions && {
- actions: [
- {
- handleClick: () =>
- deleteDatastore(ID)
- .then(refetchProvision)
- .then(() =>
- enqueueSuccess(`Datastore deleted - ID: ${ID}`)
- ),
- icon: ,
- cy: `provision-datastore-delete-${ID}`,
- },
- ],
- }
+
+ useGetResourceQuery(
+ { resource: 'datastore' },
+ {
+ selectFromResult: ({ data: result = [], ...rest }) => ({
+ data: result?.filter((datastore) =>
+ provisionDatastores.includes(+datastore.ID)
+ ),
+ ...rest,
+ }),
+ }
+ )
}
- displayEmpty
- breakpoints={{ xs: 12, md: 6 }}
+ RowComponent={({ original: datastore, handleClick: _, ...props }) => (
+ }
+ isSubmitting={loadingRemove}
+ onClick={async () => {
+ removeResource({
+ provision: id,
+ id: datastore.ID,
+ resource: 'datastore',
+ })
+ enqueueSuccess(`Datastore deleted - ID: ${datastore.ID}`)
+ }}
+ />
+ }
+ />
+ )}
/>
)
},
@@ -74,22 +88,7 @@ const Datastores = memo(
prev.hidden === next.hidden && prev.reloading === next.reloading
)
-Datastores.propTypes = {
- data: PropTypes.object.isRequired,
- hidden: PropTypes.bool,
- refetchProvision: PropTypes.func,
- reloading: PropTypes.bool,
- disableAllActions: PropTypes.bool,
-}
-
-Datastores.defaultProps = {
- data: {},
- hidden: false,
- refetchProvision: () => undefined,
- reloading: false,
- disableAllActions: false,
-}
-
+Datastores.propTypes = { id: PropTypes.string.isRequired }
Datastores.displayName = 'Datastores'
export default Datastores
diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js
index d5a90ad692..2b79e5341c 100644
--- a/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js
+++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { memo, useEffect, useState } from 'react'
+import { memo, useState } from 'react'
import PropTypes from 'prop-types'
import {
@@ -23,120 +23,120 @@ import {
} from 'iconoir-react'
import { Stack, TextField } from '@mui/material'
-import { useFetch, useFetchAll } from 'client/hooks'
-import { useHostApi, useProvisionApi } from 'client/features/One'
import { useGeneralApi } from 'client/features/General'
-import { SubmitButton } from 'client/components/FormControl'
-import { ListCards } from 'client/components/List'
+import {
+ useGetProvisionQuery,
+ useAddHostToProvisionMutation,
+ useConfigureHostMutation,
+ useRemoveResourceMutation,
+ useGetResourceQuery,
+} from 'client/features/OneApi/provision'
+
+import { HostsTable } from 'client/components/Tables'
import { HostCard } from 'client/components/Cards'
+import { SubmitButton } from 'client/components/FormControl'
import { Translate } from 'client/components/HOC'
import { T } from 'client/constants'
-const Hosts = memo(
- ({ hidden, data, reloading, refetchProvision, disableAllActions }) => {
- const [amount, setAmount] = useState(() => 1)
- const { hosts = [] } = data?.TEMPLATE?.BODY?.provision?.infrastructure
+const Hosts = memo(({ id }) => {
+ const [amount, setAmount] = useState(() => 1)
+ const { enqueueSuccess, enqueueInfo } = useGeneralApi()
- const { enqueueSuccess, enqueueInfo } = useGeneralApi()
- const { configureHost, deleteHost, addHost } = useProvisionApi()
- const { getHost } = useHostApi()
+ const [addHost, { isLoading: loadingAddHost }] =
+ useAddHostToProvisionMutation()
+ const [configureHost, { isLoading: loadingConfigure }] =
+ useConfigureHostMutation()
+ const [removeResource, { isLoading: loadingRemove }] =
+ useRemoveResourceMutation()
+ const { data = {} } = useGetProvisionQuery(id)
- const { fetchRequest, loading: loadingAddHost } = useFetch(
- async (payload) => {
- await addHost(data?.ID, payload)
- await refetchProvision()
- enqueueSuccess(`Adding hosts ${amount}x`)
- }
- )
+ const provisionHosts =
+ data?.TEMPLATE?.BODY?.provision?.infrastructure?.hosts?.map(
+ (host) => +host.id
+ ) ?? []
- const { data: list, fetchRequestAll, loading } = useFetchAll()
- const fetchHosts = () =>
- fetchRequestAll(hosts?.map(({ id }) => getHost(id)))
-
- useEffect(() => {
- !hidden && !list && fetchHosts()
- }, [hidden])
-
- useEffect(() => {
- !reloading && !loading && fetchHosts()
- }, [reloading])
-
- return (
- <>
-
- {
- const newAmount = event.target.value
- ;+newAmount > 0 && setAmount(newAmount)
- }}
- value={amount}
- />
-
- }
- label={}
- isSubmitting={loadingAddHost}
- onClick={() => fetchRequest(amount)}
- />
-
-
-
- !disableAllActions && {
- actions: [
- {
- handleClick: () =>
- configureHost(ID)
- .then(() => enqueueInfo(`Configuring host - ID: ${ID}`))
- .then(refetchProvision),
- icon: ,
- cy: `provision-host-configure-${ID}`,
- },
- {
- handleClick: () =>
- deleteHost(ID)
- .then(refetchProvision)
- .then(() => enqueueSuccess(`Host deleted - ID: ${ID}`)),
- icon: ,
- cy: `provision-host-delete-${ID}`,
- },
- ],
- }
- }
- displayEmpty
- breakpoints={{ xs: 12, md: 6 }}
+ return (
+ <>
+
+ {
+ const newAmount = event.target.value
+ ;+newAmount > 0 && setAmount(newAmount)
+ }}
+ value={amount}
/>
- >
- )
- },
- (prev, next) =>
- prev.hidden === next.hidden && prev.reloading === next.reloading
-)
-
-Hosts.propTypes = {
- data: PropTypes.object.isRequired,
- hidden: PropTypes.bool,
- refetchProvision: PropTypes.func,
- reloading: PropTypes.bool,
- disableAllActions: PropTypes.bool,
-}
-
-Hosts.defaultProps = {
- data: {},
- hidden: false,
- refetchProvision: () => undefined,
- reloading: false,
- disableAllActions: false,
-}
+
+ }
+ label={}
+ isSubmitting={loadingAddHost}
+ onClick={async () => {
+ addHost({ id, amount })
+ enqueueSuccess(`Host added ${amount}x`)
+ }}
+ />
+
+
+
+ useGetResourceQuery(
+ { resource: 'host' },
+ {
+ selectFromResult: ({ data: result = [], ...rest }) => ({
+ data: result?.filter((host) =>
+ provisionHosts.includes(+host.ID)
+ ),
+ ...rest,
+ }),
+ }
+ )
+ }
+ RowComponent={({ original: host, handleClick: _, ...props }) => (
+
+ }
+ isSubmitting={loadingConfigure}
+ onClick={async () => {
+ configureHost({ provision: id, id: host.ID })
+ enqueueInfo(`Configuring host - ID: ${host.ID}`)
+ }}
+ />
+ }
+ isSubmitting={loadingRemove}
+ onClick={async () => {
+ removeResource({
+ provision: id,
+ id: host.ID,
+ resource: 'host',
+ })
+ enqueueSuccess(`Host deleted - ID: ${host.ID}`)
+ }}
+ />
+ >
+ }
+ />
+ )}
+ />
+ >
+ )
+})
+Hosts.propTypes = { id: PropTypes.string.isRequired }
Hosts.displayName = 'Hosts'
export default Hosts
diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/index.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/index.js
index a896484358..ea72a80b73 100644
--- a/src/fireedge/src/client/containers/Provisions/DialogInfo/index.js
+++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/index.js
@@ -13,11 +13,8 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useState, useMemo } from 'react'
+import { useMemo, ReactElement } from 'react'
import PropTypes from 'prop-types'
-
-import { AppBar, Tabs, Tab, Box } from '@mui/material'
import {
InfoEmpty as InfoIcon,
HardDrive as HostIcon,
@@ -26,94 +23,61 @@ import {
Page as LogIcon,
} from 'iconoir-react'
+import Tabs from 'client/components/Tabs'
import InfoTab from 'client/containers/Provisions/DialogInfo/info'
import DatastoresTab from 'client/containers/Provisions/DialogInfo/datastores'
import NetworksTab from 'client/containers/Provisions/DialogInfo/networks'
import HostsTab from 'client/containers/Provisions/DialogInfo/hosts'
import LogTab from 'client/containers/Provisions/DialogInfo/log'
+import { T } from 'client/constants'
-const TABS = [
- { name: 'info', icon: InfoIcon, content: InfoTab },
- { name: 'datastores', icon: DatastoreIcon, content: DatastoresTab },
- { name: 'networks', icon: NetworkIcon, content: NetworksTab },
- { name: 'hosts', icon: HostIcon, content: HostsTab },
- { name: 'log', icon: LogIcon, content: LogTab },
-]
-
-const DialogInfo = ({ disableAllActions, fetchProps }) => {
- const [tabSelected, setTab] = useState(0)
- const { data, fetchRequest, reloading } = fetchProps
-
- const renderTabs = useMemo(
- () => (
-
- setTab(tab)}
- >
- {TABS.map(({ name, icon: Icon }, idx) => (
- }
- value={idx}
- label={String(name).toUpperCase()}
- />
- ))}
-
-
- ),
- [tabSelected]
+/**
+ * Renders information about provision: infrastructures, log, etc.
+ *
+ * @param {object} props - Props
+ * @param {string} props.id - Provision id
+ * @returns {ReactElement} - Provision id
+ */
+const DialogInfo = ({ id }) => {
+ const tabsAvailable = useMemo(
+ () => [
+ {
+ name: 'info',
+ label: T.Info,
+ icon: InfoIcon,
+ renderContent: () => ,
+ },
+ {
+ name: 'datastores',
+ label: T.Datastores,
+ icon: DatastoreIcon,
+ renderContent: () => ,
+ },
+ {
+ name: 'networks',
+ label: T.Networks,
+ icon: NetworkIcon,
+ renderContent: () => ,
+ },
+ {
+ name: 'hosts',
+ label: T.Hosts,
+ icon: HostIcon,
+ renderContent: () => ,
+ },
+ {
+ name: 'log',
+ label: T.Log,
+ icon: LogIcon,
+ renderContent: () => ,
+ },
+ ],
+ []
)
- return (
- <>
- {renderTabs}
- {useMemo(
- () =>
- TABS.map(({ name, content: Content }, idx) => (
-
-
- fetchRequest(undefined, { reload: true })
- }
- reloading={reloading}
- />
-
- )),
- [tabSelected, reloading]
- )}
- >
- )
+ return
}
-DialogInfo.propTypes = {
- disableAllActions: PropTypes.bool,
- fetchProps: PropTypes.shape({
- data: PropTypes.object.isRequired,
- fetchRequest: PropTypes.func,
- reloading: PropTypes.bool,
- }).isRequired,
-}
-
-DialogInfo.defaultProps = {
- disableAllActions: false,
- fetchProps: {
- data: {},
- fetchRequest: undefined,
- reloading: false,
- },
-}
+DialogInfo.propTypes = { id: PropTypes.string.isRequired }
export default DialogInfo
diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/info.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/info.js
index 6f144a6bcf..df6cb239e3 100644
--- a/src/fireedge/src/client/containers/Provisions/DialogInfo/info.js
+++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/info.js
@@ -20,13 +20,16 @@ import clsx from 'clsx'
import { List, ListItem, Typography, Grid, Paper, Divider } from '@mui/material'
import { Check as CheckIcon, Square as BlankSquareIcon } from 'iconoir-react'
+import { useGetProvisionQuery } from 'client/features/OneApi/provision'
import useStyles from 'client/containers/Provisions/DialogInfo/styles'
import { StatusChip } from 'client/components/Status'
import { Tr } from 'client/components/HOC'
import { T, PROVISIONS_STATES } from 'client/constants'
-const Info = memo(({ data = {} }) => {
+const Info = memo(({ id }) => {
const classes = useStyles()
+
+ const { data = {} } = useGetProvisionQuery(id)
const { ID, GNAME, UNAME, PERMISSIONS, TEMPLATE } = data
const {
state,
@@ -140,14 +143,7 @@ const Info = memo(({ data = {} }) => {
)
})
-Info.propTypes = {
- data: PropTypes.object.isRequired,
-}
-
-Info.defaultProps = {
- data: undefined,
-}
-
+Info.propTypes = { id: PropTypes.string.isRequired }
Info.displayName = 'Info'
export default Info
diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/log.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/log.js
index af2f84ff31..76be13b5df 100644
--- a/src/fireedge/src/client/containers/Provisions/DialogInfo/log.js
+++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/log.js
@@ -13,70 +13,42 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { memo, useEffect, useMemo } from 'react'
+import { memo, useMemo } from 'react'
import PropTypes from 'prop-types'
import { LinearProgress } from '@mui/material'
-import { useFetch, useSocket } from 'client/hooks'
-import { useProvisionApi } from 'client/features/One'
+import { useSocket } from 'client/hooks'
+import { useGetProvisionLogQuery } from 'client/features/OneApi/provision'
import DebugLog, { LogUtils } from 'client/components/DebugLog'
-const Log = memo(
- ({ hidden, data: { ID } }) => {
- const { getProvisionSocket } = useSocket()
- const { getProvisionLog } = useProvisionApi()
+const Log = memo(({ id }) => {
+ const { getProvisionSocket } = useSocket()
+ const { data, isLoading } = useGetProvisionLogQuery(id)
+ const { uuid = id, log } = data ?? {}
- const {
- data: { uuid = ID, log } = {},
- fetchRequest,
- loading,
- } = useFetch(getProvisionLog)
+ const parsedLog = useMemo(
+ () =>
+ log
+ ?.map((entry) => {
+ try {
+ return JSON.parse(entry)
+ } catch {
+ return entry
+ }
+ })
+ ?.reduce(LogUtils.concatNewMessageToLog, {}),
+ [isLoading]
+ )
- useEffect(() => {
- !log && !hidden && fetchRequest(ID)
- }, [hidden])
-
- const parsedLog = useMemo(
- () =>
- log
- ?.map((entry) => {
- try {
- return JSON.parse(entry)
- } catch {
- return entry
- }
- })
- ?.reduce(LogUtils.concatNewMessageToLog, {}),
- [loading]
- )
-
- return loading ? (
-
- ) : (
-
- )
- },
- (prev, next) =>
- prev.hidden === next.hidden && prev.reloading === next.reloading
-)
-
-Log.propTypes = {
- data: PropTypes.object.isRequired,
- hidden: PropTypes.bool,
- fetchRequest: PropTypes.func,
-}
-
-Log.defaultProps = {
- data: {},
- hidden: false,
- fetchRequest: () => undefined,
-}
+ return isLoading ? (
+
+ ) : (
+
+ )
+})
+Log.propTypes = { id: PropTypes.string.isRequired }
Log.displayName = 'Log'
export default Log
diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js
index 416e661e37..6b1205235d 100644
--- a/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js
+++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js
@@ -13,120 +13,113 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { memo, useEffect, useState } from 'react'
+import { memo, useState } from 'react'
import PropTypes from 'prop-types'
import { Trash as DeleteIcon, AddCircledOutline } from 'iconoir-react'
import { Stack, TextField } from '@mui/material'
-import { useFetch, useFetchAll } from 'client/hooks'
-import { useVNetworkApi, useProvisionApi } from 'client/features/One'
import { useGeneralApi } from 'client/features/General'
-import { SubmitButton } from 'client/components/FormControl'
-import { ListCards } from 'client/components/List'
+import {
+ useGetProvisionQuery,
+ useAddIpToProvisionMutation,
+ useRemoveResourceMutation,
+ useGetResourceQuery,
+} from 'client/features/OneApi/provision'
+
+import { VNetworksTable } from 'client/components/Tables'
import { NetworkCard } from 'client/components/Cards'
+import { SubmitButton } from 'client/components/FormControl'
import { Translate } from 'client/components/HOC'
import { T } from 'client/constants'
-const Networks = memo(
- ({ hidden, data, reloading, refetchProvision, disableAllActions }) => {
- const [amount, setAmount] = useState(() => 1)
- const { networks = [] } = data?.TEMPLATE?.BODY?.provision?.infrastructure
+const Networks = memo(({ id }) => {
+ const [amount, setAmount] = useState(() => 1)
+ const { enqueueSuccess } = useGeneralApi()
- const { enqueueSuccess } = useGeneralApi()
- const { deleteVNetwork, addIp } = useProvisionApi()
- const { getVNetwork } = useVNetworkApi()
+ const [addIp, { isLoading: loadingAddIp }] = useAddIpToProvisionMutation()
+ const [removeResource, { isLoading: loadingRemove }] =
+ useRemoveResourceMutation()
+ const { data = {} } = useGetProvisionQuery(id)
- const { fetchRequest, loading: loadingAddIp } = useFetch(
- async (payload) => {
- await addIp(data?.ID, payload)
- await refetchProvision()
- enqueueSuccess(`IP added ${amount}x`)
- }
- )
+ const provisionNetworks =
+ data?.TEMPLATE?.BODY?.provision?.infrastructure?.networks?.map(
+ (network) => +network.id
+ ) ?? []
- const { data: list, fetchRequestAll, loading } = useFetchAll()
- const fetchVNetworks = () =>
- fetchRequestAll(networks?.map(({ id }) => getVNetwork(id)))
-
- useEffect(() => {
- !hidden && !list && fetchVNetworks()
- }, [hidden])
-
- useEffect(() => {
- !reloading && !loading && fetchVNetworks()
- }, [reloading])
-
- return (
- <>
-
- {
- const newAmount = event.target.value
- ;+newAmount > 0 && setAmount(newAmount)
- }}
- value={amount}
- />
-
- }
- label={}
- sx={{ ml: 1, display: 'flex', alignItems: 'flex-start' }}
- isSubmitting={loadingAddIp}
- onClick={() => fetchRequest(amount)}
- />
-
-
-
- !disableAllActions && {
- actions: [
- {
- handleClick: () =>
- deleteVNetwork(ID)
- .then(refetchProvision)
- .then(() =>
- enqueueSuccess(`VNetwork deleted - ID: ${ID}`)
- ),
- icon: ,
- cy: `provision-vnet-delete-${ID}`,
- },
- ],
- }
- }
- displayEmpty
- breakpoints={{ xs: 12, md: 6 }}
+ return (
+ <>
+
+ {
+ const newAmount = event.target.value
+ ;+newAmount > 0 && setAmount(newAmount)
+ }}
+ value={amount}
/>
- >
- )
- },
- (prev, next) =>
- prev.hidden === next.hidden && prev.reloading === next.reloading
-)
-
-Networks.propTypes = {
- data: PropTypes.object.isRequired,
- hidden: PropTypes.bool,
- refetchProvision: PropTypes.func,
- reloading: PropTypes.bool,
- disableAllActions: PropTypes.bool,
-}
-
-Networks.defaultProps = {
- data: {},
- hidden: false,
- refetchProvision: () => undefined,
- reloading: false,
- disableAllActions: false,
-}
+
+ }
+ label={}
+ sx={{ ml: 1, display: 'flex', alignItems: 'flex-start' }}
+ isSubmitting={loadingAddIp}
+ onClick={async () => {
+ await addIp({ id, amount })
+ enqueueSuccess(`IP added ${amount}x`)
+ }}
+ />
+
+
+
+ useGetResourceQuery(
+ { resource: 'network' },
+ {
+ selectFromResult: ({ data: result = [], ...rest }) => ({
+ data: result?.filter((vnet) =>
+ provisionNetworks.includes(+vnet.ID)
+ ),
+ ...rest,
+ }),
+ }
+ )
+ }
+ RowComponent={({ original: vnet, handleClick: _, ...props }) => (
+
+ }
+ isSubmitting={loadingRemove}
+ onClick={async () => {
+ removeResource({
+ provision: id,
+ id: vnet.ID,
+ resource: 'network',
+ })
+ enqueueSuccess(`Network deleted - ID: ${vnet.ID}`)
+ }}
+ />
+ >
+ }
+ />
+ )}
+ />
+ >
+ )
+})
+Networks.propTypes = { id: PropTypes.string.isRequired }
Networks.displayName = 'Networks'
export default Networks
diff --git a/src/fireedge/src/client/containers/Provisions/index.js b/src/fireedge/src/client/containers/Provisions/index.js
index 09bf7b4a22..b8539b4524 100644
--- a/src/fireedge/src/client/containers/Provisions/index.js
+++ b/src/fireedge/src/client/containers/Provisions/index.js
@@ -13,16 +13,19 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useState, useEffect, createElement } from 'react'
+import { ReactElement } from 'react'
import { useHistory } from 'react-router-dom'
-import { Container, Box } from '@mui/material'
+import { Container, Box, Backdrop, CircularProgress } from '@mui/material'
import { Trash as DeleteIcon, Settings as EditIcon } from 'iconoir-react'
-import { PATH } from 'client/apps/provision/routes'
-import { useFetch, useSearch } from 'client/hooks'
-import { useProvision, useProvisionApi } from 'client/features/One'
+import {
+ useGetProvisionsQuery,
+ useLazyGetProvisionQuery,
+ useConfigureProvisionMutation,
+ useDeleteProvisionMutation,
+} from 'client/features/OneApi/provision'
+import { useSearch, useDialog } from 'client/hooks'
import { useGeneralApi } from 'client/features/General'
import { DeleteForm } from 'client/components/Forms/Provision'
@@ -31,127 +34,141 @@ import AlertError from 'client/components/Alerts/Error'
import { ProvisionCard } from 'client/components/Cards'
import { Translate } from 'client/components/HOC'
-import { DialogRequest } from 'client/components/Dialogs'
+import { DialogConfirmation } from 'client/components/Dialogs'
import DialogInfo from 'client/containers/Provisions/DialogInfo'
+import { PATH } from 'client/apps/provision/routes'
import { T } from 'client/constants'
+/**
+ * Renders a list of available cluster provisions.
+ *
+ * @returns {ReactElement} List of provisions
+ */
function Provisions() {
const history = useHistory()
- const [{ content, ...showDialog } = {}, setShowDialog] = useState()
- const handleCloseDialog = () => setShowDialog()
+ const { display, show, hide, values: dialogProps } = useDialog()
const { enqueueInfo } = useGeneralApi()
- const provisions = useProvision()
+ const [configureProvision] = useConfigureProvisionMutation()
+ const [deleteProvision] = useDeleteProvisionMutation()
- const { getProvisions, getProvision, configureProvision, deleteProvision } =
- useProvisionApi()
+ const {
+ refetch,
+ data: provisions = [],
+ isFetching,
+ error,
+ } = useGetProvisionsQuery()
- const { error, fetchRequest, loading, reloading } = useFetch(getProvisions)
+ const [
+ getProvision,
+ {
+ currentData: provisionDetail,
+ isLoading: provisionIsLoading,
+ error: provisionError,
+ originalArgs,
+ },
+ ] = useLazyGetProvisionQuery()
const { result, handleChange } = useSearch({
list: provisions,
listOptions: { shouldSort: true, keys: ['ID', 'NAME'] },
})
- useEffect(() => {
- fetchRequest()
- }, [])
-
return (
-
- fetchRequest(undefined, { reload: true }),
- isSubmitting: Boolean(loading || reloading),
- }}
- addButtonProps={{
- 'data-cy': 'create-provision',
- onClick: () => history.push(PATH.PROVISIONS.CREATE),
- }}
- searchProps={{ handleChange }}
- />
-
- {error ? (
- {T.CannotConnectOneProvision}
- ) : (
- ({
- handleClick: () =>
- setShowDialog({
- id: ID,
- title: `#${ID} ${NAME}`,
- content: (props) =>
- createElement(DialogInfo, {
- ...props,
- displayName: 'DialogDetailProvision',
- }),
- }),
- actions: [
- {
- handleClick: () =>
- configureProvision(ID)
- .then(() =>
- enqueueInfo(`Configuring provision - ID: ${ID}`)
- )
- .then(() => fetchRequest(undefined, { reload: true })),
- icon: ,
- cy: 'provision-configure',
+ <>
+
+ refetch(),
+ isSubmitting: isFetching,
+ }}
+ addButtonProps={{
+ 'data-cy': 'create-provision',
+ onClick: () => history.push(PATH.PROVISIONS.CREATE),
+ }}
+ searchProps={{ handleChange }}
+ />
+
+ {error ? (
+ {T.CannotConnectOneProvision}
+ ) : (
+ ({
+ handleClick: () => {
+ getProvision(ID)
+ show({ id: ID, title: `#${ID} ${NAME}` })
},
- ],
- deleteAction: {
- buttonProps: {
- 'data-cy': 'provision-delete',
- icon: ,
- color: 'error',
- },
- options: [
+ actions: [
{
- dialogProps: {
- title: (
-
- ),
- },
- form: DeleteForm,
- onSubmit: async (formData) => {
- try {
- await deleteProvision(ID, formData)
- enqueueInfo(`Deleting provision - ID: ${ID}`)
- } finally {
- handleCloseDialog()
- fetchRequest(undefined, { reload: true })
- }
+ handleClick: async () => {
+ await configureProvision({ id: ID })
+ enqueueInfo(`Configuring provision - ID: ${ID}`)
},
+ icon: ,
+ cy: 'provision-configure',
},
],
- },
- })}
- />
- )}
-
- {content && (
- getProvision(showDialog.id)}
- dialogProps={{
- fixedWidth: true,
- fixedHeight: true,
- handleCancel: handleCloseDialog,
- ...showDialog,
- }}
- >
- {(props) => content(props)}
-
- )}
-
+ deleteAction: {
+ buttonProps: {
+ 'data-cy': 'provision-delete',
+ icon: ,
+ color: 'error',
+ },
+ options: [
+ {
+ dialogProps: {
+ title: (
+
+ ),
+ },
+ form: DeleteForm,
+ onSubmit: async (formData) => {
+ try {
+ await deleteProvision({ id: ID, ...formData })
+ enqueueInfo(`Deleting provision - ID: ${ID}`)
+ } finally {
+ hide()
+ }
+ },
+ },
+ ],
+ },
+ })}
+ />
+ )}
+
+
+ {display &&
+ !provisionError &&
+ (provisionDetail?.ID !== originalArgs || provisionIsLoading ? (
+ theme.zIndex.drawer + 1,
+ color: (theme) => theme.palette.common.white,
+ }}
+ >
+
+
+ ) : (
+
+
+
+ ))}
+ >
)
}
diff --git a/src/fireedge/src/client/containers/Settings/index.js b/src/fireedge/src/client/containers/Settings/index.js
index 4dd9d419cf..6b8c2bb986 100644
--- a/src/fireedge/src/client/containers/Settings/index.js
+++ b/src/fireedge/src/client/containers/Settings/index.js
@@ -22,7 +22,7 @@ import FormWithSchema from 'client/components/Forms/FormWithSchema'
import SubmitButton from 'client/components/FormControl/SubmitButton'
import { useAuth, useAuthApi } from 'client/features/Auth'
-import { useUserApi } from 'client/features/One'
+import { useUpdateUserMutation } from 'client/features/OneApi/user'
import { useGeneralApi } from 'client/features/General'
import { Translate, Tr } from 'client/components/HOC'
import { T } from 'client/constants'
@@ -34,7 +34,7 @@ import * as Helper from 'client/models/Helper'
const Settings = () => {
const { user, settings } = useAuth()
const { getAuthUser } = useAuthApi()
- const { updateUser } = useUserApi()
+ const [updateUser] = useUpdateUserMutation()
const { enqueueError } = useGeneralApi()
const { handleSubmit, setError, reset, formState, ...methods } = useForm({
@@ -46,7 +46,8 @@ const Settings = () => {
const onSubmit = async (dataForm) => {
try {
const template = Helper.jsonToXml({ FIREEDGE: dataForm })
- await updateUser(user.ID, { template }).then(getAuthUser)
+ await updateUser({ id: user.ID, template })
+ getAuthUser()
} catch {
enqueueError(T.SomethingWrong)
}
diff --git a/src/fireedge/src/client/containers/TestApi/ResponseForm.js b/src/fireedge/src/client/containers/TestApi/ResponseForm.js
index 8a6c1ebdd8..bd5f2b6ec3 100644
--- a/src/fireedge/src/client/containers/TestApi/ResponseForm.js
+++ b/src/fireedge/src/client/containers/TestApi/ResponseForm.js
@@ -64,7 +64,7 @@ const ResponseForm = ({
color="textPrimary"
component="h2"
variant="h2"
- style={{ padding: '16px 0' }}
+ sx={{ p: '16px 0' }}
>
{name || 'Request'}
diff --git a/src/fireedge/src/client/containers/Users/index.js b/src/fireedge/src/client/containers/Users/index.js
index 6ad7e76724..eb0b0b0ad1 100644
--- a/src/fireedge/src/client/containers/Users/index.js
+++ b/src/fireedge/src/client/containers/Users/index.js
@@ -14,23 +14,52 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-
-import { Container, Box } from '@mui/material'
+import { useState } from 'react'
+import { Container, Stack, Chip } from '@mui/material'
import { UsersTable } from 'client/components/Tables'
+import UserTabs from 'client/components/Tabs/User'
+import SplitPane from 'client/components/SplitPane'
+import MultipleTags from 'client/components/MultipleTags'
function Users() {
+ const [selectedRows, onSelectedRowsChange] = useState(() => [])
+
return (
-
-
-
+
+
+
+
+ {selectedRows?.length > 0 && (
+
+ {selectedRows?.length === 1 ? (
+
+ ) : (
+
+ (
+ toggleRowSelected(false)}
+ />
+ )
+ )}
+ />
+
+ )}
+
+ )}
+
+
)
}
diff --git a/src/fireedge/src/client/containers/VNetworkTemplates/index.js b/src/fireedge/src/client/containers/VNetworkTemplates/index.js
index 0292e2cf51..2b9062b6e0 100644
--- a/src/fireedge/src/client/containers/VNetworkTemplates/index.js
+++ b/src/fireedge/src/client/containers/VNetworkTemplates/index.js
@@ -14,23 +14,52 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-
-import { Container, Box } from '@mui/material'
+import { useState } from 'react'
+import { Container, Stack, Chip } from '@mui/material'
import { VNetworkTemplatesTable } from 'client/components/Tables'
+import VNetworkTemplateTabs from 'client/components/Tabs/VNetworkTemplate'
+import SplitPane from 'client/components/SplitPane'
+import MultipleTags from 'client/components/MultipleTags'
function VNetworkTemplates() {
+ const [selectedRows, onSelectedRowsChange] = useState(() => [])
+
return (
-
-
-
+
+
+
+
+ {selectedRows?.length > 0 && (
+
+ {selectedRows?.length === 1 ? (
+
+ ) : (
+
+ (
+ toggleRowSelected(false)}
+ />
+ )
+ )}
+ />
+
+ )}
+
+ )}
+
+
)
}
diff --git a/src/fireedge/src/client/containers/VirtualMachines/index.js b/src/fireedge/src/client/containers/VirtualMachines/index.js
index 21173a7abe..e95376fe76 100644
--- a/src/fireedge/src/client/containers/VirtualMachines/index.js
+++ b/src/fireedge/src/client/containers/VirtualMachines/index.js
@@ -26,7 +26,6 @@ import MultipleTags from 'client/components/MultipleTags'
function VirtualMachines() {
const [selectedRows, onSelectedRowsChange] = useState(() => [])
const actions = VmActions()
- const dataCy = 'vms'
return (
@@ -34,8 +33,6 @@ function VirtualMachines() {
{selectedRows?.length > 0 && (
diff --git a/src/fireedge/src/client/containers/VirtualNetworks/index.js b/src/fireedge/src/client/containers/VirtualNetworks/index.js
index 7908103e8e..79c2f77b3c 100644
--- a/src/fireedge/src/client/containers/VirtualNetworks/index.js
+++ b/src/fireedge/src/client/containers/VirtualNetworks/index.js
@@ -14,23 +14,52 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-
-import { Container, Box } from '@mui/material'
+import { useState } from 'react'
+import { Container, Stack, Chip } from '@mui/material'
import { VNetworksTable } from 'client/components/Tables'
+import VNetworkTabs from 'client/components/Tabs/VNetwork'
+import SplitPane from 'client/components/SplitPane'
+import MultipleTags from 'client/components/MultipleTags'
function VirtualNetworks() {
+ const [selectedRows, onSelectedRowsChange] = useState(() => [])
+
return (
-
-
-
+
+
+
+
+ {selectedRows?.length > 0 && (
+
+ {selectedRows?.length === 1 ? (
+
+ ) : (
+
+ (
+ toggleRowSelected(false)}
+ />
+ )
+ )}
+ />
+
+ )}
+
+ )}
+
+
)
}
diff --git a/src/fireedge/src/client/containers/VmTemplates/Create.js b/src/fireedge/src/client/containers/VmTemplates/Create.js
index 418eeb3cc3..b697ce2535 100644
--- a/src/fireedge/src/client/containers/VmTemplates/Create.js
+++ b/src/fireedge/src/client/containers/VmTemplates/Create.js
@@ -13,46 +13,47 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { JSXElementConstructor } from 'react'
+import { ReactElement } from 'react'
import { useHistory, useLocation } from 'react-router'
import { Container } from '@mui/material'
import { useGeneralApi } from 'client/features/General'
-import { useVmTemplateApi } from 'client/features/One'
+import {
+ useUpdateTemplateMutation,
+ useAllocateTemplateMutation,
+} from 'client/features/OneApi/vmTemplate'
import { CreateForm } from 'client/components/Forms/VmTemplate'
import { PATH } from 'client/apps/sunstone/routesOne'
-import { isDevelopment } from 'client/utils'
/**
* Displays the creation or modification form to a VM Template.
*
- * @returns {JSXElementConstructor} VM Template form
+ * @returns {ReactElement} VM Template form
*/
function CreateVmTemplate() {
const history = useHistory()
const { state: { ID: templateId, NAME } = {} } = useLocation()
const { enqueueSuccess } = useGeneralApi()
- const { update, allocate } = useVmTemplateApi()
+ const [update] = useUpdateTemplateMutation()
+ const [allocate] = useAllocateTemplateMutation()
const onSubmit = async (xmlTemplate) => {
try {
if (!templateId) {
- const newTemplateId = await allocate(xmlTemplate)
+ const newTemplateId = await allocate({ template: xmlTemplate }).unwrap()
history.push(PATH.TEMPLATE.VMS.LIST)
enqueueSuccess(`VM Template created - #${newTemplateId}`)
} else {
- await update(templateId, xmlTemplate)
+ await update({ id: templateId, template: xmlTemplate })
history.push(PATH.TEMPLATE.VMS.LIST)
enqueueSuccess(`VM Template updated - #${templateId} ${NAME}`)
}
- } catch (err) {
- isDevelopment() && console.error(err)
- }
+ } catch {}
}
return (
-
+
)
diff --git a/src/fireedge/src/client/containers/VmTemplates/Instantiate.js b/src/fireedge/src/client/containers/VmTemplates/Instantiate.js
index 7ba4d35170..7f7f3d35c9 100644
--- a/src/fireedge/src/client/containers/VmTemplates/Instantiate.js
+++ b/src/fireedge/src/client/containers/VmTemplates/Instantiate.js
@@ -13,40 +13,45 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
+import { ReactElement } from 'react'
import { useHistory, useLocation } from 'react-router'
import { Container } from '@mui/material'
import { useGeneralApi } from 'client/features/General'
-import { useVmTemplateApi } from 'client/features/One'
+import { useInstantiateTemplateMutation } from 'client/features/OneApi/vmTemplate'
import { InstantiateForm } from 'client/components/Forms/VmTemplate'
import { PATH } from 'client/apps/sunstone/routesOne'
-import { isDevelopment } from 'client/utils'
+/**
+ * Displays the instantiation form for a VM Template.
+ *
+ * @returns {ReactElement} Instantiation form
+ */
function InstantiateVmTemplate() {
const history = useHistory()
const { state: { ID: templateId } = {} } = useLocation()
const { enqueueInfo } = useGeneralApi()
- const { instantiate } = useVmTemplateApi()
+ const [instantiate] = useInstantiateTemplateMutation()
const onSubmit = async ([templateSelected, templates]) => {
try {
const { ID, NAME } = templateSelected
+ const templatesWithId = templates.map((t) => ({ id: ID, ...t }))
- await Promise.all(templates.map((template) => instantiate(ID, template)))
+ await Promise.all(templatesWithId.map(instantiate))
- history.push(templateId ? PATH.TEMPLATE.VMS.LIST : PATH.INSTANCE.VMS.LIST)
- enqueueInfo(
- `VM Template instantiated x${templates.length} - #${ID} ${NAME}`
- )
- } catch (err) {
- isDevelopment() && console.error(err)
- }
+ templateId
+ ? history.push(PATH.TEMPLATE.VMS.LIST)
+ : history.push(PATH.INSTANCE.VMS.LIST)
+
+ const total = templates.length
+ enqueueInfo(`VM Template instantiated x${total} - #${ID} ${NAME}`)
+ } catch {}
}
return (
-
+
)
diff --git a/src/fireedge/src/client/containers/Zones/index.js b/src/fireedge/src/client/containers/Zones/index.js
index 0cbd6e4aff..bec3e55606 100644
--- a/src/fireedge/src/client/containers/Zones/index.js
+++ b/src/fireedge/src/client/containers/Zones/index.js
@@ -14,23 +14,52 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
/* eslint-disable jsdoc/require-jsdoc */
-
-import { Container, Box } from '@mui/material'
+import { useState } from 'react'
+import { Container, Stack, Chip } from '@mui/material'
import { ZonesTable } from 'client/components/Tables'
+import ZoneTabs from 'client/components/Tabs/Zone'
+import SplitPane from 'client/components/SplitPane'
+import MultipleTags from 'client/components/MultipleTags'
function Zones() {
+ const [selectedRows, onSelectedRowsChange] = useState(() => [])
+
return (
-
-
-
+
+
+
+
+ {selectedRows?.length > 0 && (
+
+ {selectedRows?.length === 1 ? (
+
+ ) : (
+
+ (
+ toggleRowSelected(false)}
+ />
+ )
+ )}
+ />
+
+ )}
+
+ )}
+
+
)
}
diff --git a/src/fireedge/src/client/features/Auth/actions.js b/src/fireedge/src/client/features/Auth/actions.js
index 4d077d0191..437478ef90 100644
--- a/src/fireedge/src/client/features/Auth/actions.js
+++ b/src/fireedge/src/client/features/Auth/actions.js
@@ -18,10 +18,7 @@ import { createAction, createAsyncThunk } from '@reduxjs/toolkit'
import { authService } from 'client/features/Auth/services'
import { dismissSnackbar } from 'client/features/General/actions'
-
-import { RESOURCES } from 'client/features/One'
-import { getGroups } from 'client/features/One/group/actions'
-import { userService } from 'client/features/One/user/services'
+import apiUser from 'client/features/OneApi/user'
import { httpCodes } from 'server/utils/constants'
import { removeStoreData, storage } from 'client/utils'
@@ -58,16 +55,11 @@ export const getUser = createAsyncThunk(
'auth/user',
async (_, { dispatch, getState }) => {
try {
- const { auth = {}, one: { [RESOURCES.group]: groups } = {} } = getState()
+ const { auth = {} } = getState()
const user = await authService.getUser()
const isOneAdmin = user?.ID === ONEADMIN_ID
const userSettings = user?.TEMPLATE?.FIREEDGE ?? {}
- const userGroupIds = [user?.GROUPS?.ID].flat()
-
- if (!groups.some((group) => userGroupIds.includes(group?.ID))) {
- await dispatch(getGroups())
- }
// Merge user settings with the existing one
const settings = {
@@ -83,6 +75,7 @@ export const getUser = createAsyncThunk(
return { user, settings, isOneAdmin }
} catch (error) {
+ console.log({ error })
dispatch(logout(T.SessionExpired))
}
},
@@ -116,7 +109,7 @@ export const changeGroup = createAsyncThunk(
const { user } = getState().auth
const data = { id: user?.ID, group }
- await userService.changeGroup(data)
+ dispatch(apiUser.endpoints.changeGroup.initiate(data)).reset()
dispatch(changeFilter(FILTER_POOL.PRIMARY_GROUP_RESOURCES))
@@ -136,3 +129,7 @@ export const changeGroup = createAsyncThunk(
}
}
)
+
+export const changeView = createAction('auth/change-view', (view) => ({
+ payload: { view },
+}))
diff --git a/src/fireedge/src/client/features/Auth/hooks.js b/src/fireedge/src/client/features/Auth/hooks.js
index 8c24dd90e5..7e4755d78f 100644
--- a/src/fireedge/src/client/features/Auth/hooks.js
+++ b/src/fireedge/src/client/features/Auth/hooks.js
@@ -19,25 +19,32 @@ import { useDispatch, useSelector, shallowEqual } from 'react-redux'
import { unwrapResult } from '@reduxjs/toolkit'
import * as actions from 'client/features/Auth/actions'
-import * as provisionActions from 'client/features/Auth/provision'
-import * as sunstoneActions from 'client/features/Auth/sunstone'
import { name as authSlice } from 'client/features/Auth/slice'
-import { name as oneSlice, RESOURCES } from 'client/features/One/slice'
+import apiGroup from 'client/features/OneApi/group'
+import apiSystem from 'client/features/OneApi/system'
import { RESOURCE_NAMES } from 'client/constants'
export const useAuth = () => {
const auth = useSelector((state) => state[authSlice], shallowEqual)
- const groups = useSelector(
- (state) => state[oneSlice][RESOURCES.group],
- shallowEqual
+ const { user, jwt, view, isLoginInProgress } = auth
+
+ const { data: views } = apiSystem.endpoints.getSunstoneViews.useQuery(
+ undefined,
+ { skip: !jwt }
)
- const { user, jwt, view, views, isLoginInProgress } = auth
-
- const userGroups = [user?.GROUPS?.ID]
- .flat()
- .map((id) => groups.find(({ ID }) => ID === id))
- .filter(Boolean)
+ const { data: userGroups } = apiGroup.endpoints.getGroups.useQuery(
+ undefined,
+ {
+ skip: !jwt,
+ selectFromResult: ({ data: groups = [] }) => ({
+ data: [user?.GROUPS?.ID]
+ .flat()
+ .map((id) => groups.find(({ ID }) => ID === id))
+ .filter(Boolean),
+ }),
+ }
+ )
const isLogged = !!jwt && !!userGroups?.length && !isLoginInProgress
@@ -49,17 +56,26 @@ export const useAuth = () => {
* resource_name: string,
* actions: object[],
* filters: object[],
- * info-tabs: object[],
+ * info-tabs: object,
* dialogs: object[]
* }} Returns view of resource
*/
const getResourceView = useCallback(
(resourceName) =>
- views?.[view]?.find(({ resource_name: name }) => name === resourceName),
+ views?.[view]?.find(
+ ({ resource_name: name }) =>
+ String(name).toLowerCase() === String(resourceName).toLowerCase()
+ ),
[view]
)
- return { ...auth, groups: userGroups, isLogged, getResourceView }
+ return {
+ ...auth,
+ groups: userGroups,
+ isLogged,
+ getResourceView,
+ views,
+ }
}
export const useAuthApi = () => {
@@ -73,15 +89,9 @@ export const useAuthApi = () => {
return {
login: (user) => unwrapDispatch(actions.login(user)),
getAuthUser: () => dispatch(actions.getUser()),
- changeGroup: (data) => unwrapDispatch(actions.changeGroup(data)),
+ changeGroup: (group) => unwrapDispatch(actions.changeGroup(group)),
logout: () => dispatch(actions.logout()),
- getProviderConfig: () =>
- unwrapDispatch(provisionActions.getProviderConfig()),
-
- getSunstoneViews: () => unwrapDispatch(sunstoneActions.getSunstoneViews()),
- getSunstoneConfig: () =>
- unwrapDispatch(sunstoneActions.getSunstoneConfig()),
- changeView: (data) => dispatch(sunstoneActions.changeView(data)),
+ changeView: (view) => dispatch(actions.changeView(view)),
}
}
diff --git a/src/fireedge/src/client/features/Auth/provision.js b/src/fireedge/src/client/features/Auth/provision.js
deleted file mode 100644
index d57f32131f..0000000000
--- a/src/fireedge/src/client/features/Auth/provision.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { createAsyncThunk } from '@reduxjs/toolkit'
-
-import { authService } from 'client/features/Auth/services'
-import { logout } from 'client/features/Auth/actions'
-
-import { httpCodes } from 'server/utils/constants'
-import { T } from 'client/constants'
-
-export const getProviderConfig = createAsyncThunk(
- 'provision/provider-config',
- async (_, { dispatch }) => {
- try {
- const config = (await authService.getProviderConfig()) ?? {}
-
- return { providerConfig: config }
- } catch (error) {
- error?.status === httpCodes.unauthorized.id &&
- dispatch(logout(T.SessionExpired))
- }
- }
-)
diff --git a/src/fireedge/src/client/features/Auth/services.js b/src/fireedge/src/client/features/Auth/services.js
index d81038a906..1eed1e62ac 100644
--- a/src/fireedge/src/client/features/Auth/services.js
+++ b/src/fireedge/src/client/features/Auth/services.js
@@ -51,37 +51,4 @@ export const authService = {
return res?.data?.USER ?? {}
},
- /**
- * @returns {object} Provider configuration
- * @throws Fails when response isn't code 200
- */
- getProviderConfig: async () => {
- const res = await RestClient.request({ url: '/api/provider/config' })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
- /**
- * @returns {object} Views available for the user authenticated
- * @throws Fails when response isn't code 200
- */
- getSunstoneViews: async () => {
- const res = await RestClient.request({ url: '/api/sunstone/views' })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
- /**
- * @returns {object} Sunstone configuration
- * @throws Fails when response isn't code 200
- */
- getSunstoneConfig: async () => {
- const res = await RestClient.request({ url: '/api/sunstone/config' })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
}
diff --git a/src/fireedge/src/client/features/Auth/slice.js b/src/fireedge/src/client/features/Auth/slice.js
index 71280f3efb..a1689d8e20 100644
--- a/src/fireedge/src/client/features/Auth/slice.js
+++ b/src/fireedge/src/client/features/Auth/slice.js
@@ -21,13 +21,8 @@ import {
logout,
changeFilter,
changeGroup,
-} from 'client/features/Auth/actions'
-import { getProviderConfig } from 'client/features/Auth/provision'
-import {
- getSunstoneViews,
- getSunstoneConfig,
changeView,
-} from 'client/features/Auth/sunstone'
+} from 'client/features/Auth/actions'
import {
JWT_NAME,
FILTER_POOL,
@@ -70,11 +65,6 @@ const { name, actions, reducer } = createSlice({
login.fulfilled.type,
getUser.fulfilled.type,
changeGroup.fulfilled.type,
- // provision
- getProviderConfig.fulfilled.type,
- // sunstone
- getSunstoneViews.fulfilled.type,
- getSunstoneConfig.fulfilled.type,
changeView.type,
].includes(type),
(state, { payload }) => ({ ...state, ...payload })
diff --git a/src/fireedge/src/client/features/Auth/sunstone.js b/src/fireedge/src/client/features/Auth/sunstone.js
deleted file mode 100644
index 2c78086917..0000000000
--- a/src/fireedge/src/client/features/Auth/sunstone.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { createAsyncThunk, createAction } from '@reduxjs/toolkit'
-
-import { authService } from 'client/features/Auth/services'
-import { logout } from 'client/features/Auth/actions'
-
-import { httpCodes } from 'server/utils/constants'
-import { T } from 'client/constants'
-
-export const getSunstoneViews = createAsyncThunk(
- 'sunstone/views',
- async (_, { dispatch }) => {
- try {
- const views = (await authService.getSunstoneViews()) ?? {}
-
- return {
- views,
- view: Object.keys(views)[0],
- }
- } catch (error) {
- error?.status === httpCodes.unauthorized.id &&
- dispatch(logout(T.SessionExpired))
- }
- }
-)
-
-export const getSunstoneConfig = createAsyncThunk(
- 'sunstone/config',
- async (_, { dispatch }) => {
- try {
- const config = (await authService.getSunstoneConfig()) ?? {}
-
- return { config }
- } catch (error) {
- error?.status === httpCodes.unauthorized.id &&
- dispatch(logout(T.SessionExpired))
- }
- }
-)
-
-export const changeView = createAction('sunstone/change-view', (view) => ({
- payload: { view },
-}))
diff --git a/src/fireedge/src/client/features/One/actions.js b/src/fireedge/src/client/features/One/actions.js
deleted file mode 100644
index 7ebab0de36..0000000000
--- a/src/fireedge/src/client/features/One/actions.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from '@reduxjs/toolkit'
-
-export const updateResourceFromFetch = createAction(
- 'update-resource-from-fetch',
- ({ data, resource }) => ({ payload: { type: resource, data } })
-)
diff --git a/src/fireedge/src/client/features/One/application/actions.js b/src/fireedge/src/client/features/One/application/actions.js
deleted file mode 100644
index 11d4a0fc71..0000000000
--- a/src/fireedge/src/client/features/One/application/actions.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { applicationService } from 'client/features/One/application/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.document} */
-const SERVICE_APPLICATION = 'document[100]'
-
-export const getApplication = createAction(
- `${SERVICE_APPLICATION}/detail`,
- applicationService.getApplication
-)
-
-export const getApplications = createAction(
- `${SERVICE_APPLICATION}/pool`,
- applicationService.getApplications,
- (response) => ({ [RESOURCES.document[100]]: response })
-)
diff --git a/src/fireedge/src/client/features/One/application/hooks.js b/src/fireedge/src/client/features/One/application/hooks.js
deleted file mode 100644
index 0dbc4ed599..0000000000
--- a/src/fireedge/src/client/features/One/application/hooks.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/application/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useApplication = () =>
- useSelector((state) => state[name]?.[RESOURCES.document[100]] ?? [])
-
-export const useApplicationApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getApplication: (id) => unwrapDispatch(actions.getApplication({ id })),
- getApplications: () => unwrapDispatch(actions.getApplications()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/application/services.js b/src/fireedge/src/client/features/One/application/services.js
deleted file mode 100644
index f8efa28cc3..0000000000
--- a/src/fireedge/src/client/features/One/application/services.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { SERVICE } from 'server/routes/api/oneflow/basepath'
-import { httpCodes } from 'server/utils/constants'
-import { RestClient } from 'client/utils'
-
-export const applicationService = {
- /**
- * Retrieves information for the service.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Service id
- * @returns {object} Get service identified by id
- * @throws Fails when response isn't code 200
- */
- getApplication: async ({ id }) => {
- const res = await RestClient.request({
- url: `/api/${SERVICE}/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.DOCUMENT ?? {}
- },
-
- /**
- * Retrieves information for all services.
- *
- * @returns {object} Get list of services
- * @throws Fails when response isn't code 200
- */
- getApplications: async () => {
- const res = await RestClient.request({
- url: `/api/${SERVICE}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.DOCUMENT_POOL?.DOCUMENT ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/One/applicationTemplate/actions.js b/src/fireedge/src/client/features/One/applicationTemplate/actions.js
deleted file mode 100644
index d42583f35c..0000000000
--- a/src/fireedge/src/client/features/One/applicationTemplate/actions.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { applicationTemplateService } from 'client/features/One/applicationTemplate/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.document} */
-const SERVICE_TEMPLATE = 'document[101]'
-
-export const getApplicationTemplate = createAction(
- `${SERVICE_TEMPLATE}/detail`,
- applicationTemplateService.getApplicationTemplate
-)
-
-export const getApplicationsTemplates = createAction(
- `${SERVICE_TEMPLATE}/pool`,
- applicationTemplateService.getApplicationsTemplates,
- (response) => ({ [RESOURCES.document[101]]: response })
-)
-
-export const createApplicationTemplate = createAction(
- `${SERVICE_TEMPLATE}/create`,
- applicationTemplateService.createApplicationTemplate
-)
-
-export const updateApplicationTemplate = createAction(
- `${SERVICE_TEMPLATE}/update`,
- applicationTemplateService.updateApplicationTemplate
-)
-
-export const instantiateApplicationTemplate = createAction(
- `${SERVICE_TEMPLATE}/instantiate`,
- applicationTemplateService.instantiateApplicationTemplate
-)
diff --git a/src/fireedge/src/client/features/One/applicationTemplate/hooks.js b/src/fireedge/src/client/features/One/applicationTemplate/hooks.js
deleted file mode 100644
index dacc553046..0000000000
--- a/src/fireedge/src/client/features/One/applicationTemplate/hooks.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/applicationTemplate/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useApplicationTemplate = () =>
- useSelector((state) => state[name]?.[RESOURCES.document[101]] ?? [])
-
-export const useApplicationTemplateApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getApplicationTemplate: (id) =>
- unwrapDispatch(actions.getApplicationTemplate({ id })),
- getApplicationsTemplates: () =>
- unwrapDispatch(actions.getApplicationsTemplates()),
- createApplicationTemplate: (data) =>
- unwrapDispatch(actions.createApplicationTemplate({ data })),
-
- updateApplicationTemplate: (id, data) =>
- unwrapDispatch(actions.updateApplicationTemplate({ id, data })),
-
- instantiateApplicationTemplate: (id, data) =>
- unwrapDispatch(actions.instantiateApplicationTemplate({ id, data })),
- }
-}
diff --git a/src/fireedge/src/client/features/One/applicationTemplate/services.js b/src/fireedge/src/client/features/One/applicationTemplate/services.js
deleted file mode 100644
index b8c4141602..0000000000
--- a/src/fireedge/src/client/features/One/applicationTemplate/services.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { SERVICE_TEMPLATE } from 'server/routes/api/oneflow/basepath'
-import { httpCodes, defaults } from 'server/utils/constants'
-import { RestClient } from 'client/utils'
-
-const { POST, PUT } = defaults?.httpMethod || {}
-
-export const applicationTemplateService = {
- /**
- * Retrieves information for the service template.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Service template id
- * @returns {object} Get service template identified by id
- * @throws Fails when response isn't code 200
- */
- getApplicationTemplate: ({ id }) => {
- const res = RestClient.request({
- url: `/api/${SERVICE_TEMPLATE}/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.DOCUMENT ?? {}
- },
-
- /**
- * @returns {object} Get list of service templates
- * @throws Fails when response isn't code 200
- */
- getApplicationsTemplates: async () => {
- const res = await RestClient.request({
- url: `/api/${SERVICE_TEMPLATE}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.DOCUMENT_POOL?.DOCUMENT ?? []].flat()
- },
-
- /**
- * Retrieves information for all service templates.
- *
- * @param {object} params - Request parameters
- * @param {object} params.data - Data of new application template
- * @returns {object} Object of document created
- * @throws Fails when response isn't code 200
- */
- createApplicationTemplate: async ({ data = {} }) => {
- const res = await RestClient.request({
- data,
- method: POST,
- url: `/api/${SERVICE_TEMPLATE}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.DOCUMENT ?? {}
- },
-
- /**
- * Update the service template.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Service template id
- * @param {object} params.data - Updated data
- * @returns {object} Object of document updated
- * @throws Fails when response isn't code 200
- */
- updateApplicationTemplate: ({ id, data = {} }) => {
- const res = RestClient.request({
- data,
- method: PUT,
- url: `/api/${SERVICE_TEMPLATE}/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.DOCUMENT ?? {}
- },
-
- /**
- * Perform instantiate action on the service template.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Service template id
- * @param {object} params.data - Additional parameters to be passed inside `params`
- * @returns {Response} Response 201
- * @throws Fails when response isn't code 200
- */
- instantiateApplicationTemplate: ({ id, data = {} }) => {
- const res = RestClient.request({
- data: {
- action: {
- perform: 'instantiate',
- params: { merge_template: data },
- },
- },
- method: PUT,
- url: `/api/${SERVICE_TEMPLATE}/action/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
-}
diff --git a/src/fireedge/src/client/features/One/cluster/actions.js b/src/fireedge/src/client/features/One/cluster/actions.js
deleted file mode 100644
index 6088b09e25..0000000000
--- a/src/fireedge/src/client/features/One/cluster/actions.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { clusterService } from 'client/features/One/cluster/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.cluster} */
-const CLUSTER = 'cluster'
-
-export const getCluster = createAction(
- `${CLUSTER}/detail`,
- clusterService.getCluster
-)
-
-export const getClusters = createAction(
- `${CLUSTER}/pool`,
- clusterService.getClusters,
- (response) => ({ [RESOURCES.cluster]: response })
-)
diff --git a/src/fireedge/src/client/features/One/cluster/hooks.js b/src/fireedge/src/client/features/One/cluster/hooks.js
deleted file mode 100644
index 6fd2396f76..0000000000
--- a/src/fireedge/src/client/features/One/cluster/hooks.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/cluster/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useCluster = () =>
- useSelector((state) => state[name]?.[RESOURCES.cluster] ?? [])
-
-export const useClusterApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getCluster: (id) => unwrapDispatch(actions.getCluster({ id })),
- getClusters: () => unwrapDispatch(actions.getClusters()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/cluster/services.js b/src/fireedge/src/client/features/One/cluster/services.js
deleted file mode 100644
index 7e00a9514f..0000000000
--- a/src/fireedge/src/client/features/One/cluster/services.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/cluster'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const clusterService = {
- /**
- * Retrieves information for the cluster.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Cluster id
- * @returns {object} Get cluster identified by id
- * @throws Fails when response isn't code 200
- */
- getCluster: async ({ id }) => {
- const name = Actions.CLUSTER_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.CLUSTER ?? {}
- },
-
- /**
- * Retrieves information for all the clusters in the pool.
- *
- * @returns {Array} List of clusters
- * @throws Fails when response isn't code 200
- */
- getClusters: async () => {
- const name = Actions.CLUSTER_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(undefined, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.CLUSTER_POOL?.CLUSTER ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/One/datastore/actions.js b/src/fireedge/src/client/features/One/datastore/actions.js
deleted file mode 100644
index 3ac31fec46..0000000000
--- a/src/fireedge/src/client/features/One/datastore/actions.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { datastoreService } from 'client/features/One/datastore/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.datastore} */
-const DATASTORE = 'datastore'
-
-export const getDatastore = createAction(
- `${DATASTORE}/detail`,
- datastoreService.getDatastore
-)
-
-export const getDatastores = createAction(
- `${DATASTORE}/pool`,
- datastoreService.getDatastores,
- (response) => ({ [RESOURCES.datastore]: response })
-)
diff --git a/src/fireedge/src/client/features/One/datastore/hooks.js b/src/fireedge/src/client/features/One/datastore/hooks.js
deleted file mode 100644
index b22f59aeb5..0000000000
--- a/src/fireedge/src/client/features/One/datastore/hooks.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/datastore/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useDatastore = () =>
- useSelector((state) => state[name]?.[RESOURCES.datastore] ?? [])
-
-export const useDatastoreApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getDatastore: (id) => unwrapDispatch(actions.getDatastore({ id })),
- getDatastores: (options) => unwrapDispatch(actions.getDatastores(options)),
- }
-}
diff --git a/src/fireedge/src/client/features/One/datastore/services.js b/src/fireedge/src/client/features/One/datastore/services.js
deleted file mode 100644
index 7ab0ebecd0..0000000000
--- a/src/fireedge/src/client/features/One/datastore/services.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/datastore'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const datastoreService = {
- /**
- * Retrieves information for the datastore.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Datastore id
- * @returns {object} Get datastore identified by id
- * @throws Fails when response isn't code 200
- */
- getDatastore: async ({ id }) => {
- const name = Actions.DATASTORE_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.DATASTORE ?? {}
- },
-
- /**
- * Retrieves information for all datastores in the pool.
- *
- * @returns {object} Get list of datastores
- * @throws Fails when response isn't code 200
- */
- getDatastores: async () => {
- const name = Actions.DATASTORE_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(undefined, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.DATASTORE_POOL?.DATASTORE ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/One/group/actions.js b/src/fireedge/src/client/features/One/group/actions.js
deleted file mode 100644
index a0417ee959..0000000000
--- a/src/fireedge/src/client/features/One/group/actions.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { groupService } from 'client/features/One/group/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.group} */
-const GROUP = 'group'
-
-export const getGroup = createAction(`${GROUP}/detail`, groupService.getGroup)
-
-export const getGroups = createAction(
- `${GROUP}/pool`,
- groupService.getGroups,
- (response) => ({ [RESOURCES.group]: response })
-)
diff --git a/src/fireedge/src/client/features/One/group/hooks.js b/src/fireedge/src/client/features/One/group/hooks.js
deleted file mode 100644
index 290cacc133..0000000000
--- a/src/fireedge/src/client/features/One/group/hooks.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/group/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useGroup = () =>
- useSelector((state) => state[name]?.[RESOURCES.group] ?? [])
-
-export const useGroupApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getGroup: (id) => unwrapDispatch(actions.getGroup({ id })),
- getGroups: () => unwrapDispatch(actions.getGroups()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/group/services.js b/src/fireedge/src/client/features/One/group/services.js
deleted file mode 100644
index 3038d953ff..0000000000
--- a/src/fireedge/src/client/features/One/group/services.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/group'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const groupService = {
- /**
- * Retrieves information for the group.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Group id
- * @returns {object} Get group identified by id
- * @throws Fails when response isn't code 200
- */
- getGroup: async ({ id }) => {
- const name = Actions.GROUP_INFO
- const command = { name, ...Commands[name] }
- const { url, options } = requestConfig({ id }, command)
-
- const res = await RestClient.get(url, options)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.GROUP ?? {}
- },
-
- /**
- * Retrieves information for all the groups in the pool.
- *
- * @returns {object} Get list of groups
- * @throws Fails when response isn't code 200
- */
- getGroups: async () => {
- const name = Actions.GROUP_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(undefined, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.GROUP_POOL?.GROUP ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/One/hooks.js b/src/fireedge/src/client/features/One/hooks.js
deleted file mode 100644
index d94a1b1dc1..0000000000
--- a/src/fireedge/src/client/features/One/hooks.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useSelector, shallowEqual } from 'react-redux'
-import { name } from 'client/features/One/slice'
-
-export const useOne = () => useSelector((state) => state[name], shallowEqual)
-
-export * from 'client/features/One/application/hooks'
-export * from 'client/features/One/applicationTemplate/hooks'
-export * from 'client/features/One/cluster/hooks'
-export * from 'client/features/One/datastore/hooks'
-export * from 'client/features/One/group/hooks'
-export * from 'client/features/One/host/hooks'
-export * from 'client/features/One/image/hooks'
-export * from 'client/features/One/marketplace/hooks'
-export * from 'client/features/One/marketplaceApp/hooks'
-export * from 'client/features/One/provider/hooks'
-export * from 'client/features/One/provision/hooks'
-export * from 'client/features/One/system/hooks'
-export * from 'client/features/One/user/hooks'
-export * from 'client/features/One/vm/hooks'
-export * from 'client/features/One/vmGroup/hooks'
-export * from 'client/features/One/vmTemplate/hooks'
-export * from 'client/features/One/vnetwork/hooks'
-export * from 'client/features/One/vnetworkTemplate/hooks'
-export * from 'client/features/One/vrouter/hooks'
-export * from 'client/features/One/zone/hooks'
diff --git a/src/fireedge/src/client/features/One/host/actions.js b/src/fireedge/src/client/features/One/host/actions.js
deleted file mode 100644
index 2d14d46d75..0000000000
--- a/src/fireedge/src/client/features/One/host/actions.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { hostService } from 'client/features/One/host/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.host} */
-const HOST = 'host'
-
-export const getHost = createAction(`${HOST}/detail`, hostService.getHost)
-
-export const getHosts = createAction(
- `${HOST}/pool`,
- hostService.getHosts,
- (response) => ({ [RESOURCES.host]: response })
-)
-
-export const allocate = createAction(`${HOST}/allocate`, hostService.allocate)
-export const remove = createAction(`${HOST}/delete`, hostService.delete)
-export const enable = createAction(`${HOST}/enable`, hostService.enable)
-export const disable = createAction(`${HOST}/disable`, hostService.disable)
-export const offline = createAction(`${HOST}/offline`, hostService.offline)
-export const update = createAction(`${HOST}/update`, hostService.update)
-export const rename = createAction(`${HOST}/rename`, hostService.rename)
-export const monitoring = createAction(
- `${HOST}/monitoring`,
- hostService.monitoring
-)
-export const monitoringPool = createAction(
- `${HOST}/monitoring-pool`, // ends with "-pool" to differentiate with resource pool
- hostService.monitoringPool
-)
diff --git a/src/fireedge/src/client/features/One/host/hooks.js b/src/fireedge/src/client/features/One/host/hooks.js
deleted file mode 100644
index b587a540b8..0000000000
--- a/src/fireedge/src/client/features/One/host/hooks.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/host/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useHost = () =>
- useSelector((state) => state[name]?.[RESOURCES.host])
-
-export const useHostApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getHost: (id) => unwrapDispatch(actions.getHost({ id })),
- getHosts: (options) => unwrapDispatch(actions.getHosts(options)),
- allocate: (data) => unwrapDispatch(actions.allocate(data)),
- remove: (id) => unwrapDispatch(actions.remove({ id })),
- enable: (id) => unwrapDispatch(actions.enable({ id })),
- disable: (id) => unwrapDispatch(actions.disable({ id })),
- offline: (id) => unwrapDispatch(actions.offline({ id })),
- update: (id, template, replace) =>
- unwrapDispatch(actions.update({ id, template, replace })),
- rename: (id, newName) =>
- unwrapDispatch(actions.rename({ id, name: newName })),
- getMonitoring: (id) => unwrapDispatch(actions.monitoring({ id })),
- getMonitoringPool: (seconds) =>
- unwrapDispatch(actions.monitoringPool({ seconds })),
- }
-}
diff --git a/src/fireedge/src/client/features/One/host/services.js b/src/fireedge/src/client/features/One/host/services.js
deleted file mode 100644
index f2fd0cec31..0000000000
--- a/src/fireedge/src/client/features/One/host/services.js
+++ /dev/null
@@ -1,253 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/host'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const hostService = {
- /**
- * Retrieves information for the host.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Host id
- * @returns {object} Get host identified by id
- * @throws Fails when response isn't code 200
- */
- getHost: async ({ id }) => {
- const name = Actions.HOST_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.HOST ?? {}
- },
-
- /**
- * Retrieves information for all the hosts in the pool.
- *
- * @returns {object} Get list of hosts
- * @throws Fails when response isn't code 200
- */
- getHosts: async () => {
- const name = Actions.HOST_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(undefined, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.HOST_POOL?.HOST ?? []].flat()
- },
- /**
- * Allocates a new host in OpenNebula.
- *
- * @param {object} params - Request params
- * @param {string} params.hostname - Hostname of the machine we want to add
- * @param {string} params.imMad
- * - The name of the information manager (im_mad_name),
- * this values are taken from the oned.conf with the tag name IM_MAD (name)
- * @param {string} params.vmmMad
- * - The name of the virtual machine manager mad name (vmm_mad_name),
- * this values are taken from the oned.conf with the tag name VM_MAD (name)
- * @param {string|number} [params.cluster] - The cluster ID
- * @returns {number} Host id
- * @throws Fails when response isn't code 200
- */
- allocate: async (params) => {
- const name = Actions.HOST_ALLOCATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-
- /**
- * Deletes the given host from the pool.
- *
- * @param {object} params - Request params
- * @param {number|string} params.id - Host id
- * @returns {number} Host id
- * @throws Fails when response isn't code 200
- */
- delete: async (params) => {
- const name = Actions.HOST_DELETE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-
- /**
- * Sets the status of the host to enabled.
- *
- * @param {object} params - Request params
- * @param {number|string} params.id - Host id
- * @returns {number} Host id
- * @throws Fails when response isn't code 200
- */
- enable: async (params) => {
- const name = Actions.HOST_STATUS
- const command = { name, ...Commands[name] }
- const config = requestConfig({ ...params, status: 0 }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-
- /**
- * Sets the status of the host to disabled.
- *
- * @param {object} params - Request params
- * @param {number|string} params.id - Host id
- * @returns {number} Host id
- * @throws Fails when response isn't code 200
- */
- disable: async (params) => {
- const name = Actions.HOST_STATUS
- const command = { name, ...Commands[name] }
- const config = requestConfig({ ...params, status: 1 }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-
- /**
- * Sets the status of the host to offline.
- *
- * @param {object} params - Request params
- * @param {number|string} params.id - Host id
- * @returns {number} Host id
- * @throws Fails when response isn't code 200
- */
- offline: async (params) => {
- const name = Actions.HOST_STATUS
- const command = { name, ...Commands[name] }
- const config = requestConfig({ ...params, status: 2 }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-
- /**
- * Replaces the host’s template contents..
- *
- * @param {object} params - Request params
- * @param {number|string} params.id - Host id
- * @param {string} params.template - The new template contents
- * @param {0|1} params.replace
- * - Update type:
- * ``0``: Replace the whole template.
- * ``1``: Merge new template with the existing one.
- * @returns {number} Host id
- * @throws Fails when response isn't code 200
- */
- update: async (params) => {
- const name = Actions.HOST_UPDATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-
- /**
- * Renames a host.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Host id
- * @param {string} params.name - New name
- * @returns {number} Host id
- * @throws Fails when response isn't code 200
- */
- rename: async (params) => {
- const name = Actions.HOST_RENAME
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Returns the host monitoring records.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Host id
- * @returns {string} The monitoring information string / The error string
- * @throws Fails when response isn't code 200
- */
- monitoring: async (params) => {
- const name = Actions.HOST_MONITORING
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Returns all the host monitoring records.
- *
- * @param {object} params - Request parameters
- * @param {string|number} [params.seconds]
- * - Retrieve monitor records in the last num seconds.
- * ``0``: Only the last record.
- * ``-1``: All records.
- * @returns {string} The monitoring information string / The error string
- * @throws Fails when response isn't code 200
- */
- monitoringPool: async (params) => {
- const name = Actions.HOST_POOL_MONITORING
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-}
diff --git a/src/fireedge/src/client/features/One/image/actions.js b/src/fireedge/src/client/features/One/image/actions.js
deleted file mode 100644
index a6d63ef559..0000000000
--- a/src/fireedge/src/client/features/One/image/actions.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { imageService } from 'client/features/One/image/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.image} */
-const IMAGE = 'image'
-
-export const getImage = createAction(`${IMAGE}/detail`, imageService.getImage)
-
-export const getImages = createAction(
- `${IMAGE}/pool`,
- imageService.getImages,
- (response) => ({ [RESOURCES.image]: response })
-)
diff --git a/src/fireedge/src/client/features/One/image/hooks.js b/src/fireedge/src/client/features/One/image/hooks.js
deleted file mode 100644
index f7e6eb4e47..0000000000
--- a/src/fireedge/src/client/features/One/image/hooks.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/image/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useImage = () =>
- useSelector((state) => state[name]?.[RESOURCES.image] ?? [])
-
-export const useImageApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getImage: (id) => unwrapDispatch(actions.getImage({ id })),
- getImages: () => unwrapDispatch(actions.getImages()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/image/services.js b/src/fireedge/src/client/features/One/image/services.js
deleted file mode 100644
index d152df92e5..0000000000
--- a/src/fireedge/src/client/features/One/image/services.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/image'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const imageService = {
- /**
- * Retrieves information for the image.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Image id
- * @returns {object} Get image identified by id
- * @throws Fails when response isn't code 200
- */
- getImage: async ({ id }) => {
- const name = Actions.IMAGE_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.IMAGE ?? {}
- },
-
- /**
- * Retrieves information for all or part of the
- * images in the pool.
- *
- * @param {object} data - Request params
- * @param {string} data.filter - Filter flag
- * @param {number} data.start - Range start ID
- * @param {number} data.end - Range end ID
- * @returns {object} Get list of images
- * @throws Fails when response isn't code 200
- */
- getImages: async ({ filter, start, end }) => {
- const name = Actions.IMAGE_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ filter, start, end }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.IMAGE_POOL?.IMAGE ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/One/index.js b/src/fireedge/src/client/features/One/index.js
deleted file mode 100644
index cb8d3e5822..0000000000
--- a/src/fireedge/src/client/features/One/index.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-export * from 'client/features/One/slice'
-export * from 'client/features/One/hooks'
-export * from 'client/features/One/actions'
diff --git a/src/fireedge/src/client/features/One/marketplace/actions.js b/src/fireedge/src/client/features/One/marketplace/actions.js
deleted file mode 100644
index 063824d19f..0000000000
--- a/src/fireedge/src/client/features/One/marketplace/actions.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { marketplaceService } from 'client/features/One/marketplace/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.marketplace} */
-const MARKETPLACE = 'marketplace'
-
-export const getMarketplace = createAction(
- `${MARKETPLACE}/detail`,
- marketplaceService.getMarketplace
-)
-
-export const getMarketplaces = createAction(
- `${MARKETPLACE}/pool`,
- marketplaceService.getMarketplaces,
- (response) => ({ [RESOURCES.marketplace]: response })
-)
diff --git a/src/fireedge/src/client/features/One/marketplace/hooks.js b/src/fireedge/src/client/features/One/marketplace/hooks.js
deleted file mode 100644
index 357acb3b3a..0000000000
--- a/src/fireedge/src/client/features/One/marketplace/hooks.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/marketplace/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useMarketplace = () =>
- useSelector((state) => state[name]?.[RESOURCES.marketplace] ?? [])
-
-export const useMarketplaceApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getMarketplace: (id) => unwrapDispatch(actions.getMarketplace({ id })),
- getMarketplaces: () => unwrapDispatch(actions.getMarketplaces()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/marketplace/services.js b/src/fireedge/src/client/features/One/marketplace/services.js
deleted file mode 100644
index 5b18015e47..0000000000
--- a/src/fireedge/src/client/features/One/marketplace/services.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/market'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const marketplaceService = {
- /**
- * Retrieves information for the marketplace.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Marketplace id
- * @returns {object} Get marketplace identified by id
- * @throws Fails when response isn't code 200
- */
- getMarketplace: async ({ id }) => {
- const name = Actions.MARKET_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.MARKETPLACE ?? {}
- },
-
- /**
- * Retrieves information for all marketplaces.
- *
- * @returns {object} Get list of marketplaces
- * @throws Fails when response isn't code 200
- */
- getMarketplaces: async () => {
- const name = Actions.MARKET_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(undefined, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.MARKETPLACE_POOL?.MARKETPLACE ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/One/marketplaceApp/actions.js b/src/fireedge/src/client/features/One/marketplaceApp/actions.js
deleted file mode 100644
index e8ca5adc7e..0000000000
--- a/src/fireedge/src/client/features/One/marketplaceApp/actions.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { marketplaceAppService } from 'client/features/One/marketplaceApp/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.app} */
-const APP = 'app'
-
-export const getMarketplaceApp = createAction(
- `${APP}/detail`,
- marketplaceAppService.getMarketplaceApp
-)
-
-export const getMarketplaceApps = createAction(
- `${APP}/pool`,
- marketplaceAppService.getMarketplaceApps,
- (response) => ({ [RESOURCES.app]: response })
-)
-
-export const getDockerHubTags = createAction(
- `${APP}/dockerhub-tags`,
- marketplaceAppService.getDockerHubTags
-)
-
-export const exportApp = createAction(
- `${APP}/export`,
- marketplaceAppService.export
-)
-
-export const create = createAction(
- `${APP}/create`,
- marketplaceAppService.create
-)
-
-export const importApp = createAction(
- `${APP}/import`,
- marketplaceAppService.import
-)
diff --git a/src/fireedge/src/client/features/One/marketplaceApp/hooks.js b/src/fireedge/src/client/features/One/marketplaceApp/hooks.js
deleted file mode 100644
index f915a43742..0000000000
--- a/src/fireedge/src/client/features/One/marketplaceApp/hooks.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/marketplaceApp/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useMarketplaceApp = () =>
- useSelector((state) => state[name]?.[RESOURCES.app])
-
-export const useMarketplaceAppApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getMarketplaceApp: (id) =>
- unwrapDispatch(actions.getMarketplaceApp({ id })),
- getMarketplaceApps: () => unwrapDispatch(actions.getMarketplaceApps()),
- getDockerHubTags: (options) =>
- unwrapDispatch(actions.getDockerHubTags(options)),
- exportApp: (id, data) => unwrapDispatch(actions.exportApp({ id, ...data })),
- create: (id, template) => unwrapDispatch(actions.create({ id, template })),
- importVm: (id, data) =>
- unwrapDispatch(actions.importApp('vm', { id, ...data })),
- importVmTemplate: (id, data) =>
- unwrapDispatch(actions.importApp('template', { id, ...data })),
- }
-}
diff --git a/src/fireedge/src/client/features/One/marketplaceApp/services.js b/src/fireedge/src/client/features/One/marketplaceApp/services.js
deleted file mode 100644
index e5eacf788e..0000000000
--- a/src/fireedge/src/client/features/One/marketplaceApp/services.js
+++ /dev/null
@@ -1,161 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/marketapp'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const marketplaceAppService = {
- /**
- * Retrieves information for the marketplace app.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Marketplace apps id
- * @returns {object} Get marketplace app identified by id
- * @throws Fails when response isn't code 200
- */
- getMarketplaceApp: async ({ id }) => {
- const name = Actions.MARKETAPP_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.MARKETPLACEAPP ?? {}
- },
-
- /**
- * Retrieves information for all or part of the
- * marketplace apps in the pool.
- *
- * @param {object} data - Request params
- * @param {string} data.filter - Filter flag
- * @param {number} data.start - Range start ID
- * @param {number} data.end - Range end ID
- * @returns {Array} List of marketplace apps
- * @throws Fails when response isn't code 200
- */
- getMarketplaceApps: async ({ filter, start, end }) => {
- const name = Actions.MARKETAPP_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ filter, start, end }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.MARKETPLACEAPP_POOL?.MARKETPLACEAPP ?? []].flat()
- },
-
- /**
- * Retrieves DockerHub tags information for marketplace app.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - App id
- * @param {string|number} [params.page] - Number of page
- * @returns {object[]} List of DockerHub tags
- * @throws Fails when response isn't code 200
- */
- getDockerHubTags: async ({ id, page }) => {
- const res = await RestClient.request({
- url: `/api/marketapp/dockertags/${id}`,
- params: { page },
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Exports the marketplace app to the OpenNebula cloud.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - App id
- * @param {string} params.name - Image name
- * @param {string|number} params.datastore - Datastore id or name
- * @param {string|number} params.file - File datastore id or name
- * @param {string} params.tag - DockerHub image tag (default latest)
- * @param {string|number} params.template - Associate with VM template
- * @param {boolean} params.associated - If `false`, Do not export associated VM templates/images
- * @param {string} params.vmname - The name for the new VM Template, if the App contains one
- * @returns {number} Template and image ids
- * @throws Fails when response isn't code 200
- */
- export: async ({ id, ...data }) => {
- const res = await RestClient.request({
- url: `/api/marketapp/export/${id}`,
- method: 'POST',
- data,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Allocates a new marketplace app in OpenNebula.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Marketplace id
- * @param {string} params.template - A string containing the template of the marketplace app
- * @returns {number} App id
- * @throws Fails when response isn't code 200
- */
- create: async (params) => {
- const name = Actions.MARKETAPP_ALLOCATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Imports a VM or VM Template into the marketplace.
- *
- * @param {'vm'|'template'} resourceName - Type of resource
- * @param {object} params - Request parameters
- * @param {string|number} params.id - VM or VM Template id
- * @param {string|number} params.marketId - Market to import all objects
- * @param {boolean} params.associated - If `true`, don't import associated VM templates/images
- * @param {string} params.vmname - Selects the name for the new VM Template, if the App contains one
- * @returns {number} App id
- * @throws Fails when response isn't code 200
- */
- import: async (resourceName, { id, ...data }) => {
- if (!['vm', 'template'].includes(resourceName)) {
- throw Error(`Invalid resource to import: ${resourceName}`)
- }
-
- const { marketId, associated, vmname } = data
-
- const res = await RestClient.request({
- url: `/api/marketapp/${resourceName}import/${id}`,
- method: 'POST',
- data: { marketId, associated, vmname },
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-}
diff --git a/src/fireedge/src/client/features/One/provider/actions.js b/src/fireedge/src/client/features/One/provider/actions.js
deleted file mode 100644
index 97f8d898d5..0000000000
--- a/src/fireedge/src/client/features/One/provider/actions.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { providerService } from 'client/features/One/provider/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-export const getProvider = createAction('provider', providerService.getProvider)
-
-export const getProviders = createAction(
- 'provider/pool',
- providerService.getProviders,
- (res) => ({ [RESOURCES.document[102]]: res })
-)
-
-export const getProviderConnection = createAction(
- 'provider',
- providerService.getProviderConnection
-)
-export const createProvider = createAction(
- 'provider/create',
- providerService.createProvider
-)
-export const updateProvider = createAction(
- 'provider/update',
- providerService.updateProvider
-)
-export const deleteProvider = createAction(
- 'provider/delete',
- providerService.deleteProvider
-)
diff --git a/src/fireedge/src/client/features/One/provider/hooks.js b/src/fireedge/src/client/features/One/provider/hooks.js
deleted file mode 100644
index 6dc5861686..0000000000
--- a/src/fireedge/src/client/features/One/provider/hooks.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/provider/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useProvider = () =>
- useSelector((state) => state[name]?.[RESOURCES.document[102]])
-
-export const useProviderApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getProvider: (id) => unwrapDispatch(actions.getProvider({ id })),
- getProviders: () => dispatch(actions.getProviders()),
- getProviderConnection: (id) =>
- unwrapDispatch(actions.getProviderConnection({ id })),
- createProvider: (data) => unwrapDispatch(actions.createProvider({ data })),
- updateProvider: (id, data) =>
- unwrapDispatch(actions.updateProvider({ id, data })),
- deleteProvider: (id) => unwrapDispatch(actions.deleteProvider({ id })),
- }
-}
diff --git a/src/fireedge/src/client/features/One/provider/services.js b/src/fireedge/src/client/features/One/provider/services.js
deleted file mode 100644
index 657f029fc3..0000000000
--- a/src/fireedge/src/client/features/One/provider/services.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { PROVIDER } from 'server/routes/api/oneprovision/basepath'
-import { httpCodes, defaults } from 'server/utils/constants'
-import { RestClient } from 'client/utils'
-
-const { POST, PUT, DELETE } = defaults?.httpMethod || {}
-
-export const providerService = {
- /**
- * Retrieves information for the provider.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Provider id
- * @returns {object} Get provider identified by id
- * @throws Fails when response isn't code 200
- */
- getProvider: async ({ id }) => {
- const res = await RestClient.request({
- url: `/api/${PROVIDER}/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.DOCUMENT ?? {}
- },
-
- /**
- * Retrieves information for all providers.
- *
- * @returns {Array} List of providers
- * @throws Fails when response isn't code 200
- */
- getProviders: async () => {
- const res = await RestClient.request({
- url: `/api/${PROVIDER}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.DOCUMENT_POOL?.DOCUMENT ?? []].flat()
- },
-
- /**
- * Retrieves connection information for the
- * provider.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Provider id
- * @returns {object} Get connection info from the
- * provider identified by id
- * @throws Fails when response isn't code 200
- */
- getProviderConnection: async ({ id }) => {
- const res = await RestClient.request({
- url: `/api/${PROVIDER}/connection/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
-
- /**
- * Create a provider.
- *
- * @param {object} params - Request parameters
- * @param {object} params.data - Template data
- * @returns {object} Object of document created
- * @throws Fails when response isn't code 200
- */
- createProvider: async ({ data = {} }) => {
- const res = await RestClient.request({
- data,
- method: POST,
- url: `/api/${PROVIDER}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
-
- /**
- * Update the provider information.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Provider id
- * @param {object} params.data - Updated data
- * @returns {object} Object of document updated
- * @throws Fails when response isn't code 200
- */
- updateProvider: async ({ id, data = {} }) => {
- const res = await RestClient.request({
- data,
- method: PUT,
- url: `/api/${PROVIDER}/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
-
- /**
- * Delete the provider.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Provider id
- * @returns {object} Object of document deleted
- * @throws Fails when response isn't code 200
- */
- deleteProvider: async ({ id }) => {
- const res = await RestClient.request({
- method: DELETE,
- url: `/api/${PROVIDER}/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
-}
diff --git a/src/fireedge/src/client/features/One/provision/actions.js b/src/fireedge/src/client/features/One/provision/actions.js
deleted file mode 100644
index 28ab06fddb..0000000000
--- a/src/fireedge/src/client/features/One/provision/actions.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { provisionService } from 'client/features/One/provision/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-export const getProvisionsTemplates = createAction(
- 'provisions-template/pool',
- provisionService.getProvisionsTemplates,
- (res) => ({ [RESOURCES.document.defaults]: res })
-)
-
-export const createProvisionTemplate = createAction(
- 'provisions-template/create',
- provisionService.createProvisionTemplate
-)
-
-export const getProvision = createAction(
- 'provision',
- provisionService.getProvision
-)
-
-export const getProvisions = createAction(
- 'provision/pool',
- provisionService.getProvisions,
- (res) => ({ [RESOURCES.document[103]]: res })
-)
-
-export const createProvision = createAction(
- 'provision/create',
- provisionService.createProvision
-)
-export const configureProvision = createAction(
- 'provision/configure',
- provisionService.configureProvision
-)
-export const deleteProvision = createAction(
- 'provision/delete',
- provisionService.deleteProvision
-)
-export const getProvisionLog = createAction(
- 'provision/log',
- provisionService.getProvisionLog
-)
-
-export const deleteDatastore = createAction(
- 'provision/datastore/delete',
- provisionService.deleteDatastore
-)
-export const deleteVNetwork = createAction(
- 'provision/vnet/delete',
- provisionService.deleteVNetwork
-)
-export const deleteHost = createAction(
- 'provision/host/delete',
- provisionService.deleteHost
-)
-export const configureHost = createAction(
- 'provision/host/configure',
- provisionService.configureHost
-)
-export const addHost = createAction(
- 'provision/host/add',
- provisionService.addHost
-)
-export const addIp = createAction('provision/ip/add', provisionService.addIp)
diff --git a/src/fireedge/src/client/features/One/provision/hooks.js b/src/fireedge/src/client/features/One/provision/hooks.js
deleted file mode 100644
index 3a7bdf4984..0000000000
--- a/src/fireedge/src/client/features/One/provision/hooks.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/provision/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useProvisionTemplate = () =>
- useSelector((state) => state[name]?.[RESOURCES.document.defaults])
-
-export const useProvision = () =>
- useSelector((state) => state[name]?.[RESOURCES.document[103]])
-
-export const useProvisionApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getProvisionsTemplates: () =>
- unwrapDispatch(actions.getProvisionsTemplates()),
- createProvisionTemplate: () =>
- unwrapDispatch(actions.createProvisionTemplate()),
-
- getProvision: (id) => unwrapDispatch(actions.getProvision({ id })),
- getProvisions: () => dispatch(actions.getProvisions()),
- createProvision: (data) =>
- unwrapDispatch(actions.createProvision({ data })),
- configureProvision: (id) =>
- unwrapDispatch(actions.configureProvision({ id })),
- deleteProvision: (id, data) =>
- unwrapDispatch(actions.deleteProvision({ id, ...data })),
- getProvisionLog: (id) => unwrapDispatch(actions.getProvisionLog({ id })),
-
- deleteDatastore: (id) => unwrapDispatch(actions.deleteDatastore({ id })),
- deleteVNetwork: (id) => unwrapDispatch(actions.deleteVNetwork({ id })),
- deleteHost: (id) => unwrapDispatch(actions.deleteHost({ id })),
- configureHost: (id) => unwrapDispatch(actions.configureHost({ id })),
- addHost: (id, amount) => unwrapDispatch(actions.addHost({ id, amount })),
- addIp: (id, amount) => unwrapDispatch(actions.addIp({ id, amount })),
- }
-}
diff --git a/src/fireedge/src/client/features/One/provision/services.js b/src/fireedge/src/client/features/One/provision/services.js
deleted file mode 100644
index e735108a82..0000000000
--- a/src/fireedge/src/client/features/One/provision/services.js
+++ /dev/null
@@ -1,313 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { PROVISION } from 'server/routes/api/oneprovision/basepath'
-import { httpCodes, defaults } from 'server/utils/constants'
-import { RestClient } from 'client/utils'
-
-const { POST, PUT, DELETE } = defaults?.httpMethod || {}
-
-export const provisionService = {
- // --------------------------------------------
- // PROVISION TEMPLATE requests
- // --------------------------------------------
-
- /**
- * Retrieves information for all the
- * provision templates.
- *
- * @returns {Array} List of provision templates
- * @throws Fails when response isn't code 200
- */
- getProvisionsTemplates: async () => {
- const res = await RestClient.request({
- url: `/api/${PROVISION}/defaults`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? []
- },
-
- /**
- * TODO: Create a provision template.
- *
- * @returns {Promise} TODO
- */
- createProvisionTemplate: () =>
- Promise.resolve().then((res) => res?.data?.DOCUMENT ?? {}),
-
- // --------------------------------------------
- // PROVISION requests
- // --------------------------------------------
-
- /**
- * Retrieves information for the provision.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Provision id
- * @returns {object} Get provision identified by id
- * @throws Fails when response isn't code 200
- */
- getProvision: async ({ id }) => {
- const res = await RestClient.request({
- url: `/api/${PROVISION}/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.DOCUMENT ?? {}
- },
-
- /**
- * Retrieves information for all providers.
- *
- * @returns {Array} List of providers
- * @throws Fails when response isn't code 200
- */
- getProvisions: async () => {
- const res = await RestClient.request({
- url: `/api/${PROVISION}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.DOCUMENT_POOL?.DOCUMENT ?? []].flat()
- },
-
- /**
- * Create a provision.
- *
- * @param {object} params - Request parameters
- * @param {object} params.data - Form data
- * @returns {object} Object of document created
- * @throws Fails when response isn't code 200
- */
- createProvision: async ({ data = {} }) => {
- const res = await RestClient.request({
- data,
- method: POST,
- url: `/api/${PROVISION}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) {
- if (res?.id === httpCodes.accepted.id) return res?.data
- throw res
- }
-
- return res?.data
- },
-
- /**
- * Configure the provision hosts.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Provision id
- * @returns {object} Object of document updated
- * @throws Fails when response isn't code 200
- */
- configureProvision: async ({ id }) => {
- const res = await RestClient.request({
- method: PUT,
- url: `/api/${PROVISION}/configure/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) {
- if (res?.id === httpCodes.accepted.id) return res
- throw res
- }
-
- return res?.data ?? {}
- },
-
- /**
- * Delete the provision and OpenNebula objects.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Provider id
- * @param {boolean} params.force - Force configure to execute
- * @param {boolean} params.cleanup
- * - If `true`, force to terminate VMs running
- * on provisioned Hosts and delete all images in the datastores
- * @returns {object} Object of document deleted
- * @throws Fails when response isn't code 200
- */
- deleteProvision: async ({ id, ...data }) => {
- const res = await RestClient.request({
- method: DELETE,
- url: `/api/${PROVISION}/${id}`,
- data,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) {
- if (res?.id === httpCodes.accepted.id) return res
- throw res
- }
-
- return res?.data ?? {}
- },
-
- /**
- * Retrieves debug log for the provision.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Provision id
- * @returns {object} Get provision log identified by id
- * @throws Fails when response isn't code 200
- */
- getProvisionLog: async ({ id }) => {
- const res = await RestClient.request({
- url: `/api/${PROVISION}/log/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) {
- if (res?.id === httpCodes.accepted.id) return res
- throw res
- }
-
- return res?.data ?? {}
- },
-
- // --------------------------------------------
- // INFRASTRUCTURE requests
- // --------------------------------------------
-
- /**
- * Delete the datastore from the provision.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Datastore id
- * @returns {object} Object of document deleted
- * @throws Fails when response isn't code 200
- */
- deleteDatastore: async ({ id }) => {
- const res = await RestClient.request({
- method: DELETE,
- url: `/api/${PROVISION}/datastore/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
-
- /**
- * Delete the virtual network from the provision.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Virtual network id
- * @returns {object} Object of document deleted
- * @throws Fails when response isn't code 200
- */
- deleteVNetwork: async ({ id }) => {
- const res = await RestClient.request({
- method: DELETE,
- url: `/api/${PROVISION}/network/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
-
- /**
- * Delete the host from the provision.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Host id
- * @returns {object} Object of document deleted
- * @throws Fails when response isn't code 200
- */
- deleteHost: async ({ id }) => {
- const res = await RestClient.request({
- method: DELETE,
- url: `/api/${PROVISION}/host/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
-
- /**
- * Configure the provision host.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Host id
- * @returns {object} Object of document updated
- * @throws Fails when response isn't code 200
- */
- configureHost: async ({ id }) => {
- const res = await RestClient.request({
- method: PUT,
- url: `/api/${PROVISION}/host/${id}`,
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) {
- if (res?.id === httpCodes.accepted.id) return res
- throw res
- }
-
- return res?.data ?? {}
- },
-
- /**
- * Provisions and configures a new host or amount of hosts.
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Provision id
- * @param {object} params.amount - Amount of hosts to add to the provision
- * @returns {object} Object of document updated
- * @throws Fails when response isn't code 200
- */
- addHost: async ({ id, amount }) => {
- const res = await RestClient.request({
- method: PUT,
- url: `/api/${PROVISION}/addhost/${id}`,
- data: { amount },
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) {
- if (res?.id === httpCodes.accepted.id) return res
- throw res
- }
-
- return res?.data ?? {}
- },
-
- /**
- * Adds more IPs to the provision..
- *
- * @param {object} params - Request parameters
- * @param {object} params.id - Provision id
- * @param {object} params.amount - Amount of ips to add to the provision
- * @returns {object} Object of document updated
- * @throws Fails when response isn't code 200
- */
- addIp: async ({ id, amount }) => {
- const res = await RestClient.request({
- method: PUT,
- url: `/api/${PROVISION}/ip/${id}`,
- data: { amount },
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) {
- if (res?.id === httpCodes.accepted.id) return res
- throw res
- }
-
- return res?.data ?? {}
- },
-}
diff --git a/src/fireedge/src/client/features/One/slice.js b/src/fireedge/src/client/features/One/slice.js
deleted file mode 100644
index 2443d6f31b..0000000000
--- a/src/fireedge/src/client/features/One/slice.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createSlice, isPending, isFulfilled } from '@reduxjs/toolkit'
-
-import { logout } from 'client/features/Auth/actions'
-import { updateResourceList } from 'client/features/One/utils'
-import { eventUpdateResourceState } from 'client/features/One/socket/actions'
-import { updateResourceFromFetch } from 'client/features/One/actions'
-
-const getNameListFromType = (type) => RESOURCES[type.split('/')[0]]
-
-const RESOURCES = {
- acl: 'acl',
- app: 'apps',
- cluster: 'clusters',
- datastore: 'datastores',
- file: 'files',
- group: 'groups',
- host: 'hosts',
- image: 'images',
- marketplace: 'marketplaces',
- secgroups: 'securityGroups',
- system: 'system',
- template: 'templates',
- user: 'users',
- vdc: 'vdc',
- vm: 'vms',
- vmgroup: 'vmGroups',
- vn: 'vNetworks',
- vntemplate: 'vNetworksTemplates',
- vrouter: 'vRouters',
- zone: 'zones',
- document: {
- 100: 'applications',
- 101: 'applicationsTemplates',
- 102: 'providers',
- 103: 'provisions',
- // extra: only for client
- defaults: 'provisionsTemplates',
- },
-}
-
-const initial = {
- requests: {},
-
- [RESOURCES.acl]: [],
- [RESOURCES.app]: [],
- [RESOURCES.cluster]: [],
- [RESOURCES.datastore]: [],
- [RESOURCES.file]: [],
- [RESOURCES.group]: [],
- [RESOURCES.host]: [],
- [RESOURCES.image]: [],
- [RESOURCES.marketplace]: [],
- [RESOURCES.secgroups]: [],
- [RESOURCES.system]: {},
- [RESOURCES.template]: [],
- [RESOURCES.user]: [],
- [RESOURCES.vdc]: [],
- [RESOURCES.vm]: [],
- [RESOURCES.vmgroup]: [],
- [RESOURCES.vn]: [],
- [RESOURCES.vntemplate]: [],
- [RESOURCES.vrouter]: [],
- [RESOURCES.zone]: [],
- [RESOURCES.document[100]]: [],
- [RESOURCES.document[101]]: [],
- [RESOURCES.document[102]]: [],
- [RESOURCES.document[103]]: [],
- [RESOURCES.document.defaults]: [],
-}
-
-const { name, actions, reducer } = createSlice({
- name: 'one',
- initialState: initial,
- extraReducers: (builder) => {
- builder
- .addMatcher(
- ({ type }) => type === logout.type,
- () => initial
- )
- .addMatcher(
- ({ type }) =>
- type.startsWith(RESOURCES.system) && type.endsWith('/fulfilled'),
- (state, { payload }) => ({ ...state, ...payload })
- )
- .addMatcher(
- ({ type }) =>
- type === updateResourceFromFetch.type ||
- (type.endsWith('/fulfilled') &&
- (type.includes(eventUpdateResourceState.typePrefix) ||
- type.includes('/detail'))),
- (state, { payload, type }) => {
- // TYPE and DATA can be force by payload
- const listName = getNameListFromType(payload?.type ?? type)
-
- const newList = updateResourceList(
- state[listName],
- payload?.data ?? payload
- )
-
- return { ...state, [listName]: newList }
- }
- )
- .addMatcher(
- ({ type }) => type.includes('/pool'),
- (state, action) => {
- const { requests } = state
- const { payload, type } = action
-
- // filter type without: /pending, /fulfilled or /rejected
- const pureType = type.match(/(.*\/pool)/)[0]
-
- if (isPending(action)) {
- return { ...state, requests: { ...requests, [pureType]: action } }
- }
-
- const { [pureType]: _, ...restOfRequests } = requests
-
- return {
- ...state,
- ...(isFulfilled(action) && payload),
- requests: restOfRequests,
- }
- }
- )
- },
-})
-
-export { name, actions, reducer, RESOURCES }
diff --git a/src/fireedge/src/client/features/One/socket/actions.js b/src/fireedge/src/client/features/One/socket/actions.js
deleted file mode 100644
index f373707a9a..0000000000
--- a/src/fireedge/src/client/features/One/socket/actions.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAsyncThunk } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/General/actions'
-import { RESOURCES } from 'client/features/One/slice'
-import { HookStateData, HookApiData } from 'client/features/One/socket/types'
-import { generateKey } from 'client/utils'
-
-const MESSAGE_PROVISION_SUCCESS_CREATED = 'Provision successfully created'
-
-const COMMANDS = {
- create: 'create',
- update: 'update',
- delete: 'delete',
-}
-
-/**
- * @param {HookStateData} data - Event data from hook event STATE
- * @returns {{name: ('vm'|'host'|'image'), value: object}}
- * - Name and new value of resource
- */
-export const getResourceFromEventState = (data) => {
- const { HOOK_OBJECT: name, [name]: value } = data?.HOOK_MESSAGE ?? {}
-
- return { name: String(name).toLowerCase(), value }
-}
-
-/**
- * @param {HookApiData} data - Event data from hook event API
- * @returns {{
- * action: string,
- * name: string,
- * value: object,
- * success: boolean,
- * output: object
- * }} - Resource information from event Api
- */
-export const getResourceFromEventApi = (data = {}) => {
- const { CALL: command = '', CALL_INFO: info = {} } = data?.HOOK_MESSAGE
- const { EXTRA: extra, RESULT: result, PARAMETERS } = info
-
- // command: 'one.resourceName.action'
- const [, resourceName, action] = command.split('.')
-
- const success = result === '1'
-
- const value = extra?.[String(resourceName).toUpperCase()]
-
- const resource = RESOURCES[resourceName]
- const name = resource?.[value?.TYPE] ?? resource
-
- const [, { VALUE: output }] = PARAMETERS?.PARAMETER?.filter(
- ({ TYPE }) => TYPE === 'OUT'
- )
-
- return { action, name, value, success, output }
-}
-
-/**
- * The API hooks are triggered after the execution of an API call.
- */
-export const eventApi = createAsyncThunk(
- 'socket/event-api',
- ({ data } = {}) => {
- const { action, name, value, success } = getResourceFromEventApi(data)
-
- // console.log({ action, name, value, success, output })
-
- return success && value && action !== COMMANDS.delete
- ? { [name]: value }
- : {}
- },
- {
- condition: ({ data } = {}) => data?.HOOK_MESSAGE?.HOOK_TYPE === 'API',
- }
-)
-
-/**
- * Dispatch new resource object when OpenNebula hooks is triggered
- * on specific state transition.
- *
- * Supported values: `HOST`, `VM`, `IMAGE`
- */
-export const eventUpdateResourceState = createAsyncThunk(
- 'socket/event-state',
- (data = {}) => {
- const { name, value } = getResourceFromEventState(data)
-
- return { type: name, data: value }
- },
- {
- condition: (data = {}) => {
- const { name, value } = getResourceFromEventState(data)
-
- return (
- data?.HOOK_MESSAGE?.HOOK_TYPE === 'STATE' &&
- // possible hook objects: VM, IMAGE, HOST
- ['vm', 'host', 'image'].includes(name) &&
- // update the list if event returns resource value
- value !== ''
- )
- },
- }
-)
-
-/**
- * Dispatch successfully notification when one provision is created
- */
-export const onCreateProvision = createAsyncThunk(
- 'socket/create-provision',
- (_, { dispatch }) => {
- dispatch(
- actions.enqueueSnackbar({
- key: generateKey(),
- message: MESSAGE_PROVISION_SUCCESS_CREATED,
- options: { variant: 'success' },
- })
- )
- },
- {
- condition: (payload = {}) => {
- const { command, data } = payload
-
- return command === 'create' && data === MESSAGE_PROVISION_SUCCESS_CREATED
- },
- }
-)
diff --git a/src/fireedge/src/client/features/One/socket/types.js b/src/fireedge/src/client/features/One/socket/types.js
deleted file mode 100644
index ac1e6d11ab..0000000000
--- a/src/fireedge/src/client/features/One/socket/types.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-
-/**
- * @typedef {object} HookStateData - Event data from hook event STATE
- * @property {HookStateMessage} HOOK_MESSAGE - Hook message from OpenNebula API
- */
-
-/**
- * @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 {string} STATE - The state that triggers the hook.
- * @property {string} [LCM_STATE]
- * - The LCM state that triggers the hook (Only for VM hooks)
- * @property {string} [REMOTE_HOST]
- * - If ``yes`` the hook will be executed in the host that triggered
- * the hook (for Host hooks) or in the host where the VM is running (for VM hooks).
- * Not used for Image hooks.
- * @property {string} RESOURCE_ID - ID of resource
- * @property {object} [VM] - New data of the VM
- * @property {object} [HOST] - New data of the HOST
- * @property {object} [IMAGE] - New data of the IMAGE
- */
-
-/**
- * @typedef {object} HookApiData - Event data from hook event API
- * @property {HookApiMessage} HOOK_MESSAGE - Hook message from OpenNebula API
- */
-
-/**
- * Call parameter.
- *
- * @typedef {object} Parameter
- * @property {number} POSITION - Parameter position in the list
- * @property {('IN'|'OUT')} TYPE - Parameter type
- * @property {string} VALUE - Parameter value as string
- */
-
-/**
- * @typedef {object} HookApiMessage - Event data from hook event API
- * @property {'API'} HOOK_TYPE - Type of event API
- * @property {string} CALL - Action name: 'one.resourceName.action'
- * @property {object} [CALL_INFO] - Information about result of action
- * @property {0|1} CALL_INFO.RESULT - `1` for success and `0` for error result
- * @property {Parameter[]|Parameter} [CALL_INFO.PARAMETERS]
- * - The list of IN and OUT parameters will match the API call parameters
- * @property {object} [CALL_INFO.EXTRA] - Extra information returned for API Hooks
- */
diff --git a/src/fireedge/src/client/features/One/system/actions.js b/src/fireedge/src/client/features/One/system/actions.js
deleted file mode 100644
index ec43ce0bda..0000000000
--- a/src/fireedge/src/client/features/One/system/actions.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { systemService } from 'client/features/One/system/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.system} */
-const SYSTEM = 'system'
-
-export const getOneVersion = createAction(
- `${SYSTEM}/one-version`,
- systemService.getOneVersion,
- (response, one) => ({
- [RESOURCES.system]: {
- ...one[RESOURCES.system],
- version: response,
- },
- })
-)
-
-export const getOneConfig = createAction(
- `${SYSTEM}/one-config`,
- systemService.getOneConfig,
- (response, one) => ({
- [RESOURCES.system]: {
- ...one[RESOURCES.system],
- config: response,
- },
- })
-)
diff --git a/src/fireedge/src/client/features/One/system/hooks.js b/src/fireedge/src/client/features/One/system/hooks.js
deleted file mode 100644
index edaf142b6d..0000000000
--- a/src/fireedge/src/client/features/One/system/hooks.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/system/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useSystem = () =>
- useSelector((state) => state[name]?.[RESOURCES.system] ?? [])
-
-export const useSystemApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- async (action) => {
- try {
- const response = await dispatch(action)
-
- return unwrapResult(response)
- } catch (error) {
- return error
- }
- },
- [dispatch]
- )
-
- return {
- getOneVersion: () => unwrapDispatch(actions.getOneVersion()),
- getOneConfig: () => unwrapDispatch(actions.getOneConfig()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/system/services.js b/src/fireedge/src/client/features/One/system/services.js
deleted file mode 100644
index 43376450e7..0000000000
--- a/src/fireedge/src/client/features/One/system/services.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/system'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const systemService = {
- /**
- * Returns the OpenNebula core version.
- *
- * @returns {object} The OpenNebula version
- * @throws Fails when response isn't code 200
- */
- getOneVersion: async () => {
- const name = Actions.SYSTEM_VERSION
- const command = { name, ...Commands[name] }
- const config = requestConfig(undefined, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Returns the OpenNebula configuration.
- *
- * @returns {object} The loaded oned.conf file
- * @throws Fails when response isn't code 200
- */
- getOneConfig: async () => {
- const name = Actions.SYSTEM_CONFIG
- const command = { name, ...Commands[name] }
- const config = requestConfig(undefined, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-}
diff --git a/src/fireedge/src/client/features/One/user/actions.js b/src/fireedge/src/client/features/One/user/actions.js
deleted file mode 100644
index 212dcccbbf..0000000000
--- a/src/fireedge/src/client/features/One/user/actions.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { userService } from 'client/features/One/user/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.user} */
-const USER = 'user'
-
-export const getUser = createAction(`${USER}/detail`, userService.getUser)
-
-export const getUsers = createAction(
- `${USER}/pool`,
- userService.getUsers,
- (response) => ({ [RESOURCES.user]: response })
-)
-
-export const updateUser = createAction(`${USER}/update`, userService.updateUser)
-export const changeGroup = createAction(
- `${USER}/change-group`,
- userService.changeGroup
-)
diff --git a/src/fireedge/src/client/features/One/user/hooks.js b/src/fireedge/src/client/features/One/user/hooks.js
deleted file mode 100644
index 01335ab06b..0000000000
--- a/src/fireedge/src/client/features/One/user/hooks.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/user/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useUser = () =>
- useSelector((state) => state[name]?.[RESOURCES.user] ?? [])
-
-export const useUserApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getUser: (id) => unwrapDispatch(actions.getUser({ id })),
- getUsers: () => unwrapDispatch(actions.getUsers()),
- changeGroup: (data) => unwrapDispatch(actions.changeGroup(data)),
- updateUser: (id, data) =>
- unwrapDispatch(actions.updateUser({ id, ...data })),
- }
-}
diff --git a/src/fireedge/src/client/features/One/user/services.js b/src/fireedge/src/client/features/One/user/services.js
deleted file mode 100644
index 7f414f1960..0000000000
--- a/src/fireedge/src/client/features/One/user/services.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/user'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const userService = {
- /**
- * Retrieves information for the user.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - User id
- * @returns {object} Get user identified by id
- * @throws Fails when response isn't code 200
- */
- getUser: async ({ id }) => {
- const name = Actions.USER_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.USER ?? {}
- },
-
- /**
- * Retrieves information for all the users in the pool.
- *
- * @returns {Array} List of users
- * @throws Fails when response isn't code 200
- */
- getUsers: async () => {
- const name = Actions.USER_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(undefined, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.USER_POOL?.USER ?? []].flat()
- },
-
- /**
- * Changes the group of the given user.
- *
- * @param {object} params - Request parameters
- * @param {object} params.data - Form data
- * @returns {number} User id
- * @throws Fails when response isn't code 200
- */
- changeGroup: async (params) => {
- const name = Actions.USER_CHGRP
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
-
- /**
- * Replaces the user template contents.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - User id
- * @param {string} params.template - The new user template contents
- * @param {0|1} params.replace
- * - Update type:
- * ``0``: Replace the whole template.
- * ``1``: Merge new template with the existing one.
- * @returns {number} User id
- * @throws Fails when response isn't code 200
- */
- updateUser: async (params) => {
- const name = Actions.USER_UPDATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data ?? {}
- },
-}
diff --git a/src/fireedge/src/client/features/One/utils.js b/src/fireedge/src/client/features/One/utils.js
deleted file mode 100644
index 05c1ad3d34..0000000000
--- a/src/fireedge/src/client/features/One/utils.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAsyncThunk, AsyncThunkAction } from '@reduxjs/toolkit'
-
-import { logout } from 'client/features/Auth/actions'
-
-import { T } from 'client/constants'
-import { httpCodes } from 'server/utils/constants'
-
-/**
- * @param {string} type - Name of redux action
- * @param {Promise} service - Request from service
- * @param {function(object, object)} [wrapResult] - Function to wrapping the response
- * @returns {AsyncThunkAction} Asynchronous redux action
- */
-export const createAction = (type, service, wrapResult) =>
- createAsyncThunk(
- type,
- async (payload, { dispatch, getState, rejectWithValue }) => {
- try {
- const {
- auth: { filterPool },
- one,
- } = getState()
-
- const response = await service({
- ...payload,
- filter: filterPool,
- })
-
- return wrapResult?.(response, one) ?? response
- } catch (error) {
- const { message, data, status, statusText } = error
-
- status === httpCodes.unauthorized.id &&
- dispatch(logout(T.SessionExpired))
-
- return rejectWithValue(
- message ?? data?.data ?? data?.message ?? statusText
- )
- }
- },
- {
- condition: (_, { getState }) => !getState().one.requests[type],
- }
- )
-
-/**
- * @param {object} currentList - Current list of resources from redux
- * @param {object} value - OpenNebula resource
- * @returns {Array} Returns a new list with the attributes editable modified
- */
-export const updateResourceList = (currentList, value) => {
- const id = value.ID
-
- const currentItem = currentList?.find(({ ID }) => ID === id)
-
- // update if exists in current list, if not add it to list
- const updatedList = currentItem
- ? currentList?.map((item) => (item?.ID === id ? value : item))
- : [value, ...currentList]
-
- return updatedList
-}
diff --git a/src/fireedge/src/client/features/One/vm/actions.js b/src/fireedge/src/client/features/One/vm/actions.js
deleted file mode 100644
index ea841737b1..0000000000
--- a/src/fireedge/src/client/features/One/vm/actions.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { vmService } from 'client/features/One/vm/services'
-import { filterBy } from 'client/utils'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.vm} */
-const VM = 'vm'
-
-export const getVm = createAction(`${VM}/detail`, vmService.getVm)
-
-export const getVms = createAction(
- `${VM}/pool`,
- vmService.getVms,
- (response, { [RESOURCES.vm]: currentVms }) => {
- const vms = filterBy([...currentVms, ...response], 'ID')
-
- return { [RESOURCES.vm]: vms }
- }
-)
-
-export const terminate = createAction(`${VM}/terminate`, ({ id }) =>
- vmService.actionVm({ id, action: 'terminate' })
-)
-export const terminateHard = createAction(`${VM}/terminate-hard`, ({ id }) =>
- vmService.actionVm({ id, action: 'terminate-hard' })
-)
-export const undeploy = createAction(`${VM}/undeploy`, ({ id }) =>
- vmService.actionVm({ id, action: 'undeploy' })
-)
-export const undeployHard = createAction(`${VM}/undeploy-hard`, ({ id }) =>
- vmService.actionVm({ id, action: 'undeploy-hard' })
-)
-export const poweroff = createAction(`${VM}/poweroff`, ({ id }) =>
- vmService.actionVm({ id, action: 'poweroff' })
-)
-export const poweroffHard = createAction(`${VM}/poweroff-hard`, ({ id }) =>
- vmService.actionVm({ id, action: 'poweroff-hard' })
-)
-export const reboot = createAction(`${VM}/reboot`, ({ id }) =>
- vmService.actionVm({ id, action: 'reboot' })
-)
-export const rebootHard = createAction(`${VM}/reboot-hard`, ({ id }) =>
- vmService.actionVm({ id, action: 'reboot-hard' })
-)
-export const hold = createAction(`${VM}/hold`, ({ id }) =>
- vmService.actionVm({ id, action: 'hold' })
-)
-export const release = createAction(`${VM}/release`, ({ id }) =>
- vmService.actionVm({ id, action: 'release' })
-)
-export const stop = createAction(`${VM}/stop`, ({ id }) =>
- vmService.actionVm({ id, action: 'stop' })
-)
-export const suspend = createAction(`${VM}/suspend`, ({ id }) =>
- vmService.actionVm({ id, action: 'suspend' })
-)
-export const resume = createAction(`${VM}/resume`, ({ id }) =>
- vmService.actionVm({ id, action: 'resume' })
-)
-export const resched = createAction(`${VM}/resched`, ({ id }) =>
- vmService.actionVm({ id, action: 'resched' })
-)
-export const unresched = createAction(`${VM}/unresched`, ({ id }) =>
- vmService.actionVm({ id, action: 'unresched' })
-)
-
-export const updateUserTemplate = createAction(
- `${VM}/update`,
- vmService.updateUserTemplate
-)
-export const rename = createAction(`${VM}/rename`, vmService.rename)
-export const resize = createAction(`${VM}/resize`, vmService.resize)
-export const changePermissions = createAction(
- `${VM}/chmod`,
- vmService.changePermissions
-)
-export const changeOwnership = createAction(
- `${VM}/chown`,
- vmService.changeOwnership
-)
-export const attachDisk = createAction(
- `${VM}/attach/disk`,
- vmService.attachDisk
-)
-export const detachDisk = createAction(
- `${VM}/detach/disk`,
- vmService.detachDisk
-)
-export const saveAsDisk = createAction(
- `${VM}/saveas/disk`,
- vmService.saveAsDisk
-)
-export const saveAsTemplate = createAction(
- `${VM}/saveas/template`,
- vmService.saveAsTemplate
-)
-export const resizeDisk = createAction(
- `${VM}/resize/disk`,
- vmService.resizeDisk
-)
-export const createDiskSnapshot = createAction(
- `${VM}/create/disk-snapshot`,
- vmService.createDiskSnapshot
-)
-export const renameDiskSnapshot = createAction(
- `${VM}/rename/disk-snapshot`,
- vmService.renameDiskSnapshot
-)
-export const revertDiskSnapshot = createAction(
- `${VM}/revert/disk-snapshot`,
- vmService.revertDiskSnapshot
-)
-export const deleteDiskSnapshot = createAction(
- `${VM}/delete/disk-snapshot`,
- vmService.deleteDiskSnapshot
-)
-export const attachNic = createAction(`${VM}/attach/nic`, vmService.attachNic)
-export const detachNic = createAction(`${VM}/detach/nic`, vmService.detachNic)
-export const createSnapshot = createAction(
- `${VM}/create/snapshot`,
- vmService.createSnapshot
-)
-export const revertSnapshot = createAction(
- `${VM}/revert/snapshot`,
- vmService.revertSnapshot
-)
-export const deleteSnapshot = createAction(
- `${VM}/delete/snapshot`,
- vmService.deleteSnapshot
-)
-export const addScheduledAction = createAction(
- `${VM}/add/scheduled-action`,
- vmService.addScheduledAction
-)
-export const updateScheduledAction = createAction(
- `${VM}/update/scheduled-action`,
- vmService.updateScheduledAction
-)
-export const deleteScheduledAction = createAction(
- `${VM}/delete/scheduled-action`,
- vmService.deleteScheduledAction
-)
-export const recover = createAction(`${VM}/recover`, vmService.recover)
-export const lock = createAction(`${VM}/lock`, vmService.lock)
-export const unlock = createAction(`${VM}/unlock`, vmService.unlock)
-export const deploy = createAction(`${VM}/deploy`, vmService.deploy)
-export const migrate = createAction(`${VM}/migrate`, vmService.migrate)
-export const migrateLive = createAction(`${VM}/migrate-live`, vmService.migrate)
diff --git a/src/fireedge/src/client/features/One/vm/hooks.js b/src/fireedge/src/client/features/One/vm/hooks.js
deleted file mode 100644
index 149de6f4dc..0000000000
--- a/src/fireedge/src/client/features/One/vm/hooks.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/vm/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useVm = () =>
- useSelector((state) => state[name]?.[RESOURCES.vm] ?? [])
-
-export const useVmApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getVm: (id) => unwrapDispatch(actions.getVm({ id })),
- getVms: (options) => unwrapDispatch(actions.getVms(options)),
- terminate: (id) => unwrapDispatch(actions.terminate({ id })),
- terminateHard: (id) => unwrapDispatch(actions.terminateHard({ id })),
- undeploy: (id) => unwrapDispatch(actions.undeploy({ id })),
- undeployHard: (id) => unwrapDispatch(actions.undeployHard({ id })),
- poweroff: (id) => unwrapDispatch(actions.poweroff({ id })),
- poweroffHard: (id) => unwrapDispatch(actions.poweroffHard({ id })),
- reboot: (id) => unwrapDispatch(actions.reboot({ id })),
- rebootHard: (id) => unwrapDispatch(actions.rebootHard({ id })),
- hold: (id) => unwrapDispatch(actions.hold({ id })),
- release: (id) => unwrapDispatch(actions.release({ id })),
- stop: (id) => unwrapDispatch(actions.stop({ id })),
- suspend: (id) => unwrapDispatch(actions.suspend({ id })),
- resume: (id) => unwrapDispatch(actions.resume({ id })),
- resched: (id) => unwrapDispatch(actions.resched({ id })),
- unresched: (id) => unwrapDispatch(actions.unresched({ id })),
- updateUserTemplate: (id, template, replace) =>
- unwrapDispatch(actions.updateUserTemplate({ id, template, replace })),
- rename: (id, newName) =>
- unwrapDispatch(actions.rename({ id, name: newName })),
- resize: (id, data) => unwrapDispatch(actions.resize({ id, ...data })),
- changePermissions: (id, permissions) =>
- unwrapDispatch(actions.changePermissions({ id, permissions })),
- changeOwnership: (id, ownership) =>
- unwrapDispatch(actions.changeOwnership({ id, ownership })),
- attachDisk: (id, template) =>
- unwrapDispatch(actions.attachDisk({ id, template })),
- detachDisk: (id, disk) => unwrapDispatch(actions.detachDisk({ id, disk })),
- saveAsDisk: (id, data) =>
- unwrapDispatch(actions.saveAsDisk({ id, ...data })),
- saveAsTemplate: (id, data) =>
- unwrapDispatch(actions.saveAsTemplate({ id, ...data })),
- resizeDisk: (id, data) =>
- unwrapDispatch(actions.resizeDisk({ id, ...data })),
- createDiskSnapshot: (id, data) =>
- unwrapDispatch(actions.createDiskSnapshot({ id, ...data })),
- renameDiskSnapshot: (id, data) =>
- unwrapDispatch(actions.renameDiskSnapshot({ id, ...data })),
- revertDiskSnapshot: (id, data) =>
- unwrapDispatch(actions.revertDiskSnapshot({ id, ...data })),
- deleteDiskSnapshot: (id, data) =>
- unwrapDispatch(actions.deleteDiskSnapshot({ id, ...data })),
- attachNic: (id, template) =>
- unwrapDispatch(actions.attachNic({ id, template })),
- detachNic: (id, nic) => unwrapDispatch(actions.detachNic({ id, nic })),
- createSnapshot: (id, data) =>
- unwrapDispatch(actions.createSnapshot({ id, ...data })),
- revertSnapshot: (id, snapshot) =>
- unwrapDispatch(actions.revertSnapshot({ id, snapshot })),
- deleteSnapshot: (id, snapshot) =>
- unwrapDispatch(actions.deleteSnapshot({ id, snapshot })),
- addScheduledAction: (id, data) =>
- unwrapDispatch(actions.addScheduledAction({ id, ...data })),
- updateScheduledAction: (id, data) =>
- unwrapDispatch(actions.updateScheduledAction({ id, ...data })),
- deleteScheduledAction: (id, data) =>
- unwrapDispatch(actions.deleteScheduledAction({ id, ...data })),
- recover: (id, operation) =>
- unwrapDispatch(actions.recover({ id, operation })),
- lock: (id, data) => unwrapDispatch(actions.lock({ id, ...data })),
- unlock: (id) => unwrapDispatch(actions.unlock({ id })),
- deploy: (id, data) => unwrapDispatch(actions.deploy({ id, ...data })),
- migrate: (id, data) =>
- unwrapDispatch(actions.migrate({ id, ...data, live: false })),
- migrateLive: (id, data) =>
- unwrapDispatch(actions.migrate({ id, ...data, live: true })),
- }
-}
diff --git a/src/fireedge/src/client/features/One/vm/services.js b/src/fireedge/src/client/features/One/vm/services.js
deleted file mode 100644
index ca6451a2fa..0000000000
--- a/src/fireedge/src/client/features/One/vm/services.js
+++ /dev/null
@@ -1,722 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/vm'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const vmService = {
- /**
- * Retrieves information for the virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string} params.id - User id
- * @returns {object} Get user identified by id
- * @throws Fails when response isn't code 200
- */
- getVm: async (params) => {
- const name = Actions.VM_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.VM ?? {}
- },
-
- /**
- * Retrieves information for all or part of
- * the VMs in the pool.
- *
- * @param {object} params - Request parameters
- * @param {string} params.filter - Filter flag
- * @param {number} params.start - Range start ID
- * @param {number} params.end - Range end ID
- * @param {string|number} params.state - Filter state
- * @returns {Array} List of VMs
- * @throws Fails when response isn't code 200
- */
- getVms: async (params) => {
- const name = Actions.VM_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.VM_POOL?.VM ?? []].flat()
- },
-
- /**
- * Submits an action to be performed on a virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string} params.id - Virtual machine id
- * @param {(
- * 'terminate-hard'|
- * 'terminate'|
- * 'undeploy-hard'|
- * 'undeploy'|
- * 'poweroff-hard'|
- * 'poweroff'|
- * 'reboot-hard'|
- * 'reboot'|
- * 'hold'|
- * 'release'|
- * 'stop'|
- * 'suspend'|
- * 'resume'|
- * 'resched'|
- * 'unresched'
- * )} params.action - The action name to be performed
- * @returns {Response} Response
- * @throws Fails when response isn't code 200
- */
- actionVm: async (params) => {
- const name = Actions.VM_ACTION
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.VM ?? {}
- },
-
- /**
- * Clones the VM's source Template, replacing the disks with live snapshots
- * of the current disks. The VM capacity and NICs are also preserved.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string} params.name - Template name
- * @param {boolean} params.persistent - Make the new images persistent
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- saveAsTemplate: async ({ id, name, persistent }) => {
- const res = await RestClient.request({
- url: `/api/vm/save/${id}`,
- method: 'POST',
- data: { name, persistent },
- })
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Renames a virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string} params.name - New name
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- rename: async (params) => {
- const name = Actions.VM_RENAME
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Changes the capacity of the virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string} params.template - Template containing the new capacity
- * @param {boolean} params.enforce
- * - `true` to enforce the Host capacity isn't over committed.
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- resize: async (params) => {
- const name = Actions.VM_RESIZE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Replaces the user template contents.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string} params.template - The new user template contents
- * @param {0|1} params.replace
- * - Update type:
- * ``0``: Replace the whole template.
- * ``1``: Merge new template with the existing one.
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- updateUserTemplate: async (params) => {
- const name = Actions.VM_UPDATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Changes the permission bits of a virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {{
- * ownerUse: number,
- * ownerManage: number,
- * ownerAdmin: number,
- * groupUse: number,
- * groupManage: number,
- * groupAdmin: number,
- * otherUse: number,
- * otherManage: number,
- * otherAdmin: number
- * }} params.permissions - Permissions data
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- changePermissions: async ({ id, permissions }) => {
- const name = Actions.VM_CHMOD
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id, ...permissions }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Changes the ownership bits of a virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {{user: number, group: number}} params.ownership - Ownership data
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- changeOwnership: async ({ id, ownership }) => {
- const name = Actions.VM_CHOWN
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id, ...ownership }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Attaches a new disk to the virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string} params.template
- * - A string containing a single DISK vector attribute
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- attachDisk: async (params) => {
- const name = Actions.VM_DISK_ATTACH
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Detaches a disk from a virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.disk - Disk id
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- detachDisk: async (params) => {
- const name = Actions.VM_DISK_DETACH
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Sets the disk to be saved in the given image.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.disk - Disk id
- * @param {string} params.name - Name for the new Image
- * @param {string} params.type - Type for the new Image.
- * If it is an empty string, then the default one will be used
- * @param {string|number} params.snapshot - Id of the snapshot to export.
- * If -1 the current image state will be used.
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- saveAsDisk: async (params) => {
- const name = Actions.VM_DISK_SAVEAS
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Resizes a disk of a virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.disk - Disk id
- * @param {string} params.size - The new size string
- * - Options to perform action
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- resizeDisk: async (params) => {
- const name = Actions.VM_DISK_RESIZE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Takes a new snapshot of the disk image.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.disk - Disk id
- * @param {string} params.description - Description for the snapshot
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- createDiskSnapshot: async (params) => {
- const name = Actions.VM_DISK_SNAP_CREATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Renames a disk snapshot.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.disk - Disk id
- * @param {string|number} params.snapshot - Snapshot id
- * @param {string} params.name - New snapshot name
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- renameDiskSnapshot: async (params) => {
- const name = Actions.VM_DISK_SNAP_RENAME
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Reverts disk state to a previously taken snapshot.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.disk - Disk id
- * @param {string|number} params.snapshot - Snapshot id
- * @returns {number} The snapshot id used
- * @throws Fails when response isn't code 200
- */
- revertDiskSnapshot: async (params) => {
- const name = Actions.VM_DISK_SNAP_REVERT
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Deletes a disk snapshot.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.disk - Disk id
- * @param {string|number} params.snapshot - Snapshot id
- * @returns {number} The id of the snapshot deleted
- * @throws Fails when response isn't code 200
- */
- deleteDiskSnapshot: async (params) => {
- const name = Actions.VM_DISK_SNAP_DELETE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Attaches a new network interface to the virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string} params.template
- * - A string containing a single NIC vector attribute
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- attachNic: async (params) => {
- const name = Actions.VM_NIC_ATTACH
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Detaches a network interface from a virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.nic - NIC id
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- detachNic: async (params) => {
- const name = Actions.VM_NIC_DETACH
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Creates a new virtual machine snapshot.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string} params.name - The new snapshot name
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- createSnapshot: async (params) => {
- const name = Actions.VM_SNAP_CREATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Reverts a virtual machine to a snapshot.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.snapshot - The snapshot id
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- revertSnapshot: async (params) => {
- const name = Actions.VM_SNAP_REVERT
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Deletes a virtual machine snapshot.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.snapshot - The snapshot id
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- deleteSnapshot: async (params) => {
- const name = Actions.VM_SNAP_DELETE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Add scheduled action to VM.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string} params.template - Template containing the new scheduled action
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- addScheduledAction: async (params) => {
- const name = Actions.VM_SCHED_ADD
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Update scheduled VM action.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string} params.id_sched - The ID of the scheduled action
- * @param {string} params.template - Template containing the updated scheduled action
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- updateScheduledAction: async (params) => {
- const name = Actions.VM_SCHED_UPDATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Delete scheduled action from VM.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string} params.id_sched - The ID of the scheduled action
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- deleteScheduledAction: async (params) => {
- const name = Actions.VM_SCHED_DELETE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Recovers a stuck VM that is waiting for a driver operation.
- * The recovery may be done by failing or succeeding the pending operation.
- *
- * You need to manually check the vm status on the host, to decide
- * if the operation was successful or not.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {0|1|2|3|4} params.operation - Recover operation:
- * success (1), failure (0), retry (2), delete (3), delete-recreate (4)
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- recover: async (params) => {
- const name = Actions.VM_RECOVER
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Locks a virtual machine. Lock certain actions depending on blocking level.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {1|2|3|4} params.level
- * - Lock level:
- * ``1``: Use
- * ``2``: Manage
- * ``3``: Admin
- * ``4``: All
- * @param {boolean} params.test - Check if the object is already locked to return an error
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- lock: async (params) => {
- const name = Actions.VM_LOCK
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Unlocks a virtual machine.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- unlock: async (params) => {
- const name = Actions.VM_UNLOCK
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Initiates the instance of the given VM id on the target host.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.host - The target host id
- * @param {boolean} params.enforce
- * - If `true`, will enforce the Host capacity isn't over committed.
- * @param {string|number} params.datastore - The target datastore id.
- * It is optional, and can be set to -1 to let OpenNebula choose the datastore
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- deploy: async (params) => {
- const name = Actions.VM_DEPLOY
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Migrates one virtual machine to the target host.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Virtual machine id
- * @param {string|number} params.host - The target host id
- * @param {boolean} params.live
- * - If `true` we are indicating that we want live migration, otherwise `false`.
- * @param {boolean} params.enforce
- * - If `true`, will enforce the Host capacity isn't over committed.
- * @param {string|number} params.datastore - The target datastore id.
- * It is optional, and can be set to -1 to let OpenNebula choose the datastore
- * @param {0|1|2} params.type - Migration type: save (0), poweroff (1), poweroff-hard (2)
- * @returns {number} Virtual machine id
- * @throws Fails when response isn't code 200
- */
- migrate: async (params) => {
- const name = Actions.VM_MIGRATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-}
diff --git a/src/fireedge/src/client/features/One/vmGroup/actions.js b/src/fireedge/src/client/features/One/vmGroup/actions.js
deleted file mode 100644
index 99ec6d4d5e..0000000000
--- a/src/fireedge/src/client/features/One/vmGroup/actions.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { vmGroupService } from 'client/features/One/vmGroup/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.vmgroup} */
-const VM_GROUP = 'vmgroup'
-
-export const getVmGroup = createAction(
- `${VM_GROUP}/detail`,
- vmGroupService.getVmGroup
-)
-
-export const getVmGroups = createAction(
- `${VM_GROUP}/pool`,
- vmGroupService.getVmGroups,
- (response) => ({ [RESOURCES.vmgroup]: response })
-)
diff --git a/src/fireedge/src/client/features/One/vmGroup/hooks.js b/src/fireedge/src/client/features/One/vmGroup/hooks.js
deleted file mode 100644
index 8b5394516e..0000000000
--- a/src/fireedge/src/client/features/One/vmGroup/hooks.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/vmGroup/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useVmGroup = () =>
- useSelector((state) => state[name]?.[RESOURCES.vmgroup])
-
-export const useVmGroupApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getVmGroup: (id) => unwrapDispatch(actions.getVmGroup({ id })),
- getVmGroups: () => unwrapDispatch(actions.getVmGroups()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/vmGroup/services.js b/src/fireedge/src/client/features/One/vmGroup/services.js
deleted file mode 100644
index b2bf19bb3d..0000000000
--- a/src/fireedge/src/client/features/One/vmGroup/services.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/vmgroup'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const vmGroupService = {
- /**
- * Retrieves information for the VM group.
- *
- * @param {object} params - Request parameters
- * @param {string} params.id - VM group id
- * @param {boolean} params.decrypt - `true` to decrypt contained secrets
- * @returns {object} Get VM group identified by id
- * @throws Fails when response isn't code 200
- */
- getVmGroup: async (params) => {
- const name = Actions.VM_GROUP_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.VM_GROUP ?? {}
- },
-
- /**
- * Retrieves information for all or part of the
- * VM groups in the pool.
- *
- * @param {object} data - Request params
- * @param {string} data.filter - Filter flag
- * @param {number} data.start - Range start ID
- * @param {number} data.end - Range end ID
- * @returns {Array} List of VM groups
- * @throws Fails when response isn't code 200
- */
- getVmGroups: async ({ filter, start, end }) => {
- const name = Actions.VM_GROUP_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ filter, start, end }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.VM_GROUP_POOL?.VM_GROUP ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/One/vmTemplate/actions.js b/src/fireedge/src/client/features/One/vmTemplate/actions.js
deleted file mode 100644
index 7bb29d6a46..0000000000
--- a/src/fireedge/src/client/features/One/vmTemplate/actions.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { vmTemplateService } from 'client/features/One/vmTemplate/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.template} */
-const TEMPLATE = 'template'
-
-export const getVmTemplate = createAction(
- `${TEMPLATE}/detail`,
- vmTemplateService.getVmTemplate
-)
-
-export const getVmTemplates = createAction(
- `${TEMPLATE}/pool`,
- vmTemplateService.getVmTemplates,
- (response) => ({ [RESOURCES.template]: response })
-)
-
-export const instantiate = createAction(
- `${TEMPLATE}/instantiate`,
- vmTemplateService.instantiate
-)
-export const allocate = createAction(
- `${TEMPLATE}/allocate`,
- vmTemplateService.allocate
-)
-export const clone = createAction(`${TEMPLATE}/clone`, vmTemplateService.clone)
-export const remove = createAction(
- `${TEMPLATE}/delete`,
- vmTemplateService.delete
-)
-export const update = createAction(
- `${TEMPLATE}/update`,
- vmTemplateService.update
-)
-export const changePermissions = createAction(
- `${TEMPLATE}/chmod`,
- vmTemplateService.changePermissions
-)
-export const changeOwnership = createAction(
- `${TEMPLATE}/chown`,
- vmTemplateService.changeOwnership
-)
-export const rename = createAction(
- `${TEMPLATE}/rename`,
- vmTemplateService.rename
-)
-export const lock = createAction(`${TEMPLATE}/lock`, vmTemplateService.lock)
-export const unlock = createAction(
- `${TEMPLATE}/unlock`,
- vmTemplateService.unlock
-)
diff --git a/src/fireedge/src/client/features/One/vmTemplate/hooks.js b/src/fireedge/src/client/features/One/vmTemplate/hooks.js
deleted file mode 100644
index 975598b893..0000000000
--- a/src/fireedge/src/client/features/One/vmTemplate/hooks.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/vmTemplate/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useVmTemplate = () =>
- useSelector((state) => state[name]?.[RESOURCES.template] ?? [])
-
-export const useVmTemplateApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getVmTemplate: (id, data) =>
- unwrapDispatch(actions.getVmTemplate({ id, ...data })),
- getVmTemplates: () => unwrapDispatch(actions.getVmTemplates()),
- instantiate: (id, data) =>
- unwrapDispatch(actions.instantiate({ id, ...data })),
- allocate: (template) => unwrapDispatch(actions.allocate({ template })),
- clone: (id, data) => unwrapDispatch(actions.clone({ id, ...data })),
- remove: (id, image) => unwrapDispatch(actions.remove({ id, image })),
- update: (id, template, replace) =>
- unwrapDispatch(actions.update({ id, template, replace })),
- changePermissions: (id, data) =>
- unwrapDispatch(actions.changePermissions({ id, ...data })),
- changeOwnership: (id, ownership) =>
- unwrapDispatch(actions.changeOwnership({ id, ownership })),
- rename: (id, newName) =>
- unwrapDispatch(actions.rename({ id, name: newName })),
- lock: (id, data) => unwrapDispatch(actions.lock({ id, ...data })),
- unlock: (id) => unwrapDispatch(actions.unlock({ id })),
- }
-}
diff --git a/src/fireedge/src/client/features/One/vmTemplate/services.js b/src/fireedge/src/client/features/One/vmTemplate/services.js
deleted file mode 100644
index 1b03c6977c..0000000000
--- a/src/fireedge/src/client/features/One/vmTemplate/services.js
+++ /dev/null
@@ -1,302 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/template'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const vmTemplateService = {
- /**
- * Retrieves information for the vm template.
- *
- * @param {object} params - Request parameters
- * @param {string} params.id - Template id
- * @param {boolean} params.extended - True to include extended information
- * @param {boolean} params.decrypt - True to decrypt contained secrets (only admin)
- * @returns {object} Get template identified by id
- * @throws Fails when response isn't code 200
- */
- getVmTemplate: async (params) => {
- const name = Actions.TEMPLATE_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.VMTEMPLATE ?? {}
- },
-
- /**
- * Retrieves information for all or part of
- * the virtual machine templates in the pool.
- *
- * @param {object} params - Request params
- * @param {string} params.filter - Filter flag
- * @param {number} params.start - Range start ID
- * @param {number} params.end - Range end ID
- * @returns {Array} List of VM templates
- * @throws Fails when response isn't code 200
- */
- getVmTemplates: async (params) => {
- const name = Actions.TEMPLATE_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.VMTEMPLATE_POOL?.VMTEMPLATE ?? []].flat()
- },
-
- /**
- * Allocates a new template in OpenNebula.
- *
- * @param {object} params - Request params
- * @param {string} params.template - A string containing the template contents
- * @returns {number} Template id
- * @throws Fails when response isn't code 200
- */
- allocate: async (params) => {
- const name = Actions.TEMPLATE_ALLOCATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-
- /**
- * Clones an existing virtual machine template.
- *
- * @param {object} params - Request params
- * @param {number|string} params.id - The ID of the template to be cloned
- * @param {string} params.name - Name for the new template
- * @param {boolean} params.image
- * - `true` to clone the template plus any image defined in DISK.
- * The new IMAGE_ID is set into each DISK
- * @returns {number} Template id
- * @throws Fails when response isn't code 200
- */
- clone: async (params) => {
- const name = Actions.TEMPLATE_CLONE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-
- /**
- * Deletes the given template from the pool.
- *
- * @param {object} params - Request params
- * @param {number|string} params.id - Template id
- * @param {boolean} params.image
- * - `true` to delete the template plus any image defined in DISK
- * @returns {number} Template id
- * @throws Fails when response isn't code 200
- */
- delete: async (params) => {
- const name = Actions.TEMPLATE_DELETE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-
- /**
- * Replaces the template contents.
- *
- * @param {object} params - Request params
- * @param {number|string} params.id - Template id
- * @param {string} params.template - The new template contents
- * @param {0|1} params.replace
- * - Update type:
- * ``0``: Replace the whole template.
- * ``1``: Merge new template with the existing one.
- * @returns {number} Template id
- * @throws Fails when response isn't code 200
- */
- update: async (params) => {
- const name = Actions.TEMPLATE_UPDATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-
- /**
- * Changes the permission bits of a template.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Template id
- * @param {{
- * ownerUse: number,
- * ownerManage: number,
- * ownerAdmin: number,
- * groupUse: number,
- * groupManage: number,
- * groupAdmin: number,
- * otherUse: number,
- * otherManage: number,
- * otherAdmin: number
- * }} params.permissions - Permissions data
- * @param {boolean} params.image
- * - `true` to chmod the template plus any image defined in DISK
- * @returns {number} Template id
- * @throws Fails when response isn't code 200
- */
- changePermissions: async ({ id, image, permissions }) => {
- const name = Actions.TEMPLATE_CHMOD
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id, image, ...permissions }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Changes the ownership of a template.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Template id
- * @param {{user: number, group: number}} params.ownership - Ownership data
- * @returns {number} Template id
- * @throws Fails when response isn't code 200
- */
- changeOwnership: async ({ id, ownership }) => {
- const name = Actions.TEMPLATE_CHOWN
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id, ...ownership }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Renames a Template.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Template id
- * @param {string} params.name - New name
- * @returns {number} Template id
- * @throws Fails when response isn't code 200
- */
- rename: async (params) => {
- const name = Actions.TEMPLATE_RENAME
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Locks a Template.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Template id
- * @param {1|2|3|4} params.level
- * - Lock level:
- * ``1``: Use
- * ``2``: Manage
- * ``3``: Admin
- * ``4``: All
- * @param {boolean} params.test - Check if the object is already locked to return an error
- * @returns {number} Template id
- * @throws Fails when response isn't code 200
- */
- lock: async (params) => {
- const name = Actions.TEMPLATE_LOCK
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Unlocks a Template.
- *
- * @param {object} params - Request parameters
- * @param {string|number} params.id - Template id
- * @returns {number} Template id
- * @throws Fails when response isn't code 200
- */
- unlock: async (params) => {
- const name = Actions.TEMPLATE_UNLOCK
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res?.data
-
- return res?.data
- },
-
- /**
- * Instantiates a new virtual machine from a template.
- *
- * @param {object} params - Request params
- * @param {number|string} params.id - Template id
- * @param {string} params.name - Name for the new VM instance
- * @param {boolean} params.hold - True to create it on hold state
- * @param {boolean} params.persistent - True to create a private persistent copy
- * @param {string} params.template - Extra template to be merged with the one being instantiated
- * @returns {number} Template id
- * @throws Fails when response isn't code 200
- */
- instantiate: async (params) => {
- const name = Actions.TEMPLATE_INSTANTIATE
- const command = { name, ...Commands[name] }
- const config = requestConfig(params, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data
- },
-}
diff --git a/src/fireedge/src/client/features/One/vnetwork/actions.js b/src/fireedge/src/client/features/One/vnetwork/actions.js
deleted file mode 100644
index 3370aaebda..0000000000
--- a/src/fireedge/src/client/features/One/vnetwork/actions.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { vNetworkService } from 'client/features/One/vnetwork/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.vn} */
-const VNET = 'vn'
-
-export const getVNetwork = createAction(
- `${VNET}/detail`,
- vNetworkService.getVNetwork
-)
-
-export const getVNetworks = createAction(
- `${VNET}/pool`,
- vNetworkService.getVNetworks,
- (response) => ({ [RESOURCES.vn]: response })
-)
diff --git a/src/fireedge/src/client/features/One/vnetwork/hooks.js b/src/fireedge/src/client/features/One/vnetwork/hooks.js
deleted file mode 100644
index e924f95e4c..0000000000
--- a/src/fireedge/src/client/features/One/vnetwork/hooks.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/vnetwork/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useVNetwork = () =>
- useSelector((state) => state[name]?.[RESOURCES.vn] ?? [])
-
-export const useVNetworkApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getVNetwork: (id) => unwrapDispatch(actions.getVNetwork({ id })),
- getVNetworks: () => unwrapDispatch(actions.getVNetworks()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/vnetwork/services.js b/src/fireedge/src/client/features/One/vnetwork/services.js
deleted file mode 100644
index eaee6e404b..0000000000
--- a/src/fireedge/src/client/features/One/vnetwork/services.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/vn'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const vNetworkService = {
- /**
- * Retrieves information for the virtual network.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Virtual network id
- * @returns {object} Get virtual network identified by id
- * @throws Fails when response isn't code 200
- */
- getVNetwork: async ({ id }) => {
- const name = Actions.VN_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.VNET ?? {}
- },
-
- /**
- * Retrieves information for all or part of the
- * virtual networks in the pool.
- *
- * @param {object} data - Request params
- * @param {string} data.filter - Filter flag
- * @param {number} data.start - Range start ID
- * @param {number} data.end - Range end ID
- * @returns {Array} List of virtual networks
- * @throws Fails when response isn't code 200
- */
- getVNetworks: async ({ filter, start, end }) => {
- const name = Actions.VN_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ filter, start, end }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.VNET_POOL?.VNET ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/One/vnetworkTemplate/actions.js b/src/fireedge/src/client/features/One/vnetworkTemplate/actions.js
deleted file mode 100644
index d577d987eb..0000000000
--- a/src/fireedge/src/client/features/One/vnetworkTemplate/actions.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { vNetworkTemplateService } from 'client/features/One/vnetworkTemplate/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.vntemplate} */
-const VNET_TEMPLATE = 'vntemplate'
-
-export const getVNetworkTemplate = createAction(
- `${VNET_TEMPLATE}/detail`,
- vNetworkTemplateService.getVNetworkTemplate
-)
-
-export const getVNetworkTemplates = createAction(
- `${VNET_TEMPLATE}/pool`,
- vNetworkTemplateService.getVNetworkTemplates,
- (response) => ({ [RESOURCES.vntemplate]: response })
-)
diff --git a/src/fireedge/src/client/features/One/vnetworkTemplate/hooks.js b/src/fireedge/src/client/features/One/vnetworkTemplate/hooks.js
deleted file mode 100644
index 6e395f331c..0000000000
--- a/src/fireedge/src/client/features/One/vnetworkTemplate/hooks.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/vnetworkTemplate/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useVNetworkTemplate = () =>
- useSelector((state) => state[name]?.[RESOURCES.vntemplate] ?? [])
-
-export const useVNetworkTemplateApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getVNetworkTemplate: (id) =>
- unwrapDispatch(actions.getVNetworkTemplate({ id })),
- getVNetworkTemplates: () => unwrapDispatch(actions.getVNetworkTemplates()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/vnetworkTemplate/services.js b/src/fireedge/src/client/features/One/vnetworkTemplate/services.js
deleted file mode 100644
index 66c48c8fb8..0000000000
--- a/src/fireedge/src/client/features/One/vnetworkTemplate/services.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/vntemplate'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const vNetworkTemplateService = {
- /**
- * Retrieves information for the virtual network template.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Virtual Network Template id
- * @returns {object} Get virtual network template identified by id
- * @throws Fails when response isn't code 200
- */
- getVNetworkTemplate: async ({ id }) => {
- const name = Actions.VNTEMPLATE_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.VNTEMPLATE ?? {}
- },
-
- /**
- * Retrieves information for all or part of th
- * virtual network templates in the pool.
- *
- * @param {object} data - Request params
- * @param {string} data.filter - Filter flag
- * @param {number} data.start - Range start ID
- * @param {number} data.end - Range end ID
- * @returns {Array} List of virtual network templates
- * @throws Fails when response isn't code 200
- */
- getVNetworkTemplates: async ({ filter, start, end }) => {
- const name = Actions.VNTEMPLATE_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ filter, start, end }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.VNTEMPLATE_POOL?.VNTEMPLATE ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/One/vrouter/actions.js b/src/fireedge/src/client/features/One/vrouter/actions.js
deleted file mode 100644
index 1f33ea11bf..0000000000
--- a/src/fireedge/src/client/features/One/vrouter/actions.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { vRouterService } from 'client/features/One/vrouter/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.vrouter} */
-const VROUTER = 'vrouter'
-
-export const getVRouter = createAction(
- `${VROUTER}/detail`,
- vRouterService.getVRouter
-)
-
-export const getVRouters = createAction(
- `${VROUTER}/pool`,
- vRouterService.getVRouters,
- (response) => ({ [RESOURCES.vrouter]: response })
-)
diff --git a/src/fireedge/src/client/features/One/vrouter/hooks.js b/src/fireedge/src/client/features/One/vrouter/hooks.js
deleted file mode 100644
index b15fced304..0000000000
--- a/src/fireedge/src/client/features/One/vrouter/hooks.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/vrouter/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useVRouter = () =>
- useSelector((state) => state[name]?.[RESOURCES.vrouter] ?? [])
-
-export const useVRouterApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getVRouter: (id) => unwrapDispatch(actions.getVRouter({ id })),
- getVRouters: () => unwrapDispatch(actions.getVRouters()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/vrouter/services.js b/src/fireedge/src/client/features/One/vrouter/services.js
deleted file mode 100644
index f5addf3e72..0000000000
--- a/src/fireedge/src/client/features/One/vrouter/services.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/vrouter'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const vRouterService = {
- /**
- * Retrieves information for the virtual router.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Virtual router id
- * @returns {object} Get virtual router identified by id
- * @throws Fails when response isn't code 200
- */
- getVRouter: async ({ id }) => {
- const name = Actions.VROUTER_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.VROUTER ?? {}
- },
-
- /**
- * Retrieves information for all or part of the
- * virtual routers in the pool.
- *
- * @param {object} data - Request params
- * @param {string} data.filter - Filter flag
- * @param {number} data.start - Range start ID
- * @param {number} data.end - Range end ID
- * @returns {Array} List of virtual routers
- * @throws Fails when response isn't code 200
- */
- getVRouters: async ({ filter, start, end }) => {
- const name = Actions.VROUTER_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ filter, start, end }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.VROUTER_POOL?.VROUTER ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/One/zone/actions.js b/src/fireedge/src/client/features/One/zone/actions.js
deleted file mode 100644
index 8cab4e76be..0000000000
--- a/src/fireedge/src/client/features/One/zone/actions.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { createAction } from 'client/features/One/utils'
-import { zoneService } from 'client/features/One/zone/services'
-import { RESOURCES } from 'client/features/One/slice'
-
-/** @see {@link RESOURCES.zone} */
-const ZONE = 'zone'
-
-export const getZone = createAction(`${ZONE}/detail`, zoneService.getZone)
-
-export const getZones = createAction(
- `${ZONE}/pool`,
- zoneService.getZones,
- (response) => ({ [RESOURCES.zone]: response })
-)
diff --git a/src/fireedge/src/client/features/One/zone/hooks.js b/src/fireedge/src/client/features/One/zone/hooks.js
deleted file mode 100644
index 74a03ad82d..0000000000
--- a/src/fireedge/src/client/features/One/zone/hooks.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { unwrapResult } from '@reduxjs/toolkit'
-
-import * as actions from 'client/features/One/zone/actions'
-import { name, RESOURCES } from 'client/features/One/slice'
-
-export const useZone = () =>
- useSelector((state) => state[name]?.[RESOURCES.zone] ?? [])
-
-export const useZoneApi = () => {
- const dispatch = useDispatch()
-
- const unwrapDispatch = useCallback(
- (action) => dispatch(action).then(unwrapResult),
- [dispatch]
- )
-
- return {
- getZone: (id) => unwrapDispatch(actions.getZone({ id })),
- getZones: () => unwrapDispatch(actions.getZones()),
- }
-}
diff --git a/src/fireedge/src/client/features/One/zone/services.js b/src/fireedge/src/client/features/One/zone/services.js
deleted file mode 100644
index 165a9245cf..0000000000
--- a/src/fireedge/src/client/features/One/zone/services.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/zone'
-import { httpCodes } from 'server/utils/constants'
-import { requestConfig, RestClient } from 'client/utils'
-
-export const zoneService = {
- /**
- * Retrieves information for the zone.
- *
- * @param {object} data - Request parameters
- * @param {string} data.id - Zone id
- * @returns {object} Get zone identified by id
- * @throws Fails when response isn't code 200
- */
- getZone: async ({ id }) => {
- const name = Actions.ZONE_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig({ id }, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return res?.data?.ZONE ?? {}
- },
-
- /**
- * Retrieves information for all the zones in the pool.
- *
- * @returns {Array} List of zones
- * @throws Fails when response isn't code 200
- */
- getZones: async () => {
- const name = Actions.ZONE_POOL_INFO
- const command = { name, ...Commands[name] }
- const config = requestConfig(undefined, command)
-
- const res = await RestClient.request(config)
-
- if (!res?.id || res?.id !== httpCodes.ok.id) throw res
-
- return [res?.data?.ZONE_POOL?.ZONE ?? []].flat()
- },
-}
diff --git a/src/fireedge/src/client/features/OneApi/cluster.js b/src/fireedge/src/client/features/OneApi/cluster.js
new file mode 100644
index 0000000000..827c877461
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/cluster.js
@@ -0,0 +1,279 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/cluster'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { Cluster } from 'client/constants'
+
+const { CLUSTER } = ONE_RESOURCES
+
+const clusterApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getClusters: builder.query({
+ /**
+ * Retrieves information for all the clusters in the pool.
+ *
+ * @returns {Cluster[]} List of clusters
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.CLUSTER_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) => [data?.CLUSTER_POOL?.CLUSTER ?? []].flat(),
+ providesTags: [CLUSTER],
+ }),
+ getCluster: builder.query({
+ /**
+ * Retrieves information for the cluster.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - Cluster id
+ * @param {boolean} [params.decrypt] - Optional flag to decrypt contained secrets, valid only for admin
+ * @returns {Cluster} Get cluster identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.CLUSTER_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.CLUSTER ?? {},
+ providesTags: (_, __, { id }) => [{ type: CLUSTER, id }],
+ async onQueryStarted({ id }, { dispatch, queryFulfilled }) {
+ try {
+ const { data: queryVm } = await queryFulfilled
+
+ dispatch(
+ clusterApi.util.updateQueryData(
+ 'getClusters',
+ undefined,
+ (draft) => {
+ const index = draft.findIndex(({ ID }) => +ID === +id)
+ index !== -1 && (draft[index] = queryVm)
+ }
+ )
+ )
+ } catch {}
+ },
+ }),
+ allocateCluster: builder.mutation({
+ /**
+ * Allocates a new cluster in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.name - Name for the new cluster
+ * @returns {number} The allocated cluster id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.CLUSTER_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [CLUSTER],
+ }),
+ removeCluster: builder.mutation({
+ /**
+ * Deletes the given cluster from the pool.
+ *
+ * @param {number|string} id - Cluster id
+ * @returns {number} Cluster id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.CLUSTER_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ invalidatesTags: [CLUSTER],
+ }),
+ updateCluster: builder.mutation({
+ /**
+ * Replaces the cluster template contents.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Cluster id
+ * @param {string} params.template - The new template contents
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} Cluster id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.CLUSTER_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: CLUSTER, id }],
+ }),
+ addHostToCluster: builder.mutation({
+ /**
+ * Adds a host to the given cluster.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - The cluster id
+ * @param {string} params.host - The host id
+ * @returns {number} Cluster id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.CLUSTER_ADDHOST
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: CLUSTER, id }],
+ }),
+ removeHostFromCluster: builder.mutation({
+ /**
+ * Removes a host from the given cluster.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - The cluster id
+ * @param {string} params.host - The host id
+ * @returns {number} Cluster id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.CLUSTER_DELHOST
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: CLUSTER, id }],
+ }),
+ addDatastoreToCluster: builder.mutation({
+ /**
+ * Adds a datastore to the given cluster.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - The cluster id
+ * @param {string} params.datastore - The datastore id
+ * @returns {number} Cluster id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.CLUSTER_ADDDATASTORE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: CLUSTER, id }],
+ }),
+ removeDatastoreFromCluster: builder.mutation({
+ /**
+ * Removes a datastore from the given cluster.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - The cluster id
+ * @param {string} params.datastore - The datastore id
+ * @returns {number} Cluster id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.CLUSTER_DELDATASTORE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: CLUSTER, id }],
+ }),
+ addNetworkToCluster: builder.mutation({
+ /**
+ * Adds a vnet to the given cluster.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - The cluster id
+ * @param {string} params.vnet - The vnet id
+ * @returns {number} Cluster id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.CLUSTER_ADDVNET
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: CLUSTER, id }],
+ }),
+ removeNetworkFromCluster: builder.mutation({
+ /**
+ * Removes a vnet from the given cluster.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - The cluster id
+ * @param {string} params.vnet - The vnet id
+ * @returns {number} Cluster id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.CLUSTER_DELVNET
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: CLUSTER, id }],
+ }),
+ renameCluster: builder.mutation({
+ /**
+ * Renames a cluster.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Cluster id
+ * @param {string} params.name - The new name
+ * @returns {number} Cluster id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.CLUSTER_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: CLUSTER, id }, CLUSTER],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetClustersQuery,
+ useLazyGetClustersQuery,
+ useGetClusterQuery,
+ useLazyGetClusterQuery,
+
+ // Mutations
+ useAllocateClusterMutation,
+ useRemoveClusterMutation,
+ useUpdateClusterMutation,
+ useAddHostToClusterMutation,
+ useRemoveHostFromClusterMutation,
+ useAddDatastoreToClusterMutation,
+ useRemoveDatastoreFromClusterMutation,
+ useAddNetworkToClusterMutation,
+ useRemoveNetworkFromClusterMutation,
+ useRenameClusterMutation,
+} = clusterApi
+
+export default clusterApi
diff --git a/src/fireedge/src/client/features/OneApi/datastore.js b/src/fireedge/src/client/features/OneApi/datastore.js
new file mode 100644
index 0000000000..9476b65905
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/datastore.js
@@ -0,0 +1,234 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/datastore'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { Permission, Datastore } from 'client/constants'
+
+const { DATASTORE } = ONE_RESOURCES
+
+const datastoreApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getDatastores: builder.query({
+ /**
+ * Retrieves information for all or part of the datastores in the pool.
+ *
+ * @returns {Datastore[]} List of datastores
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.DATASTORE_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) =>
+ [data?.DATASTORE_POOL?.DATASTORE ?? []].flat(),
+ providesTags: [DATASTORE],
+ }),
+ getDatastore: builder.query({
+ /**
+ * Retrieves information for the datastore.
+ *
+ * @param {object} params - Request params
+ * @param {string|number} params.id - Datastore id
+ * @param {boolean} [params.decrypt] - Optional flag to decrypt contained secrets, valid only for admin
+ * @returns {Datastore} Get datastore identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.DATASTORE_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.DATASTORE ?? {},
+ invalidatesTags: (_, __, { id }) => [{ type: DATASTORE, id }],
+ }),
+ allocateDatastore: builder.mutation({
+ /**
+ * Allocates a new datastore in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.template - The string containing the template of the resource on syntax XML
+ * @param {number|'-1'} params.cluster - The cluster ID. If it's -1, the default one will be used
+ * @returns {number} The allocated datastore id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.DATASTORE_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [DATASTORE],
+ }),
+ removeDatastore: builder.mutation({
+ /**
+ * Deletes the given datastore from the pool.
+ *
+ * @param {number|string} id - Datastore id
+ * @returns {number} Datastore id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.DATASTORE_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ invalidatesTags: [DATASTORE],
+ }),
+ updateDatastore: builder.mutation({
+ /**
+ * Replaces the datastore contents.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Datastore id
+ * @param {string} params.template - The new template contents
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} Datastore id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.DATASTORE_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: DATASTORE, id }],
+ }),
+ changeDatastorePermissions: builder.mutation({
+ /**
+ * Changes the permission bits of a virtual network.
+ * If set any permission to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual network id
+ * @param {Permission|'-1'} params.ownerUse - User use
+ * @param {Permission|'-1'} params.ownerManage - User manage
+ * @param {Permission|'-1'} params.ownerAdmin - User administrator
+ * @param {Permission|'-1'} params.groupUse - Group use
+ * @param {Permission|'-1'} params.groupManage - Group manage
+ * @param {Permission|'-1'} params.groupAdmin - Group administrator
+ * @param {Permission|'-1'} params.otherUse - Other use
+ * @param {Permission|'-1'} params.otherManage - Other manage
+ * @param {Permission|'-1'} params.otherAdmin - Other administrator
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_CHMOD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: DATASTORE, id }],
+ }),
+ changeDatastoreOwnership: builder.mutation({
+ /**
+ * Changes the ownership of a datastore.
+ * If set to `-1`, the user or group aren't changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Datastore id
+ * @param {number|'-1'} params.user - The user id
+ * @param {number|'-1'} params.group - The group id
+ * @returns {number} Datastore id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.DATASTORE_CHOWN
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: DATASTORE, id }, DATASTORE],
+ }),
+ renameDatastore: builder.mutation({
+ /**
+ * Renames a datastore.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Datastore id
+ * @param {string} params.name - The new name
+ * @returns {number} Datastore id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.DATASTORE_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: DATASTORE, id }, DATASTORE],
+ }),
+ enableDatastore: builder.mutation({
+ /**
+ * Sets the status of the datastore to enabled.
+ *
+ * @param {number|string} id - Datastore id
+ * @returns {number} Datastore id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.DATASTORE_ENABLE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, enable: true }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: DATASTORE, id }, DATASTORE],
+ }),
+ disableDatastore: builder.mutation({
+ /**
+ * Sets the status of the datastore to disabled.
+ *
+ * @param {number|string} id - Datastore id
+ * @returns {number} Datastore id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.DATASTORE_ENABLE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, enable: false }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: DATASTORE, id }, DATASTORE],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetDatastoreQuery,
+ useLazyGetDatastoreQuery,
+ useGetDatastoresQuery,
+ useLazyGetDatastoresQuery,
+
+ // Mutations
+ useAllocateDatastoreMutation,
+ useRemoveDatastoreMutation,
+ useUpdateDatastoreMutation,
+ useChangeDatastorePermissionsMutation,
+ useChangeDatastoreOwnershipMutation,
+ useRenameDatastoreMutation,
+ useEnableDatastoreMutation,
+ useDisableDatastoreMutation,
+} = datastoreApi
+
+export default datastoreApi
diff --git a/src/fireedge/src/client/features/OneApi/group.js b/src/fireedge/src/client/features/OneApi/group.js
new file mode 100644
index 0000000000..c2089a5a92
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/group.js
@@ -0,0 +1,219 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/group'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { Group } from 'client/constants'
+
+const { GROUP } = ONE_RESOURCES
+
+const groupApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getGroups: builder.query({
+ /**
+ * Retrieves information for all the groups in the pool.
+ *
+ * @returns {Group[]} Get list of groups
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.GROUP_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) => [data?.GROUP_POOL?.GROUP ?? []].flat(),
+ providesTags: [GROUP],
+ }),
+ getGroup: builder.query({
+ /**
+ * Retrieves information for the group.
+ *
+ * @param {string|number} id - Group id
+ * @returns {Group} Get group identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.GROUP_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ transformResponse: (data) => data?.GROUP ?? {},
+ invalidatesTags: (_, __, id) => [{ type: GROUP, id }],
+ }),
+ allocateGroup: builder.mutation({
+ /**
+ * Allocates a new group in OpenNebula.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.name - Name for the new group
+ * @returns {number} The allocated Group id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.GROUP_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [GROUP],
+ }),
+ updateGroup: builder.mutation({
+ /**
+ * Replaces the group template contents.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Group id
+ * @param {string} params.template - The new template contents on syntax XML
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} Group id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.GROUP_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: GROUP, id }],
+ }),
+ removeGroup: builder.mutation({
+ /**
+ * Deletes the given group from the pool.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Group id
+ * @returns {number} Group id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.GROUP_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [GROUP],
+ }),
+ addAdminToGroup: builder.mutation({
+ /**
+ * Adds a User to the Group administrators set.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Group id
+ * @param {string|number} params.user - User id
+ * @returns {number} Group id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.GROUP_ADDADMIN
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: GROUP, id }],
+ }),
+ removeAdminFromGroup: builder.mutation({
+ /**
+ * Removes a User from the Group administrators set.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Group id
+ * @param {string|number} params.user - User id
+ * @returns {number} Group id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.GROUP_DELADMIN
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: GROUP, id }],
+ }),
+ getGroupQuota: builder.query({
+ /**
+ * Returns the default group quota limits.
+ *
+ * @returns {string} The quota template contents
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.GROUP_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ }),
+ updateGroupQuota: builder.mutation({
+ /**
+ * Sets the group quota limits.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Group id
+ * @param {string|number} params.template - The new quota template contents on syntax XML
+ * @returns {string} The quota template contents
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.GROUP_QUOTA
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: GROUP, id }],
+ }),
+ updateDefaultGroupQuota: builder.mutation({
+ /**
+ * Updates the default group quota limits.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.template - The new quota template contents on syntax XML
+ * @returns {string} The quota template contents
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.GROUP_QUOTA_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetGroupQuery,
+ useLazyGetGroupQuery,
+ useGetGroupsQuery,
+ useLazyGetGroupsQuery,
+ useGetGroupQuotaQuery,
+ useLazyGetGroupQuotaQuery,
+
+ // Mutations
+ useAllocateGroupMutation,
+ useUpdateGroupMutation,
+ useRemoveGroupMutation,
+ useAddAdminToGroupMutation,
+ useRemoveAdminFromGroupMutation,
+ useUpdateGroupQuotaMutation,
+ useUpdateDefaultGroupQuotaMutation,
+} = groupApi
+
+export default groupApi
diff --git a/src/fireedge/src/client/features/OneApi/host.js b/src/fireedge/src/client/features/OneApi/host.js
new file mode 100644
index 0000000000..e7be460324
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/host.js
@@ -0,0 +1,275 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/host'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { UpdateFromSocket } from 'client/features/OneApi/socket'
+import { Host } from 'client/constants'
+
+const { HOST } = ONE_RESOURCES
+
+const hostApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getHosts: builder.query({
+ /**
+ * Retrieves information for all the hosts in the pool.
+ *
+ * @returns {Host[]} Get list of hosts
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.HOST_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) => [data?.HOST_POOL?.HOST ?? []].flat(),
+ providesTags: [HOST],
+ }),
+ getHost: builder.query({
+ /**
+ * Retrieves information for the host.
+ *
+ * @param {string} id - Host id
+ * @returns {Host} Get host identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.HOST_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ transformResponse: (data) => data?.HOST ?? {},
+ providesTags: (_, __, id) => [{ type: HOST, id }],
+ async onQueryStarted(id, { dispatch, queryFulfilled }) {
+ try {
+ const { data: queryVm } = await queryFulfilled
+
+ dispatch(
+ hostApi.util.updateQueryData('getHosts', undefined, (draft) => {
+ const index = draft.findIndex(({ ID }) => +ID === +id)
+ index !== -1 && (draft[index] = queryVm)
+ })
+ )
+ } catch {}
+ },
+ onCacheEntryAdded: UpdateFromSocket({
+ updateQueryData: (updateFn) =>
+ hostApi.util.updateQueryData('getHosts', undefined, updateFn),
+ resource: HOST.toLowerCase(),
+ }),
+ }),
+ allocateHost: builder.mutation({
+ /**
+ * Allocates a new host in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.hostname - Hostname of the machine we want to add
+ * @param {string} params.imMad
+ * - The name of the information manager (im_mad_name),
+ * this values are taken from the oned.conf with the tag name IM_MAD (name)
+ * @param {string} params.vmmMad
+ * - The name of the virtual machine manager mad name (vmm_mad_name),
+ * this values are taken from the oned.conf with the tag name VM_MAD (name)
+ * @param {string|number} [params.cluster] - The cluster ID
+ * @returns {number} Host id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.HOST_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [HOST],
+ }),
+ updateHost: builder.mutation({
+ /**
+ * Replaces the host’s template contents.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Host id
+ * @param {string} params.template - The new template contents
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} Host id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.HOST_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: HOST, id }],
+ }),
+ removeHost: builder.mutation({
+ /**
+ * Deletes the given host from the pool.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Host id
+ * @returns {number} Host id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.HOST_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [HOST],
+ }),
+ enableHost: builder.mutation({
+ /**
+ * Sets the status of the host to enabled.
+ *
+ * @param {number|string} id - Host id
+ * @returns {number} Host id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.HOST_STATUS
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, status: 0 }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: HOST, id }, HOST],
+ }),
+ disableHost: builder.mutation({
+ /**
+ * Sets the status of the host to disabled.
+ *
+ * @param {number|string} id - Host id
+ * @returns {number} Host id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.HOST_STATUS
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, status: 1 }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: HOST, id }, HOST],
+ }),
+ offlineHost: builder.mutation({
+ /**
+ * Sets the status of the host to offline.
+ *
+ * @param {number|string} id - Host id
+ * @returns {number} Host id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.HOST_STATUS
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, status: 2 }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: HOST, id }, HOST],
+ }),
+ renameHost: builder.mutation({
+ /**
+ * Renames a host.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Host id
+ * @param {string} params.name - New name
+ * @returns {number} Host id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.HOST_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: HOST, id }],
+ async onQueryStarted({ id, name }, { dispatch, queryFulfilled }) {
+ try {
+ await queryFulfilled
+
+ dispatch(
+ hostApi.util.updateQueryData('getHosts', undefined, (draft) => {
+ const host = draft.find(({ ID }) => +ID === +id)
+ host && (host.NAME = name)
+ })
+ )
+ } catch {}
+ },
+ }),
+ getHostMonitoring: builder.query({
+ /**
+ * Returns the host monitoring records.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Host id
+ * @returns {string} The monitoring information string / The error string
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.HOST_MONITORING
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ }),
+ getHostMonitoringPool: builder.query({
+ /**
+ * Returns all the host monitoring records.
+ *
+ * @param {object} params - Request parameters
+ * @param {number|'0'|'-1'} [params.seconds]
+ * - Retrieve monitor records in the last num seconds.
+ * `0`: Only the last record.
+ * `-1`: All records.
+ * @returns {string} The monitoring information string / The error string
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.HOST_POOL_MONITORING
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetHostQuery,
+ useLazyGetHostQuery,
+ useGetHostsQuery,
+ useLazyGetHostsQuery,
+ useGetHostMonitoringQuery,
+ useLazyGetHostMonitoringQuery,
+ useGetHostMonitoringPoolQuery,
+ useLazyGetHostMonitoringPoolQuery,
+
+ // Mutations
+ useAllocateHostMutation,
+ useUpdateHostMutation,
+ useRemoveHostMutation,
+ useEnableHostMutation,
+ useDisableHostMutation,
+ useOfflineHostMutation,
+ useRenameHostMutation,
+} = hostApi
+
+export default hostApi
diff --git a/src/fireedge/src/client/features/OneApi/image.js b/src/fireedge/src/client/features/OneApi/image.js
new file mode 100644
index 0000000000..af4d4354ba
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/image.js
@@ -0,0 +1,401 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/image'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { UpdateFromSocket } from 'client/features/OneApi/socket'
+import {
+ FilterFlag,
+ Image,
+ Permission,
+ IMAGE_TYPES_STR,
+} from 'client/constants'
+
+const { IMAGE } = ONE_RESOURCES
+
+const imageApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getImages: builder.query({
+ /**
+ * Retrieves information for all or part of the images in the pool.
+ *
+ * @param {object} params - Request params
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.start] - Range start ID
+ * @param {number} [params.end] - Range end ID
+ * @returns {Image[]} List of images
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => [data?.IMAGE_POOL?.IMAGE ?? []].flat(),
+ providesTags: [IMAGE],
+ }),
+ getImage: builder.query({
+ /**
+ * Retrieves information for the image.
+ *
+ * @param {object} params - Request params
+ * @param {string|number} params.id - Image id
+ * @param {boolean} [params.decrypt] - Optional flag to decrypt contained secrets, valid only for admin
+ * @returns {Image} Get Image identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.IMAGE ?? {},
+ providesTags: (_, __, { id }) => [{ type: IMAGE, id }],
+ onCacheEntryAdded: ({ id }, endpointProps) =>
+ UpdateFromSocket({
+ updateQueryData: (updateFn) =>
+ imageApi.util.updateQueryData('getImages', undefined, updateFn),
+ resource: IMAGE.toLowerCase(),
+ })(id, endpointProps),
+ }),
+ allocateImage: builder.mutation({
+ /**
+ * Allocates a new image in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.template - A string containing the template of the image on syntax XML
+ * @param {string} params.id - The datastore ID
+ * @param {boolean} [params.capacity] - `true` to avoid checking datastore capacity
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [IMAGE],
+ }),
+ cloneImage: builder.mutation({
+ /**
+ * Clones an existing image.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - The id of the image to be cloned
+ * @param {string} params.name - Name for the new image
+ * @param {string|-1} [params.datastore] - The ID of the target datastore
+ * @returns {number} The new image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_CLONE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [IMAGE],
+ }),
+ removeImage: builder.mutation({
+ /**
+ * Deletes the given image from the pool.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - The object id
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [IMAGE],
+ }),
+ enableImage: builder.mutation({
+ /**
+ * Enables an image.
+ *
+ * @param {string} id - Image id
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.IMAGE_ENABLE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, enable: true }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: IMAGE, id }, IMAGE],
+ }),
+ disableImage: builder.mutation({
+ /**
+ * Disables an image.
+ *
+ * @param {string} id - Image id
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.IMAGE_ENABLE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, enable: false }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: IMAGE, id }, IMAGE],
+ }),
+ persistentImage: builder.mutation({
+ /**
+ * Sets the Image as persistent or not persistent.
+ *
+ * @param {number|string} params - Request params
+ * @param {string} params.id - Image id
+ * @param {boolean} params.persistent - `True` for persistent
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_PERSISTENT
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: IMAGE, id }, IMAGE],
+ }),
+ changeImageType: builder.mutation({
+ /**
+ * Changes the type of an Image.
+ *
+ * @param {number|string} params - Request params
+ * @param {string} params.id - Image id
+ * @param {IMAGE_TYPES_STR} params.type - New type for the Image
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_CHTYPE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: IMAGE, id }, IMAGE],
+ }),
+ updateImage: builder.mutation({
+ /**
+ * Replaces the image template contents.
+ *
+ * @param {number|string} params - Request params
+ * @param {string} params.id - Image id
+ * @param {string} params.template - The new template contents on syntax XML
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: IMAGE, id }],
+ }),
+ changeImagePermissions: builder.mutation({
+ /**
+ * Changes the permission bits of a Image.
+ * If set any permission to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Image id
+ * @param {Permission|'-1'} params.ownerUse - User use
+ * @param {Permission|'-1'} params.ownerManage - User manage
+ * @param {Permission|'-1'} params.ownerAdmin - User administrator
+ * @param {Permission|'-1'} params.groupUse - Group use
+ * @param {Permission|'-1'} params.groupManage - Group manage
+ * @param {Permission|'-1'} params.groupAdmin - Group administrator
+ * @param {Permission|'-1'} params.otherUse - Other use
+ * @param {Permission|'-1'} params.otherManage - Other manage
+ * @param {Permission|'-1'} params.otherAdmin - Other administrator
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_CHMOD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: IMAGE, id }],
+ }),
+ changeImageOwnership: builder.mutation({
+ /**
+ * Changes the ownership of a Image.
+ * If set `user` or `group` to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Image id
+ * @param {string|number|'-1'} [params.userId] - User id
+ * @param {Permission|'-1'} [params.groupId] - Group id
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_CHOWN
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: IMAGE, id }, IMAGE],
+ }),
+ renameImage: builder.mutation({
+ /**
+ * Renames a Image.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Image id
+ * @param {string} params.name - The new name
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: IMAGE, id }, IMAGE],
+ }),
+ deleteImageSnapshot: builder.mutation({
+ /**
+ * Deletes a snapshot from the Image.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Image id
+ * @param {string} params.snapshot - ID of the snapshot to delete
+ * @returns {number} Snapshot ID
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_SNAPDEL
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: IMAGE, id }],
+ }),
+ revertImageSnapshot: builder.mutation({
+ /**
+ * Reverts image state to a previous snapshot.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Image id
+ * @param {string} params.snapshot - ID of the snapshot to revert to
+ * @returns {number} Snapshot ID
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_SNAPREV
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: IMAGE, id }],
+ }),
+ flattenImageSnapshot: builder.mutation({
+ /**
+ * Flatten the snapshot of image and discards others.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Image id
+ * @param {string} params.snapshot - ID of the snapshot to revert to
+ * @returns {number} Snapshot ID
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_SNAPFLAT
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: IMAGE, id }],
+ }),
+ lockImage: builder.mutation({
+ /**
+ * Locks an image. Lock certain actions depending on blocking level.
+ * - `USE` (1): locks Admin, Manage and Use actions.
+ * - `MANAGE` (2): locks Manage and Use actions.
+ * - `ADMIN` (3): locks only Admin actions.
+ * - `ALL` (4): locks all actions.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Image id
+ * @param {'1'|'2'|'3'|'4'} params.lock - Lock level
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_LOCK
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: IMAGE, id }, IMAGE],
+ }),
+ unlockImage: builder.mutation({
+ /**
+ * Unlocks an image.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Image id
+ * @returns {number} Image id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.IMAGE_UNLOCK
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: IMAGE, id }, IMAGE],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetImageQuery,
+ useLazyGetImageQuery,
+ useGetImagesQuery,
+ useLazyGetImagesQuery,
+
+ // Mutations
+ useAllocateImageMutation,
+ useCloneImageMutation,
+ useRemoveImageMutation,
+ useEnableImageMutation,
+ useDisableImageMutation,
+ usePersistentImageMutation,
+ useChangeImageTypeMutation,
+ useUpdateImageMutation,
+ useChangeImagePermissionsMutation,
+ useChangeImageOwnershipMutation,
+ useRenameImageMutation,
+ useDeleteImageSnapshotMutation,
+ useRevertImageSnapshotMutation,
+ useFlattenImageSnapshotMutation,
+ useLockImageMutation,
+ useUnlockImageMutation,
+} = imageApi
diff --git a/src/fireedge/src/client/features/OneApi/index.js b/src/fireedge/src/client/features/OneApi/index.js
new file mode 100644
index 0000000000..1b942400b9
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/index.js
@@ -0,0 +1,111 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { createApi } from '@reduxjs/toolkit/query/react'
+
+import { enqueueSnackbar } from 'client/features/General/actions'
+import { logout } from 'client/features/Auth/actions'
+import { httpCodes } from 'server/utils/constants'
+import { requestConfig, generateKey } from 'client/utils'
+import { T } from 'client/constants'
+import http from 'client/utils/rest'
+
+const ONE_RESOURCES = {
+ ACL: 'Acl',
+ APP: 'App',
+ CLUSTER: 'Cluster',
+ DATASTORE: 'Datastore',
+ FILE: 'File',
+ GROUP: 'Group',
+ HOST: 'Host',
+ IMAGE: 'Image',
+ MARKETPLACE: 'Marketplace',
+ SECURITYGROUP: 'SecurityGroup',
+ SYSTEM: 'System',
+ TEMPLATE: 'Template',
+ USER: 'User',
+ VDC: 'Vdc',
+ VM: 'Vm',
+ VMGROUP: 'VmGroup',
+ VNET: 'VNetwork',
+ VNTEMPLATE: 'NetworkTemplate',
+ VROUTER: 'VirtualRouter',
+ ZONE: 'Zone',
+}
+
+const DOCUMENT = {
+ SERVICE: 'applicationService',
+ SERVICE_TEMPLATE: 'applicationServiceTemplate',
+ PROVISION: 'provision',
+ PROVISION_TEMPLATE: 'provisionTemplate',
+ PROVIDER: 'provider',
+ PROVIDER_CONFIG: 'providerConfig',
+ PROVISION_RESOURCES: {
+ CLUSTER: 'provisionCluster',
+ DATASTORE: 'provisionDatastore',
+ HOST: 'provisionHost',
+ TEMPLATE: 'provisionVmTemplate',
+ IMAGE: 'provisionImage',
+ NETWORK: 'provisionVNetwork',
+ VNTEMPLATE: 'provisionNetworkTemplate',
+ FLOWTEMPLATE: 'provisionFlowTemplate',
+ },
+}
+
+const oneApi = createApi({
+ reducerPath: 'oneApi',
+ baseQuery: async ({ params, command }, { dispatch, signal }) => {
+ try {
+ const config = requestConfig(params, command)
+ const response = await http.request({ ...config, signal })
+
+ return { data: response.data ?? {} }
+ } catch (axiosError) {
+ const { message, data, status, statusText } = axiosError
+ const error = message ?? data?.message ?? statusText
+
+ status === httpCodes.unauthorized.id
+ ? dispatch(logout(T.SessionExpired))
+ : dispatch(
+ enqueueSnackbar({
+ key: generateKey(),
+ message: error,
+ options: { variant: 'error' },
+ })
+ )
+
+ return {
+ error: {
+ status: status,
+ data: message ?? data?.data ?? statusText,
+ },
+ }
+ }
+ },
+ refetchOnMountOrArgChange: 30,
+ tagTypes: [
+ ...Object.values(ONE_RESOURCES),
+ DOCUMENT.SERVICE,
+ DOCUMENT.SERVICE_TEMPLATE,
+ DOCUMENT.PROVISION,
+ DOCUMENT.PROVISION_TEMPLATE,
+ DOCUMENT.PROVIDER,
+ DOCUMENT.PROVIDER_CONFIG,
+ ...Object.values(DOCUMENT.PROVISION_RESOURCES),
+ ],
+ endpoints: () => ({}),
+})
+
+export { oneApi, ONE_RESOURCES, DOCUMENT }
diff --git a/src/fireedge/src/client/features/OneApi/marketplace.js b/src/fireedge/src/client/features/OneApi/marketplace.js
new file mode 100644
index 0000000000..94b9d192c2
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/marketplace.js
@@ -0,0 +1,240 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/market'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { Permission, Marketplace } from 'client/constants'
+
+const { MARKETPLACE } = ONE_RESOURCES
+
+const marketplaceApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getMarketplaces: builder.query({
+ /**
+ * Retrieves information for all or part of the marketplaces in the pool.
+ *
+ * @returns {Marketplace[]} List of marketplaces
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.MARKET_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) =>
+ [data?.MARKETPLACE_POOL?.MARKETPLACE ?? []].flat(),
+ providesTags: [MARKETPLACE],
+ }),
+ getMarketplace: builder.query({
+ /**
+ * Retrieves information for the marketplace.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - Marketplace id
+ * @param {boolean} [params.decrypt] - Optional flag to decrypt contained secrets, valid only for admin
+ * @returns {Marketplace} Get marketplace identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKET_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.MARKETPLACE ?? {},
+ providesTags: (_, __, { id }) => [{ type: MARKETPLACE, id }],
+ }),
+ allocateMarketplace: builder.mutation({
+ /**
+ * Allocates a new marketplace in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.template - A string containing the template of the marketplace on syntax XML
+ * @returns {number} Marketplace id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKET_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [MARKETPLACE],
+ }),
+ removeMarketplace: builder.mutation({
+ /**
+ * Deletes the given marketplace from the pool.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - Marketplace id
+ * @returns {number} Marketplace id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKET_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [MARKETPLACE],
+ }),
+ updateMarketplace: builder.mutation({
+ /**
+ * Replaces the marketplace template contents.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Marketplace id
+ * @param {string} params.template - The new template contents
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKET_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ providesTags: (_, __, { id }) => [{ type: MARKETPLACE, id }],
+ }),
+ changeMarketplacePermissions: builder.mutation({
+ /**
+ * Changes the permission bits of a marketplace.
+ * If set any permission to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Marketplace id
+ * @param {Permission|'-1'} params.ownerUse - User use
+ * @param {Permission|'-1'} params.ownerManage - User manage
+ * @param {Permission|'-1'} params.ownerAdmin - User administrator
+ * @param {Permission|'-1'} params.groupUse - Group use
+ * @param {Permission|'-1'} params.groupManage - Group manage
+ * @param {Permission|'-1'} params.groupAdmin - Group administrator
+ * @param {Permission|'-1'} params.otherUse - Other use
+ * @param {Permission|'-1'} params.otherManage - Other manage
+ * @param {Permission|'-1'} params.otherAdmin - Other administrator
+ * @returns {number} Marketplace id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKET_CHMOD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: MARKETPLACE, id }],
+ }),
+ changeMarketplaceOwnership: builder.mutation({
+ /**
+ * Changes the ownership of a marketplace.
+ * If set `user` or `group` to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Marketplace id
+ * @param {string|'-1'} [params.userId] - User id
+ * @param {string|'-1'} [params.groupId] - Group id
+ * @returns {number} Marketplace id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKET_CHOWN
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [
+ { type: MARKETPLACE, id },
+ MARKETPLACE,
+ ],
+ }),
+ renameMarketplace: builder.mutation({
+ /**
+ * Renames a marketplace.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Marketplace id
+ * @param {string} params.name - The new name
+ * @returns {number} Marketplace id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKET_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [
+ { type: MARKETPLACE, id },
+ MARKETPLACE,
+ ],
+ }),
+ enableMarketplace: builder.mutation({
+ /**
+ * Enables a marketplace.
+ *
+ * @param {object} params - Request params
+ * @param {number} params.id - Marketplace id
+ * @returns {number} Marketplace id
+ * @throws Fails when response isn't code 200
+ */
+ query: ({ id }) => {
+ const name = Actions.MARKET_ENABLE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, enable: true }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: MARKETPLACE, id }, MARKETPLACE],
+ }),
+ disableMarketplace: builder.mutation({
+ /**
+ * Disables a marketplace.
+ *
+ * @param {object} params - Request params
+ * @param {number} params.id - Marketplace id
+ * @returns {number} Marketplace id
+ * @throws Fails when response isn't code 200
+ */
+ query: ({ id }) => {
+ const name = Actions.MARKET_ENABLE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, enable: false }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: MARKETPLACE, id }, MARKETPLACE],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetMarketplaceQuery,
+ useLazyGetMarketplaceQuery,
+ useGetMarketplacesQuery,
+ useLazyGetMarketplacesQuery,
+
+ // Mutations
+ useAllocateMarketplaceMutation,
+ useRemoveMarketplaceMutation,
+ useUpdateMarketplaceMutation,
+ useChangeMarketplacePermissionsMutation,
+ useChangeMarketplaceOwnershipMutation,
+ useRenameMarketplaceMutation,
+ useEnableMarketplaceMutation,
+ useDisableMarketplaceMutation,
+} = marketplaceApi
diff --git a/src/fireedge/src/client/features/OneApi/marketplaceApp.js b/src/fireedge/src/client/features/OneApi/marketplaceApp.js
new file mode 100644
index 0000000000..f191dd67ea
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/marketplaceApp.js
@@ -0,0 +1,348 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/marketapp'
+import {
+ Actions as ExtraActions,
+ Commands as ExtraCommands,
+} from 'server/routes/api/marketapp/routes'
+
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { FilterFlag, Permission, MarketplaceApp } from 'client/constants'
+
+const { APP } = ONE_RESOURCES
+
+const marketAppApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getMarketplaceApps: builder.query({
+ /**
+ * Retrieves information for all or part of the
+ * marketplace apps in the pool.
+ *
+ * @param {object} params - Request params
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.start] - Range start ID
+ * @param {number} [params.end] - Range end ID
+ * @returns {MarketplaceApp[]} List of marketplace apps
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKETAPP_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) =>
+ [data?.MARKETPLACEAPP_POOL?.MARKETPLACEAPP ?? []].flat(),
+ providesTags: [APP],
+ }),
+ getMarketplaceApp: builder.query({
+ /**
+ * Retrieves information for the marketplace app.
+ *
+ * @param {string} id - Marketplace apps id
+ * @returns {MarketplaceApp} Get marketplace app identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.MARKETAPP_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ transformResponse: (data) => data?.MARKETPLACEAPP ?? {},
+ providesTags: (_, __, id) => [{ type: APP, id }],
+ }),
+ getDockerHubTags: builder.query({
+ /**
+ * Retrieves DockerHub tags information for marketplace app.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - App id
+ * @param {string} [params.page] - Number of page
+ * @returns {object[]} List of DockerHub tags
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = ExtraActions.MARKETAPP_DOCKERTAGS
+ const command = { name, ...ExtraCommands[name] }
+
+ return { params, command }
+ },
+ }),
+ allocateApp: builder.mutation({
+ /**
+ * Allocates a new marketplace app in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.template - A string containing the template of the marketplace app on syntax XML
+ * @param {string} params.id - The Marketplace ID
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKETAPP_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [APP],
+ }),
+ updateApp: builder.mutation({
+ /**
+ * Replaces the marketplace app template contents.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - Marketplace app id
+ * @param {string} params.template - The new template contents
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKETAPP_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ providesTags: (_, __, { id }) => [{ type: APP, id }],
+ }),
+ removeApp: builder.mutation({
+ /**
+ * Deletes the given marketplace app from the pool.
+ *
+ * @param {string} id - Marketplace app id
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.MARKETAPP_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ providesTags: [APP],
+ }),
+ enableApp: builder.mutation({
+ /**
+ * Enables a marketplace app.
+ *
+ * @param {string} id - Marketplace app id
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.MARKETAPP_ENABLE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, enable: true }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: APP, id }, APP],
+ }),
+ disableApp: builder.mutation({
+ /**
+ * Disables a marketplace app.
+ *
+ * @param {string} id - Marketplace app id
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.MARKETAPP_ENABLE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, enable: false }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: APP, id }, APP],
+ }),
+ changeAppPermissions: builder.mutation({
+ /**
+ * Changes the permission bits of a marketplace app.
+ * If set any permission to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Marketplace app id
+ * @param {Permission|'-1'} params.ownerUse - User use
+ * @param {Permission|'-1'} params.ownerManage - User manage
+ * @param {Permission|'-1'} params.ownerAdmin - User administrator
+ * @param {Permission|'-1'} params.groupUse - Group use
+ * @param {Permission|'-1'} params.groupManage - Group manage
+ * @param {Permission|'-1'} params.groupAdmin - Group administrator
+ * @param {Permission|'-1'} params.otherUse - Other use
+ * @param {Permission|'-1'} params.otherManage - Other manage
+ * @param {Permission|'-1'} params.otherAdmin - Other administrator
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKETAPP_CHMOD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: APP, id }],
+ }),
+ changeAppOwnership: builder.mutation({
+ /**
+ * Changes the ownership of a marketplace app.
+ * If set `user` or `group` to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Marketplace app id
+ * @param {string|'-1'} [params.userId] - User id
+ * @param {string|'-1'} [params.groupId] - Group id
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKETAPP_CHOWN
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: APP, id }, APP],
+ }),
+ renameApp: builder.mutation({
+ /**
+ * Renames a marketplace app.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Marketplace app id
+ * @param {string} params.name - The new name
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKETAPP_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: APP, id }, APP],
+ }),
+ lockApp: builder.mutation({
+ /**
+ * Locks a MarketPlaceApp. Lock certain actions depending on blocking level.
+ * - `USE` (1): locks Admin, Manage and Use actions.
+ * - `MANAGE` (2): locks Manage and Use actions.
+ * - `ADMIN` (3): locks only Admin actions.
+ * - `ALL` (4): locks all actions.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Marketplace app id
+ * @param {'1'|'2'|'3'|'4'} params.lock - Lock level
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.MARKETAPP_LOCK
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: APP, id }, APP],
+ }),
+ unlockApp: builder.mutation({
+ /**
+ * Unlocks a MarketPlaceApp.
+ *
+ * @param {string} id - Marketplace app id
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.MARKETAPP_UNLOCK
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: APP, id }, APP],
+ }),
+ importApp: builder.mutation({
+ /**
+ * Imports a VM or VM Template into the marketplace.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - VM or VM Template id
+ * @param {'vm'|'vm-template'} params.resource - Type of resource
+ * @param {string} params.marketId - Market to import all objects
+ * @param {boolean} params.associated - If `true`, don't import associated VM templates/images
+ * @param {string} params.vmname - Selects the name for the new VM Template, if the App contains one
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ queryFn: async (params) => {
+ const name = ExtraActions.MARKETAPP_IMPORT
+ const command = { name, ...ExtraCommands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [APP],
+ }),
+ exportApp: builder.mutation({
+ /**
+ * Exports the marketplace app to the OpenNebula cloud.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Marketplace App id
+ * @param {string} params.name - Image name
+ * @param {string} params.datastore - Datastore id or name
+ * @param {string} params.file - File datastore id or name
+ * @param {string} params.tag - DockerHub image tag (default latest)
+ * @param {boolean} params.template - Associate with VM template
+ * @param {boolean} params.associated - If `false`, Do not export associated VM templates/images
+ * @param {string} params.vmname - The name for the new VM Template, if the App contains one
+ * @returns {number} Marketplace app id
+ * @throws Fails when response isn't code 200
+ */
+ query: async (params) => {
+ const name = ExtraActions.MARKETAPP_EXPORT
+ const command = { name, ...ExtraCommands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [APP],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetMarketplaceAppQuery,
+ useLazyGetMarketplaceAppQuery,
+ useGetMarketplaceAppsQuery,
+ useLazyGetMarketplaceAppsQuery,
+ useGetDockerHubTagsQuery,
+ useLazyGetDockerHubTagsQuery,
+
+ // Mutations
+ useAllocateAppMutation,
+ useUpdateAppMutation,
+ useRemoveAppMutation,
+ useEnableAppMutation,
+ useDisableAppMutation,
+ useChangeAppPermissionsMutation,
+ useChangeAppOwnershipMutation,
+ useRenameAppMutation,
+ useLockAppMutation,
+ useUnlockAppMutation,
+ useImportAppMutation,
+ useExportAppMutation,
+} = marketAppApi
+
+export default marketAppApi
diff --git a/src/fireedge/src/client/features/OneApi/network.js b/src/fireedge/src/client/features/OneApi/network.js
new file mode 100644
index 0000000000..705ef3c3af
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/network.js
@@ -0,0 +1,386 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/vn'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import {
+ LockLevel,
+ FilterFlag,
+ Permission,
+ VirtualNetwork,
+} from 'client/constants'
+
+const { VNET } = ONE_RESOURCES
+
+const vNetworkApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getVNetworks: builder.query({
+ /**
+ * Retrieves information for all or part of the virtual networks in the pool.
+ *
+ * @param {object} params - Request params
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.start] - Range start ID
+ * @param {number} [params.end] - Range end ID
+ * @returns {VirtualNetwork[]} List of virtual networks
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => [data?.VNET_POOL?.VNET ?? []].flat(),
+ providesTags: [VNET],
+ }),
+ getVNetwork: builder.query({
+ /**
+ * Retrieves information for the virtual network.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - Virtual network id
+ * @param {boolean} [params.decrypt] - Optional flag to decrypt contained secrets, valid only for admin
+ * @returns {VirtualNetwork} Get Virtual network identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.VNET ?? {},
+ providesTags: (_, __, { id }) => [{ type: VNET, id }],
+ }),
+ allocateVnet: builder.mutation({
+ /**
+ * Allocates a new virtual network in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.template - The string containing the template of the resource on syntax XML
+ * @param {number|'-1'} params.cluster - The cluster ID. If it's -1, the default one will be used
+ * @returns {number} The allocated virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [VNET],
+ }),
+ removeVNet: builder.mutation({
+ /**
+ * Deletes the given virtual network from the pool.
+ *
+ * @param {number|string} id - Virtual network id
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.VN_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ invalidatesTags: [VNET],
+ }),
+ addRangeToVNet: builder.mutation({
+ /**
+ * Adds address ranges to a virtual network.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Virtual network id
+ * @param {string} params.template - Template of the address ranges to add on syntax XML
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_AR_ADD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }, VNET],
+ }),
+ removeRangeFromVNet: builder.mutation({
+ /**
+ * Removes an address range from a virtual network.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Virtual network id
+ * @param {number|string} params.address - ID of the address range to remove
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_AR_RM
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }, VNET],
+ }),
+ updateVNetRange: builder.mutation({
+ /**
+ * Updates the attributes of an address range.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Virtual network id
+ * @param {string} params.template - Template of the address ranges to update on syntax XML
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_AR_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }, VNET],
+ }),
+ reserveAddress: builder.mutation({
+ /**
+ * Reserve network addresses.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Virtual network id
+ * @param {string} params.template - The third parameter must be
+ * an OpenNebula ATTRIBUTE=VALUE template, with these values:
+ * - `SIZE`: Size of the reservation (**Mandatory**)
+ * - `NAME`: If set, the reservation will be created in a new Virtual Network with this name
+ * - `AR_ID`: ID of the AR from where to take the addresses
+ * - `NETWORK_ID`: Instead of creating a new Virtual Network,
+ * the reservation will be added to the existing virtual network with this ID
+ * - `MAC`: First MAC address to start the reservation range [MAC, MAC+SIZE)
+ * - `IP`: First IPv4 address to start the reservation range [IP, IP+SIZE)
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_RESERVE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }],
+ }),
+ freeReservedAR: builder.mutation({
+ /**
+ * Frees a reserved address range from a virtual network.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Virtual network id
+ * @param {string} params.range - ID of the address range to free
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_AR_FREE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }, VNET],
+ }),
+ holdLease: builder.mutation({
+ /**
+ * Holds a virtual network Lease as used.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Virtual network id
+ * @param {string} params.template - Template of the lease to hold, e.g. `LEASES=[IP=192.168.0.5]`
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_HOLD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }],
+ }),
+ releaseLease: builder.mutation({
+ /**
+ * Releases a virtual network Lease on hold.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Virtual network id
+ * @param {string} params.template - Template of the lease to hold, e.g. `LEASES=[IP=192.168.0.5]`
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_RELEASE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }],
+ }),
+ updateVNet: builder.mutation({
+ /**
+ * Replaces the virtual network template contents.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Virtual network id
+ * @param {string} params.template - The new template contents
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }],
+ }),
+ changeVNetPermissions: builder.mutation({
+ /**
+ * Changes the permission bits of a virtual network.
+ * If set any permission to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual network id
+ * @param {Permission|'-1'} params.ownerUse - User use
+ * @param {Permission|'-1'} params.ownerManage - User manage
+ * @param {Permission|'-1'} params.ownerAdmin - User administrator
+ * @param {Permission|'-1'} params.groupUse - Group use
+ * @param {Permission|'-1'} params.groupManage - Group manage
+ * @param {Permission|'-1'} params.groupAdmin - Group administrator
+ * @param {Permission|'-1'} params.otherUse - Other use
+ * @param {Permission|'-1'} params.otherManage - Other manage
+ * @param {Permission|'-1'} params.otherAdmin - Other administrator
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_CHMOD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }],
+ }),
+ changeVNetOwnership: builder.mutation({
+ /**
+ * Changes the ownership of a virtual network.
+ * If set to `-1`, the user or group aren't changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual network id
+ * @param {number|'-1'} params.user - The user id
+ * @param {number|'-1'} params.group - The group id
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_CHOWN
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }, VNET],
+ }),
+ renameVNet: builder.mutation({
+ /**
+ * Renames a virtual network.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual network id
+ * @param {string} params.name - The new name
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }, VNET],
+ }),
+ lockVNet: builder.mutation({
+ /**
+ * Locks a virtual network.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual network id
+ * @param {LockLevel} params.lock - Lock level
+ * @param {boolean} params.test - Checks if the object is already locked to return an error
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VN_LOCK
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }, VNET],
+ }),
+ unlockVNet: builder.mutation({
+ /**
+ * Unlocks a virtual network.
+ *
+ * @param {string|number} id - Virtual network id
+ * @returns {number} Virtual network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.VN_UNLOCK
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNET, id }, VNET],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetVNetworksQuery,
+ useLazyGetVNetworksQuery,
+ useGetVNetworkQuery,
+ useLazyGetVNetworkQuery,
+
+ // Mutations
+ useAllocateVnetMutation,
+ useRemoveVNetMutation,
+ useAddRangeToVNetMutation,
+ useRemoveRangeFromVNetMutation,
+ useUpdateVNetRangeMutation,
+ useReserveAddressMutation,
+ useFreeReservedARMutation,
+ useHoldLeaseMutation,
+ useReleaseLeaseMutation,
+ useUpdateVNetMutation,
+ useChangeVNetPermissionsMutation,
+ useChangeVNetOwnershipMutation,
+ useRenameVNetMutation,
+ useLockVNetMutation,
+ useUnlockVNetMutation,
+} = vNetworkApi
+
+export default vNetworkApi
diff --git a/src/fireedge/src/client/features/OneApi/networkTemplate.js b/src/fireedge/src/client/features/OneApi/networkTemplate.js
new file mode 100644
index 0000000000..0a5d3e5021
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/networkTemplate.js
@@ -0,0 +1,294 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/vntemplate'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { FilterFlag, Permission, VNetworkTemplate } from 'client/constants'
+
+const { VNET, VNTEMPLATE } = ONE_RESOURCES
+
+const vNetworkTemplateApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getVNTemplates: builder.query({
+ /**
+ * Retrieves information for all or part of the VN template in the pool.
+ *
+ * @param {object} params - Request params
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.start] - Range start ID
+ * @param {number} [params.end] - Range end ID
+ * @returns {VNetworkTemplate[]} List of virtual network templates
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) =>
+ [data?.VNTEMPLATE_POOL?.VNTEMPLATE ?? []].flat(),
+ providesTags: [VNTEMPLATE],
+ }),
+ getVNTemplate: builder.query({
+ /**
+ * Retrieves information for the virtual network template.
+ *
+ * @param {object} params - Request params
+ * @param {string|number} params.id - Virtual network template id
+ * @param {boolean} [params.decrypt] - Optional flag to decrypt contained secrets, valid only for admin
+ * @returns {VNetworkTemplate} Get virtual network template identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.VNTEMPLATE ?? {},
+ providesTags: (_, __, { id }) => [{ type: VNTEMPLATE, id }],
+ }),
+ allocateVNTemplate: builder.mutation({
+ /**
+ * Allocates a new VN Template in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.template - A string containing the template of the VN Template on syntax XML
+ * @returns {number} VN Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [VNTEMPLATE],
+ }),
+ cloneVNTemplate: builder.mutation({
+ /**
+ * Clones an existing VN template.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - The ID of the VN template to be cloned
+ * @param {string} params.name - Name for the new resource
+ * @returns {number} VN Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_CLONE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [VNTEMPLATE],
+ }),
+ removeVNTemplate: builder.mutation({
+ /**
+ * Deletes the given VN template from the pool.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - The ID of the VN template
+ * @returns {number} VN Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [VNTEMPLATE],
+ }),
+ instantiateVNTemplate: builder.mutation({
+ /**
+ * Instantiates a new Virtual Network from a VN template.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - The object id
+ * @param {string} [params.name] - Name for the new Virtual Network
+ * @param {string} [params.template]
+ * - A string containing an extra VN template
+ * to be merged with the one being instantiated on syntax XML
+ * @returns {number} The new Virtual Network id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_INSTANTIATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [VNET],
+ }),
+ updateVNTemplate: builder.mutation({
+ /**
+ * Replaces the VN Template template contents.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - VN Template id
+ * @param {string} params.template - The new template contents
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} VN Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ providesTags: (_, __, { id }) => [{ type: VNTEMPLATE, id }],
+ }),
+ changeVNTemplatePermissions: builder.mutation({
+ /**
+ * Changes the permission bits of a VN Template.
+ * If set any permission to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - VN Template id
+ * @param {Permission|'-1'} params.ownerUse - User use
+ * @param {Permission|'-1'} params.ownerManage - User manage
+ * @param {Permission|'-1'} params.ownerAdmin - User administrator
+ * @param {Permission|'-1'} params.groupUse - Group use
+ * @param {Permission|'-1'} params.groupManage - Group manage
+ * @param {Permission|'-1'} params.groupAdmin - Group administrator
+ * @param {Permission|'-1'} params.otherUse - Other use
+ * @param {Permission|'-1'} params.otherManage - Other manage
+ * @param {Permission|'-1'} params.otherAdmin - Other administrator
+ * @returns {number} VN Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_CHMOD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VNTEMPLATE, id }],
+ }),
+ changeVNTemplateOwnership: builder.mutation({
+ /**
+ * Changes the ownership of a VN Template.
+ * If set `user` or `group` to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - VN Template id
+ * @param {string|number|'-1'} [params.userId] - User id
+ * @param {Permission|'-1'} [params.groupId] - Group id
+ * @returns {number} VN Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_CHOWN
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [
+ { type: VNTEMPLATE, id },
+ VNTEMPLATE,
+ ],
+ }),
+ renameVNTemplate: builder.mutation({
+ /**
+ * Renames a VN Template.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - VN Template id
+ * @param {string} params.name - The new name
+ * @returns {number} VN Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [
+ { type: VNTEMPLATE, id },
+ VNTEMPLATE,
+ ],
+ }),
+ lockVNTemplate: builder.mutation({
+ /**
+ * Locks a VN Template. Lock certain actions depending on blocking level.
+ * - `USE` (1): locks Admin, Manage and Use actions.
+ * - `MANAGE` (2): locks Manage and Use actions.
+ * - `ADMIN` (3): locks only Admin actions.
+ * - `ALL` (4): locks all actions.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - VN Template id
+ * @param {'1'|'2'|'3'|'4'} params.lock - Lock level
+ * @returns {number} VN Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VNTEMPLATE_LOCK
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [
+ { type: VNTEMPLATE, id },
+ VNTEMPLATE,
+ ],
+ }),
+ unlockVNTemplate: builder.mutation({
+ /**
+ * Unlocks a VN Template.
+ *
+ * @param {string|number} id - VN Template id
+ * @returns {number} VN Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.VNTEMPLATE_UNLOCK
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: VNTEMPLATE, id }, VNTEMPLATE],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetVNTemplateQuery,
+ useLazyGetVNTemplateQuery,
+ useGetVNTemplatesQuery,
+ useLazyGetVNTemplatesQuery,
+
+ // Mutations
+ useAllocateVNTemplateMutation,
+ useCloneVNTemplateMutation,
+ useRemoveVNTemplateMutation,
+ useInstantiateVNTemplateMutation,
+ useUpdateVNTemplateMutation,
+ useChangeVNTemplatePermissionsMutation,
+ useChangeVNTemplateOwnershipMutation,
+ useRenameVNTemplateMutation,
+ useLockVNTemplateMutation,
+ useUnlockVNTemplateMutation,
+} = vNetworkTemplateApi
+
+export default vNetworkTemplateApi
diff --git a/src/fireedge/src/client/features/OneApi/provider.js b/src/fireedge/src/client/features/OneApi/provider.js
new file mode 100644
index 0000000000..9cab558df8
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/provider.js
@@ -0,0 +1,178 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 {
+ Actions,
+ Commands,
+} from 'server/routes/api/oneprovision/provider/routes'
+import { oneApi, DOCUMENT } from 'client/features/OneApi'
+
+const { PROVIDER, PROVIDER_CONFIG } = DOCUMENT
+
+const providerApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getProviderConfig: builder.query({
+ /**
+ * Gets provider configuration.
+ *
+ * @returns {object} Configuration
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.PROVIDER_CONFIG
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ providesTags: [PROVIDER_CONFIG],
+ }),
+ getProviders: builder.query({
+ /**
+ * Retrieves information for all providers.
+ *
+ * @returns {object[]} List of providers
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.PROVIDER_LIST
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) => [data?.DOCUMENT_POOL?.DOCUMENT ?? []].flat(),
+ providesTags: [PROVIDER],
+ }),
+ getProvider: builder.query({
+ /**
+ * Retrieves information for the provider.
+ *
+ * @param {string} id - Provider id
+ * @returns {object} Get provider identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.PROVIDER_LIST
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ transformResponse: (data) => data?.DOCUMENT ?? {},
+ providesTags: (_, __, id) => [{ type: PROVIDER, id }],
+ async onQueryStarted(id, { dispatch, queryFulfilled }) {
+ try {
+ const { data: queryProvider } = await queryFulfilled
+
+ dispatch(
+ providerApi.util.updateQueryData(
+ 'getProviders',
+ undefined,
+ (draft) => {
+ const index = draft.findIndex(({ ID }) => +ID === +id)
+ index !== -1 && (draft[index] = queryProvider)
+ }
+ )
+ )
+ } catch {}
+ },
+ }),
+ getProviderConnection: builder.query({
+ /**
+ * Retrieves connection information for the provider.
+ *
+ * @param {string} id - Provider id
+ * @returns {object} Connection info from the provider identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.PROVIDER_CONNECTION
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ keepUnusedDataFor: 5,
+ }),
+ createProvider: builder.mutation({
+ /**
+ * Creates a new provider.
+ *
+ * @param {object} params - Request parameters
+ * @param {object} params.data - Provider configuration
+ * @returns {object} Object of document created
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.PROVIDER_CREATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [PROVIDER],
+ }),
+ updateProvider: builder.mutation({
+ /**
+ * Updates the provider information.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Provider id
+ * @param {string} params.data - Updated data
+ * @returns {object} Object of document updated
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.PROVIDER_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: PROVIDER, id }, PROVIDER],
+ }),
+ deleteProvider: builder.mutation({
+ /**
+ * Deletes the provider.
+ *
+ * @param {object} params - Request parameters
+ * @param {object} params.id - Provider id
+ * @returns {object} Object of document deleted
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.PROVIDER_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [PROVIDER],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetProviderConfigQuery,
+ useLazyGetProviderConfigQuery,
+ useGetProvidersQuery,
+ useLazyGetProvidersQuery,
+ useGetProviderQuery,
+ useLazyGetProviderQuery,
+ useGetProviderConnectionQuery,
+ useLazyGetProviderConnectionQuery,
+
+ // Mutations
+ useCreateProviderMutation,
+ useUpdateProviderMutation,
+ useDeleteProviderMutation,
+} = providerApi
+
+export default providerApi
diff --git a/src/fireedge/src/client/features/OneApi/provision.js b/src/fireedge/src/client/features/OneApi/provision.js
new file mode 100644
index 0000000000..70d959bce1
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/provision.js
@@ -0,0 +1,303 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 {
+ Actions,
+ Commands,
+} from 'server/routes/api/oneprovision/provision/routes'
+import { oneApi, DOCUMENT } from 'client/features/OneApi'
+
+const { PROVISION, PROVISION_TEMPLATE, PROVISION_RESOURCES } = DOCUMENT
+
+const provisionApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getProvisions: builder.query({
+ /**
+ * List all available provisions.
+ *
+ * @returns {object[]} List of provision
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.PROVISION_LIST
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) => [data?.DOCUMENT_POOL?.DOCUMENT ?? []].flat(),
+ providesTags: [PROVISION],
+ }),
+ getProvision: builder.query({
+ /**
+ * Retrieves information for the provision.
+ *
+ * @param {string} id - Provision id
+ * @returns {object} Get provision identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.PROVISION_LIST
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ transformResponse: (data) => data?.DOCUMENT ?? {},
+ providesTags: (_, __, id) => [{ type: PROVISION, id }],
+ async onQueryStarted(id, { dispatch, queryFulfilled }) {
+ try {
+ const { data: queryProvision } = await queryFulfilled
+
+ dispatch(
+ provisionApi.util.updateQueryData(
+ 'getProvisions',
+ undefined,
+ (draft) => {
+ const index = draft.findIndex(({ ID }) => +ID === +id)
+ index !== -1 && (draft[index] = queryProvision)
+ }
+ )
+ )
+ } catch {}
+ },
+ }),
+ getProvisionTemplates: builder.query({
+ /**
+ * Retrieves information for all the provision templates.
+ *
+ * @returns {object[]} List of provision templates
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.PROVISION_DEFAULTS
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ providesTags: [PROVISION_TEMPLATE],
+ }),
+ getProvisionLog: builder.query({
+ /**
+ * Retrieves debug log for the provision.
+ *
+ * @param {string} id - Provision id
+ * @returns {object} Debug log
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.PROVISION_LOGS
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ }),
+ getResource: builder.query({
+ /**
+ * Delete the datastore from the provision.
+ *
+ * @param {object} params - Request parameters
+ * @param {
+ * 'cluster'|'datastore'|'host'|'image'|
+ * 'network'|'template'|'vntemplate'|'flowtemplate'
+ * } params.resource - Resource name
+ * @returns {object[]} List of resources
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.PROVISION_GET_RESOURCE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => {
+ // example: { HOST_POOL: { HOST: [1, 2] } } => [1, 2]
+ const pool = Object.values(data)[0] ?? {}
+ const resources = Object.values(pool)[0] ?? []
+
+ return [resources].flat()
+ },
+ providesTags: (_, __, { id, resource }) => {
+ const provisionResource = PROVISION_RESOURCES[resource.toUpperCase()]
+
+ return [{ type: provisionResource, id }, provisionResource]
+ },
+ }),
+ createProvision: builder.mutation({
+ /**
+ * Provision a new cluster.
+ *
+ * @param {object} params - Request parameters
+ * @param {object} params.data - Provision configuration
+ * @returns {object} Object of document created
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.PROVISION_CREATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [PROVISION],
+ }),
+ configureProvision: builder.mutation({
+ /**
+ * Configure the provision hosts.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Provision id
+ * @returns {object} Object of document updated
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.PROVISION_CONFIGURE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: PROVISION, id }],
+ }),
+ deleteProvision: builder.mutation({
+ /**
+ * Delete the provision and OpenNebula objects.
+ *
+ * @param {object} params - Request parameters
+ * @param {object} params.id - Provision id
+ * @param {boolean} params.force - Force configure to execute
+ * @param {boolean} params.cleanup - Delete all vms and images first, then delete the resources
+ * @returns {object} Object of document deleted
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.PROVISION_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [PROVISION],
+ }),
+ removeResource: builder.mutation({
+ /**
+ * Delete the datastore from the provision.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.provision - Provision id
+ * @param {string} params.id - Resource id
+ * @param {
+ * 'cluster'|'datastore'|'host'|'image'|
+ * 'network'|'template'|'vntemplate'|'flowtemplate'
+ * } params.resource - Resource name
+ * @returns {object} Object of document deleted
+ * @throws Fails when response isn't code 200
+ */
+ query: ({ provision: _, ...params }) => {
+ const name = Actions.PROVISION_DELETE_RESOURCE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { provision, resource }) => [
+ { type: PROVISION, id: provision },
+ PROVISION_RESOURCES[resource.toUpperCase()],
+ ],
+ }),
+ configureHost: builder.mutation({
+ /**
+ * Run configuration on the host.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.provision - Provision id
+ * @param {string} params.id - Host id
+ * @returns {number} - Host id
+ * @throws Fails when response isn't code 200
+ */
+ query: ({ provision: _, ...params }) => {
+ const name = Actions.PROVISION_HOST_CONFIGURE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { provision }) => [
+ { type: PROVISION, id: provision },
+ PROVISION_RESOURCES.HOST,
+ ],
+ }),
+ addHostToProvision: builder.mutation({
+ /**
+ * Provisions and configures a new host or amount of hosts.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Provision id
+ * @param {number} params.amount - Amount of hosts to add to the provision
+ * @returns {string} - Provision id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.PROVISION_ADD_HOST
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [
+ { type: PROVISION, id },
+ PROVISION_RESOURCES.HOST,
+ ],
+ }),
+ addIpToProvision: builder.mutation({
+ /**
+ * Adds more IPs to the provision.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Provision id
+ * @param {number} params.amount - Amount of IPs to add to the provision
+ * @returns {string} - Provision id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.PROVISION_ADD_HOST
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [
+ { type: PROVISION, id },
+ PROVISION_RESOURCES.HOST,
+ ],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetProvisionsQuery,
+ useLazyGetProvisionsQuery,
+ useGetProvisionQuery,
+ useLazyGetProvisionQuery,
+ useGetProvisionTemplatesQuery,
+ useLazyGetProvisionTemplatesQuery,
+ useGetProvisionLogQuery,
+ useLazyGetProvisionLogQuery,
+ useGetResourceQuery,
+ useLazyGetResourceQuery,
+
+ // Mutations
+ useCreateProvisionMutation,
+ useConfigureProvisionMutation,
+ useDeleteProvisionMutation,
+ useRemoveResourceMutation,
+ useConfigureHostMutation,
+ useAddHostToProvisionMutation,
+ useAddIpToProvisionMutation,
+} = provisionApi
+
+export default provisionApi
diff --git a/src/fireedge/src/client/features/OneApi/securityGroup.js b/src/fireedge/src/client/features/OneApi/securityGroup.js
new file mode 100644
index 0000000000..60ab103966
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/securityGroup.js
@@ -0,0 +1,75 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/secgroup'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { FilterFlag } from 'client/constants'
+
+const { SECURITYGROUP } = ONE_RESOURCES
+
+const securityGroupApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getSecGroups: builder.query({
+ /**
+ * Retrieves information for all or part of the security groups in the pool.
+ *
+ * @param {object} params - Request params
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.start] - Range start ID
+ * @param {number} [params.end] - Range end ID
+ * @returns {Array} List of security groups
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.SECGROUP_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) =>
+ [data?.SECURITY_GROUP_POOL?.SECURITY_GROUP ?? []].flat(),
+ providesTags: [SECURITYGROUP],
+ }),
+ getSecGroup: builder.query({
+ /**
+ * Retrieves information for the security group.
+ *
+ * @param {object} params - Request params
+ * @param {string|number} params.id - Security group id
+ * @param {boolean} [params.decrypt] - Optional flag to decrypt contained secrets, valid only for admin
+ * @returns {object} Get security group identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.SECGROUP_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.SECURITY_GROUP ?? {},
+ providesTags: (_, __, { id }) => [{ type: SECURITYGROUP, id }],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetSecGroupQuery,
+ useLazyGetSecGroupQuery,
+ useGetSecGroupsQuery,
+ useLazyGetSecGroupsQuery,
+} = securityGroupApi
+
+export default securityGroupApi
diff --git a/src/fireedge/src/client/features/OneApi/service.js b/src/fireedge/src/client/features/OneApi/service.js
new file mode 100644
index 0000000000..2d8252e86a
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/service.js
@@ -0,0 +1,85 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/routes/api/oneflow/service/routes'
+import { oneApi, DOCUMENT } from 'client/features/OneApi'
+import { Service } from 'client/constants'
+
+const { SERVICE } = DOCUMENT
+
+const serviceApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getServices: builder.query({
+ /**
+ * Retrieves information for all the services in the pool.
+ *
+ * @returns {Service[]} List of services
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.SERVICE_SHOW
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) => [data?.DOCUMENT_POOL?.DOCUMENT ?? []].flat(),
+ providesTags: [SERVICE],
+ }),
+ getService: builder.query({
+ /**
+ * Retrieves information for the service.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - Service id
+ * @returns {Service} Get service identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.SERVICE_SHOW
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.DOCUMENT ?? {},
+ providesTags: (_, __, { id }) => [{ type: SERVICE, id }],
+ async onQueryStarted({ id }, { dispatch, queryFulfilled }) {
+ try {
+ const { data: queryService } = await queryFulfilled
+
+ dispatch(
+ serviceApi.util.updateQueryData(
+ 'getServices',
+ undefined,
+ (draft) => {
+ const index = draft.findIndex(({ ID }) => +ID === +id)
+ index !== -1 && (draft[index] = queryService)
+ }
+ )
+ )
+ } catch {}
+ },
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetServicesQuery,
+ useLazyGetServicesQuery,
+ useGetServiceQuery,
+ useLazyGetServiceQuery,
+} = serviceApi
+
+export default serviceApi
diff --git a/src/fireedge/src/client/features/OneApi/serviceTemplate.js b/src/fireedge/src/client/features/OneApi/serviceTemplate.js
new file mode 100644
index 0000000000..58098690ae
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/serviceTemplate.js
@@ -0,0 +1,171 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/routes/api/oneflow/template/routes'
+import { oneApi, DOCUMENT } from 'client/features/OneApi'
+import { ServiceTemplate } from 'client/constants'
+
+const { SERVICE, SERVICE_TEMPLATE } = DOCUMENT
+
+const serviceTemplateApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getServiceTemplates: builder.query({
+ /**
+ * Retrieves information for all the service templates in the pool.
+ *
+ * @returns {ServiceTemplate[]} List of service templates
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.SERVICE_TEMPLATE_SHOW
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) => [data?.DOCUMENT_POOL?.DOCUMENT ?? []].flat(),
+ providesTags: [SERVICE_TEMPLATE],
+ }),
+ getServiceTemplate: builder.query({
+ /**
+ * Retrieves information for the service template.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - Service template id
+ * @returns {ServiceTemplate} Get service template identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.SERVICE_TEMPLATE_SHOW
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.DOCUMENT ?? {},
+ providesTags: (_, __, { id }) => [{ type: SERVICE_TEMPLATE, id }],
+ async onQueryStarted({ id }, { dispatch, queryFulfilled }) {
+ try {
+ const { data: queryService } = await queryFulfilled
+
+ dispatch(
+ serviceTemplateApi.util.updateQueryData(
+ 'getServiceTemplates',
+ undefined,
+ (draft) => {
+ const index = draft.findIndex(({ ID }) => +ID === +id)
+ index !== -1 && (draft[index] = queryService)
+ }
+ )
+ )
+ } catch {}
+ },
+ }),
+ createServiceTemplate: builder.mutation({
+ /**
+ * Create a new service template.
+ *
+ * @param {object} params - Request params
+ * @param {object} params.template - Service template data in JSON syntax
+ * @returns {number} Service template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.SERVICE_TEMPLATE_CREATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ providesTags: [SERVICE_TEMPLATE],
+ }),
+ updateServiceTemplate: builder.mutation({
+ /**
+ * Updates the service template contents.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - Service template id
+ * @param {object} [params.template] - Service template data
+ * @returns {number} Service template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.SERVICE_TEMPLATE_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ providesTags: (_, __, { id }) => [{ type: SERVICE_TEMPLATE, id }],
+ }),
+ removeServiceTemplate: builder.mutation({
+ /**
+ * Removes a given service template.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - Service template id
+ * @returns {number} Service template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.SERVICE_TEMPLATE_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ providesTags: [SERVICE_TEMPLATE],
+ }),
+ instantiateServiceTemplate: builder.mutation({
+ /**
+ * Perform instantiate action on the service template.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.id - Service template id
+ * @param {object} params.template - Additional parameters to be passed inside `params`
+ * @returns {number} Service id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ /*
+ data: {
+ action: {
+ perform: 'instantiate',
+ params: { merge_template: data },
+ },
+ },
+ method: PUT,
+ url: `/api/${SERVICE_TEMPLATE}/action/${id}`,
+ */
+ const name = Actions.SERVICE_TEMPLATE_ACTION
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ providesTags: [SERVICE],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetServiceTemplatesQuery,
+ useLazyGetServiceTemplatesQuery,
+ useGetServiceTemplateQuery,
+ useLazyGetServiceTemplateQuery,
+
+ // Mutations
+ useCreateServiceTemplateMutation,
+ useUpdateServiceTemplateMutation,
+ useRemoveServiceTemplateMutation,
+ useInstantiateServiceTemplateMutation,
+} = serviceTemplateApi
+
+export default serviceTemplateApi
diff --git a/src/fireedge/src/client/features/OneApi/socket.js b/src/fireedge/src/client/features/OneApi/socket.js
new file mode 100644
index 0000000000..0a0226194b
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/socket.js
@@ -0,0 +1,118 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { ThunkDispatch } from 'redux-thunk'
+import socketIO, { Socket } from 'socket.io-client'
+import { WEBSOCKET_URL, SOCKETS } from 'client/constants'
+
+/**
+ * @typedef {object} HookStateData - Event data from hook event STATE
+ * @property {HookStateMessage} HOOK_MESSAGE - Hook message from OpenNebula API
+ */
+
+/**
+ * @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 {string} STATE - The state that triggers the hook.
+ * @property {string} [LCM_STATE]
+ * - The LCM state that triggers the hook (Only for VM hooks)
+ * @property {string} [REMOTE_HOST]
+ * - If ``yes`` the hook will be executed in the host that triggered
+ * the hook (for Host hooks) or in the host where the VM is running (for VM hooks).
+ * Not used for Image hooks.
+ * @property {string} RESOURCE_ID - ID of resource
+ * @property {object} [VM] - New data of the VM
+ * @property {object} [HOST] - New data of the HOST
+ * @property {object} [IMAGE] - New data of the IMAGE
+ */
+
+/**
+ * Creates a socket.
+ *
+ * @param {Socket} path - The path to get our client file from
+ * @param {Socket} query - Any query parameters in our uri
+ * @returns {Socket} Socket
+ */
+const createWebsocket = (path, query) =>
+ socketIO({
+ path: `${WEBSOCKET_URL}/${path}`,
+ query,
+ autoConnect: false,
+ timeout: 10_000,
+ reconnectionAttempts: 5,
+ })
+
+/**
+ * @param {HookStateData} data - Event data from hook event STATE
+ * @returns {{name: ('vm'|'host'|'image'), value: object}}
+ * - Name and new value of resource
+ */
+const getResourceFromEventState = (data) => {
+ const { HOOK_OBJECT: name, [name]: value } = data?.HOOK_MESSAGE ?? {}
+
+ return { name: String(name).toLowerCase(), value }
+}
+
+/**
+ * Creates a function to update the data from socket.
+ *
+ * @param {object} params - Parameters
+ * @param {Function(Function)} params.updateQueryData - Api
+ * @param {string} params.resource - Resource name
+ * @returns {function(
+ * string,
+ * { dispatch: ThunkDispatch }
+ * ):Promise} Function to update data from socket
+ */
+const UpdateFromSocket =
+ ({ updateQueryData, resource }) =>
+ async (
+ id,
+ { cacheEntryRemoved, cacheDataLoaded, updateCachedData, getState, dispatch }
+ ) => {
+ const { zone } = getState().general
+ const { jwt: token } = getState().auth
+
+ const query = { token, zone, resource: resource.toLowerCase(), id }
+ const socket = createWebsocket(SOCKETS.HOOKS, query)
+
+ try {
+ await cacheDataLoaded
+
+ const listener = ({ data } = {}) => {
+ const { value } = getResourceFromEventState(data)
+ if (!value) return
+
+ dispatch(
+ updateQueryData((draft) => {
+ const index = draft.findIndex(({ ID }) => +ID === +id)
+ index !== -1 && (draft[index] = value)
+ })
+ )
+
+ updateCachedData((draft) => {
+ Object.assign(draft, value)
+ })
+ }
+
+ socket.on(SOCKETS.HOOKS, listener)
+ socket.open()
+ } catch {}
+ await cacheEntryRemoved
+ socket.close()
+ }
+
+export { createWebsocket, UpdateFromSocket }
diff --git a/src/fireedge/src/client/features/OneApi/system.js b/src/fireedge/src/client/features/OneApi/system.js
new file mode 100644
index 0000000000..39b47657b4
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/system.js
@@ -0,0 +1,113 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/system'
+import {
+ Actions as SunstoneActions,
+ Commands as SunstoneCommands,
+} from 'server/routes/api/sunstone/routes'
+import { changeView } from 'client/features/Auth/actions'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+
+const { SYSTEM } = ONE_RESOURCES
+
+const systemApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getOneVersion: builder.query({
+ /**
+ * Returns the OpenNebula core version.
+ *
+ * @returns {object} The OpenNebula version
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.SYSTEM_VERSION
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ providesTags: [{ type: SYSTEM, id: 'version' }],
+ keepUnusedDataFor: 600,
+ }),
+ getOneConfig: builder.query({
+ /**
+ * Returns the OpenNebula configuration.
+ *
+ * @returns {object} The loaded oned.conf file
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.SYSTEM_CONFIG
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ providesTags: [{ type: SYSTEM, id: 'config' }],
+ keepUnusedDataFor: 600,
+ }),
+ getSunstoneConfig: builder.query({
+ /**
+ * Returns the Sunstone configuration.
+ *
+ * @returns {object} The loaded sunstone-server.conf file
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = SunstoneActions.SUNSTONE_CONFIG
+ const command = { name, ...SunstoneCommands[name] }
+
+ return { command }
+ },
+ providesTags: [{ type: SYSTEM, id: 'sunstone-config' }],
+ keepUnusedDataFor: 600,
+ }),
+ getSunstoneViews: builder.query({
+ /**
+ * Returns the Sunstone configuration for resource tabs.
+ *
+ * @returns {object} The loaded sunstone view files
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = SunstoneActions.SUNSTONE_VIEWS
+ const command = { name, ...SunstoneCommands[name] }
+
+ return { command }
+ },
+ async onQueryStarted(_, { dispatch, queryFulfilled }) {
+ try {
+ const { data: views = {} } = await queryFulfilled
+ dispatch(changeView(Object.keys(views)[0]))
+ } catch {}
+ },
+ providesTags: [{ type: SYSTEM, id: 'sunstone-views' }],
+ keepUnusedDataFor: 600,
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetOneVersionQuery,
+ useLazyGetOneVersionQuery,
+ useGetOneConfigQuery,
+ useLazyGetOneConfigQuery,
+ useGetSunstoneConfigQuery,
+ useLazyGetSunstoneConfigQuery,
+ useGetSunstoneViewsQuery,
+ useLazyGetSunstoneViewsQuery,
+} = systemApi
+
+export default systemApi
diff --git a/src/fireedge/src/client/features/OneApi/user.js b/src/fireedge/src/client/features/OneApi/user.js
new file mode 100644
index 0000000000..6b9cc6ca53
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/user.js
@@ -0,0 +1,330 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/user'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { User } from 'client/constants'
+
+const { USER } = ONE_RESOURCES
+
+const userApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getUsers: builder.query({
+ /**
+ * Retrieves information for all the users in the pool.
+ *
+ * @returns {User[]} List of users
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.USER_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) => [data?.USER_POOL?.USER ?? []].flat(),
+ providesTags: [USER],
+ }),
+ getUser: builder.query({
+ /**
+ * Retrieves information for the user.
+ *
+ * @param {string} id - User id
+ * @returns {User} Get user identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.USER_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ transformResponse: (data) => data?.USER ?? {},
+ providesTags: (_, __, id) => [{ type: USER, id }],
+ }),
+ allocateUser: builder.mutation({
+ /**
+ * Allocates a new user in OpenNebula.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.username - Username for the new user
+ * @param {string} params.password - Password for the new user
+ * @param {string} params.driver - Authentication driver for the new user.
+ * If it is an empty string, then the default 'core' is used
+ * @param {string[]} params.group - array of Group IDs.
+ * **The first ID will be used as the main group.**
+ * This array can be empty, in which case the default group will be used
+ * @returns {number} The allocated User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.USER_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [USER],
+ }),
+ updateUser: builder.mutation({
+ /**
+ * Replaces the user template contents.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - User id
+ * @param {string} params.template - The new user template contents on syntax XML
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.USER_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: USER, id }],
+ }),
+ removeUser: builder.mutation({
+ /**
+ * Deletes the given user from the pool.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - User id
+ * @returns {number} User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.USER_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: USER, id }, USER],
+ }),
+ changePassword: builder.mutation({
+ /**
+ * Changes the password for the given user.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - User id
+ * @param {string} params.password - The new password
+ * @returns {number} User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.USER_PASSWD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: USER, id }],
+ }),
+ changeAuthDriver: builder.mutation({
+ /**
+ * Changes the authentication driver and the password for the given user.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - User id
+ * @param {string} params.driver - The new authentication driver
+ * @param {string} [params.password] - The new password.
+ * If it is an empty string, the password is not changed.
+ * @returns {number} User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.USER_CHAUTH
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: USER, id }],
+ }),
+ changeGroup: builder.mutation({
+ /**
+ * Changes the group of the given user.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - User id
+ * @param {string|number} params.group - New group
+ * @returns {number} User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.USER_CHGRP
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: USER, id }],
+ async onQueryStarted({ id, group }, { dispatch, queryFulfilled }) {
+ try {
+ await queryFulfilled
+
+ dispatch(
+ userApi.util.updateQueryData('getUsers', undefined, (draft) => {
+ const user = draft.find(({ ID }) => +ID === +id)
+ user && (user.GID = group)
+ })
+ )
+ } catch {}
+ },
+ }),
+ addToGroup: builder.mutation({
+ /**
+ * Adds the User to a secondary group.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - User id
+ * @param {string|number} params.group - The Group id of the new group
+ * @returns {number} User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.USER_ADDGROUP
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: USER, id }, USER],
+ }),
+ removeFromGroup: builder.mutation({
+ /**
+ * Removes the User from a secondary group.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - User id
+ * @param {string|number} params.group - The Group id
+ * @returns {number} User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.USER_DELGROUP
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: USER, id }, USER],
+ }),
+ enableUser: builder.mutation({
+ /**
+ * Enables a user.
+ *
+ * @param {string|number} id - User id
+ * @returns {number} User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.USER_ENABLE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, enable: false }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: USER, id }, USER],
+ }),
+ disableUser: builder.mutation({
+ /**
+ * Disables a user.
+ *
+ * @param {string|number} id - User id
+ * @returns {number} User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.USER_ENABLE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id, enable: false }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: USER, id }, USER],
+ }),
+ getUserQuota: builder.query({
+ /**
+ * Returns the default user quota limits.
+ *
+ * @returns {string} The quota template contents
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.USER_QUOTA_INFO
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ }),
+ updateUserQuota: builder.mutation({
+ /**
+ * Sets the user quota limits.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - User id
+ * @param {string} params.template - The new quota template contents on syntax XML
+ * @returns {number} User id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.USER_QUOTA
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: USER, id }],
+ }),
+ updateDefaultUserQuota: builder.mutation({
+ /**
+ * Returns the default user quota limits.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.template - The new quota template contents on syntax XML
+ * @returns {string} The quota template contents
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.USER_QUOTA_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetUserQuery,
+ useLazyGetUserQuery,
+ useGetUsersQuery,
+ useLazyGetUsersQuery,
+ useGetUserQuotaQuery,
+ useLazyGetUserQuotaQuery,
+
+ // Mutations
+ useAllocateUserMutation,
+ useUpdateUserMutation,
+ useRemoveUserMutation,
+ useChangePasswordMutation,
+ useChangeAuthDriverMutation,
+ useChangeGroupMutation,
+ useAddToGroupMutation,
+ useRemoveFromGroupMutation,
+ useEnableUserMutation,
+ useDisableUserMutation,
+ useUpdateUserQuotaMutation,
+ useUpdateDefaultUserQuotaMutation,
+} = userApi
+
+export default userApi
diff --git a/src/fireedge/src/client/features/OneApi/vm.js b/src/fireedge/src/client/features/OneApi/vm.js
new file mode 100644
index 0000000000..e7dd27f63c
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/vm.js
@@ -0,0 +1,883 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/vm'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { UpdateFromSocket } from 'client/features/OneApi/socket'
+import http from 'client/utils/rest'
+import {
+ LockLevel,
+ FilterFlag,
+ Permission,
+ VM as VmType,
+} from 'client/constants'
+
+const { VM } = ONE_RESOURCES
+
+const vmApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getVms: builder.query({
+ /**
+ * Retrieves information for all or part of
+ * the VMs in the pool.
+ *
+ * @param {object} params - Request params
+ * @param {boolean} params.extended - Retrieves information for all or part
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.start] - Range start ID
+ * @param {number} [params.end] - Range end ID
+ * @param {number} [params.state] - VM state to filter by
+ * - `-2`: Any state, including DONE
+ * - `-1`: Any state, except DONE
+ * - `0`: INIT
+ * - `1`: PENDING
+ * - `2`: HOLD
+ * - `3`: ACTIVE
+ * - `4`: STOPPED
+ * - `5`: SUSPENDED
+ * - `6`: DONE
+ * - `8`: POWEROFF
+ * - `9`: UNDEPLOYED
+ * - `10`: CLONING
+ * - `11`: CLONING_FAILURE
+ * @param {string} [params.filterByKey] - Filter in KEY=VALUE format
+ * @returns {VmType[]} List of VMs
+ * @throws Fails when response isn't code 200
+ */
+ query: ({ extended = false, ...params } = {}) => {
+ const name = extended
+ ? Actions.VM_POOL_INFO_EXTENDED
+ : Actions.VM_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => [data?.VM_POOL?.VM ?? []].flat(),
+ providesTags: [VM],
+ }),
+ getVm: builder.query({
+ /**
+ * Retrieves information for the virtual machine.
+ *
+ * @param {string} id - VM id
+ * @returns {VmType} Get VM identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.VM_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ transformResponse: (data) => data?.VM ?? {},
+ providesTags: (_, __, id) => [{ type: VM, id }],
+ async onQueryStarted(id, { dispatch, queryFulfilled }) {
+ try {
+ const { data: queryVm } = await queryFulfilled
+
+ dispatch(
+ vmApi.util.updateQueryData('getVms', undefined, (draft) => {
+ const index = draft.findIndex(({ ID }) => +ID === +id)
+ index !== -1 && (draft[index] = queryVm)
+ })
+ )
+ } catch {}
+ },
+ onCacheEntryAdded: UpdateFromSocket({
+ updateQueryData: (updateFn) =>
+ vmApi.util.updateQueryData('getVms', undefined, updateFn),
+ resource: VM.toLowerCase(),
+ }),
+ }),
+ getMonitoring: builder.query({
+ /**
+ * Returns the virtual machine monitoring records.
+ *
+ * @param {string|number} id - Virtual machine id
+ * @returns {string} The monitoring information
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.VM_MONITORING
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ }),
+ getMonitoringPool: builder.query({
+ /**
+ * Returns all the virtual machine monitoring records.
+ *
+ * @param {object} params - Request parameters
+ * @param {FilterFlag} params.filter - Filter flag
+ * @param {number|'0'|'-1'} [params.seconds]
+ * - Retrieve monitor records in the last num seconds
+ * - `0`: Only the last record.
+ * - `-1`: All records.
+ * @returns {string} The monitoring information
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_POOL_MONITORING
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ }),
+ getAccountingPool: builder.query({
+ /**
+ * Returns the virtual machine history records.
+ *
+ * @param {object} params - Request parameters
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.start] - Range start ID
+ * @param {number} [params.end] - Range end ID
+ * @returns {string} The information string
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_POOL_ACCOUNTING
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ }),
+ getShowbackPool: builder.query({
+ /**
+ * Returns the virtual machine showback records.
+ *
+ * @param {object} params - Request parameters
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.startMonth] - First month for the time interval
+ * @param {number} [params.startYear] - First year for the time interval
+ * @param {number} [params.endMonth] - Last month for the time interval
+ * @param {number} [params.endYear] - Last year for the time interval
+ * @returns {string} The information string
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_POOL_SHOWBACK
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ }),
+ calculateShowback: builder.query({
+ /**
+ * Processes all the history records, and stores the monthly cost for each VM.
+ *
+ * @param {object} params - Request parameters
+ * @param {number} [params.startMonth] - First month for the time interval
+ * @param {number} [params.startYear] - First year for the time interval
+ * @param {number} [params.endMonth] - Last month for the time interval
+ * @param {number} [params.endYear] - Last year for the time interval
+ * @returns {''} Empty
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_POOL_CALCULATE_SHOWBACK
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ }),
+ allocateVm: builder.mutation({
+ /**
+ * Allocates a new virtual machine in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.template - A string containing the template of the VM on syntax XML
+ * @param {boolean} [params.status] - False to create the VM on pending (default), True to create it on hold.
+ * @returns {number} VM id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [VM],
+ }),
+ saveAsTemplate: builder.mutation({
+ /**
+ * Clones the VM's source Template, replacing the disks with live snapshots
+ * of the current disks. The VM capacity and NICs are also preserved.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.name - Template name
+ * @param {boolean} params.persistent - Make the new images persistent
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ queryFn: async ({ id, name, persistent }) => {
+ try {
+ const response = await http.request({
+ url: `/api/vm/save/${id}`,
+ method: 'POST',
+ data: { name, persistent },
+ })
+
+ return { data: response.data }
+ } catch (axiosError) {
+ const { response } = axiosError
+
+ return { error: { status: response?.status, data: response?.data } }
+ }
+ },
+ }),
+ deploy: builder.mutation({
+ /**
+ * Initiates the instance of the given VM id on the target host.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.host - The target host id
+ * @param {boolean} [params.enforce] - If `true`, will enforce the Host capacity isn't over committed.
+ * @param {string|number} [params.datastore] - The target datastore id.
+ * It is optional, and can be set to -1 to let OpenNebula choose the datastore
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_DEPLOY
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [VM],
+ }),
+ actionVm: builder.mutation({
+ /**
+ * Submits an action to be performed on a virtual machine.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Virtual machine id
+ * @param {(
+ * 'terminate-hard'|'terminate'|'undeploy-hard'|'undeploy'|
+ * 'poweroff-hard'|'poweroff'|'reboot-hard'|'reboot'|
+ * 'hold'|'release'|'stop'|'suspend'|'resume'|'resched'|'unresched'
+ * )} params.action - The action name to be performed
+ * @returns {Response} Response
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_ACTION
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ migrate: builder.mutation({
+ /**
+ * Migrates one virtual machine to the target host.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.host - The target host id
+ * @param {boolean} [params.live]
+ * - If `true` we are indicating that we want live migration, otherwise `false`.
+ * @param {boolean} params.enforce
+ * - If `true`, will enforce the Host capacity isn't over committed.
+ * @param {string|number} params.datastore - The target datastore id.
+ * It is optional, and can be set to -1 to let OpenNebula choose the datastore
+ * @param {0|1|2} params.type - Migration type: save (0), poweroff (1), poweroff-hard (2)
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_MIGRATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ saveAsDisk: builder.mutation({
+ /**
+ * Sets the disk to be saved in the given image.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.disk - Disk id
+ * @param {string} params.name - Name for the new Image
+ * @param {string} [params.type] - Type for the new Image.
+ * If it is an empty string, then the default one will be used
+ * @param {string|number} params.snapshot - Id of the snapshot to export.
+ * If -1 the current image state will be used.
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_DISK_SAVEAS
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ createDiskSnapshot: builder.mutation({
+ /**
+ * Takes a new snapshot of the disk image.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.disk - Disk id
+ * @param {string} params.name - Name for the snapshot
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_DISK_SNAP_CREATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ deleteDiskSnapshot: builder.mutation({
+ /**
+ * Deletes a disk snapshot.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.disk - Disk id
+ * @param {string|number} params.snapshot - Snapshot id
+ * @returns {number} The id of the snapshot deleted
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_DISK_SNAP_CREATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ revertDiskSnapshot: builder.mutation({
+ /**
+ * Reverts disk state to a previously taken snapshot.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.disk - Disk id
+ * @param {string|number} params.snapshot - Snapshot id
+ * @returns {number} The snapshot id used
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_DISK_SNAP_REVERT
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ renameDiskSnapshot: builder.mutation({
+ /**
+ * Renames a disk snapshot.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.disk - Disk id
+ * @param {string|number} params.snapshot - Snapshot id
+ * @param {string} params.name - New snapshot name
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_DISK_SNAP_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ attachDisk: builder.mutation({
+ /**
+ * Attaches a new disk to the virtual machine.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.template
+ * - A string containing a single DISK vector attribute
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_DISK_ATTACH
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ detachDisk: builder.mutation({
+ /**
+ * Detaches a disk from a virtual machine.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.disk - Disk id
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_DISK_DETACH
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ resizeDisk: builder.mutation({
+ /**
+ * Resizes a disk of a virtual machine.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.disk - Disk id
+ * @param {string} params.size - The new size string
+ * - Options to perform action
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_DISK_RESIZE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ attachNic: builder.mutation({
+ /**
+ * Attaches a new network interface to the virtual machine.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.template
+ * - A string containing a single NIC vector attribute
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_NIC_ATTACH
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ detachNic: builder.mutation({
+ /**
+ * Detaches a network interface from a virtual machine.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.nic - NIC id
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_NIC_DETACH
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ changeVmPermissions: builder.mutation({
+ /**
+ * Changes the permission bits of a virtual machine.
+ * If set any permission to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {Permission|'-1'} params.ownerUse - User use
+ * @param {Permission|'-1'} params.ownerManage - User manage
+ * @param {Permission|'-1'} params.ownerAdmin - User administrator
+ * @param {Permission|'-1'} params.groupUse - Group use
+ * @param {Permission|'-1'} params.groupManage - Group manage
+ * @param {Permission|'-1'} params.groupAdmin - Group administrator
+ * @param {Permission|'-1'} params.otherUse - Other use
+ * @param {Permission|'-1'} params.otherManage - Other manage
+ * @param {Permission|'-1'} params.otherAdmin - Other administrator
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_CHMOD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ changeVmOwnership: builder.mutation({
+ /**
+ * Changes the ownership bits of a virtual machine.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {number} params.user - The user id
+ * @param {number} params.group - The group id
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_CHOWN
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ renameVm: builder.mutation({
+ /**
+ * Renames a virtual machine.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.name - The new name
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ async onQueryStarted({ id, name }, { dispatch, queryFulfilled }) {
+ try {
+ await queryFulfilled
+
+ dispatch(
+ vmApi.util.updateQueryData('getVms', undefined, (draft) => {
+ const vm = draft.find(({ ID }) => +ID === +id)
+ vm && (vm.NAME = name)
+ })
+ )
+ } catch {}
+ },
+ }),
+ createVmSnapshot: builder.mutation({
+ /**
+ * Creates a new virtual machine snapshot.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.name - The new snapshot name
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_SNAP_CREATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ revertVmSnapshot: builder.mutation({
+ /**
+ * Reverts a virtual machine to a snapshot.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.snapshot - The snapshot id
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_SNAP_REVERT
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ deleteVmSnapshot: builder.mutation({
+ /**
+ * Deletes a virtual machine snapshot.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string|number} params.snapshot - The snapshot id
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_SNAP_REVERT
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ resize: builder.mutation({
+ /**
+ * Changes the capacity of the virtual machine.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.template - Template containing the new capacity
+ * @param {boolean} params.enforce - `true` to enforce the Host capacity isn't over committed
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_RESIZE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ updateUserTemplate: builder.mutation({
+ /**
+ * Replaces the user template contents.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.template - The new user template contents on syntax XML
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ updateConfiguration: builder.mutation({
+ /**
+ * Updates (appends) a set of supported configuration attributes in the VM template.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.template - The new configuration contents on syntax XML
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_CONF_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ recover: builder.mutation({
+ /**
+ * Recovers a stuck VM that is waiting for a driver operation.
+ * The recovery may be done by failing or succeeding the pending operation.
+ *
+ * You need to manually check the vm status on the host, to decide
+ * if the operation was successful or not.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {0|1|2|3|4} params.operation - Recover operation:
+ * failure (0), success (1), retry (2), delete (3), delete-recreate (4)
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_RECOVER
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ lockVm: builder.mutation({
+ /**
+ * Locks a Virtual Machine. Lock certain actions depending on blocking level.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {LockLevel} params.level - Lock level
+ * @param {boolean} params.test - Checks if the object is already locked to return an error
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_LOCK
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ async onQueryStarted({ id, level = '4' }, { dispatch, queryFulfilled }) {
+ try {
+ await queryFulfilled
+
+ dispatch(
+ vmApi.util.updateQueryData('getVms', undefined, (draft) => {
+ const vm = draft.find(({ ID }) => +ID === +id)
+ vm && (vm.LOCK = { LOCKED: level })
+ })
+ )
+ } catch {}
+ },
+ }),
+ unlockVm: builder.mutation({
+ /**
+ * Unlocks a Virtual Machine.
+ *
+ * @param {string|number} id - Virtual machine id
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.VM_UNLOCK
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: VM, id }],
+ async onQueryStarted(id, { dispatch, queryFulfilled }) {
+ try {
+ await queryFulfilled
+
+ dispatch(
+ vmApi.util.updateQueryData('getVms', undefined, (draft) => {
+ const vm = draft.find(({ ID }) => +ID === +id)
+ vm && (vm.LOCK = undefined)
+ })
+ )
+ } catch {}
+ },
+ }),
+ addScheduledAction: builder.mutation({
+ /**
+ * Add scheduled action to VM.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.template - Template containing the new scheduled action
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_SCHED_ADD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ updateScheduledAction: builder.mutation({
+ /**
+ * Update scheduled VM action.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.schedId - The ID of the scheduled action
+ * @param {string} params.template - Template containing the updated scheduled action
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_SCHED_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ deleteScheduledAction: builder.mutation({
+ /**
+ * Delete scheduled action from VM.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Virtual machine id
+ * @param {string} params.schedId - The ID of the scheduled action
+ * @returns {number} Virtual machine id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_SCHED_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: VM, id }],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetVmsQuery,
+ useLazyGetVmsQuery,
+ useGetVmQuery,
+ useLazyGetVmQuery,
+ useGetMonitoringQuery,
+ useLazyGetMonitoringQuery,
+ useGetMonitoringPoolQuery,
+ useLazyGetMonitoringPoolQuery,
+ useGetAccountingPoolQuery,
+ useLazyGetAccountingPoolQuery,
+ useGetShowbackPoolQuery,
+ useLazyGetShowbackPoolQuery,
+ useCalculateShowbackQuery,
+ useLazyCalculateShowbackQuery,
+
+ // Mutations
+ useAllocateVmMutation,
+ useSaveAsTemplateMutation,
+ useDeployMutation,
+ useActionVmMutation,
+ useMigrateMutation,
+ useSaveAsDiskMutation,
+ useCreateDiskSnapshotMutation,
+ useDeleteDiskSnapshotMutation,
+ useRevertDiskSnapshotMutation,
+ useRenameDiskSnapshotMutation,
+ useAttachDiskMutation,
+ useDetachDiskMutation,
+ useResizeDiskMutation,
+ useAttachNicMutation,
+ useDetachNicMutation,
+ useChangeVmPermissionsMutation,
+ useChangeVmOwnershipMutation,
+ useRenameVmMutation,
+ useCreateVmSnapshotMutation,
+ useRevertVmSnapshotMutation,
+ useDeleteVmSnapshotMutation,
+ useResizeMutation,
+ useUpdateUserTemplateMutation,
+ useUpdateConfigurationMutation,
+ useRecoverMutation,
+ useLockVmMutation,
+ useUnlockVmMutation,
+ useAddScheduledActionMutation,
+ useUpdateScheduledActionMutation,
+ useDeleteScheduledActionMutation,
+} = vmApi
+
+export default vmApi
diff --git a/src/fireedge/src/client/features/OneApi/vmGroup.js b/src/fireedge/src/client/features/OneApi/vmGroup.js
new file mode 100644
index 0000000000..f4fc100618
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/vmGroup.js
@@ -0,0 +1,75 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/vmgroup'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { FilterFlag } from 'client/constants'
+
+const { VMGROUP } = ONE_RESOURCES
+
+const vmGroupApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getVMGroups: builder.query({
+ /**
+ * Retrieves information for all or part of the VM groups in the pool.
+ *
+ * @param {object} params - Request params
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.start] - Range start ID
+ * @param {number} [params.end] - Range end ID
+ * @returns {Array} List of VM groups
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_GROUP_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => [data?.VM_GROUP_POOL?.VM_GROUP ?? []].flat(),
+ providesTags: (result) =>
+ result
+ ? [...result.map(({ ID }) => ({ type: VMGROUP, ID })), VMGROUP]
+ : [VMGROUP],
+ }),
+ getVMGroup: builder.query({
+ /**
+ * Retrieves information for the VM group.
+ *
+ * @param {object} params - Request params
+ * @param {string|number} params.id - VM group id
+ * @param {boolean} [params.decrypt] - Optional flag to decrypt contained secrets, valid only for admin
+ * @returns {object} Get VM group identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VM_GROUP_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.VM_GROUP ?? {},
+ providesTags: (_, __, arg) => ({ type: VMGROUP, id: arg }),
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetVMGroupsQuery,
+ useLazyGetVMGroupsQuery,
+ useGetVMGroupQuery,
+ useLazyGetVMGroupQuery,
+} = vmGroupApi
diff --git a/src/fireedge/src/client/features/OneApi/vmTemplate.js b/src/fireedge/src/client/features/OneApi/vmTemplate.js
new file mode 100644
index 0000000000..db02a3fa44
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/vmTemplate.js
@@ -0,0 +1,352 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/template'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { LockLevel, FilterFlag, Permission, VmTemplate } from 'client/constants'
+
+const { TEMPLATE, VM } = ONE_RESOURCES
+
+const vmTemplateApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getTemplates: builder.query({
+ /**
+ * Retrieves information for all or part of the Resources in the pool.
+ *
+ * @param {object} params - Request params
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.start] - Range start ID
+ * @param {number} [params.end] - Range end ID
+ * @returns {VmTemplate[]} List of VM Templates
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) =>
+ [data?.VMTEMPLATE_POOL?.VMTEMPLATE ?? []].flat(),
+ providesTags: [TEMPLATE],
+ }),
+ getTemplate: builder.query({
+ /**
+ * Retrieves information for the vm template.
+ *
+ * @param {object} params - Request parameters
+ * @param {string} params.id - Template id
+ * @param {boolean} params.extended - True to include extended information
+ * @param {boolean} [params.decrypt] - True to decrypt contained secrets (only admin)
+ * @returns {VmTemplate} Get template identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.VMTEMPLATE ?? {},
+ providesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
+ async onQueryStarted({ id }, { dispatch, queryFulfilled }) {
+ try {
+ const { data: queryTemplate } = await queryFulfilled
+
+ dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplates',
+ undefined,
+ (draft) => {
+ const index = draft.findIndex(({ ID }) => +ID === +id)
+ index !== -1 && (draft[index] = queryTemplate)
+ }
+ )
+ )
+ } catch {}
+ },
+ }),
+ allocateTemplate: builder.mutation({
+ /**
+ * Allocates a new VM Template in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.template - A string containing the template on syntax XML
+ * @returns {number} VM Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [TEMPLATE],
+ }),
+ cloneTemplate: builder.mutation({
+ /**
+ * Clones an existing virtual machine template.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - The ID of the template to be cloned
+ * @param {string} params.name - Name for the new template
+ * @param {boolean} params.image
+ * - `true` to clone the template plus any image defined in DISK.
+ * The new IMAGE_ID is set into each DISK
+ * @returns {number} Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_CLONE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [TEMPLATE],
+ }),
+ removeTemplate: builder.mutation({
+ /**
+ * Deletes the given template from the pool.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Template id
+ * @param {boolean} params.image - `true` to delete the template plus any image defined in DISK
+ * @returns {number} Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [TEMPLATE],
+ }),
+ instantiateTemplate: builder.mutation({
+ /**
+ * Instantiates a new virtual machine from a template.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Template id
+ * @param {string} params.name - Name for the new VM instance
+ * @param {boolean} params.hold - True to create it on hold state
+ * @param {boolean} params.persistent - True to create a private persistent copy
+ * @param {string} params.template - Extra template to be merged with the one being instantiated
+ * @returns {number} Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_INSTANTIATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [VM],
+ }),
+ updateTemplate: builder.mutation({
+ /**
+ * Replaces the template contents.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Template id
+ * @param {string} params.template - The new template contents
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
+ }),
+ changeTemplatePermissions: builder.mutation({
+ /**
+ * Changes the permission bits of a VM template.
+ * If set any permission to -1, it's not changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - VM Template id
+ * @param {Permission|'-1'} params.ownerUse - User use
+ * @param {Permission|'-1'} params.ownerManage - User manage
+ * @param {Permission|'-1'} params.ownerAdmin - User administrator
+ * @param {Permission|'-1'} params.groupUse - Group use
+ * @param {Permission|'-1'} params.groupManage - Group manage
+ * @param {Permission|'-1'} params.groupAdmin - Group administrator
+ * @param {Permission|'-1'} params.otherUse - Other use
+ * @param {Permission|'-1'} params.otherManage - Other manage
+ * @param {Permission|'-1'} params.otherAdmin - Other administrator
+ * @param {boolean} [params.image] - `true` to chmod the template plus any image defined in DISK
+ * @returns {number} VM Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_CHMOD
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
+ }),
+ changeTemplateOwnership: builder.mutation({
+ /**
+ * Changes the ownership bits of a VM template.
+ * If set to `-1`, the user or group aren't changed.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - VM Template id
+ * @param {number|'-1'} params.user - The user id
+ * @param {number|'-1'} params.group - The group id
+ * @returns {number} VM Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_CHOWN
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
+ }),
+ renameTemplate: builder.mutation({
+ /**
+ * Renames a VM template.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - VM Template id
+ * @param {string} params.name - The new name
+ * @returns {number} VM Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
+ async onQueryStarted({ id, name }, { dispatch, queryFulfilled }) {
+ try {
+ await queryFulfilled
+
+ dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplates',
+ undefined,
+ (draft) => {
+ const template = draft.find(({ ID }) => +ID === +id)
+ template && (template.NAME = name)
+ }
+ )
+ )
+ } catch {}
+ },
+ }),
+ lockTemplate: builder.mutation({
+ /**
+ * Locks a VM Template.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - VM Template id
+ * @param {LockLevel} params.lock - Lock level
+ * @param {boolean} params.test - Checks if the object is already locked to return an error
+ * @returns {number} VM Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.TEMPLATE_LOCK
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: TEMPLATE, id }],
+ async onQueryStarted({ id, level = '4' }, { dispatch, queryFulfilled }) {
+ try {
+ await queryFulfilled
+
+ dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplates',
+ undefined,
+ (draft) => {
+ const template = draft.find(({ ID }) => +ID === +id)
+ template && (template.LOCK = { LOCKED: level })
+ }
+ )
+ )
+ } catch {}
+ },
+ }),
+ unlockTemplate: builder.mutation({
+ /**
+ * Unlocks a VM Template.
+ *
+ * @param {string|number} id - VM Template id
+ * @returns {number} VM Template id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.TEMPLATE_UNLOCK
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ invalidatesTags: (_, __, id) => [{ type: TEMPLATE, id }],
+ async onQueryStarted(id, { dispatch, queryFulfilled }) {
+ try {
+ await queryFulfilled
+
+ dispatch(
+ vmTemplateApi.util.updateQueryData(
+ 'getTemplates',
+ undefined,
+ (draft) => {
+ const template = draft.find(({ ID }) => +ID === +id)
+ template && (template.LOCK = undefined)
+ }
+ )
+ )
+ } catch {}
+ },
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetTemplatesQuery,
+ useLazyGetTemplatesQuery,
+ useGetTemplateQuery,
+ useLazyGetTemplateQuery,
+
+ // Mutations
+ useAllocateTemplateMutation,
+ useCloneTemplateMutation,
+ useRemoveTemplateMutation,
+ useInstantiateTemplateMutation,
+ useUpdateTemplateMutation,
+ useChangeTemplatePermissionsMutation,
+ useChangeTemplateOwnershipMutation,
+ useRenameTemplateMutation,
+ useLockTemplateMutation,
+ useUnlockTemplateMutation,
+} = vmTemplateApi
+
+export default vmTemplateApi
diff --git a/src/fireedge/src/client/features/OneApi/vrouter.js b/src/fireedge/src/client/features/OneApi/vrouter.js
new file mode 100644
index 0000000000..ed4cbe29a5
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/vrouter.js
@@ -0,0 +1,72 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/vrouter'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { FilterFlag } from 'client/constants'
+
+const { VROUTER } = ONE_RESOURCES
+
+const virtualRouterApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getVRouters: builder.query({
+ /**
+ * Retrieves information for all or part of the virtual routers in the pool.
+ *
+ * @param {object} params - Request params
+ * @param {FilterFlag} [params.filter] - Filter flag
+ * @param {number} [params.start] - Range start ID
+ * @param {number} [params.end] - Range end ID
+ * @returns {Array} List of virtual routers
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VROUTER_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => [data?.VROUTER_POOL?.VROUTER ?? []].flat(),
+ providesTags: [VROUTER],
+ }),
+ getVRouter: builder.query({
+ /**
+ * Retrieves information for the virtual router.
+ *
+ * @param {object} params - Request params
+ * @param {string|number} params.id - Virtual router id
+ * @param {boolean} [params.decrypt] - Optional flag to decrypt contained secrets, valid only for admin
+ * @returns {object} Get virtual router identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.VROUTER_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ transformResponse: (data) => data?.VROUTER ?? {},
+ providesTags: (_, __, { id }) => [{ type: VROUTER, id }],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetVRouterQuery,
+ useLazyGetVRouterQuery,
+ useGetVRoutersQuery,
+ useLazyGetVRoutersQuery,
+} = virtualRouterApi
diff --git a/src/fireedge/src/client/features/OneApi/zone.js b/src/fireedge/src/client/features/OneApi/zone.js
new file mode 100644
index 0000000000..0e25ae6415
--- /dev/null
+++ b/src/fireedge/src/client/features/OneApi/zone.js
@@ -0,0 +1,163 @@
+/* ------------------------------------------------------------------------- *
+ * Copyright 2002-2021, 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 { Actions, Commands } from 'server/utils/constants/commands/zone'
+import { oneApi, ONE_RESOURCES } from 'client/features/OneApi'
+import { Zone } from 'client/constants'
+
+const { ZONE } = ONE_RESOURCES
+
+const zoneApi = oneApi.injectEndpoints({
+ endpoints: (builder) => ({
+ getZones: builder.query({
+ /**
+ * Retrieves information for all the zones in the pool.
+ *
+ * @returns {Zone[]} List of zones
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.ZONE_POOL_INFO
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ transformResponse: (data) => [data?.ZONE_POOL?.ZONE ?? []].flat(),
+ providesTags: [ZONE],
+ }),
+ getZone: builder.query({
+ /**
+ * Retrieves information for the zone.
+ *
+ * @param {string} id - Zone id
+ * @returns {Zone} Get zone identified by id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.ZONE_INFO
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ transformResponse: (data) => data?.ZONE ?? {},
+ providesTags: (_, __, { id }) => [{ type: ZONE, id }],
+ }),
+ getRaftStatus: builder.query({
+ /**
+ * Retrieves raft status one servers.
+ *
+ * @returns {string} The information string
+ * @throws Fails when response isn't code 200
+ */
+ query: () => {
+ const name = Actions.ZONE_RAFTSTATUS
+ const command = { name, ...Commands[name] }
+
+ return { command }
+ },
+ }),
+ allocateZone: builder.mutation({
+ /**
+ * Allocates a new zone in OpenNebula.
+ *
+ * @param {object} params - Request params
+ * @param {string} params.template - The string containing the template of the zone on syntax XML
+ * @returns {number} The allocated zone id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.ZONE_ALLOCATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: [ZONE],
+ }),
+ removeZone: builder.mutation({
+ /**
+ * Deletes the given zone from the pool.
+ *
+ * @param {number|string} id - Zone id
+ * @returns {number} Zone id
+ * @throws Fails when response isn't code 200
+ */
+ query: (id) => {
+ const name = Actions.ZONE_DELETE
+ const command = { name, ...Commands[name] }
+
+ return { params: { id }, command }
+ },
+ invalidatesTags: [ZONE],
+ }),
+ updateZone: builder.mutation({
+ /**
+ * Replaces the zone template contents.
+ *
+ * @param {object} params - Request params
+ * @param {number|string} params.id - Zone id
+ * @param {string} params.template - The new template contents
+ * @param {0|1} params.replace
+ * - Update type:
+ * ``0``: Replace the whole template.
+ * ``1``: Merge new template with the existing one.
+ * @returns {number} Zone id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.ZONE_UPDATE
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: ZONE, id }, ZONE],
+ }),
+ renameZone: builder.mutation({
+ /**
+ * Renames a zone.
+ *
+ * @param {object} params - Request parameters
+ * @param {string|number} params.id - Zone id
+ * @param {string} params.name - The new name
+ * @returns {number} Zone id
+ * @throws Fails when response isn't code 200
+ */
+ query: (params) => {
+ const name = Actions.ZONE_RENAME
+ const command = { name, ...Commands[name] }
+
+ return { params, command }
+ },
+ invalidatesTags: (_, __, { id }) => [{ type: ZONE, id }, ZONE],
+ }),
+ }),
+})
+
+export const {
+ // Queries
+ useGetZonesQuery,
+ useLazyGetZonesQuery,
+ useGetZoneQuery,
+ useLazyGetZoneQuery,
+ useGetRaftStatusQuery,
+ useLazyGetRaftStatusQuery,
+
+ // Mutations
+ useAllocateZoneMutation,
+ useRemoveZoneMutation,
+ useUpdateZoneMutation,
+ useRenameZoneMutation,
+} = zoneApi
+
+export default zoneApi
diff --git a/src/fireedge/src/client/hooks/useSocket.js b/src/fireedge/src/client/hooks/useSocket.js
index 6a18b61684..ee6dfaee81 100644
--- a/src/fireedge/src/client/hooks/useSocket.js
+++ b/src/fireedge/src/client/hooks/useSocket.js
@@ -14,101 +14,41 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
import { useCallback } from 'react'
-import socketIO from 'socket.io-client'
-import { useDispatch } from 'react-redux'
-
-import { WEBSOCKET_URL, SOCKETS } from 'client/constants'
+import { Socket } from 'socket.io-client'
import { useAuth } from 'client/features/Auth'
import { useGeneral } from 'client/features/General'
-import {
- eventUpdateResourceState,
- getResourceFromEventState,
-} from 'client/features/One/socket/actions'
-import { updateResourceFromFetch } from 'client/features/One/actions'
-
-const createWebsocket = (path, query) =>
- socketIO({
- path: `${WEBSOCKET_URL}/${path}`,
- query,
- autoConnect: false,
- timeout: 10_000,
- reconnectionAttempts: 5,
- })
+import { createWebsocket } from 'client/features/OneApi/socket'
+import { SOCKETS } from 'client/constants'
/**
* Hook to manage the OpenNebula sockets.
*
- * @returns {{
- * getHooksSocket: Function,
- * getProvisionSocket: Function
- * }} - List of functions to interactive with FireEdge sockets
+ * @returns {{ getProvisionSocket: Function }} - List of functions to interactive with FireEdge sockets
*/
const useSocket = () => {
- const dispatch = useDispatch()
const { jwt } = useAuth()
const { zone } = useGeneral()
/**
- * @param {('vm'|'host'|'image')} resource - Resource name
- * @param {string} id - Resource id
- * @returns {{ connect: Function, disconnect: Function }}
- * - Functions to manage the socket connections
+ * @param {Function} callback - Callback from socket
+ * @returns {Socket} - Socket
*/
- const getHooksSocket = useCallback(
- ({ resource, id }) => {
- const socket = createWebsocket(SOCKETS.HOOKS, {
- token: jwt,
- zone,
- resource,
- id,
- })
+ const getProvisionSocket = useCallback(
+ (callback) => {
+ const socket = createWebsocket(SOCKETS.PROVISION, { token: jwt, zone })
+
+ socket.on(SOCKETS.PROVISION, callback)
return {
- connect: ({ dataFromFetch, callback }) => {
- dataFromFetch &&
- socket.on(SOCKETS.CONNECT, () => {
- // update redux state from data fetched
- dispatch(
- updateResourceFromFetch({ data: dataFromFetch, resource })
- )
- })
-
- socket.on(SOCKETS.HOOKS, ({ data } = {}) => {
- // update the list on redux state
- dispatch(eventUpdateResourceState(data))
- // return data from event
- callback(getResourceFromEventState(data).value)
- })
-
- socket.connect()
- },
- disconnect: () => socket.connected && socket.disconnect(),
+ on: () => socket.connect(),
+ off: () => socket.disconnect(),
}
},
[jwt, zone]
)
- /**
- * @param {Function} callback - Callback from socket
- * @returns {{ on: Function, off: Function }}
- * - Functions to manage the socket connections
- */
- const getProvisionSocket = useCallback((callback) => {
- const socket = createWebsocket(SOCKETS.PROVISION, { token: jwt, zone })
-
- socket.on(SOCKETS.PROVISION, callback)
-
- return {
- on: () => socket.connect(),
- off: () => socket.disconnect(),
- }
- }, [])
-
- return {
- getHooksSocket,
- getProvisionSocket,
- }
+ return { getProvisionSocket }
}
export default useSocket
diff --git a/src/fireedge/src/client/models/Helper.js b/src/fireedge/src/client/models/Helper.js
index d5b2083ee2..82cc31446f 100644
--- a/src/fireedge/src/client/models/Helper.js
+++ b/src/fireedge/src/client/models/Helper.js
@@ -17,6 +17,7 @@ import { DateTime } from 'luxon'
import { j2xParser as Parser, J2xOptions } from 'fast-xml-parser'
import { T, UserInputObject, USER_INPUT_TYPES } from 'client/constants'
+import { camelCase } from 'client/utils'
/**
* @param {object} json - JSON
@@ -215,6 +216,35 @@ export const getActionsAvailable = (actions = {}, hypervisor = '') =>
})
.map(([actionName, _]) => actionName)
+/**
+ * Returns the resource info tabs.
+ *
+ * @param {object} infoTabs - Info tabs from view yaml
+ * @param {Function} getTabComponent - Function to get tab component
+ * @param {string} id - Resource id
+ * @returns {{
+ * id: string,
+ * name: string,
+ * renderContent: Function
+ * }[]} - List of available info tabs for the resource
+ */
+export const getAvailableInfoTabs = (infoTabs = {}, getTabComponent, id) =>
+ Object.entries(infoTabs)
+ ?.filter(([_, { enabled } = {}]) => !!enabled)
+ ?.map(([tabName, tabProps]) => {
+ const camelName = camelCase(tabName)
+ const TabContent = getTabComponent?.(camelName)
+
+ return (
+ TabContent && {
+ name: camelName,
+ id: tabName,
+ renderContent: () => ,
+ }
+ )
+ })
+ ?.filter(Boolean)
+
/**
*
* @param {object} list - List of attributes
diff --git a/src/fireedge/src/client/models/Image.js b/src/fireedge/src/client/models/Image.js
index 4a1b494f14..7f4cb1cb20 100644
--- a/src/fireedge/src/client/models/Image.js
+++ b/src/fireedge/src/client/models/Image.js
@@ -18,13 +18,13 @@ import {
DISK_TYPES,
IMAGE_STATES,
StateInfo,
+ Image,
} from 'client/constants'
/**
* Returns the image type.
*
- * @param {object} image - Image
- * @param {number|string} image.TYPE - Type numeric code
+ * @param {Image} image - Image
* @returns {IMAGE_TYPES} - Image type
*/
export const getType = ({ TYPE } = {}) =>
@@ -33,8 +33,7 @@ export const getType = ({ TYPE } = {}) =>
/**
* Returns the image state.
*
- * @param {object} image - Image
- * @param {number|string} image.STATE - State code
+ * @param {Image} image - Image
* @returns {StateInfo} - Image state information
*/
export const getState = ({ STATE } = {}) => IMAGE_STATES[+STATE]
@@ -42,8 +41,7 @@ export const getState = ({ STATE } = {}) => IMAGE_STATES[+STATE]
/**
* Returns the disk type.
*
- * @param {object} image - Image
- * @param {number|string} image.DISK_TYPE - Disk type numeric code
+ * @param {Image} image - Image
* @returns {DISK_TYPES} - Disk type
*/
export const getDiskType = ({ DISK_TYPE } = {}) =>
diff --git a/src/fireedge/src/client/models/Marketplace.js b/src/fireedge/src/client/models/Marketplace.js
index b8327a33e7..159d76ed77 100644
--- a/src/fireedge/src/client/models/Marketplace.js
+++ b/src/fireedge/src/client/models/Marketplace.js
@@ -14,13 +14,12 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
import { prettyBytes } from 'client/utils'
-import { MARKETPLACE_STATES, StateInfo } from 'client/constants'
+import { MARKETPLACE_STATES, StateInfo, Marketplace } from 'client/constants'
/**
* Returns the marketplace state.
*
- * @param {object} marketplace - Marketplace
- * @param {number|string} marketplace.STATE - Marketplace state numeric code
+ * @param {Marketplace} marketplace - Marketplace
* @returns {StateInfo} Marketplace state information
*/
export const getState = ({ STATE } = {}) => MARKETPLACE_STATES[+STATE]
@@ -28,9 +27,7 @@ export const getState = ({ STATE } = {}) => MARKETPLACE_STATES[+STATE]
/**
* Returns the marketplace capacity information.
*
- * @param {object} marketplace - Marketplace
- * @param {number|string} marketplace.TOTAL_MB - Total capacity MB available
- * @param {number|string} marketplace.USED_MB - Capacity used MB
+ * @param {Marketplace} marketplace - Marketplace
* @returns {{
* percentOfUsed: number,
* percentLabel: string
@@ -44,8 +41,5 @@ export const getCapacityInfo = ({ TOTAL_MB, USED_MB } = {}) => {
percentOfUsed
)}%)`
- return {
- percentOfUsed,
- percentLabel,
- }
+ return { percentOfUsed, percentLabel }
}
diff --git a/src/fireedge/src/client/models/Scheduler.js b/src/fireedge/src/client/models/Scheduler.js
index 1f3007df32..9ad716e6da 100644
--- a/src/fireedge/src/client/models/Scheduler.js
+++ b/src/fireedge/src/client/models/Scheduler.js
@@ -13,9 +13,17 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
+/* eslint-disable jsdoc/valid-types */
import { isDate, timeToString } from 'client/models/Helper'
import { Tr } from 'client/components/HOC'
-import { T, VM_ACTIONS } from 'client/constants'
+import {
+ T,
+ VM_ACTIONS,
+ ARGS_TYPES,
+ PERIOD_TYPES,
+ ScheduleAction,
+ CharterOptions,
+} from 'client/constants'
const {
SNAPSHOT_DISK_CREATE,
@@ -26,70 +34,6 @@ const {
SNAPSHOT_DELETE,
} = VM_ACTIONS
-/**
- * @typedef ScheduledAction
- * @property {string} ACTION - Action to execute
- * @property {string} ID - Id
- * @property {string} TIME - Time
- * @property {string} [WARNING] - Warning time
- * @property {string} [ARGS] - Arguments separated by comma
- * @property {string} [DAYS] - Days that the users wants execute the action.
- * List separated by comma. Depend of REPEAT:
- * - weekly: 0 (Sunday) to 6 (Saturday)
- * - monthly: 1 to 31
- * - yearly: 1 to 365
- * - hourly: each ‘x’ hours
- * @property {'0'|'1'|'2'} [END_TYPE] - Way to end the repetition. Can be:
- * - never: 0
- * - repetition: 1
- * - date: 2
- * @property {string} [END_VALUE] - End value
- * @property {'0'|'1'|'2'|'3'} [REPEAT] - Type of repetition. Can be:
- * - weekly: '0',
- * - monthly: '1',
- * - yearly: '2',
- * - hourly: '3',
- */
-
-/**
- * @typedef CharterOptions
- * @property {boolean} [edit] - If `true`, the charter can be edited in form
- * @property {number|string} execute_after_days - Days to execute the action
- * @property {number|string} warn_before_days - Alert a time before the action (in days)
- */
-
-/** @enum {string} Values to end an action */
-export const END_TYPE_VALUES = {
- NEVER: '0',
- REPETITION: '1',
- DATE: '2',
-}
-
-/** @enum {string} Values to repeat an action */
-export const REPEAT_VALUES = {
- WEEKLY: '0',
- MONTHLY: '1',
- YEARLY: '2',
- HOURLY: '3',
-}
-
-/** @enum {string} Argument attributes */
-export const ARGS_TYPES = {
- DISK_ID: 'DISK_ID',
- NAME: 'NAME',
- SNAPSHOT_ID: 'SNAPSHOT_ID',
-}
-
-/** @enum {string} Period type */
-export const PERIOD_TYPES = {
- YEARS: 'years',
- MONTHS: 'months',
- WEEKS: 'weeks',
- DAYS: 'days',
- HOURS: 'hours',
- MINUTES: 'minutes',
-}
-
/**
* Checks if time is relative.
*
@@ -160,7 +104,7 @@ export const timeToSecondsByPeriodicity = (period, time) =>
/**
* Returns information about the repetition of an action: periodicity and the end.
*
- * @param {ScheduledAction} action - Schedule action
+ * @param {ScheduleAction} action - Schedule action
* @returns {{repeat: string|string[], end: string}} - Periodicity of the action.
*/
export const getRepeatInformation = (action) => {
@@ -209,7 +153,7 @@ export const getRequiredArgsByAction = (action) => {
/**
* Transforms the arguments from the scheduled action to object.
*
- * @param {scheduledAction} [scheduledAction] - Schedule action
+ * @param {ScheduleAction} [scheduleAction] - Schedule action
* @returns {object} Arguments in object format
*/
export const transformStringToArgsObject = ({ ACTION, ARGS = {} } = {}) => {
@@ -253,7 +197,7 @@ const getTimeAndPeriodTypeFromCharter = (options, prefix) => {
*
* @param {[string, CharterOptions][]} charters - Charters from configuration yaml
* @param {boolean} relative - If `true`, returns times in relative format
- * @returns {ScheduledAction[]} - Scheduled action
+ * @returns {ScheduleAction[]} - Scheduled action
*/
export const transformChartersToSchedActions = (charters, relative = false) => {
const now = Math.round(Date.now() / 1000)
diff --git a/src/fireedge/src/client/models/SecurityGroup.js b/src/fireedge/src/client/models/SecurityGroup.js
index 3bc5ad5eda..74c4f4102d 100644
--- a/src/fireedge/src/client/models/SecurityGroup.js
+++ b/src/fireedge/src/client/models/SecurityGroup.js
@@ -19,23 +19,9 @@ import {
RULE_TYPE_STRING,
ICMP_STRING,
ICMP_V6_STRING,
+ SecurityGroupRule,
} from 'client/constants'
-/**
- * @typedef {object} SecurityGroupRule
- * @property {number|string} SECURITY_GROUP_ID - ID
- * @property {string} SECURITY_GROUP_NAME - Name
- * @property {string} PROTOCOL - Protocol
- * @property {string} RULE_TYPE - Rule type
- * @property {number|string} ICMP_TYPE - ICMP type
- * @property {number|string} [ICMPv6_TYPE] - ICMP v6 type
- * @property {number|string} [RANGE] - Range
- * @property {number|string} [NETWORK_ID] - Network id
- * @property {number|string} [SIZE] - Network size
- * @property {string} [IP] - Network IP
- * @property {string} [MAC] - Network MAC
- */
-
/**
* Converts a security group attributes into a readable format.
*
diff --git a/src/fireedge/src/client/models/VirtualMachine.js b/src/fireedge/src/client/models/VirtualMachine.js
index bf1bc4caea..0a7c72becd 100644
--- a/src/fireedge/src/client/models/VirtualMachine.js
+++ b/src/fireedge/src/client/models/VirtualMachine.js
@@ -28,14 +28,21 @@ import {
HISTORY_ACTIONS,
HYPERVISORS,
StateInfo,
+ VM,
+ Disk,
+ Nic,
+ NicAlias,
+ ScheduleAction,
+ HistoryRecord,
+ Snapshot,
} from 'client/constants'
/**
* This function removes, from the given list,
* the Virtual machines in state DONE.
*
- * @param {Array} vms - List of virtual machines
- * @returns {Array} Clean list of vms with done state
+ * @param {VM[]} vms - List of virtual machines
+ * @returns {VM[]} Clean list of vms with done state
*/
export const filterDoneVms = (vms = []) =>
vms.filter(({ STATE }) => VM_STATES[STATE]?.name !== STATES.DONE)
@@ -47,15 +54,15 @@ export const filterDoneVms = (vms = []) =>
export const getHistoryAction = (action) => HISTORY_ACTIONS[+action]
/**
- * @param {object} vm - Virtual machine
- * @returns {object} History records from resource
+ * @param {VM} vm - Virtual machine
+ * @returns {HistoryRecord[]} History records from resource
*/
export const getHistoryRecords = (vm) =>
[vm?.HISTORY_RECORDS?.HISTORY ?? []].flat()
/**
- * @param {object} vm - Virtual machine
- * @returns {object} Last history record from resource
+ * @param {VM} vm - Virtual machine
+ * @returns {HistoryRecord} Last history record from resource
*/
export const getLastHistory = (vm) => {
const records = getHistoryRecords(vm)
@@ -64,7 +71,7 @@ export const getLastHistory = (vm) => {
}
/**
- * @param {object} vm - Virtual machine
+ * @param {VM} vm - Virtual machine
* @returns {string} Resource type: VR, FLOW or VM
*/
export const getType = (vm) =>
@@ -75,20 +82,20 @@ export const getType = (vm) =>
: 'VM'
/**
- * @param {object} vm - Virtual machine
+ * @param {VM} vm - Virtual machine
* @returns {string} Resource hypervisor
*/
export const getHypervisor = (vm) =>
String(getLastHistory(vm)?.VM_MAD).toLowerCase()
/**
- * @param {object} vm - Virtual machine
+ * @param {VM} vm - Virtual machine
* @returns {boolean} If the hypervisor is vCenter
*/
export const isVCenter = (vm) => getHypervisor(vm) === HYPERVISORS.vcenter
/**
- * @param {object} vm - Virtual machine
+ * @param {VM} vm - Virtual machine
* @returns {StateInfo} State information from resource
*/
export const getState = (vm) => {
@@ -99,8 +106,8 @@ export const getState = (vm) => {
}
/**
- * @param {object} vm - Virtual machine
- * @returns {Array} List of disks from resource
+ * @param {VM} vm - Virtual machine
+ * @returns {Disk[]} List of disks from resource
*/
export const getDisks = (vm) => {
const { TEMPLATE = {}, MONITORING = {}, SNAPSHOTS = {} } = vm ?? {}
@@ -152,13 +159,13 @@ export const getDisks = (vm) => {
}
/**
- * @param {object} vm - Virtual machine
+ * @param {VM} vm - Virtual machine
* @param {object} [options] - Options
* @param {boolean} [options.groupAlias]
* - Create ALIAS attribute with result to mapping NIC_ALIAS and ALIAS_IDS
* @param {boolean} [options.securityGroupsFromTemplate]
* - Create SECURITY_GROUPS attribute with rules from TEMPLATE.SECURITY_GROUP_RULE
- * @returns {object[]} List of nics from resource
+ * @returns {Nic[]} List of nics from resource
*/
export const getNics = (vm, options = {}) => {
const { groupAlias = false, securityGroupsFromTemplate = false } = options
@@ -204,8 +211,8 @@ export const getNics = (vm, options = {}) => {
}
/**
- * @param {object} vm - Virtual machine
- * @returns {Array} List of ips from resource
+ * @param {VM} vm - Virtual machine
+ * @returns {string[]} List of ips from resource
*/
export const getIps = (vm) => {
const getIpsFromNic = (nic) =>
@@ -215,8 +222,8 @@ export const getIps = (vm) => {
}
/**
- * @param {object} vm - Virtual machine
- * @returns {{ nics: Array, alias: Array }} Lists of nics and alias from resource
+ * @param {VM} vm - Virtual machine
+ * @returns {{ nics: Nic[], alias: NicAlias[] }} Lists of nics and alias from resource
*/
export const splitNicAlias = (vm) =>
getNics(vm).reduce(
@@ -229,8 +236,8 @@ export const splitNicAlias = (vm) =>
)
/**
- * @param {object} vm - Virtual machine
- * @returns {Array} List of snapshots from resource
+ * @param {VM} vm - Virtual machine
+ * @returns {Snapshot[]} List of snapshots from resource
*/
export const getSnapshotList = (vm) => {
const { TEMPLATE = {} } = vm ?? {}
@@ -239,8 +246,8 @@ export const getSnapshotList = (vm) => {
}
/**
- * @param {object} vm - Virtual machine
- * @returns {Array} List of schedule actions from resource
+ * @param {VM} vm - Virtual machine
+ * @returns {ScheduleAction[]} List of schedule actions from resource
*/
export const getScheduleActions = (vm) => {
const { STIME: vmStartTime, TEMPLATE = {} } = vm ?? {}
diff --git a/src/fireedge/src/client/models/VirtualNetwork.js b/src/fireedge/src/client/models/VirtualNetwork.js
index 34f93d4038..b3e20a9b0f 100644
--- a/src/fireedge/src/client/models/VirtualNetwork.js
+++ b/src/fireedge/src/client/models/VirtualNetwork.js
@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
+import { VirtualNetwork } from 'client/constants'
+
/**
* Returns the total number of leases in the virtual network.
*
- * @param {object} virtualNetwork - Virtual network
- * @param {object} virtualNetwork.AR_POOL - Address range pool
+ * @param {VirtualNetwork} virtualNetwork - Virtual network
* @returns {number} Total leases
*/
export const getTotalLeases = ({ AR_POOL } = {}) => {
@@ -29,12 +30,8 @@ export const getTotalLeases = ({ AR_POOL } = {}) => {
/**
* Returns the virtual network leases information.
*
- * @param {object} virtualNetwork - Virtual network
- * @param {object} virtualNetwork.USED_LEASES - Used network leases
- * @returns {{
- * percentOfUsed: number,
- * percentLabel: string
- * }} Leases information
+ * @param {VirtualNetwork} virtualNetwork - Virtual network
+ * @returns {{ percentOfUsed: number, percentLabel: string }} Leases information
*/
export const getLeasesInfo = ({ USED_LEASES, ...virtualNetwork } = {}) => {
const totalLeases = getTotalLeases(virtualNetwork)
diff --git a/src/fireedge/src/client/providers/socketProvider.js b/src/fireedge/src/client/providers/socketProvider.js
deleted file mode 100644
index 304d9453a0..0000000000
--- a/src/fireedge/src/client/providers/socketProvider.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import { createContext, useEffect, useState } from 'react'
-import PropTypes from 'prop-types'
-
-import socketIO from 'socket.io-client'
-import { useSelector, useDispatch } from 'react-redux'
-
-import { WEBSOCKET_URL, SOCKETS } from 'client/constants'
-import * as sockets from 'client/features/One/socket/actions'
-
-const createProvisionWebsocket = (query) =>
- socketIO({
- path: `${WEBSOCKET_URL}/${SOCKETS.PROVISION}`,
- query,
- })
-
-export const SocketContext = createContext(null)
-
-const SocketProvider = ({ children }) => {
- const [socket, setSocket] = useState({})
-
- const dispatch = useDispatch()
- const { jwt, zone } = useSelector((state) => ({
- zone: state?.general?.zone,
- jwt: state?.auth?.jwt,
- }))
-
- useEffect(() => {
- if (!jwt) return
-
- const client = createProvisionWebsocket({ token: jwt, zone })
- setSocket(client)
-
- client.on(SOCKETS.PROVISION, (data) => {
- dispatch(sockets.onCreateProvision(data))
- })
-
- return () => {
- setSocket(null)
- client?.disconnect()
- }
- }, [jwt, zone])
-
- return (
-
- {children}
-
- )
-}
-
-SocketProvider.propTypes = {
- children: PropTypes.oneOfType([
- PropTypes.node,
- PropTypes.arrayOf(PropTypes.node),
- ]),
-}
-
-SocketProvider.defaultProps = {
- children: undefined,
-}
-
-export default SocketProvider
diff --git a/src/fireedge/src/client/store/index.js b/src/fireedge/src/client/store/index.js
index a0c34ee7ca..0b64f7f8da 100644
--- a/src/fireedge/src/client/store/index.js
+++ b/src/fireedge/src/client/store/index.js
@@ -13,37 +13,36 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import {
- configureStore,
- getDefaultMiddleware,
- EnhancedStore,
-} from '@reduxjs/toolkit'
-import thunkMiddleware from 'redux-thunk'
+import { configureStore, EnhancedStore } from '@reduxjs/toolkit'
+import { setupListeners } from '@reduxjs/toolkit/query/react'
-import rootReducer from 'client/store/reducers'
import { isDevelopment } from 'client/utils'
+import * as Auth from 'client/features/Auth/slice'
+import * as General from 'client/features/General/slice'
+import { oneApi } from 'client/features/OneApi'
+
/**
* @param {object} props - Props
* @param {object} props.initState - Initial state
- * @param {*} props.services - Services
* @returns {{ store: EnhancedStore }} Configured Redux Store
*/
-export const createStore = ({ initState = {}, services }) => {
- const middleware = getDefaultMiddleware({
- immutableCheck: true,
- serializableCheck: false,
- thunk: false,
- })
-
- middleware.push(thunkMiddleware.withExtraArgument({ services }))
-
+export const createStore = ({ initState = {} }) => {
const store = configureStore({
- reducer: rootReducer,
+ reducer: {
+ [Auth.name]: Auth.reducer,
+ [General.name]: General.reducer,
+ [oneApi.reducerPath]: oneApi.reducer,
+ },
devTools: isDevelopment(),
- middleware,
+ middleware: (getDefaultMiddleware) =>
+ getDefaultMiddleware({
+ immutableCheck: true,
+ }).concat(oneApi.middleware),
preloadedState: initState,
})
+ setupListeners(store.dispatch)
+
return { store }
}
diff --git a/src/fireedge/src/client/store/reducers.js b/src/fireedge/src/client/store/reducers.js
index c7cc93ba8b..a2c46410f9 100644
--- a/src/fireedge/src/client/store/reducers.js
+++ b/src/fireedge/src/client/store/reducers.js
@@ -16,12 +16,12 @@
const { combineReducers } = require('redux')
const Auth = require('client/features/Auth/slice')
const General = require('client/features/General/slice')
-const One = require('client/features/One/slice')
+const { oneApi } = require('client/features/OneApi')
const rootReducer = combineReducers({
general: General.reducer,
auth: Auth.reducer,
- one: One.reducer,
+ [oneApi.reducerPath]: oneApi.reducer,
})
module.exports = rootReducer
diff --git a/src/fireedge/src/client/utils/helpers.js b/src/fireedge/src/client/utils/helpers.js
index 3125ee22d8..fa3d14a3ad 100644
--- a/src/fireedge/src/client/utils/helpers.js
+++ b/src/fireedge/src/client/utils/helpers.js
@@ -93,7 +93,7 @@ export const encodeBase64 = (string, defaultValue = '') => {
* Converts a long string of units into a readable format e.g KB, MB, GB, TB, YB.
*
* @param {number|string} value - The quantity of units.
- * @param {string} unit - The unit of value.
+ * @param {'KB'|'MB'|'GB'|'TB'|'PB'|'EB'|'ZB'|'YB'} unit - The unit of value. Defaults in KB
* @param {number} fractionDigits
* - Number of digits after the decimal point. Must be in the range 0 - 20, inclusive
* @returns {string} Returns an string displaying sizes for humans.
diff --git a/src/fireedge/src/client/utils/request.js b/src/fireedge/src/client/utils/request.js
index 933f64f0fa..56231d5198 100644
--- a/src/fireedge/src/client/utils/request.js
+++ b/src/fireedge/src/client/utils/request.js
@@ -16,57 +16,69 @@
import { AxiosRequestConfig, Method } from 'axios'
import { defaults } from 'server/utils/constants'
-const { from: resourceFrom } = defaults
+const { from: fromTypes } = defaults
const getQueries = (params) =>
Object.entries(params)
- ?.filter(
- ([, { from, value }]) =>
- from === resourceFrom.query && value !== undefined
+ ?.filter(([, { from }]) => from === fromTypes.query)
+ ?.filter(([, { value }]) => value !== undefined)
+ ?.reduce(
+ (acc, [name, { value }]) => ({ ...acc, [name]: encodeURI(value) }),
+ {}
+ )
+
+const replacePathWithResources = (path = '', params) =>
+ Object.entries(params)
+ ?.filter(([, { from }]) => from === fromTypes.resource)
+ ?.reduce(
+ (replacedPath, [name, { value = '' }]) =>
+ replacedPath.replace(new RegExp(`:${name}(\\??)`), value),
+ path
)
- ?.map(([name, { value }]) => `${name}=${encodeURI(value)}`)
- ?.join('&')
const getResources = (params) =>
Object.values(params)
- ?.filter(({ from }) => from === resourceFrom.resource)
+ ?.filter(({ from }) => from === fromTypes.resource)
?.map(({ value }) => value)
?.join('/')
const getDataBody = (params) =>
Object.entries(params)
- ?.filter(([, { from }]) => from === resourceFrom.postBody)
+ ?.filter(([, { from }]) => from === fromTypes.postBody)
?.reduce((acc, [name, { value }]) => ({ ...acc, [name]: value }), {})
/**
* @param {object} data - Data for the request
* @param {object} command - Command request
- * @param {object} command.name - Command name
+ * @param {string} command.name - Command name
+ * @param {string} [command.path] - Path to replace with resources
* @param {Method} command.httpMethod - Method http
* @param {object} command.params - Params to map
* @returns {AxiosRequestConfig} Request configuration
*/
export const requestConfig = (data, command) => {
if (command === undefined) throw new Error('command not exists')
- const { name, httpMethod, params = {} } = command
+ const { name, path, httpMethod, params = {} } = command
/* Spread 'from' values in current params */
const mappedParams = Object.entries(params)?.reduce(
(result, [paraName, { from }]) => ({
...result,
- [paraName]: { from, value: data[paraName] },
+ [paraName]: { from, value: data?.[paraName] },
}),
{}
)
const queries = getQueries(mappedParams)
- const resources = getResources(mappedParams)
const body = getDataBody(mappedParams)
- const url = `/api/${name.replace('.', '/')}`
+ const url = path
+ ? `/api${replacePathWithResources(path, mappedParams)}`
+ : `/api/${name.replace('.', '/')}/${getResources(mappedParams)}`
return {
- url: `${url}/${resources}?${queries}`,
+ url,
+ params: queries,
data: body,
method: httpMethod,
}
diff --git a/src/fireedge/src/client/utils/rest.js b/src/fireedge/src/client/utils/rest.js
index bbc703f996..20ef07b4b2 100644
--- a/src/fireedge/src/client/utils/rest.js
+++ b/src/fireedge/src/client/utils/rest.js
@@ -16,9 +16,7 @@
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
import { httpCodes } from 'server/utils/constants'
-import { messageTerminal } from 'server/utils/general'
-
-import { findStorageData, isDevelopment } from 'client/utils'
+import { findStorageData } from 'client/utils'
import { T, JWT_NAME, APP_URL } from 'client/constants'
const http = axios.create({ baseURL: APP_URL })
@@ -47,16 +45,6 @@ http.interceptors.response.use(
return typeof response === 'string' ? response.data.json() : response.data
}
- if (response.status === httpCodes.unauthorized.id) {
- const configErrorParser = {
- color: 'red',
- error: response?.data?.message ?? response?.statusText,
- message: 'Error request: %s',
- }
-
- isDevelopment() && messageTerminal(configErrorParser)
- }
-
return Promise.reject(response)
},
(error) => error
@@ -69,3 +57,5 @@ export const RestClient = {
*/
request: (options) => http.request(options),
}
+
+export default http
diff --git a/src/fireedge/src/server/routes/api/marketapp/basepath.js b/src/fireedge/src/server/routes/api/marketapp/basepath.js
deleted file mode 100644
index 87d527994f..0000000000
--- a/src/fireedge/src/server/routes/api/marketapp/basepath.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-
-module.exports = 'marketapp'
diff --git a/src/fireedge/src/server/routes/api/marketapp/functions.js b/src/fireedge/src/server/routes/api/marketapp/functions.js
index c2f9dfdb9b..a66c4a5e99 100644
--- a/src/fireedge/src/server/routes/api/marketapp/functions.js
+++ b/src/fireedge/src/server/routes/api/marketapp/functions.js
@@ -109,23 +109,22 @@ const exportApp = (
}
/**
- * Import the marketplace VM or VM TEPLATE to the OpenNebula cloud.
+ * Import the marketplace VM or VM TEMPLATE to the OpenNebula cloud.
*
* @param {object} res - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
- * @param {number} [params.vmId] - vm id
- * @param {number} [params.templateId] - template id
+ * @param {string} [params.id] - Resource id
+ * @param {string} [params.resource] - Resource name
* @param {number} [params.marketId] - market id
* @param {string} [params.associated=''] - associated resource
* @param {number} [params.vmname] - vm name
*/
const importMarket = (res = {}, next = defaultEmptyFunction, params = {}) => {
let rtn = httpBadRequest
- const { vmId, templateId, marketId, associated, vmname } = params
- const resource = vmId ? 'vm' : 'vm-template'
- const id = vmId || templateId
- if (id) {
+ const { resource, id, marketId, associated, vmname } = params
+
+ if (id && ['vm', 'vm-template'].includes(params.resource)) {
let message = ''
const paramsCommand = [resource, 'import', `${id}`]
diff --git a/src/fireedge/src/server/routes/api/marketapp/index.js b/src/fireedge/src/server/routes/api/marketapp/index.js
index 7705843ecc..9820486b4f 100644
--- a/src/fireedge/src/server/routes/api/marketapp/index.js
+++ b/src/fireedge/src/server/routes/api/marketapp/index.js
@@ -21,12 +21,7 @@ const {
getDockerTags,
} = require('server/routes/api/marketapp/functions')
-const {
- MARKETAPP_EXPORT,
- MARKETAPP_VMIMPORT,
- MARKETAPP_TEMPLATEIMPORT,
- MARKETAPP_DOCKERTAGS,
-} = Actions
+const { MARKETAPP_EXPORT, MARKETAPP_IMPORT, MARKETAPP_DOCKERTAGS } = Actions
module.exports = [
{
@@ -34,11 +29,7 @@ module.exports = [
action: exportApp,
},
{
- ...Commands[MARKETAPP_VMIMPORT],
- action: importMarket,
- },
- {
- ...Commands[MARKETAPP_TEMPLATEIMPORT],
+ ...Commands[MARKETAPP_IMPORT],
action: importMarket,
},
{
diff --git a/src/fireedge/src/server/routes/api/marketapp/routes.js b/src/fireedge/src/server/routes/api/marketapp/routes.js
index 97444247c7..e335c60992 100644
--- a/src/fireedge/src/server/routes/api/marketapp/routes.js
+++ b/src/fireedge/src/server/routes/api/marketapp/routes.js
@@ -17,21 +17,20 @@
const {
httpMethod,
from: fromData,
-} = require('server/utils/constants/defaults')
-const MARKETAPP = require('server/routes/api/marketapp/basepath')
+} = require('../../../utils/constants/defaults')
const { POST, GET } = httpMethod
-const basepath = `/${MARKETAPP}`
const { query, resource, postBody } = fromData
+
+const basepath = '/marketapp'
+
const MARKETAPP_EXPORT = 'marketapp.export'
-const MARKETAPP_VMIMPORT = 'marketapp.vmimport'
-const MARKETAPP_TEMPLATEIMPORT = 'marketapp.templateimport'
+const MARKETAPP_IMPORT = 'marketapp.import'
const MARKETAPP_DOCKERTAGS = 'marketapp.dockertags'
const Actions = {
MARKETAPP_EXPORT,
- MARKETAPP_VMIMPORT,
- MARKETAPP_TEMPLATEIMPORT,
+ MARKETAPP_IMPORT,
MARKETAPP_DOCKERTAGS,
}
@@ -69,31 +68,15 @@ module.exports = {
},
},
},
- [MARKETAPP_VMIMPORT]: {
- path: `${basepath}/vmimport/:vmId`,
+ [MARKETAPP_IMPORT]: {
+ path: `${basepath}/import/:resource/:id`,
httpMethod: POST,
auth: true,
params: {
- vmId: {
+ id: {
from: resource,
},
- associated: {
- from: postBody,
- },
- marketId: {
- from: postBody,
- },
- vmname: {
- from: postBody,
- },
- },
- },
- [MARKETAPP_TEMPLATEIMPORT]: {
- path: `${basepath}/templateimport/:templateId`,
- httpMethod: POST,
- auth: true,
- params: {
- templateId: {
+ resource: {
from: resource,
},
associated: {
diff --git a/src/fireedge/src/server/routes/api/oneflow/index.js b/src/fireedge/src/server/routes/api/oneflow/index.js
index 52cd2186ec..0438a48823 100644
--- a/src/fireedge/src/server/routes/api/oneflow/index.js
+++ b/src/fireedge/src/server/routes/api/oneflow/index.js
@@ -52,11 +52,11 @@ const {
} = ActionsService
const {
- SERVICETEMPLATE_SHOW,
- SERVICETEMPLATE_ACTION,
- SERVICETEMPLATE_CREATE,
- SERVICETEMPLATE_UPDATE,
- SERVICETEMPLATE_DELETE,
+ SERVICE_TEMPLATE_SHOW,
+ SERVICE_TEMPLATE_ACTION,
+ SERVICE_TEMPLATE_CREATE,
+ SERVICE_TEMPLATE_UPDATE,
+ SERVICE_TEMPLATE_DELETE,
} = ActionsTemplate
const services = [
@@ -96,23 +96,23 @@ const services = [
const template = [
{
- ...CommandsTemplate[SERVICETEMPLATE_SHOW],
+ ...CommandsTemplate[SERVICE_TEMPLATE_SHOW],
action: serviceTemplate,
},
{
- ...CommandsTemplate[SERVICETEMPLATE_ACTION],
+ ...CommandsTemplate[SERVICE_TEMPLATE_ACTION],
action: serviceTemplateAction,
},
{
- ...CommandsTemplate[SERVICETEMPLATE_CREATE],
+ ...CommandsTemplate[SERVICE_TEMPLATE_CREATE],
action: serviceTemplateCreate,
},
{
- ...CommandsTemplate[SERVICETEMPLATE_UPDATE],
+ ...CommandsTemplate[SERVICE_TEMPLATE_UPDATE],
action: serviceTemplateUpdate,
},
{
- ...CommandsTemplate[SERVICETEMPLATE_DELETE],
+ ...CommandsTemplate[SERVICE_TEMPLATE_DELETE],
action: serviceTemplateDelete,
},
]
diff --git a/src/fireedge/src/server/routes/api/oneflow/service/routes.js b/src/fireedge/src/server/routes/api/oneflow/service/routes.js
index 0c18c253f5..63a8acff04 100644
--- a/src/fireedge/src/server/routes/api/oneflow/service/routes.js
+++ b/src/fireedge/src/server/routes/api/oneflow/service/routes.js
@@ -17,12 +17,11 @@
const {
httpMethod,
from: fromData,
-} = require('server/utils/constants/defaults')
-const { SERVICE } = require('server/routes/api/oneflow/basepath')
+} = require('../../../../utils/constants/defaults')
-const basepath = `/${SERVICE}`
const { GET, POST, DELETE, PUT } = httpMethod
const { resource, postBody } = fromData
+const basepath = '/service'
const SERVICE_SHOW = 'service.show'
const SERVICE_ADD_ACTION = 'service.addaction'
diff --git a/src/fireedge/src/server/routes/api/oneflow/template/routes.js b/src/fireedge/src/server/routes/api/oneflow/template/routes.js
index 6f9ea22ed1..e177f6f163 100644
--- a/src/fireedge/src/server/routes/api/oneflow/template/routes.js
+++ b/src/fireedge/src/server/routes/api/oneflow/template/routes.js
@@ -17,31 +17,30 @@
const {
httpMethod,
from: fromData,
-} = require('server/utils/constants/defaults')
-const { SERVICE_TEMPLATE } = require('server/routes/api/oneflow/basepath')
+} = require('../../../../utils/constants/defaults')
const { GET, POST, DELETE, PUT } = httpMethod
-const basepath = `/${SERVICE_TEMPLATE}`
const { resource, postBody } = fromData
+const basepath = '/service_template'
-const SERVICETEMPLATE_SHOW = 'servicetemplate.show'
-const SERVICETEMPLATE_ACTION = 'servicetemplate.action'
-const SERVICETEMPLATE_CREATE = 'servicetemplate.create'
-const SERVICETEMPLATE_UPDATE = 'servicetemplate.update'
-const SERVICETEMPLATE_DELETE = 'servicetemplate.delete'
+const SERVICE_TEMPLATE_SHOW = 'servicetemplate.show'
+const SERVICE_TEMPLATE_ACTION = 'servicetemplate.action'
+const SERVICE_TEMPLATE_CREATE = 'servicetemplate.create'
+const SERVICE_TEMPLATE_UPDATE = 'servicetemplate.update'
+const SERVICE_TEMPLATE_DELETE = 'servicetemplate.delete'
const Actions = {
- SERVICETEMPLATE_SHOW,
- SERVICETEMPLATE_ACTION,
- SERVICETEMPLATE_CREATE,
- SERVICETEMPLATE_UPDATE,
- SERVICETEMPLATE_DELETE,
+ SERVICE_TEMPLATE_SHOW,
+ SERVICE_TEMPLATE_ACTION,
+ SERVICE_TEMPLATE_CREATE,
+ SERVICE_TEMPLATE_UPDATE,
+ SERVICE_TEMPLATE_DELETE,
}
module.exports = {
Actions,
Commands: {
- [SERVICETEMPLATE_SHOW]: {
+ [SERVICE_TEMPLATE_SHOW]: {
path: `${basepath}/:id`,
httpMethod: GET,
auth: true,
@@ -51,7 +50,7 @@ module.exports = {
},
},
},
- [SERVICETEMPLATE_ACTION]: {
+ [SERVICE_TEMPLATE_ACTION]: {
path: `${basepath}/action/:id`,
httpMethod: POST,
auth: true,
@@ -64,7 +63,7 @@ module.exports = {
},
},
},
- [SERVICETEMPLATE_CREATE]: {
+ [SERVICE_TEMPLATE_CREATE]: {
path: `${basepath}`,
httpMethod: POST,
auth: true,
@@ -74,7 +73,7 @@ module.exports = {
},
},
},
- [SERVICETEMPLATE_UPDATE]: {
+ [SERVICE_TEMPLATE_UPDATE]: {
path: `${basepath}/:id`,
httpMethod: PUT,
auth: true,
@@ -87,7 +86,7 @@ module.exports = {
},
},
},
- [SERVICETEMPLATE_DELETE]: {
+ [SERVICE_TEMPLATE_DELETE]: {
path: `${basepath}/:id`,
httpMethod: DELETE,
auth: true,
diff --git a/src/fireedge/src/server/routes/api/oneprovision/basepath.js b/src/fireedge/src/server/routes/api/oneprovision/basepath.js
deleted file mode 100644
index a856276608..0000000000
--- a/src/fireedge/src/server/routes/api/oneprovision/basepath.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-
-const PROVIDER = 'provider'
-const PROVISION = 'provision'
-const PROVISION_TEMPLATE = 'provision-template'
-
-module.exports = {
- PROVIDER,
- PROVISION,
- PROVISION_TEMPLATE,
-}
diff --git a/src/fireedge/src/server/routes/api/oneprovision/index.js b/src/fireedge/src/server/routes/api/oneprovision/index.js
index dd531ff0dc..cbadd9dab2 100644
--- a/src/fireedge/src/server/routes/api/oneprovision/index.js
+++ b/src/fireedge/src/server/routes/api/oneprovision/index.js
@@ -25,7 +25,6 @@ const {
deleteResource,
deleteProvision,
hostCommand,
- hostCommandSSH,
hostAdd,
ipAdd,
createProvision,
@@ -61,33 +60,17 @@ const {
} = require('server/routes/api/oneprovision/provider/functions')
const {
- PROVISION_CLUSTER_RESOURCE,
- PROVISION_DATASTORE_RESOURCE,
- PROVISION_HOST_RESOURCE,
- PROVISION_IMAGE_RESOURCE,
- PROVISION_NETWORK_RESOURCE,
- PROVISION_TEMPLATE_RESOURCE,
- PROVISION_VNTEMPLATE_RESOURCE,
PROVISION_LOGS,
PROVISION_DEFAULTS,
PROVISION_LIST,
PROVISION_VALIDATE,
- PROVISION_HOST_POWEROFF,
- PROVISION_HOST_REBOOT,
- PROVISION_HOST_RESUME,
PROVISION_CREATE,
- PROVISION_HOST_SSH,
- PROVISION_DATASTORE,
- PROVISION_FLOWTEMPLATE,
- PROVISION_DELETE_HOST_RESOURCE,
- PROVISION_DELETE_IMAGE_RESOURCE,
- PROVISION_DELETE_NETWORK_RESOURCE,
- PROVISION_DELETE_VNTEMPLATE_RESOURCE,
- PROVISION_DELETE_TEMPLATE_RESOURCE,
- PROVISION_DELETE_CLUSTER_RESOURCE,
- PROVISION_DELETE_PROVISION,
- PROVISION_UPDATE_CONFIGURE,
- PROVISION_UPDATE_HOST,
+ PROVISION_DELETE,
+ PROVISION_CONFIGURE,
+ PROVISION_GET_RESOURCE,
+ PROVISION_DELETE_RESOURCE,
+ PROVISION_HOST_ACTION,
+ PROVISION_HOST_CONFIGURE,
PROVISION_ADD_HOST,
PROVISION_ADD_IP,
} = ActionsProvision
@@ -112,32 +95,12 @@ const {
module.exports = [
// Provision
{
- ...CommandsProvision[PROVISION_CLUSTER_RESOURCE],
+ ...CommandsProvision[PROVISION_GET_RESOURCE],
action: getListResourceProvision,
},
{
- ...CommandsProvision[PROVISION_DATASTORE_RESOURCE],
- action: getListResourceProvision,
- },
- {
- ...CommandsProvision[PROVISION_HOST_RESOURCE],
- action: getListResourceProvision,
- },
- {
- ...CommandsProvision[PROVISION_IMAGE_RESOURCE],
- action: getListResourceProvision,
- },
- {
- ...CommandsProvision[PROVISION_NETWORK_RESOURCE],
- action: getListResourceProvision,
- },
- {
- ...CommandsProvision[PROVISION_TEMPLATE_RESOURCE],
- action: getListResourceProvision,
- },
- {
- ...CommandsProvision[PROVISION_VNTEMPLATE_RESOURCE],
- action: getListResourceProvision,
+ ...CommandsProvision[PROVISION_DELETE_RESOURCE],
+ action: deleteResource,
},
{
...CommandsProvision[PROVISION_LOGS],
@@ -156,15 +119,7 @@ module.exports = [
action: validate,
},
{
- ...CommandsProvision[PROVISION_HOST_POWEROFF],
- action: hostCommand,
- },
- {
- ...CommandsProvision[PROVISION_HOST_REBOOT],
- action: hostCommand,
- },
- {
- ...CommandsProvision[PROVISION_HOST_RESUME],
+ ...CommandsProvision[PROVISION_HOST_ACTION],
action: hostCommand,
},
{
@@ -172,51 +127,15 @@ module.exports = [
action: createProvision,
},
{
- ...CommandsProvision[PROVISION_HOST_SSH],
- action: hostCommandSSH,
- },
- {
- ...CommandsProvision[PROVISION_DATASTORE],
- action: deleteResource,
- },
- {
- ...CommandsProvision[PROVISION_FLOWTEMPLATE],
- action: deleteResource,
- },
- {
- ...CommandsProvision[PROVISION_DELETE_HOST_RESOURCE],
- action: deleteResource,
- },
- {
- ...CommandsProvision[PROVISION_DELETE_IMAGE_RESOURCE],
- action: deleteResource,
- },
- {
- ...CommandsProvision[PROVISION_DELETE_NETWORK_RESOURCE],
- action: deleteResource,
- },
- {
- ...CommandsProvision[PROVISION_DELETE_VNTEMPLATE_RESOURCE],
- action: deleteResource,
- },
- {
- ...CommandsProvision[PROVISION_DELETE_TEMPLATE_RESOURCE],
- action: deleteResource,
- },
- {
- ...CommandsProvision[PROVISION_DELETE_CLUSTER_RESOURCE],
- action: deleteResource,
- },
- {
- ...CommandsProvision[PROVISION_DELETE_PROVISION],
- action: deleteProvision,
- },
- {
- ...CommandsProvision[PROVISION_UPDATE_CONFIGURE],
+ ...CommandsProvision[PROVISION_CONFIGURE],
action: configureProvision,
},
{
- ...CommandsProvision[PROVISION_UPDATE_HOST],
+ ...CommandsProvision[PROVISION_DELETE],
+ action: deleteProvision,
+ },
+ {
+ ...CommandsProvision[PROVISION_HOST_CONFIGURE],
action: configureHost,
},
{
@@ -227,8 +146,8 @@ module.exports = [
...CommandsProvision[PROVISION_ADD_IP],
action: ipAdd,
},
- // Template
+ // Template
{
...CommandsTemplate[PROVISIONTEMPLATE_SHOW],
action: getListProvisionTemplates,
diff --git a/src/fireedge/src/server/routes/api/oneprovision/provider/functions.js b/src/fireedge/src/server/routes/api/oneprovision/provider/functions.js
index d1b24b625a..6e47b6585a 100644
--- a/src/fireedge/src/server/routes/api/oneprovision/provider/functions.js
+++ b/src/fireedge/src/server/routes/api/oneprovision/provider/functions.js
@@ -270,11 +270,12 @@ const createProviders = (
) => {
const { user, password } = userData
const rtn = httpInternalError
- if (params && params.resource && user && password) {
+ if (params && params.data && user && password) {
const authCommand = ['--user', user, '--password', password]
const endpoint = getEndpoint()
- const resource = parsePostData(params.resource)
+ const resource = parsePostData(params.data)
const content = createYMLContent(resource)
+
if (content) {
const file = createTemporalFile(
`${global.paths.CPI}/${defaultFolderTmpProvision}`,
@@ -331,10 +332,10 @@ const updateProviders = (
) => {
const { user, password } = userData
const rtn = httpInternalError
- if (params && params.resource && params.id && user && password) {
+ if (params && params.data && params.id && user && password) {
const authCommand = ['--user', user, '--password', password]
const endpoint = getEndpoint()
- const resource = parsePostData(params.resource)
+ const resource = parsePostData(params.data)
const file = createTemporalFile(
`${global.paths.CPI}/${defaultFolderTmpProvision}`,
'json',
diff --git a/src/fireedge/src/server/routes/api/oneprovision/provider/routes.js b/src/fireedge/src/server/routes/api/oneprovision/provider/routes.js
index b5d0160cd0..ac3817fc4b 100644
--- a/src/fireedge/src/server/routes/api/oneprovision/provider/routes.js
+++ b/src/fireedge/src/server/routes/api/oneprovision/provider/routes.js
@@ -17,12 +17,11 @@
const {
from: fromData,
httpMethod,
-} = require('server/utils/constants/defaults')
-const { PROVIDER } = require('server/routes/api/oneprovision/basepath')
+} = require('../../../../utils/constants/defaults')
const { GET, POST, PUT, DELETE } = httpMethod
-const basepath = `/${PROVIDER}`
const { resource, postBody } = fromData
+const basepath = '/provider'
const PROVIDER_CONNECTION = 'provider.connection'
const PROVIDER_CONFIG = 'provider.config'
@@ -73,9 +72,8 @@ module.exports = {
httpMethod: POST,
auth: true,
params: {
- resource: {
+ data: {
from: postBody,
- all: true,
},
},
},
@@ -84,9 +82,8 @@ module.exports = {
httpMethod: PUT,
auth: true,
params: {
- resource: {
+ data: {
from: postBody,
- all: true,
},
id: { from: resource },
},
diff --git a/src/fireedge/src/server/routes/api/oneprovision/provision/functions.js b/src/fireedge/src/server/routes/api/oneprovision/provision/functions.js
index 4a56e7ad3c..5f0291b9ea 100644
--- a/src/fireedge/src/server/routes/api/oneprovision/provision/functions.js
+++ b/src/fireedge/src/server/routes/api/oneprovision/provision/functions.js
@@ -790,67 +790,6 @@ const hostCommand = (
next()
}
-/**
- * SSH command of host into provision.
- *
- * @param {object} res - http response
- * @param {Function} next - express stepper
- * @param {object} params - params of http request
- * @param {string} params.action - provision action
- * @param {number} params.id - provision id
- * @param {string} params.command - provision command
- * @param {object} userData - user of http request
- * @param {string} userData.user - username
- * @param {string} userData.password - user password
- */
-const hostCommandSSH = (
- res = {},
- next = defaultEmptyFunction,
- params = {},
- userData = {}
-) => {
- const { user, password } = userData
- const { action, id, command } = params
- let rtn = httpInternalError
- if (
- action &&
- Number.isInteger(parseInt(id, 10)) &&
- command &&
- user &&
- password
- ) {
- const endpoint = getEndpoint()
- const authCommand = ['--user', user, '--password', password]
- const paramsCommand = [
- 'host',
- `${action}`.toLowerCase(),
- `${id}`.toLowerCase(),
- `${command}`.toLowerCase(),
- ...authCommand,
- ...endpoint,
- ]
- const executedCommand = executeCommand(
- defaultCommandProvision,
- paramsCommand,
- getSpecificConfig('oneprovision_prepend_command')
- )
- try {
- const response = executedCommand.success ? ok : internalServerError
- res.locals.httpCode = httpResponse(
- response,
- executedCommand.data ? JSON.parse(executedCommand.data) : params.id
- )
- next()
-
- return
- } catch (error) {
- rtn = httpResponse(internalServerError, '', executedCommand.data)
- }
- }
- res.locals.httpCode = rtn
- next()
-}
-
/**
* Create a provision.
*
@@ -876,11 +815,12 @@ const createProvision = (
const relFileYML = `${relFile}.${ext}`
const relFileLOCK = `${relFile}.lock`
const { user, password, id } = userData
- const { resource } = params
+ const { data } = params
const rtn = httpInternalError
- if (resource && user && password) {
+ if (data && user && password) {
const optionalCommand = addOptionalCreateCommand()
- const content = createYMLContent(parsePostData(params.resource))
+ const content = createYMLContent(parsePostData(data))
+
if (content) {
const command = 'create'
const authCommand = ['--user', user, '--password', password]
@@ -1053,7 +993,7 @@ const createProvision = (
* @param {object} res - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
- * @param {number} params.id - proivision id
+ * @param {number} params.id - provision id
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
@@ -1489,7 +1429,6 @@ const provisionFunctionsApi = {
deleteResource,
deleteProvision,
hostCommand,
- hostCommandSSH,
createProvision,
configureProvision,
configureHost,
diff --git a/src/fireedge/src/server/routes/api/oneprovision/provision/routes.js b/src/fireedge/src/server/routes/api/oneprovision/provision/routes.js
index f913ddb35b..0c1dc0e80e 100644
--- a/src/fireedge/src/server/routes/api/oneprovision/provision/routes.js
+++ b/src/fireedge/src/server/routes/api/oneprovision/provision/routes.js
@@ -17,71 +17,40 @@
const {
httpMethod,
from: fromData,
-} = require('server/utils/constants/defaults')
-const { PROVISION } = require('server/routes/api/oneprovision/basepath')
+} = require('../../../../utils/constants/defaults')
const { GET, POST, DELETE, PUT } = httpMethod
-const basepath = `/${PROVISION}`
const { resource, postBody } = fromData
+const basepath = '/provision'
-const PROVISION_CLUSTER_RESOURCE = 'provision.clusterresource'
-const PROVISION_DATASTORE_RESOURCE = 'provision.datastoreresource'
-const PROVISION_HOST_RESOURCE = 'provision.hostresource'
-const PROVISION_IMAGE_RESOURCE = 'provision.imageresource'
-const PROVISION_NETWORK_RESOURCE = 'provision.networkresource'
-const PROVISION_TEMPLATE_RESOURCE = 'provision.templateresource'
-const PROVISION_VNTEMPLATE_RESOURCE = 'provision.vntemplateresource'
const PROVISION_LOGS = 'provision.logs'
-const PROVISION_DEFAULTS = 'provision.defauls'
+const PROVISION_DEFAULTS = 'provision.defaults'
const PROVISION_LIST = 'provision.list'
const PROVISION_VALIDATE = 'provision.validate'
-const PROVISION_HOST_POWEROFF = 'provision.hostpoweroff'
-const PROVISION_HOST_REBOOT = 'provision.hostreboot'
-const PROVISION_HOST_RESUME = 'provision.hostresume'
const PROVISION_CREATE = 'provision.create'
-const PROVISION_HOST_SSH = 'provision.hostssh'
-const PROVISION_DATASTORE = 'provision.datastore'
-const PROVISION_FLOWTEMPLATE = 'provision.flowtemplate'
-const PROVISION_DELETE_HOST_RESOURCE = 'provision.deletehostresource'
-const PROVISION_DELETE_IMAGE_RESOURCE = 'provision.deleteimageresource'
-const PROVISION_DELETE_NETWORK_RESOURCE = 'provision.deletenetworkresource'
-const PROVISION_DELETE_VNTEMPLATE_RESOURCE = 'provision.deletevntemplate'
-const PROVISION_DELETE_TEMPLATE_RESOURCE = 'provision.deletetemplateresource'
-const PROVISION_DELETE_CLUSTER_RESOURCE = 'provision.deleteclusterresource'
-const PROVISION_DELETE_PROVISION = 'provision.deleteprovision'
-const PROVISION_UPDATE_CONFIGURE = 'provision.updateconfigure'
-const PROVISION_UPDATE_HOST = 'provision.updatehost'
-const PROVISION_ADD_HOST = 'provison.addhost'
-const PROVISION_ADD_IP = 'provision.addip'
+const PROVISION_DELETE = 'provision.delete'
+const PROVISION_CONFIGURE = 'provision.configure'
+// cluster, datastore, host, image, network, template, vntemplate, flowtemplate
+const PROVISION_GET_RESOURCE = 'provision.get_resource'
+const PROVISION_DELETE_RESOURCE = 'provision.delete_resource'
+// actions: poweroff, reboot, resume, update, configure, ssh
+const PROVISION_HOST_ACTION = 'provision.host_action'
+const PROVISION_HOST_CONFIGURE = 'provision.host_configure'
+const PROVISION_ADD_HOST = 'provison.add_host'
+const PROVISION_ADD_IP = 'provision.add_ip'
const Actions = {
- PROVISION_CLUSTER_RESOURCE,
- PROVISION_DATASTORE_RESOURCE,
- PROVISION_HOST_RESOURCE,
- PROVISION_IMAGE_RESOURCE,
- PROVISION_NETWORK_RESOURCE,
- PROVISION_TEMPLATE_RESOURCE,
- PROVISION_VNTEMPLATE_RESOURCE,
PROVISION_LOGS,
PROVISION_DEFAULTS,
PROVISION_LIST,
PROVISION_VALIDATE,
- PROVISION_HOST_POWEROFF,
- PROVISION_HOST_REBOOT,
- PROVISION_HOST_RESUME,
PROVISION_CREATE,
- PROVISION_HOST_SSH,
- PROVISION_DATASTORE,
- PROVISION_FLOWTEMPLATE,
- PROVISION_DELETE_HOST_RESOURCE,
- PROVISION_DELETE_IMAGE_RESOURCE,
- PROVISION_DELETE_NETWORK_RESOURCE,
- PROVISION_DELETE_VNTEMPLATE_RESOURCE,
- PROVISION_DELETE_TEMPLATE_RESOURCE,
- PROVISION_DELETE_CLUSTER_RESOURCE,
- PROVISION_DELETE_PROVISION,
- PROVISION_UPDATE_CONFIGURE,
- PROVISION_UPDATE_HOST,
+ PROVISION_DELETE,
+ PROVISION_CONFIGURE,
+ PROVISION_GET_RESOURCE,
+ PROVISION_DELETE_RESOURCE,
+ PROVISION_HOST_ACTION,
+ PROVISION_HOST_CONFIGURE,
PROVISION_ADD_HOST,
PROVISION_ADD_IP,
}
@@ -89,76 +58,6 @@ const Actions = {
module.exports = {
Actions,
Commands: {
- [PROVISION_CLUSTER_RESOURCE]: {
- path: `${basepath}/cluster/:resource`,
- httpMethod: GET,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- },
- },
- [PROVISION_DATASTORE_RESOURCE]: {
- path: `${basepath}/datastore/:resource`,
- httpMethod: GET,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- },
- },
- [PROVISION_HOST_RESOURCE]: {
- path: `${basepath}/host/:resource`,
- httpMethod: GET,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- },
- },
- [PROVISION_IMAGE_RESOURCE]: {
- path: `${basepath}/image/:resource`,
- httpMethod: GET,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- },
- },
- [PROVISION_NETWORK_RESOURCE]: {
- path: `${basepath}/network/:resource`,
- httpMethod: GET,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- },
- },
- [PROVISION_TEMPLATE_RESOURCE]: {
- path: `${basepath}/template/:resource`,
- httpMethod: GET,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- },
- },
- [PROVISION_VNTEMPLATE_RESOURCE]: {
- path: `${basepath}/vntemplate/:resource`,
- httpMethod: GET,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- },
- },
[PROVISION_LOGS]: {
path: `${basepath}/log/:id`,
httpMethod: GET,
@@ -194,177 +93,17 @@ module.exports = {
},
},
},
- [PROVISION_HOST_POWEROFF]: {
- path: `${basepath}/host/poweroff/:action/:id`,
- httpMethod: POST,
- auth: true,
- params: {
- action: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
- [PROVISION_HOST_REBOOT]: {
- path: `${basepath}/host/reboot/:action/:id`,
- httpMethod: POST,
- auth: true,
- params: {
- action: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
- [PROVISION_HOST_RESUME]: {
- path: `${basepath}/host/resume/:action/:id`,
- httpMethod: POST,
- auth: true,
- params: {
- action: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
[PROVISION_CREATE]: {
path: `${basepath}`,
httpMethod: POST,
auth: true,
params: {
- resource: {
- from: postBody,
- all: true,
- },
- },
- },
- [PROVISION_HOST_SSH]: {
- path: `${basepath}/host/ssh/:action/:id/:command`,
- httpMethod: DELETE,
- auth: true,
- params: {
- action: {
- from: resource,
- },
- id: {
- from: resource,
- },
- command: {
+ data: {
from: postBody,
},
},
},
- [PROVISION_DATASTORE]: {
- path: `${basepath}/datastore/:resource/:id`,
- httpMethod: DELETE,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
- [PROVISION_FLOWTEMPLATE]: {
- path: `${basepath}/flowtemplate/:resource/:id`,
- httpMethod: DELETE,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
- [PROVISION_DELETE_HOST_RESOURCE]: {
- path: `${basepath}/:resource/:id`,
- httpMethod: DELETE,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
- [PROVISION_DELETE_IMAGE_RESOURCE]: {
- path: `${basepath}/:resource/:id`,
- httpMethod: DELETE,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
- [PROVISION_DELETE_NETWORK_RESOURCE]: {
- path: `${basepath}/:resource/:id`,
- httpMethod: DELETE,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
- [PROVISION_DELETE_VNTEMPLATE_RESOURCE]: {
- path: `${basepath}/:resource/:id`,
- httpMethod: DELETE,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
- [PROVISION_DELETE_TEMPLATE_RESOURCE]: {
- path: `${basepath}/:resource/:id`,
- httpMethod: DELETE,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
- [PROVISION_DELETE_CLUSTER_RESOURCE]: {
- path: `${basepath}/:resource/:id`,
- httpMethod: DELETE,
- auth: true,
- params: {
- resource: {
- from: resource,
- },
- id: {
- from: resource,
- },
- },
- },
- [PROVISION_DELETE_PROVISION]: {
+ [PROVISION_DELETE]: {
path: `${basepath}/:id`,
httpMethod: DELETE,
auth: true,
@@ -380,7 +119,7 @@ module.exports = {
},
},
},
- [PROVISION_UPDATE_CONFIGURE]: {
+ [PROVISION_CONFIGURE]: {
path: `${basepath}/configure/:id`,
httpMethod: PUT,
auth: true,
@@ -390,7 +129,43 @@ module.exports = {
},
},
},
- [PROVISION_UPDATE_HOST]: {
+ [PROVISION_GET_RESOURCE]: {
+ path: `${basepath}/resource/:resource`,
+ httpMethod: GET,
+ auth: true,
+ params: {
+ resource: {
+ from: resource,
+ },
+ },
+ },
+ [PROVISION_DELETE_RESOURCE]: {
+ path: `${basepath}/resource/:resource/:id`,
+ httpMethod: DELETE,
+ auth: true,
+ params: {
+ resource: {
+ from: resource,
+ },
+ id: {
+ from: resource,
+ },
+ },
+ },
+ [PROVISION_HOST_ACTION]: {
+ path: `${basepath}/host/:action/:id`,
+ httpMethod: POST,
+ auth: true,
+ params: {
+ action: {
+ from: resource,
+ },
+ id: {
+ from: resource,
+ },
+ },
+ },
+ [PROVISION_HOST_CONFIGURE]: {
path: `${basepath}/host/:id`,
httpMethod: PUT,
auth: true,
diff --git a/src/fireedge/src/server/routes/api/oneprovision/template/routes.js b/src/fireedge/src/server/routes/api/oneprovision/template/routes.js
index cbe4bcb7e2..7f37eb4983 100644
--- a/src/fireedge/src/server/routes/api/oneprovision/template/routes.js
+++ b/src/fireedge/src/server/routes/api/oneprovision/template/routes.js
@@ -16,11 +16,8 @@
const { from: fromData } = require('server/utils/constants/defaults')
const { httpMethod } = require('server/utils/constants/defaults')
-const {
- PROVISION_TEMPLATE,
-} = require('server/routes/api/oneprovision/basepath')
-const basepath = `/${PROVISION_TEMPLATE}`
+const basepath = '/provision-template'
const { GET, POST, PUT, DELETE } = httpMethod
const { resource, postBody } = fromData
diff --git a/src/fireedge/src/server/routes/api/sunstone/basepath.js b/src/fireedge/src/server/routes/api/sunstone/basepath.js
deleted file mode 100644
index 6681f23fe1..0000000000
--- a/src/fireedge/src/server/routes/api/sunstone/basepath.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* ------------------------------------------------------------------------- *
- * Copyright 2002-2021, 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. *
- * ------------------------------------------------------------------------- */
-
-module.exports = 'sunstone'
diff --git a/src/fireedge/src/server/routes/api/sunstone/routes.js b/src/fireedge/src/server/routes/api/sunstone/routes.js
index 7b427993d0..04ae62adf0 100644
--- a/src/fireedge/src/server/routes/api/sunstone/routes.js
+++ b/src/fireedge/src/server/routes/api/sunstone/routes.js
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-
-const { httpMethod } = require('server/utils/constants/defaults')
-const SUNSTONE = require('server/routes/api/sunstone/basepath')
+const { httpMethod } = require('../../../utils/constants/defaults')
const { GET } = httpMethod
-const basepath = `/${SUNSTONE}`
+
+const basepath = '/sunstone'
const SUNSTONE_VIEWS = 'sunstone.views'
const SUNSTONE_CONFIG = 'sunstone.config'
diff --git a/src/fireedge/src/server/utils/constants/commands/market.js b/src/fireedge/src/server/utils/constants/commands/market.js
index 8b69e1abab..3232a720f2 100644
--- a/src/fireedge/src/server/utils/constants/commands/market.js
+++ b/src/fireedge/src/server/utils/constants/commands/market.js
@@ -25,6 +25,7 @@ const MARKET_UPDATE = 'market.update'
const MARKET_CHMOD = 'market.chmod'
const MARKET_CHOWN = 'market.chown'
const MARKET_RENAME = 'market.rename'
+const MARKET_ENABLE = 'market.enable'
const MARKET_INFO = 'market.info'
const MARKET_POOL_INFO = 'marketpool.info'
@@ -35,6 +36,7 @@ const Actions = {
MARKET_CHMOD,
MARKET_CHOWN,
MARKET_RENAME,
+ MARKET_ENABLE,
MARKET_INFO,
MARKET_POOL_INFO,
}
@@ -158,6 +160,20 @@ module.exports = {
},
},
},
+ [MARKET_ENABLE]: {
+ // inspected
+ httpMethod: PUT,
+ params: {
+ id: {
+ from: resource,
+ default: 0,
+ },
+ enable: {
+ from: postBody,
+ default: true,
+ },
+ },
+ },
[MARKET_INFO]: {
// inspected
httpMethod: GET,
diff --git a/src/fireedge/src/server/utils/constants/commands/user.js b/src/fireedge/src/server/utils/constants/commands/user.js
index 0a34f04dbb..f844b378a3 100644
--- a/src/fireedge/src/server/utils/constants/commands/user.js
+++ b/src/fireedge/src/server/utils/constants/commands/user.js
@@ -29,6 +29,7 @@ const USER_QUOTA = 'user.quota'
const USER_CHGRP = 'user.chgrp'
const USER_ADDGROUP = 'user.addgroup'
const USER_DELGROUP = 'user.delgroup'
+const USER_ENABLE = 'user.enable'
const USER_INFO = 'user.info'
const USER_POOL_INFO = 'userpool.info'
const USER_QUOTA_INFO = 'userquota.info'
@@ -214,6 +215,20 @@ module.exports = {
},
},
},
+ [USER_ENABLE]: {
+ // inspected
+ httpMethod: PUT,
+ params: {
+ id: {
+ from: resource,
+ default: 0,
+ },
+ enable: {
+ from: postBody,
+ default: true,
+ },
+ },
+ },
[USER_INFO]: {
// inspected
httpMethod: GET,
diff --git a/src/fireedge/src/server/utils/constants/commands/vm.js b/src/fireedge/src/server/utils/constants/commands/vm.js
index 34d0b6e674..7f2f767593 100644
--- a/src/fireedge/src/server/utils/constants/commands/vm.js
+++ b/src/fireedge/src/server/utils/constants/commands/vm.js
@@ -612,7 +612,7 @@ module.exports = {
from: resource,
default: 0,
},
- id_sched: {
+ schedId: {
from: postBody,
default: 0,
},
@@ -629,7 +629,7 @@ module.exports = {
from: resource,
default: 0,
},
- id_sched: {
+ schedId: {
from: postBody,
default: 0,
},
@@ -653,7 +653,7 @@ module.exports = {
},
state: {
from: query,
- default: -2,
+ default: -1,
},
filterByKey: {
from: query,
@@ -679,7 +679,7 @@ module.exports = {
},
state: {
from: query,
- default: -2,
+ default: -1,
},
filterBykey: {
from: query,
@@ -695,6 +695,10 @@ module.exports = {
from: query,
default: -2,
},
+ seconds: {
+ from: query,
+ default: -1,
+ },
},
},
[VM_POOL_ACCOUNTING]: {