| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- <template>
- <div>
- <a-card class="mb-2 card" v-for="(item, i) in serverConfigList" :key="item.key">
- <a-button v-if="i !== 0" @click="decrease(item.key, i)" type="link" size="small" class="error-color position-absolute" style="right: 10px; top: 10px;">{{ $t('common.delete') }}</a-button>
- <slot name="hypervisor" :formItemLayout="formItemLayout" :i="item.key" />
- <!-- <a-form-item label="CPU" v-bind="formItemLayout">
- <a-input-number v-decorator="decorator.vcpu_count(item.key)" :formatter="value => $t('k8s.text_119', [value])" :parser="v => parser(v, $t('k8s.text_100'))" :min="4" :max="32" />
- </a-form-item>
- <a-form-item :label="$t('k8s.text_101')" v-bind="formItemLayout">
- <a-input-number v-decorator="decorator.vmem_size(item.key)" :formatter="value => `${value}G`" :parser="v => parser(v, 'G')" :min="1" :max="128" />
- </a-form-item> -->
- <!-- <a-form-item :label="$t('network.text_24')" v-bind="formItemLayout">
- <a-select
- v-decorator="decorator.zone(item.key)"
- :placeholder="$t('network.text_287')"
- @change="handleZoneChanage(i, $event)">
- <a-select-option
- v-for="zone in getZones(i)"
- :key="zone.id"
- :value="zone.id">{{zone.name}}</a-select-option>
- </a-select>
- </a-form-item>-->
- <a-form-item :label="$t('k8s.text_121')" v-bind="formItemLayout" required>
- <a-row :gutter="8">
- <a-col :span="24">
- <a-form-item
- :wrapperCol="{ span: 24 }"
- style="min-width: 200px;"
- class="w-100 mb-0 mr-1">
- <base-select
- class="w-100"
- v-decorator="decorator.network(item.key)"
- resource="networks"
- remote
- is-default-select
- @change="handleNetworkChange(i, $event)"
- :item.sync="item.network"
- :need-params="true"
- :params="getNetworkParams(item.key)"
- :mapper="networkResourceMapper"
- :labelFormat="networkLabelFormat"
- :select-props="{ allowClear: true, placeholder: $t('k8s.text_122') }" />
- </a-form-item>
- </a-col>
- <a-col :span="10" v-if="item.ipShow">
- <a-form-item class="mb-0 mr-2" :wrapperCol="{ span: 24 }">
- <a-input
- :placeholder="$t('k8s.text_123')"
- @change="e => ipChange(e, i)"
- v-decorator="decorator.ip(item.key, item.network)" />
- </a-form-item>
- </a-col>
- <a-col :span="2">
- <a-button v-if="item.ipShow" type="link" class="mr-1 mt-1" @click="hideIp(item)">{{$t('k8s.text_410')}}</a-button>
- <a-button v-else type="link" class="mr-1 mt-1" @click="showIp(item)">{{$t('k8s.text_124')}}</a-button>
- </a-col>
- </a-row>
- </a-form-item>
- <a-form-item>
- <sku
- v-decorator="decorator.sku(item.key)"
- @change="handleSkuChange(i, $event)"
- :hypervisor="hypervisor"
- :sku-params="skuParam(i)" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_267')" v-bind="formItemLayout" class="mb-0" v-if="useImage">
- <os-select
- :type="type"
- :uefi="uefi"
- :form="form"
- :hypervisor="hypervisor"
- :decorator="decorator.imageOS(item.key)[1]"
- @updateImageMsg="updateImageMsg(i, $event)"
- :cloudType="platform"
- :imageType="getImageType()"
- :imageParams="getImageParams()"
- :cacheImageParams="getCacheImageParams()" />
- </a-form-item>
- <a-form-item :label="$t('k8s.text_120')" v-bind="formItemLayout" class="mb-0">
- <system-disk
- :decorator="decorator.disk(item.key)"
- :type="platform"
- :form="form"
- :image="imageMock"
- :hypervisor="hypervisor"
- :capability-data="getCapability(i)"
- :sku="getSku(i)"
- :domain="userInfo.projectDomainId" />
- </a-form-item>
- <a-form-item :label="$t('dictionary.role')" v-bind="formItemLayout">
- <a-radio-group
- v-decorator="decorator.role(item.key)">
- <a-radio-button v-for="role in roleList" :key="role.value" :value="role.value">
- {{ role.label}}
- </a-radio-button>
- </a-radio-group>
- </a-form-item>
- <a-form-item v-show="!item.ipShow" :label="$t('k8s.text_125')" v-bind="formItemLayout" :extra="$t('k8s.text_126')">
- <a-input-number v-decorator="decorator.num(item.key)" :min="1" :max="item.ipShow ? 1 : 10" :parser="v => parser(v, '', '1')" />
- </a-form-item>
- </a-card>
- <div class="d-flex align-items-center" v-if="serverConfigRemaining > 0">
- <a-button type="primary" shape="circle" icon="plus" size="small" @click="add" />
- <a-button type="link" @click="add">{{$t('k8s.text_127')}}</a-button>
- <span class="network-count-tips">{{$t('k8s.text_128')}}<span class="remain-num">{{ serverConfigRemaining }}</span>{{$t('k8s.text_129')}}</span>
- </div>
- </div>
- </template>
- <script>
- import * as R from 'ramda'
- import { mapGetters } from 'vuex'
- import { NODE_ROLE_MAP } from '../../views/cluster/constants'
- import { IMAGES_TYPE_MAP } from '@/constants/compute'
- import { HYPERVISORS_MAP } from '@/constants'
- import { uuid } from '@/utils/utils'
- import SystemDisk from '@Compute/views/vminstance/create/components/SystemDisk'
- import Sku from '@Compute/sections/SKU'
- import OsSelect from '@Compute/sections/OsSelect'
- export default {
- name: 'K8SClusterServerConfig',
- components: {
- SystemDisk,
- Sku,
- OsSelect,
- },
- props: {
- decorator: {
- type: Object,
- required: true,
- },
- form: {
- type: Object,
- validator: val => val.fc,
- },
- cloudregionId: {
- type: String,
- required: true,
- },
- hypervisor: {
- type: String,
- required: true,
- },
- platform: {
- type: String,
- required: true,
- },
- networkParams: {
- type: Object,
- required: true,
- },
- },
- data () {
- const roleList = []
- R.forEachObjIndexed((value, key) => {
- roleList.push({ label: value, value: key })
- }, NODE_ROLE_MAP)
- return {
- imageMock: { min_disk: 40960 }, // 通过mock image数据设置最小磁盘大小
- selectedImage: {},
- formItemLayout: {
- wrapperCol: { span: 20 },
- labelCol: { span: 3 },
- },
- serverConfigList: [],
- limit: 10,
- roleList,
- }
- },
- computed: {
- ...mapGetters(['isAdminMode', 'scope', 'isDomainMode', 'userInfo', 'l3PermissionEnable']),
- useImage () {
- const hypervisor = this.$props.hypervisor
- if (hypervisor === HYPERVISORS_MAP.kvm.key || hypervisor === HYPERVISORS_MAP.cloudpods.key) {
- return true
- }
- return false
- },
- serverConfigRemaining () {
- return this.limit - this.serverConfigList.length
- },
- },
- watch: {
- hypervisor: {
- handler (val, oldVal) {
- console.log(`hypervisor change: ${val}`)
- },
- },
- },
- created () {
- this.add()
- },
- methods: {
- showIp (item) {
- item.ipShow = true
- },
- hideIp (item) {
- item.ipShow = false
- },
- ipChange (e, i) {
- this.serverConfigList[i].ip = e.target.value
- },
- decrease (uid, index) {
- this.serverConfigList.splice(index, 1)
- },
- networkLabelFormat (net) {
- return ( // IP子网
- <div>
- <span>{ net.name } ({ net.guest_ip_start } - { net.guest_ip_end }, zone={ net.zone })</span>
- </div>
- )
- },
- add () {
- const uid = uuid()
- const data = {
- ipShow: false,
- key: uid,
- }
- this.serverConfigList.push(data)
- this.$nextTick(() => {
- this.$emit('vmAdd', data)
- })
- },
- parser (val, unit, defaultValue = '4') {
- const value = val.replace(unit, '')
- const valueNum = Number(value)
- if (!Number.isNaN(valueNum) && R.is(Number, valueNum)) {
- return value
- }
- return defaultValue
- },
- networkResourceMapper (list) {
- return list
- .map(val => {
- const remain = val.ports - val.ports_used
- if (remain <= 0) {
- return {
- ...val,
- __disabled: true,
- }
- }
- return val
- })
- .sort((a, b) => (b.ports - b.ports_used) - (a.ports - a.ports_used))
- },
- getNetworkParams (key) {
- return {
- ...this.networkParams,
- $t: key,
- }
- },
- getConfig (index) {
- return this.serverConfigList[index]
- },
- setConfig (index, setFunc) {
- let conf = this.getConfig(index)
- conf = setFunc(conf)
- this.$set(this.serverConfigList, index, conf)
- },
- getCurrentNetwork (index) {
- return this.getConfig(index).network
- },
- getCurrentZone (index) {
- const curNet = this.getCurrentNetwork(index)
- if (curNet && curNet.zone_id) {
- return curNet.zone_id
- }
- return null
- },
- skuParam (index) {
- const filters = []
- filters.push('cpu_core_count.gt(1)')
- filters.push('memory_size_mb.gt(4095)')
- const orderBy = []
- orderBy.push('memory_size_mb')
- const param = {
- limit: 0,
- enabled: true,
- usable: true,
- filter: filters,
- order_by: orderBy,
- order: 'asc',
- cloudregion: this.cloudregionId,
- ...this.scopeParams,
- }
- const curZone = this.getCurrentZone(index)
- if (curZone) {
- param.zone = curZone
- }
- return param
- },
- handleNetworkChange (index, networkId) {
- this.fetchCapability(index)
- },
- handleSkuChange (index, sku) {
- this.setConfig(index, (conf) => {
- conf.sku = sku
- console.log(`set config(${index}) sku to ${sku.name}`)
- return conf
- })
- },
- updateImageMsg (index, { imageMsg }) {
- this.selectedImage = imageMsg
- this.setConfig(index, (conf) => {
- conf.image = imageMsg
- console.log(`set config(${index}) image to ${imageMsg.name}`)
- return conf
- })
- },
- getSku (index) {
- return this.getConfig(index).sku
- },
- fetchCapability (index) {
- const params = {
- show_emulated: true,
- resource_type: 'shared',
- scope: this.scope,
- }
- let id = this.getCurrentZone(index)
- let res = 'zones'
- if (!id) {
- id = this.cloudregionId
- res = 'cloudregions'
- }
- const capabilityParams = { id, spec: 'capability', params }
- this.capabilityParams = capabilityParams
- new this.$Manager(res).getSpecific(this.capabilityParams)
- .then(({ data }) => {
- this.setConfig(index, (conf) => {
- conf.capability = data
- /* console.log(`set config(${index}) capability to ${JSON.stringify(data)}`) */
- return conf
- })
- })
- },
- getCapability (index) {
- return this.getConfig(index).capability
- },
- isPublicCloud () {
- return this.platform === 'public'
- },
- isOnPremise () {
- return this.platform === 'idc'
- },
- getImageType () {
- if (this.isPublicCloud()) {
- return IMAGES_TYPE_MAP.public.key
- }
- if (this.isOnPremise()) {
- return IMAGES_TYPE_MAP.standard.key
- }
- throw Error(`Not support platform ${this.platform}`)
- },
- getImageParams () {
- return {
- distributions: ['CentOS', 'Kylin'],
- distribution_precise_match: true,
- }
- },
- getCacheImageParams () {
- if (!this.isPublicCloud()) {
- return {}
- }
- return {
- public_cloud: true,
- region: this.cloudregionId,
- }
- },
- /*
- * getImageIgnoreOptions () {
- * const opts = [
- * IMAGES_TYPE_MAP.private,
- * IMAGES_TYPE_MAP.customize,
- * IMAGES_TYPE_MAP.iso,
- * IMAGES_TYPE_MAP.snapshot,
- * IMAGES_TYPE_MAP.host,
- * ]
- * return opts.map(item => item.key)
- * },
- */
- },
- }
- </script>
|