diff --git a/src/fireedge/src/client/components/Cards/DatastoreCard.js b/src/fireedge/src/client/components/Cards/DatastoreCard.js
index d3994db972..c9d727c374 100644
--- a/src/fireedge/src/client/components/Cards/DatastoreCard.js
+++ b/src/fireedge/src/client/components/Cards/DatastoreCard.js
@@ -69,7 +69,7 @@ const DatastoreCard = memo(
{NAME}
-
+
}
subheader={`#${ID}`}
diff --git a/src/fireedge/src/client/components/Forms/Provision/DeleteForm/schema.js b/src/fireedge/src/client/components/Forms/Provision/DeleteForm/schema.js
index 50f91c1d52..d09123d7ca 100644
--- a/src/fireedge/src/client/components/Forms/Provision/DeleteForm/schema.js
+++ b/src/fireedge/src/client/components/Forms/Provision/DeleteForm/schema.js
@@ -13,24 +13,30 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-/* eslint-disable jsdoc/require-jsdoc */
-import * as yup from 'yup'
-import { INPUT_TYPES } from 'client/constants'
+import { object, boolean } from 'yup'
+import { T, INPUT_TYPES } from 'client/constants'
import { getValidationFromFields } from 'client/utils'
const CLEANUP = {
name: 'cleanup',
- label: 'Cleanup',
+ label: T.Cleanup,
type: INPUT_TYPES.SWITCH,
- tooltip: `
- Force to terminate VMs running on provisioned Hosts
- and delete all images in the datastores.`,
- validation: yup
- .boolean()
+ tooltip: T.CleanupConcept,
+ validation: boolean()
.notRequired()
.default(() => false),
}
-export const FIELDS = [CLEANUP]
+const FORCE = {
+ name: 'force',
+ label: T.Force,
+ type: INPUT_TYPES.SWITCH,
+ tooltip: T.ForceConcept,
+ validation: boolean()
+ .notRequired()
+ .default(() => false),
+}
-export const SCHEMA = yup.object(getValidationFromFields(FIELDS))
+export const FIELDS = [CLEANUP, FORCE]
+
+export const SCHEMA = object(getValidationFromFields(FIELDS))
diff --git a/src/fireedge/src/client/constants/translates.js b/src/fireedge/src/client/constants/translates.js
index 6165330db7..a9eb94af2c 100644
--- a/src/fireedge/src/client/constants/translates.js
+++ b/src/fireedge/src/client/constants/translates.js
@@ -228,6 +228,12 @@ module.exports = {
ProviderTemplate: 'Provider template',
ProvisionTemplate: 'Provision template',
ConfigureInputs: 'Configure inputs',
+ AddIP: 'Add IP',
+ AddHost: 'Add Host',
+ Cleanup: 'Cleanup',
+ CleanupConcept: 'Delete all vms and images first, then delete the resources',
+ Force: 'Force',
+ ForceConcept: 'Force configure to execute',
/* sections */
Dashboard: 'Dashboard',
diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js
index dbfcc7ae62..c08b25ac2c 100644
--- a/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js
+++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/hosts.js
@@ -13,25 +13,42 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { memo, useEffect } from 'react'
+import { memo, useEffect, useState } from 'react'
import PropTypes from 'prop-types'
-import { Trash as DeleteIcon, Settings as ConfigureIcon } from 'iconoir-react'
+import {
+ Trash as DeleteIcon,
+ Settings as ConfigureIcon,
+ AddCircledOutline,
+} from 'iconoir-react'
+import { Stack, TextField } from '@mui/material'
-import { useFetchAll } from 'client/hooks'
+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 { HostCard } from 'client/components/Cards'
+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 { enqueueSuccess, enqueueInfo } = useGeneralApi()
- const { configureHost, deleteHost } = useProvisionApi()
+ const { configureHost, deleteHost, addHost } = useProvisionApi()
const { getHost } = useHostApi()
+ const { fetchRequest, loading: loadingAddHost } = useFetch(
+ async (payload) => {
+ await addHost(data?.ID, payload)
+ await refetchProvision()
+ enqueueSuccess(`Host added ${amount}x`)
+ }
+ )
+
const { data: list, fetchRequestAll, loading } = useFetchAll()
const fetchHosts = () =>
fetchRequestAll(hosts?.map(({ id }) => getHost(id)))
@@ -45,35 +62,59 @@ const Hosts = memo(
}, [reloading])
return (
-
- !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}`,
- },
- ],
+ <>
+
+ {
+ 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 }}
- />
+ displayEmpty
+ breakpoints={{ xs: 12, md: 6 }}
+ />
+ >
)
},
(prev, next) =>
diff --git a/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js b/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js
index 32d5d981b5..416e661e37 100644
--- a/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js
+++ b/src/fireedge/src/client/containers/Provisions/DialogInfo/networks.js
@@ -13,25 +13,38 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
-import { memo, useEffect } from 'react'
+import { memo, useEffect, useState } from 'react'
import PropTypes from 'prop-types'
-import { Trash as DeleteIcon } from 'iconoir-react'
+import { Trash as DeleteIcon, AddCircledOutline } from 'iconoir-react'
+import { Stack, TextField } from '@mui/material'
-import { useFetchAll } from 'client/hooks'
+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 { NetworkCard } from 'client/components/Cards'
+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 { enqueueSuccess } = useGeneralApi()
- const { deleteVNetwork } = useProvisionApi()
+ const { deleteVNetwork, addIp } = useProvisionApi()
const { getVNetwork } = useVNetworkApi()
+ const { fetchRequest, loading: loadingAddIp } = useFetch(
+ async (payload) => {
+ await addIp(data?.ID, payload)
+ await refetchProvision()
+ enqueueSuccess(`IP added ${amount}x`)
+ }
+ )
+
const { data: list, fetchRequestAll, loading } = useFetchAll()
const fetchVNetworks = () =>
fetchRequestAll(networks?.map(({ id }) => getVNetwork(id)))
@@ -45,27 +58,53 @@ const Networks = memo(
}, [reloading])
return (
-
- !disableAllActions && {
- actions: [
- {
- handleClick: () =>
- deleteVNetwork(ID)
- .then(refetchProvision)
- .then(() => enqueueSuccess(`VNetwork deleted - ID: ${ID}`)),
- icon: ,
- cy: `provision-vnet-delete-${ID}`,
- },
- ],
+ <>
+
+ {
+ 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 }}
- />
+ displayEmpty
+ breakpoints={{ xs: 12, md: 6 }}
+ />
+ >
)
},
(prev, next) =>
diff --git a/src/fireedge/src/client/features/One/provision/actions.js b/src/fireedge/src/client/features/One/provision/actions.js
index f80773b6e5..28ab06fddb 100644
--- a/src/fireedge/src/client/features/One/provision/actions.js
+++ b/src/fireedge/src/client/features/One/provision/actions.js
@@ -72,3 +72,8 @@ 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
index 50e8abcfc0..3a7bdf4984 100644
--- a/src/fireedge/src/client/features/One/provision/hooks.js
+++ b/src/fireedge/src/client/features/One/provision/hooks.js
@@ -55,5 +55,7 @@ export const useProvisionApi = () => {
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
index 5934e8d622..e893aabb5b 100644
--- a/src/fireedge/src/client/features/One/provision/services.js
+++ b/src/fireedge/src/client/features/One/provision/services.js
@@ -137,7 +137,8 @@ export const provisionService = {
*
* @param {object} params - Request parameters
* @param {object} params.id - Provider id
- * @param {object} params.cleanup
+ * @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
@@ -261,4 +262,52 @@ export const provisionService = {
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}/host/${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/server/routes/api/oneprovision/provision/functions.js b/src/fireedge/src/server/routes/api/oneprovision/provision/functions.js
index 9f54e939ba..9efc2dadfe 100644
--- a/src/fireedge/src/server/routes/api/oneprovision/provision/functions.js
+++ b/src/fireedge/src/server/routes/api/oneprovision/provision/functions.js
@@ -1381,7 +1381,7 @@ const hostAdd = (
'host',
'add',
id,
- 'amount',
+ '--amount',
amount,
...authCommand,
...endpoint,
@@ -1423,7 +1423,7 @@ const ipAdd = (
'ip',
'add',
id,
- 'amount',
+ '--amount',
amount,
...authCommand,
...endpoint,
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 36bf3c708e..a20854d87f 100644
--- a/src/fireedge/src/server/routes/api/oneprovision/provision/routes.js
+++ b/src/fireedge/src/server/routes/api/oneprovision/provision/routes.js
@@ -287,7 +287,7 @@ module.exports = {
},
},
[PROVISION_DELETE_HOST_RESOURCE]: {
- path: `${basepath}/host/:resource/:id`,
+ path: `${basepath}/:resource/:id`,
httpMethod: DELETE,
auth: true,
params: {
@@ -300,7 +300,7 @@ module.exports = {
},
},
[PROVISION_DELETE_IMAGE_RESOURCE]: {
- path: `${basepath}/image/:resource/:id`,
+ path: `${basepath}/:resource/:id`,
httpMethod: DELETE,
auth: true,
params: {
@@ -313,7 +313,7 @@ module.exports = {
},
},
[PROVISION_DELETE_NETWORK_RESOURCE]: {
- path: `${basepath}/network/:resource/:id`,
+ path: `${basepath}/:resource/:id`,
httpMethod: DELETE,
auth: true,
params: {
@@ -326,7 +326,7 @@ module.exports = {
},
},
[PROVISION_DELETE_VNTEMPLATE_RESOURCE]: {
- path: `${basepath}/vntemplate/:resource/:id`,
+ path: `${basepath}/:resource/:id`,
httpMethod: DELETE,
auth: true,
params: {
@@ -339,7 +339,7 @@ module.exports = {
},
},
[PROVISION_DELETE_TEMPLATE_RESOURCE]: {
- path: `${basepath}/template/:resource/:id`,
+ path: `${basepath}/:resource/:id`,
httpMethod: DELETE,
auth: true,
params: {
@@ -352,7 +352,7 @@ module.exports = {
},
},
[PROVISION_DELETE_CLUSTER_RESOURCE]: {
- path: `${basepath}/cluster/:resource/:id`,
+ path: `${basepath}/:resource/:id`,
httpMethod: DELETE,
auth: true,
params: {