| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- <template>
- <base-dialog @cancel="cancelDialog">
- <div slot="header">{{$t('compute.text_359')}}</div>
- <div slot="body">
- <dialog-selected-tips :name="$t('dictionary.server')" :count="params.data.length" :action="$t('compute.text_359')" />
- <dialog-table :data="params.data" :columns="params.columns.slice(0, 3)" />
- <a-form :form="form.fc" hideRequiredMark v-bind="formItemLayout">
- <a-form-item :label="$t('compute.text_228')">
- <a-input v-decorator="decorators.name" @change="e => { form.fi.generate_name = e.target.value }" />
- <template #extra>
- <name-repeated
- res="servers"
- :name="form.fi.generate_name"
- :default-text="$t('compute.text_893')" />
- </template>
- </a-form-item>
- <a-form-item :label="$t('compute.text_294')">
- <a-input-number v-decorator="decorators.__count__" :min="1" :max="10" :step="1" :parser="Math.round" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_267')" v-if="isPublic">
- <os-select
- :type="type"
- :form="form"
- :types="osTypes"
- :osType="osType"
- :hypervisor="firstData.hypervisor"
- :image-params="imageParams"
- :cache-image-params="cacheImageParams"
- :cloudproviderParamsExtra="cloudproviderParamsExtra"
- :decorator="decorators.imageOS" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_1041')" v-if="isOpenWorkflow">
- <a-input v-decorator="decorators.reason" :placeholder="$t('compute.text_1105')" />
- </a-form-item>
- </a-form>
- </div>
- <div slot="footer">
- <a-button type="primary" @click="handleConfirm" :loading="loading">{{ confirmText }}</a-button>
- <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
- </div>
- </base-dialog>
- </template>
- <script>
- import * as R from 'ramda'
- import _ from 'lodash'
- import { mapGetters } from 'vuex'
- import { SERVER_TYPE } from '@Compute/constants'
- import OsSelect from '@Compute/sections/OsSelect'
- import DialogMixin from '@/mixins/dialog'
- import WindowsMixin from '@/mixins/windows'
- import WorkflowMixin from '@/mixins/workflow'
- import { findPlatform } from '@/utils/common/hypervisor'
- import { IMAGES_TYPE_MAP } from '@/constants/compute'
- import NameRepeated from '@/sections/NameRepeated'
- import { HYPERVISORS_MAP } from '@/constants'
- export default {
- name: 'VmCloneDialog',
- components: {
- OsSelect,
- NameRepeated,
- },
- mixins: [DialogMixin, WindowsMixin, WorkflowMixin],
- provide () {
- return {
- form: this.form,
- }
- },
- data () {
- return {
- loading: false,
- form: {
- fc: this.$form.createForm(this, {
- onValuesChange: (props, values) => {
- if (values.hasOwnProperty('imageType')) {
- this.form.fi.imageType = values.imageType
- }
- },
- }),
- fi: {
- generate_name: '',
- imageType: IMAGES_TYPE_MAP.public.key,
- },
- fd: {},
- },
- decorators: {
- name: [
- 'name',
- {
- validateFirst: true,
- rules: [
- { required: true, message: this.$t('compute.text_210') },
- ],
- },
- ],
- __count__: [
- '__count__',
- {
- initialValue: 1,
- rules: [
- { required: true, message: this.$t('compute.text_1195') },
- ],
- },
- ],
- imageOS: {
- prefer_manager: [
- 'prefer_manager',
- {
- rules: [
- { required: true, message: this.$t('compute.text_149') },
- ],
- },
- ],
- os: [
- 'os',
- {
- rules: [
- { required: true, message: this.$t('compute.text_153') },
- ],
- },
- ],
- image: [
- 'image',
- {
- rules: [
- { required: true, message: this.$t('compute.text_214') },
- ],
- },
- ],
- imageType: [
- 'imageType',
- {
- initialValue: IMAGES_TYPE_MAP.public.key,
- },
- ],
- },
- reason: [
- 'reason',
- {
- initialValue: '',
- },
- ],
- },
- formItemLayout: {
- wrapperCol: {
- span: 20,
- },
- labelCol: {
- span: 4,
- },
- },
- servers: [],
- createParams: {},
- specificationList: [],
- cloudproviderParamsExtra: {
- provider: _.get(this.params, 'data[0].provider'),
- },
- }
- },
- computed: {
- ...mapGetters(['scope', 'isAdminMode', 'userInfo']),
- firstData () {
- return this.params.data[0]
- },
- type () {
- return findPlatform(this.firstData.hypervisor)
- },
- isPublic () {
- return this.type === SERVER_TYPE.public
- },
- imageParams () {
- const params = {
- status: 'active',
- details: true,
- limit: 0,
- 'filter.0': 'disk_format.notequals(iso)',
- scope: this.scope,
- is_standard: true,
- }
- if (this.form.fi.imageType === IMAGES_TYPE_MAP.standard.key) {
- return params
- }
- if (this.form.fi.imageType === IMAGES_TYPE_MAP.customize.key) {
- params.is_standard = false
- return params
- }
- return params
- },
- cacheImageParams () {
- const params = {
- details: false,
- order_by: 'ref_count',
- order: 'desc',
- zone: this.firstData.zone_id,
- }
- return params
- },
- osType () {
- return this.params.data[0].os_type
- },
- osTypes () {
- if (HYPERVISORS_MAP.ctyun.key === this.firstData.hypervisor) {
- return ['public', 'public_customize']
- }
- return []
- },
- isOpenWorkflow () {
- return this.checkWorkflowEnabled(this.WORKFLOW_TYPES.APPLY_MACHINE)
- },
- confirmText () {
- return this.isOpenWorkflow ? this.$t('compute.text_288') : this.$t('dialog.ok')
- },
- },
- created () {
- this.manager = new this.$Manager('servers')
- this.fetchServerCreateParams()
- if (this.params.type === 'baremetal') {
- this.fetchHosts()
- }
- },
- methods: {
- async fetchServerCreateParams () {
- const params = {
- id: this.firstData.id,
- spec: 'create-params',
- }
- try {
- const response = await this.manager.getSpecific(params)
- const data = response.data || {}
- this.createParams = data
- } catch (error) {
- throw error
- }
- },
- async fetchHosts () {
- new this.$Manager('hosts').list({
- params: {
- enabled: 1,
- usable: true,
- is_empty: true,
- host_type: 'baremetal',
- scope: this.$store.getters.scope,
- },
- }).then(({ data = {} }) => {
- if (data.data.length) {
- this.specificationList = data.data
- }
- })
- },
- async handleConfirm () {
- this.loading = true
- try {
- const values = await this.form.fc.validateFields()
- const data = this.genCloneData(values)
- if (this.params.type === 'baremetal') {
- if (this.specificationList.length) {
- this.$message.warning(this.$t('compute.text_1196'))
- return
- } else {
- const specificationItem = this.specificationList.filter(item => { return item.id === data.host_id })
- if (R.isEmpty(specificationItem.spec) || R.isNil(specificationItem.spec)) {
- this.$message.warning(this.$t('compute.text_1197'))
- return
- }
- }
- }
- const schedulerManager = new this.$Manager('schedulers', 'v1')
- const schedulerReponse = await schedulerManager.rpc({
- methodname: 'DoForecast',
- params: data,
- })
- if (!schedulerReponse.data.can_create) {
- this.$message.warning(this.$t('compute.text_1198'))
- return
- }
- if (this.isOpenWorkflow) {
- const variables = {
- project: this.params.data[0].tenant_id,
- project_domain: this.params.data[0].domain_id,
- process_definition_key: this.WORKFLOW_TYPES.APPLY_MACHINE,
- initiator: this.userInfo.id,
- 'server-create-paramter': JSON.stringify(data),
- description: values.reason,
- }
- await this.createWorkflow(variables)
- this.$message.success(this.$t('compute.text_1045', [data.name]))
- this.$router.push('/workflow')
- } else {
- await this.params.onManager('create', {
- managerArgs: {
- data,
- },
- })
- }
- this.cancelDialog()
- } finally {
- this.loading = false
- }
- },
- genCloneData (fd) {
- const server = {
- ...this.generateCreateParams(this.createParams, fd),
- __count__: fd.__count__,
- name: fd.name,
- generate_name: fd.name,
- }
- const disks = this.createParams.disks
- if (disks && disks.length > 0) {
- disks.forEach((disk) => {
- if (disk.disk_type === 'data') {
- delete disk.image_id
- }
- })
- }
- delete server.eip
- if (this.isPublic) {
- server.disks[0].image_id = fd.image.key
- server.imageType = fd.imageType
- server.prefer_manager = fd.prefer_manager
- }
- return server
- },
- generateCreateParams (createParams, fd) {
- const delProps = ['domain', 'domain_id', 'project', 'project_domain', 'project_domain_id', 'project_id', 'tenant', 'tenant_id']
- delProps.forEach(v => {
- delete createParams[v]
- })
- createParams.project_id = this.params.data[0].tenant_id
- return createParams
- },
- },
- }
- </script>
|