index.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <template>
  2. <div>
  3. <a-form-item>
  4. <a-radio-group v-decorator="decorator.networkType" @change="change">
  5. <template v-for="(item, key) in originNetworkMaps">
  6. <a-radio-button v-if="(isServertemplate && (key !== 'schedtag')) || !isServertemplate" :value="key" :key="key">
  7. {{ item.t ? $t(item.t) : item.label }}
  8. <help-tooltip v-if="key === 'default'" :name="`${key}ServerNetwork`" class="ml-2" />
  9. </a-radio-button>
  10. </template>
  11. </a-radio-group>
  12. </a-form-item>
  13. <a-form-item v-if="networkComponent === 'config'">
  14. <network-config
  15. :form="form"
  16. :decorator="decorator.networkConfig"
  17. :isBonding="isBonding"
  18. :network-params="networkListParams"
  19. v-bind="configs"
  20. ref="networkConfigRef"
  21. :vpc-params="networkVpcParams"
  22. :vpc-resource="vpcResource"
  23. :ipsDisable="ipsDisable"
  24. :network-resource-mapper="networkResourceMapper"
  25. :vpc-resource-mapper="vpcResourceMapper"
  26. :limit="form.fi.capability.max_nic_count"
  27. :show-vpc="showVpc"
  28. :is-dialog="isDialog"
  29. :showMacConfig="showMacConfig"
  30. :showDeviceConfig="showDeviceConfig"
  31. :showSecgroupConfig="showSecgroupConfig"
  32. :secgroupParams="secgroupParams"
  33. :hiddenAdd="hiddenAdd" />
  34. </a-form-item>
  35. <a-form-item v-if="networkComponent === 'schedtag'">
  36. <network-schedtag
  37. ref="networkSchedtagRef"
  38. :form="form"
  39. :decorator="decorator.networkSchedtag"
  40. :isBonding="isBonding"
  41. :schedtag-params="schedtagParams"
  42. :limit="form.fi.capability.max_nic_count"
  43. :showDeviceConfig="showDeviceConfig" />
  44. </a-form-item>
  45. </div>
  46. </template>
  47. <script>
  48. import { NETWORK_OPTIONS_MAP } from '@Compute/constants'
  49. import { HYPERVISORS_MAP } from '@/constants'
  50. import NetworkConfig from './NetworkConfig'
  51. import NetworkSchedtag from './NetworkSchedtag'
  52. export default {
  53. name: 'ServerNetwork',
  54. components: {
  55. NetworkSchedtag,
  56. NetworkConfig,
  57. },
  58. props: {
  59. decorator: {
  60. type: Object,
  61. required: true,
  62. validator: val => val.networkType && val.networkConfig && val.networkSchedtag,
  63. // val.segment && val.ip && val.schedtag && val.strategy,
  64. },
  65. form: {
  66. type: Object,
  67. required: true,
  68. validator: val => val.fc,
  69. },
  70. networkListParams: {
  71. type: Object,
  72. default: () => ({}),
  73. },
  74. networkVpcParams: {
  75. type: Object,
  76. default: () => ({}),
  77. },
  78. vpcResource: {
  79. type: String,
  80. },
  81. schedtagParams: {
  82. type: Object,
  83. default: () => ({}),
  84. },
  85. isBonding: {
  86. type: Boolean,
  87. default: false,
  88. },
  89. networkResourceMapper: {
  90. type: Function,
  91. default: data => data,
  92. },
  93. vpcResourceMapper: {
  94. type: Function,
  95. default: data => data,
  96. },
  97. hypervisor: {
  98. type: String,
  99. },
  100. cloudprovider: {
  101. type: String,
  102. },
  103. serverCount: {
  104. type: Number,
  105. default: 1,
  106. },
  107. isServertemplate: {
  108. type: Boolean,
  109. default: false,
  110. },
  111. defaultNetwork: {
  112. type: Boolean,
  113. default: true,
  114. },
  115. vpcObj: {
  116. type: Object,
  117. },
  118. allowNetworkTypes: {
  119. type: Array,
  120. },
  121. showVpc: {
  122. type: Boolean,
  123. default: true,
  124. },
  125. isDialog: {
  126. type: Boolean,
  127. default: false,
  128. },
  129. showMacConfig: {
  130. type: Boolean,
  131. default: false,
  132. },
  133. showDeviceConfig: {
  134. type: Boolean,
  135. default: false,
  136. },
  137. showSecgroupConfig: {
  138. type: Boolean,
  139. default: false,
  140. },
  141. secgroupParams: {
  142. type: Object,
  143. default: () => ({}),
  144. },
  145. hiddenNetworkOptions: {
  146. type: Array,
  147. },
  148. defaultNetworkType: {
  149. type: String,
  150. },
  151. hiddenAdd: {
  152. type: Boolean,
  153. default: false,
  154. },
  155. },
  156. data () {
  157. const { auto_alloc_network_count } = this.$store.getters.capability
  158. const { hypervisor } = this.form.fd || {}
  159. const _networkMaps = { ...NETWORK_OPTIONS_MAP }
  160. if (!auto_alloc_network_count || auto_alloc_network_count <= 0) {
  161. if (hypervisor !== HYPERVISORS_MAP.proxmox.key) {
  162. delete _networkMaps.default
  163. }
  164. }
  165. if (this.allowNetworkTypes && this.allowNetworkTypes.length) {
  166. this.allowNetworkTypes.forEach(key => {
  167. delete _networkMaps[key]
  168. })
  169. }
  170. if (!this.defaultNetwork) delete _networkMaps.default
  171. return {
  172. networkComponent: '', // 指定IP子网 / 指定调度标签 的控件
  173. networkMaps: _networkMaps,
  174. }
  175. },
  176. computed: {
  177. ipsDisable () {
  178. return this.serverCount > 1
  179. },
  180. configs () {
  181. if (this.vpcObj && this.vpcObj.id && this.vpcObj.name) {
  182. return {
  183. vpcObj: this.vpcObj,
  184. }
  185. }
  186. return {}
  187. },
  188. originNetworkMaps () {
  189. if (this.hiddenNetworkOptions?.length > 0) {
  190. this.hiddenNetworkOptions.forEach(v => {
  191. this.$delete(this.networkMaps, v)
  192. })
  193. }
  194. return this.networkMaps
  195. },
  196. /** form.fi.capability 与 store 可能不同步,合并后再驱动网络类型 */
  197. effectiveAutoAllocNetworkCountTt () {
  198. const cap = this.form.fi?.capability
  199. if (cap && Object.prototype.hasOwnProperty.call(cap, 'auto_alloc_network_count')) {
  200. return cap.auto_alloc_network_count
  201. }
  202. return this.$store.getters.capability?.auto_alloc_network_count
  203. },
  204. },
  205. watch: {
  206. effectiveAutoAllocNetworkCountTt: {
  207. handler () {
  208. this.applyNetworkTypeByAutoAllocCountTt()
  209. },
  210. immediate: true,
  211. },
  212. async hypervisor (val, oldVal) {
  213. if (val === HYPERVISORS_MAP.esxi.key || oldVal === HYPERVISORS_MAP.esxi.key) {
  214. await this.refreshNetworkConfig()
  215. this.changeIpDisable(this.serverCount > 1)
  216. }
  217. },
  218. async cloudprovider (val, oldVal) {
  219. if (val !== oldVal) {
  220. await this.refreshNetworkConfig()
  221. }
  222. },
  223. serverCount (val, oldVal) {
  224. if (val !== oldVal && (val === 1 || oldVal === 1)) {
  225. this.changeIpDisable(val > 1)
  226. }
  227. },
  228. defaultNetworkType: {
  229. handler (val) {
  230. if (val) {
  231. switch (val) {
  232. case NETWORK_OPTIONS_MAP.default.key:
  233. this.networkComponent = ''
  234. break
  235. case NETWORK_OPTIONS_MAP.manual.key:
  236. this.networkComponent = 'config'
  237. break
  238. case NETWORK_OPTIONS_MAP.schedtag.key:
  239. this.networkComponent = 'schedtag'
  240. break
  241. }
  242. }
  243. },
  244. immediate: true,
  245. },
  246. },
  247. methods: {
  248. /** 无自动分配(0 / 未下发 / 空)时网络类型应为「指定 IP 子网」(compute.text_2,界面常称「其他」) */
  249. applyNetworkTypeByAutoAllocCountTt () {
  250. const val = this.effectiveAutoAllocNetworkCountTt
  251. const noAutoAlloc = val == null || val === '' || Number(val) <= 0
  252. if (noAutoAlloc) {
  253. const { hypervisor } = this.form.fd || {}
  254. if (hypervisor !== HYPERVISORS_MAP.proxmox.key) {
  255. this.$delete(this.networkMaps, NETWORK_OPTIONS_MAP.default.key)
  256. }
  257. const manual = NETWORK_OPTIONS_MAP.manual.key
  258. this.$nextTick(() => {
  259. this.form.fc.setFieldsValue({ networkType: manual })
  260. if (this.form.fd) {
  261. this.form.fd.networkType = manual
  262. }
  263. this.networkComponent = 'config'
  264. })
  265. } else {
  266. const maps = { ...NETWORK_OPTIONS_MAP }
  267. if (!this.defaultNetwork) delete maps[NETWORK_OPTIONS_MAP.default.key]
  268. if (this.allowNetworkTypes && this.allowNetworkTypes.length) {
  269. this.allowNetworkTypes.forEach(key => {
  270. delete maps[key]
  271. })
  272. }
  273. this.networkMaps = maps
  274. const value = {
  275. networkType: NETWORK_OPTIONS_MAP[Object.keys(maps)[0]].key,
  276. }
  277. this.$nextTick(() => {
  278. this.form.fc.setFieldsValue(value)
  279. if (this.form.fd) {
  280. this.form.fd.networkType = value.networkType
  281. }
  282. this.networkComponent = value.networkType === NETWORK_OPTIONS_MAP.default.key ? '' : 'config'
  283. })
  284. }
  285. },
  286. change (e) {
  287. if (this.form.fd) {
  288. this.form.fd.networkType = e.target.value
  289. }
  290. switch (e.target.value) {
  291. case NETWORK_OPTIONS_MAP.default.key:
  292. this.networkComponent = ''
  293. break
  294. case NETWORK_OPTIONS_MAP.manual.key:
  295. this.networkComponent = 'config'
  296. break
  297. case NETWORK_OPTIONS_MAP.schedtag.key:
  298. this.networkComponent = 'schedtag'
  299. break
  300. }
  301. },
  302. async refreshNetworkConfig () {
  303. if (this.networkComponent === 'config') {
  304. this.networkComponent = ''
  305. await this.$nextTick() // 刷新 network-config 组件
  306. this.networkComponent = 'config'
  307. }
  308. return true
  309. },
  310. changeIpDisable (ipDisable) {
  311. if (this.$refs.networkConfigRef) this.$refs.networkConfigRef.reset(ipDisable)
  312. },
  313. },
  314. }
  315. </script>