diff --git a/ui/src/locales/en.json b/ui/src/locales/en.json
index 3134b000802..0faabc37e35 100644
--- a/ui/src/locales/en.json
+++ b/ui/src/locales/en.json
@@ -481,6 +481,7 @@
"label.add.ldap.list.users": "List LDAP users",
"label.add.list.name":"ACL List Name",
"label.add.netScaler.device": "Add Netscaler device",
+"label.add.network":"Add Network",
"label.add.network.offering": "Add network offering",
"label.add.new.gateway": "Add new gateway",
"label.add.new.tier": "Add new tier",
@@ -1308,5 +1309,7 @@
"writeback": "Write-back disk caching",
"writethrough": "Write-through",
"none": "None",
-"maxcpunumber": "Max CPU Cores"
+"maxcpunumber": "Max CPU Cores",
+"message.template.iso": "Please select a template or ISO to continue",
+"label.launch.vm": "Launch Virtual Machine"
}
diff --git a/ui/src/views/compute/CreateKubernetesCluster.vue b/ui/src/views/compute/CreateKubernetesCluster.vue
index 15b9237a4db..e306d72f4a7 100644
--- a/ui/src/views/compute/CreateKubernetesCluster.vue
+++ b/ui/src/views/compute/CreateKubernetesCluster.vue
@@ -49,7 +49,7 @@
}"
:loading="zoneLoading"
:placeholder="apiParams.zoneid.description"
- @change="val => { this.handleZoneChanged(this.zones[val]) }">
+ @change="val => { this.handleZoneChange(this.zones[val]) }">
{{ opt.name || opt.description }}
diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue
index 4459141407a..4943cbb876c 100644
--- a/ui/src/views/compute/DeployVM.vue
+++ b/ui/src/views/compute/DeployVM.vue
@@ -72,11 +72,7 @@
>
-
+
+ @update-template-iso="updateFieldValue" />
this.hypervisor = value"
- >
-
+ @change="value => this.hypervisor = value" />
@@ -318,8 +311,8 @@ import { mixin, mixinDevice } from '@/utils/mixin.js'
import store from '@/store'
import InfoCard from '@/components/view/InfoCard'
-import ComputeOfferingSelection from './wizard/ComputeOfferingSelection'
-import ComputeSelection from './wizard/ComputeSelection'
+import ComputeOfferingSelection from '@views/compute/wizard/ComputeOfferingSelection'
+import ComputeSelection from '@views/compute/wizard/ComputeSelection'
import DiskOfferingSelection from '@views/compute/wizard/DiskOfferingSelection'
import DiskSizeSelection from '@views/compute/wizard/DiskSizeSelection'
import TemplateIsoSelection from '@views/compute/wizard/TemplateIsoSelection'
@@ -424,6 +417,7 @@ export default {
initDataConfig: {},
defaultNetwork: '',
networkConfig: [],
+ dataNetworkCreated: [],
tabList: [
{
key: 'templateid',
@@ -548,14 +542,6 @@ export default {
type: 'Routing'
},
field: 'hostid'
- },
- groups: {
- list: 'listInstanceGroups',
- options: {
- listall: false
- },
- isLoad: true,
- field: 'group'
}
}
},
@@ -609,14 +595,6 @@ export default {
value: keyboard.id
}
})
- },
- groupsSelectOptions () {
- return this.options.groups.map((group) => {
- return {
- label: group.name,
- value: group.id
- }
- })
}
},
watch: {
@@ -854,10 +832,23 @@ export default {
handleSubmit (e) {
console.log('wizard submit')
e.preventDefault()
- this.form.validateFields((err, values) => {
+ this.form.validateFields(async (err, values) => {
if (err) {
return
}
+
+ if (!values.templateid && !values.isoid) {
+ this.$notification.error({
+ message: 'Request Failed',
+ description: this.$t('message.template.iso')
+ })
+ return
+ }
+
+ this.loading.deploy = true
+
+ let networkIds = []
+
const deployVmData = {}
// step 1 : select zone
deployVmData.zoneid = values.zoneid
@@ -902,15 +893,30 @@ export default {
// step 5: select an affinity group
deployVmData.affinitygroupids = (values.affinitygroupids || []).join(',')
// step 6: select network
- if (values.networkids && values.networkids.length > 0) {
- for (let i = 0; i < values.networkids.length; i++) {
- deployVmData['iptonetworklist[' + i + '].networkid'] = values.networkids[i]
- if (this.networkConfig.length > 0) {
- const networkConfig = this.networkConfig.filter((item) => item.key === values.networkids[i])
- if (networkConfig && networkConfig.length > 0) {
- deployVmData['iptonetworklist[' + i + '].ip'] = networkConfig[0].ipAddress ? networkConfig[0].ipAddress : undefined
- deployVmData['iptonetworklist[' + i + '].mac'] = networkConfig[0].macAddress ? networkConfig[0].macAddress : undefined
+ const arrNetwork = []
+ networkIds = values.networkids
+ if (networkIds.length > 0) {
+ for (let i = 0; i < networkIds.length; i++) {
+ if (networkIds[i] === this.defaultNetwork) {
+ const ipToNetwork = {
+ networkid: this.defaultNetwork
}
+ arrNetwork.unshift(ipToNetwork)
+ } else {
+ const ipToNetwork = {
+ networkid: networkIds[i]
+ }
+ arrNetwork.push(ipToNetwork)
+ }
+ }
+ }
+ for (let j = 0; j < arrNetwork.length; j++) {
+ deployVmData['iptonetworklist[' + j + '].networkid'] = arrNetwork[j].networkid
+ if (this.networkConfig.length > 0) {
+ const networkConfig = this.networkConfig.filter((item) => item.key === arrNetwork[j].networkid)
+ if (networkConfig && networkConfig.length > 0) {
+ deployVmData['iptonetworklist[' + j + '].ip'] = networkConfig[0].ipAddress ? networkConfig[0].ipAddress : undefined
+ deployVmData['iptonetworklist[' + j + '].mac'] = networkConfig[0].macAddress ? networkConfig[0].macAddress : undefined
}
}
}
@@ -918,31 +924,34 @@ export default {
deployVmData.keypair = values.keypair
deployVmData.name = values.name
deployVmData.displayname = values.name
- const title = this.$t('Launch Virtual Machine')
- const description = deployVmData.name ? deployVmData.name : values.zoneid
- this.loading.deploy = true
+ const title = this.$t('label.launch.vm')
+ const description = values.name || ''
+ const password = this.$t('password')
api('deployVirtualMachine', deployVmData).then(response => {
const jobId = response.deployvirtualmachineresponse.jobid
if (jobId) {
this.$pollJob({
jobId,
successMethod: result => {
- let successDescription = ''
- if (result.jobresult.virtualmachine.name) {
- successDescription = result.jobresult.virtualmachine.name
- } else {
- successDescription = result.jobresult.virtualmachine.id
+ const vm = result.jobresult.virtualmachine
+ const name = vm.displayname || vm.name || vm.id
+ if (vm.password) {
+ this.$notification.success({
+ message: password + ' for ' + name,
+ description: vm.password,
+ duration: 0
+ })
}
- this.$store.dispatch('AddAsyncJob', {
- title: title,
- jobid: jobId,
- description: successDescription,
- status: 'progress'
- })
},
- loadingMessage: `${title} in progress for ${description}`,
+ loadingMessage: `${title} in progress`,
catchMessage: 'Error encountered while fetching async job result'
})
+ this.$store.dispatch('AddAsyncJob', {
+ title: title,
+ jobid: jobId,
+ description: description,
+ status: 'progress'
+ })
}
this.$router.back()
}).catch(error => {
@@ -1036,12 +1045,12 @@ export default {
})
})
},
- fetchAllTemplates (filterKey) {
+ fetchAllTemplates (filterKeys) {
const promises = []
this.options.templates = []
this.loading.templates = true
this.templateFilter.forEach((filter) => {
- if (filterKey && filterKey !== filter) {
+ if (filterKeys && !filterKeys.includes(filter)) {
return true
}
promises.push(this.fetchTemplates(filter))
@@ -1095,7 +1104,7 @@ export default {
this.tabKey = 'templateid'
_.each(this.params, (param, name) => {
if (!('isLoad' in param) || param.isLoad) {
- this.fetchOptions(param, name, ['zones', 'groups'])
+ this.fetchOptions(param, name, ['zones'])
}
})
this.fetchAllTemplates()
diff --git a/ui/src/views/compute/wizard/ComputeOfferingSelection.vue b/ui/src/views/compute/wizard/ComputeOfferingSelection.vue
index 4403ee49476..6f2304dfb75 100644
--- a/ui/src/views/compute/wizard/ComputeOfferingSelection.vue
+++ b/ui/src/views/compute/wizard/ComputeOfferingSelection.vue
@@ -137,8 +137,10 @@ export default {
this.selectedRowKeys = [this.preFillContent.computeofferingid]
this.$emit('select-compute-item', this.preFillContent.computeofferingid)
} else {
- this.selectedRowKeys = []
- this.$emit('select-compute-item', null)
+ if (this.computeItems && this.computeItems.length > 0) {
+ this.selectedRowKeys = [this.computeItems[0].id]
+ this.$emit('select-compute-item', this.computeItems[0].id)
+ }
}
}
}
diff --git a/ui/src/views/compute/wizard/NetworkConfiguration.vue b/ui/src/views/compute/wizard/NetworkConfiguration.vue
index af205680353..d2c0a4dc869 100644
--- a/ui/src/views/compute/wizard/NetworkConfiguration.vue
+++ b/ui/src/views/compute/wizard/NetworkConfiguration.vue
@@ -19,7 +19,7 @@
0) {
+ this.selectedRowKeys = [this.dataItems[0].id]
+ this.$emit('select-default-network-item', this.dataItems[0].id)
+ }
},
computed: {
rowSelection () {
@@ -112,6 +114,7 @@ export default {
const keyEx = this.dataItems.filter((item) => this.selectedRowKeys.includes(item.id))
if (!keyEx || keyEx.length === 0) {
this.selectedRowKeys = [this.dataItems[0].id]
+ this.$emit('select-default-network-item', this.dataItems[0].id)
}
}
}
@@ -122,7 +125,8 @@ export default {
this.$emit('select-default-network-item', value[0])
},
updateNetworkData (name, key, value) {
- if (this.networks.length === 0) {
+ const index = this.networks.findIndex(item => item.key === key)
+ if (index === -1) {
const networkItem = {}
networkItem.key = key
networkItem[name] = value
@@ -137,6 +141,15 @@ export default {
}
})
this.$emit('update-network-config', this.networks)
+ },
+ removeItem (id) {
+ this.dataItems = this.dataItems.filter(item => item.id !== id)
+ if (this.selectedRowKeys.includes(id)) {
+ if (this.dataItems && this.dataItems.length > 0) {
+ this.selectedRowKeys = [this.dataItems[0].id]
+ this.$emit('select-default-network-item', this.dataItems[0].id)
+ }
+ }
}
}
}
diff --git a/ui/src/views/compute/wizard/NetworkSelection.vue b/ui/src/views/compute/wizard/NetworkSelection.vue
index 74678b00109..a80c891d32a 100644
--- a/ui/src/views/compute/wizard/NetworkSelection.vue
+++ b/ui/src/views/compute/wizard/NetworkSelection.vue
@@ -18,17 +18,13 @@
-
-
- {{ $t('addNewNetworks') }}
-
-
+
+ {{ $t('label.add.network') }}
+
+
+
+
@@ -62,9 +72,13 @@
import _ from 'lodash'
import { api } from '@/api'
import store from '@/store'
+import CreateNetwork from '@/views/network/CreateNetwork'
export default {
name: 'NetworkSelection',
+ components: {
+ CreateNetwork
+ },
props: {
items: {
type: Array,
@@ -96,7 +110,8 @@ export default {
networkOffering: {
loading: false,
opts: []
- }
+ },
+ showCreateForm: false
}
},
computed: {
@@ -173,8 +188,13 @@ export default {
this.selectedRowKeys = this.preFillContent.networkids
this.$emit('select-network-item', this.preFillContent.networkids)
} else {
- this.selectedRowKeys = []
- this.$emit('select-network-item', null)
+ if (this.items && this.items.length > 0) {
+ this.selectedRowKeys = [this.items[0].id]
+ this.$emit('select-network-item', this.selectedRowKeys)
+ } else {
+ this.selectedRowKeys = []
+ this.$emit('select-network-item', [])
+ }
}
}
}
diff --git a/ui/src/views/compute/wizard/TemplateIsoSelection.vue b/ui/src/views/compute/wizard/TemplateIsoSelection.vue
index 7edef3c0ace..bffc9b5f77b 100644
--- a/ui/src/views/compute/wizard/TemplateIsoSelection.vue
+++ b/ui/src/views/compute/wizard/TemplateIsoSelection.vue
@@ -37,6 +37,7 @@
{
+ if (this.filter.length === 0) {
+ this.filter += 'is:' + item
+ } else {
+ this.filter += '; is:' + item
+ }
+ })
+ this.filterDataSource(this.filter)
})
},
onClear () {
const field = { filter: undefined }
this.form.setFieldsValue(field)
- if (this.inputDecorator === 'template') {
- this.vmFetchTemplates()
- } else {
- this.vmFetchIsos()
- }
+ this.filter = ''
+ this.filterDataSource('')
},
changeOsName (value) {
this.osType = value
@@ -288,8 +291,27 @@ export default {
}
.filter-group {
+ /deep/.ant-input-affix-wrapper {
+ float: right;
+ width: calc(100% - 32px);
+
+ .ant-input {
+ border-radius: 4px;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+ }
+
/deep/.ant-input-group-addon {
- padding: 0 5px;
+ float: left;
+ width: 32px;
+ height: 32px;
+ border-radius: 4px;
+ border-right: 0;
+ border-left: 1px solid #d9d9d9;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ padding: 0 0 0 1px;
}
&-button {
@@ -301,7 +323,7 @@ export default {
&-button {
position: relative;
display: block;
- min-height: 25px;
+ min-height: 30px;
&-clear {
position: absolute;
diff --git a/ui/src/views/network/CreateIsolatedNetworkForm.vue b/ui/src/views/network/CreateIsolatedNetworkForm.vue
index 15ebf19ccfe..a4c40a62f31 100644
--- a/ui/src/views/network/CreateIsolatedNetworkForm.vue
+++ b/ui/src/views/network/CreateIsolatedNetworkForm.vue
@@ -54,7 +54,7 @@
}"
:loading="zoneLoading"
:placeholder="this.$t('.zoneid')"
- @change="val => { this.handleZoneChanged(this.zones[val]) }">
+ @change="val => { this.handleZoneChange(this.zones[val]) }">
{{ opt.name || opt.description }}
diff --git a/ui/src/views/network/CreateL2NetworkForm.vue b/ui/src/views/network/CreateL2NetworkForm.vue
index 4eff20addb9..0489aa7b49a 100644
--- a/ui/src/views/network/CreateL2NetworkForm.vue
+++ b/ui/src/views/network/CreateL2NetworkForm.vue
@@ -54,7 +54,7 @@
}"
:loading="zoneLoading"
:placeholder="this.$t('zoneid')"
- @change="val => { this.handleZoneChanged(this.zones[val]) }">
+ @change="val => { this.handleZoneChange(this.zones[val]) }">
{{ opt.name || opt.description }}
diff --git a/ui/src/views/network/CreateSharedNetworkForm.vue b/ui/src/views/network/CreateSharedNetworkForm.vue
index 2303feee79b..f47a0085d03 100644
--- a/ui/src/views/network/CreateSharedNetworkForm.vue
+++ b/ui/src/views/network/CreateSharedNetworkForm.vue
@@ -54,7 +54,7 @@
}"
:loading="zoneLoading"
:placeholder="this.$t('zoneid')"
- @change="val => { this.handleZoneChanged(this.zones[val]) }">
+ @change="val => { this.handleZoneChange(this.zones[val]) }">
{{ opt.name || opt.description }}
@@ -70,7 +70,7 @@
}"
:loading="zoneLoading"
:placeholder="this.$t('physicalnetworkid')"
- @change="val => { this.handleZoneChanged(this.formPhysicalNetworks[val]) }">
+ @change="val => { this.handleZoneChange(this.formPhysicalNetworks[val]) }">
{{ opt.name || opt.description }}