mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-20 14:03:36 +03:00
B OpenNebula/one#6725: Fix problems in vrouters in Sunstone (#3230)
Signed-off-by: dcarracedo <dcarracedo@opennebula.io> Co-authored-by: Tino Vázquez <cvazquez@opennebula.io>
This commit is contained in:
parent
a95a94b5a6
commit
b2fe5a3010
@ -34,7 +34,7 @@ const NAME = {
|
||||
|
||||
const DESCRIPTION = {
|
||||
name: 'description',
|
||||
label: 'Description',
|
||||
label: T.Description,
|
||||
type: INPUT_TYPES.TEXT,
|
||||
multiline: true,
|
||||
validation: string().trim().default(''),
|
||||
@ -64,7 +64,7 @@ const KEEPALIVEPASS = {
|
||||
const VMNAME = {
|
||||
name: 'vmname',
|
||||
label: T.VmName,
|
||||
tooltip: T.VmTemplateNameHelper,
|
||||
tooltip: T.VmVrTemplateNameHelper,
|
||||
type: INPUT_TYPES.TEXT,
|
||||
validation: string()
|
||||
.trim()
|
||||
@ -107,15 +107,6 @@ const HOLD = {
|
||||
grid: { md: 12 },
|
||||
}
|
||||
|
||||
const PERSISTENT = {
|
||||
name: 'persistent',
|
||||
label: T.InstantiateAsPersistent,
|
||||
type: INPUT_TYPES.SWITCH,
|
||||
tooltip: T.InstantiateAsPersistentConcept,
|
||||
validation: boolean().default(() => false),
|
||||
grid: { md: 12 },
|
||||
}
|
||||
|
||||
export const FIELDS = [
|
||||
NAME,
|
||||
DESCRIPTION,
|
||||
@ -124,7 +115,6 @@ export const FIELDS = [
|
||||
VMNAME,
|
||||
INSTANCES,
|
||||
HOLD,
|
||||
PERSISTENT,
|
||||
]
|
||||
|
||||
export const SCHEMA = getObjectSchemaFromFields(FIELDS)
|
||||
|
@ -47,8 +47,8 @@ const NicCard = ({ info = {}, removeNic, selectNic, active } = {}) => {
|
||||
nicId,
|
||||
VROUTER_MANAGEMENT: management,
|
||||
autonetworkselect,
|
||||
sshconnection,
|
||||
rdpconnection,
|
||||
SSH: sshconnection,
|
||||
RDP: rdpconnection,
|
||||
} = info
|
||||
|
||||
return (
|
||||
|
@ -13,14 +13,13 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { mixed, number, boolean } from 'yup'
|
||||
import { mixed, boolean, array, string } from 'yup'
|
||||
import { VNetworksTable, SecurityGroupsTable } from 'client/components/Tables'
|
||||
import { getObjectSchemaFromFields } from 'client/utils'
|
||||
|
||||
import { getObjectSchemaFromFields, REG_V4, REG_V6 } from 'client/utils'
|
||||
import { T, INPUT_TYPES } from 'client/constants'
|
||||
|
||||
const NETWORK = {
|
||||
name: 'network_id',
|
||||
name: 'NETWORK_ID',
|
||||
label: T.Network,
|
||||
type: INPUT_TYPES.TABLE,
|
||||
cy: 'network',
|
||||
@ -36,17 +35,21 @@ const NETWORK = {
|
||||
}
|
||||
|
||||
const RDP = {
|
||||
name: 'rdpconnection',
|
||||
name: 'RDP',
|
||||
label: T.RdpConnection,
|
||||
type: INPUT_TYPES.SWITCH,
|
||||
validation: boolean().default(() => false),
|
||||
validation: boolean()
|
||||
.yesOrNo()
|
||||
.default(() => false),
|
||||
grid: { md: 6 },
|
||||
}
|
||||
const SSH = {
|
||||
name: 'sshconnection',
|
||||
name: 'SSH',
|
||||
label: T.SshConnection,
|
||||
type: INPUT_TYPES.SWITCH,
|
||||
validation: boolean().default(() => false),
|
||||
validation: boolean()
|
||||
.yesOrNo()
|
||||
.default(() => false),
|
||||
grid: { md: 6 },
|
||||
}
|
||||
|
||||
@ -54,15 +57,15 @@ const FORCEIPV4 = {
|
||||
name: 'IP',
|
||||
label: T.VirtualRouterNICForceIpv4,
|
||||
type: INPUT_TYPES.TEXT,
|
||||
validation: number()
|
||||
.min(7) // Shortest possible IPv4
|
||||
.max(16) // Longest possible
|
||||
validation: string()
|
||||
.trim()
|
||||
.matches(REG_V4, { message: T.InvalidIPv4 })
|
||||
.default(() => undefined),
|
||||
grid: { md: 6 },
|
||||
}
|
||||
|
||||
const FLOATINGIP = {
|
||||
name: 'floating_ip',
|
||||
name: 'FLOATING_IP',
|
||||
label: T.VirtualRouterNICFloatingIP,
|
||||
type: INPUT_TYPES.CHECKBOX,
|
||||
validation: boolean().yesOrNo(),
|
||||
@ -73,9 +76,9 @@ const FORCEIPV6 = {
|
||||
name: 'IP6',
|
||||
label: T.VirtualRouterNICForceIpv6,
|
||||
type: INPUT_TYPES.TEXT,
|
||||
validation: number()
|
||||
.min(7)
|
||||
.max(39)
|
||||
validation: string()
|
||||
.trim()
|
||||
.matches(REG_V6, { message: T.InvalidIPv6 })
|
||||
.default(() => undefined),
|
||||
grid: { md: 6 },
|
||||
}
|
||||
@ -89,7 +92,7 @@ const MANAGEMENINTERFACE = {
|
||||
}
|
||||
|
||||
const SECURITY_GROUPS = {
|
||||
name: 'secgroup',
|
||||
name: 'SECURITY_GROUPS',
|
||||
label: T.SecurityGroups,
|
||||
type: INPUT_TYPES.TABLE,
|
||||
cy: 'secgroup',
|
||||
@ -115,4 +118,4 @@ export const FIELDS = [
|
||||
SECURITY_GROUPS,
|
||||
]
|
||||
|
||||
export const SCHEMA = getObjectSchemaFromFields(FIELDS)
|
||||
export const SCHEMA = array().of(getObjectSchemaFromFields(FIELDS))
|
||||
|
@ -42,12 +42,12 @@ const Content = () => {
|
||||
append,
|
||||
remove,
|
||||
} = useFieldArray({
|
||||
name: `${STEP_ID}.NIC`,
|
||||
name: `${STEP_ID}`,
|
||||
})
|
||||
|
||||
const watchedNicsArray = useWatch({
|
||||
control,
|
||||
name: `${STEP_ID}.NIC`,
|
||||
name: `${STEP_ID}`,
|
||||
})
|
||||
|
||||
const handleAddnewNic = () => {
|
||||
@ -92,11 +92,11 @@ const Content = () => {
|
||||
) : (
|
||||
<FormWithSchema
|
||||
legend={Tr(T.VirtualRouterNICNetworkConfiguration)}
|
||||
key={`${STEP_ID}-NIC-${activeNic}`}
|
||||
key={`${STEP_ID}-${activeNic}`}
|
||||
cy={STEP_ID}
|
||||
fields={FIELDS}
|
||||
saveState={true}
|
||||
id={`${STEP_ID}.NIC.${activeNic}`}
|
||||
id={`${STEP_ID}.${activeNic}`}
|
||||
/>
|
||||
),
|
||||
[nics, activeNic]
|
||||
|
@ -77,23 +77,33 @@ const Steps = createSteps(
|
||||
)
|
||||
},
|
||||
transformBeforeSubmit: (formData, vmTemplate) => {
|
||||
const { [BASIC_ID]: { name, instances, hold, persistent, vmname } = {} } =
|
||||
const { [BASIC_ID]: { name, instances, hold, vmname } = {} } =
|
||||
formData ?? {}
|
||||
|
||||
const selectedTemplateID = formData?.template_selection?.vmTemplate
|
||||
|
||||
delete formData?.template_selection
|
||||
|
||||
const templates = [...new Array(instances)].map((__, idx) => ({
|
||||
id: vmTemplate?.ID ?? selectedTemplateID,
|
||||
vrname: name,
|
||||
name: vmname?.replace(/%idx/gi, idx), // VM NAME
|
||||
number: instances,
|
||||
pending: hold, // start on hold
|
||||
persistent: persistent,
|
||||
...(selectedTemplateID && { initiateFromSelection: true }),
|
||||
...formData,
|
||||
}))
|
||||
// Delete nic id
|
||||
formData.networking.forEach((nic) => {
|
||||
delete nic.nicId
|
||||
})
|
||||
|
||||
const templates = [
|
||||
{
|
||||
id: vmTemplate?.ID ?? selectedTemplateID,
|
||||
vrname: name,
|
||||
name: vmname
|
||||
? vmname.includes('%i')
|
||||
? vmname
|
||||
: vmname + '-%i'
|
||||
: undefined,
|
||||
number: instances,
|
||||
pending: hold, // start on hold
|
||||
...(selectedTemplateID && { initiateFromSelection: true }),
|
||||
...formData,
|
||||
},
|
||||
]
|
||||
|
||||
return templates
|
||||
},
|
||||
|
@ -1107,6 +1107,10 @@ module.exports = {
|
||||
Defaults to 'template name-<vmid>' when empty.
|
||||
When creating several VMs, the wildcard %%idx will be
|
||||
replaced with a number starting from 0`,
|
||||
VmVrTemplateNameHelper: `
|
||||
Defaults to 'template name-<vmid>' when empty.
|
||||
When creating several VMs, the wildcard %%i will be
|
||||
replaced with a number starting from 0`,
|
||||
NumberOfInstances: 'Number of instances',
|
||||
NumberOfVms: 'Number of VMs',
|
||||
MakeTemplateAvailableForVROnly:
|
||||
|
@ -20,7 +20,6 @@ import { useGeneralApi } from 'client/features/General'
|
||||
import { useGetGroupsQuery } from 'client/features/OneApi/group'
|
||||
import { useGetUsersQuery } from 'client/features/OneApi/user'
|
||||
import { useGetTemplateQuery } from 'client/features/OneApi/vmTemplate'
|
||||
import { convertKeysToCase } from 'client/utils'
|
||||
|
||||
import {
|
||||
useInstantiateVRouterTemplateMutation,
|
||||
@ -76,20 +75,40 @@ function InstantiateVrTemplate() {
|
||||
const promises = templates.map(async (t) => {
|
||||
t.template = jsonToXml(t)
|
||||
|
||||
/**
|
||||
* In allocate request template send only the following info:
|
||||
* - Name - Name of the vrouter
|
||||
* - Description - Description of the vrouter
|
||||
* - Keep alive ID
|
||||
* - Keep alive password
|
||||
* - NICS
|
||||
*/
|
||||
const allocationResult = await allocate({
|
||||
template: jsonToXml({
|
||||
NAME: t.vrname,
|
||||
...(t?.networking?.NIC
|
||||
? { NIC: convertKeysToCase(t.networking.NIC, false) }
|
||||
: {}),
|
||||
DESCRIPTION: t.general?.description,
|
||||
KEEPALIVED_ID: t.general?.keepaliveid,
|
||||
KEEPALIVED_PASSWORD: t.general?.keepalivepass,
|
||||
NIC: t.networking,
|
||||
}),
|
||||
}).unwrap()
|
||||
|
||||
/**
|
||||
* In instantiate request send only the following info:
|
||||
* - id - If of the vrouter (created in the previous allocate request)
|
||||
* - templateId - Id of the vrouter template
|
||||
* - number - Number of virtual machines that are gonna be instantiated
|
||||
* - pending - Start virtual machines on hold state
|
||||
* - template - XML template only with the user inputs
|
||||
*/
|
||||
return instantiate({
|
||||
...t,
|
||||
fromPostbody: t?.initiateFromSelection,
|
||||
id: allocationResult,
|
||||
templateId: templateId ?? parseInt(t?.id, 10),
|
||||
...(t?.initiateFromSelection && { fromPostbody: true }),
|
||||
number: t?.number,
|
||||
name: t?.name,
|
||||
pending: t?.pending,
|
||||
template: jsonToXml(t?.user_inputs),
|
||||
}).unwrap()
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user