createElasticcache.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. // 创建主机相应组件的参数
  2. import * as R from 'ramda'
  3. import {
  4. DEFAULT_PARAMS,
  5. NETWORK_OPTIONS_MAP,
  6. SERVER_TYPE,
  7. EIP_TYPES_MAP,
  8. EIP_CHARGE_TYPES_MAP,
  9. BILL_TYPES_MAP,
  10. LOGIN_TYPES_MAP,
  11. SCHED_POLICY_OPTIONS_MAP,
  12. STORAGE_AUTO,
  13. SECGROUP_OPTIONS_MAP,
  14. FORECAST_FILTERS_MAP,
  15. RESOURCE_TYPES_MAP,
  16. } from '@Compute/constants'
  17. import { IMAGES_TYPE_MAP } from '@/constants/compute'
  18. import { HYPERVISORS_MAP } from '@/constants'
  19. import validateForm, { isRequired } from '@/utils/validate'
  20. import store from '@/store'
  21. import i18n from '@/locales'
  22. export const decorators = {
  23. generate_name: [
  24. 'generate_name',
  25. {
  26. initialValue: '',
  27. validateTrigger: ['change', 'blur'],
  28. validateFirst: true,
  29. rules: [
  30. { required: true, message: i18n.t('db.text_136') },
  31. { validator: validateForm('serverName') },
  32. ],
  33. },
  34. ],
  35. count: [
  36. 'count',
  37. {
  38. initialValue: 1,
  39. },
  40. ],
  41. billing_type: [
  42. 'billing_type',
  43. {
  44. initialValue: 'postpaid',
  45. },
  46. ],
  47. sku: [
  48. 'sku',
  49. {
  50. rules: [
  51. { required: true, message: i18n.t('db.text_258') },
  52. ],
  53. },
  54. ],
  55. regionZone: {
  56. cloudregion: [
  57. 'region',
  58. {
  59. initialValue: { key: '', label: '' },
  60. rules: [
  61. { validator: isRequired(), message: i18n.t('db.text_259') },
  62. ],
  63. },
  64. ],
  65. zone: [
  66. 'zone',
  67. {
  68. initialValue: { key: '', label: '' },
  69. rules: [
  70. { validator: isRequired(), message: i18n.t('db.text_260') },
  71. ],
  72. },
  73. ],
  74. },
  75. cityProviderRegion: {
  76. city: ['city', {
  77. initialValue: undefined,
  78. }],
  79. provider: ['provider', {
  80. initialValue: undefined,
  81. }],
  82. region: ['region', {
  83. initialValue: undefined,
  84. }],
  85. zone: ['zone', {
  86. initialValue: undefined,
  87. }],
  88. },
  89. loginConfig: {
  90. loginType: [
  91. 'loginType',
  92. {
  93. initialValue: 'random',
  94. },
  95. ],
  96. keypair: [
  97. 'loginKeypair',
  98. {
  99. initialValue: undefined, // { key: '', label: '' }
  100. rules: [
  101. { validator: isRequired(), message: i18n.t('db.text_137') },
  102. ],
  103. },
  104. ],
  105. },
  106. vpcNetwork: {
  107. vpc: [
  108. 'vpc',
  109. {
  110. initialValue: undefined,
  111. rules: [
  112. { required: true, message: i18n.t('db.text_261') },
  113. ],
  114. },
  115. ],
  116. network: [
  117. 'network',
  118. {
  119. initialValue: undefined,
  120. rules: [
  121. { required: true, message: i18n.t('db.text_262') },
  122. ],
  123. },
  124. ],
  125. },
  126. }
  127. export class ControlParams {
  128. constructor (type) {
  129. this.type = type
  130. this.scope = store.getters.scope
  131. this.params = DEFAULT_PARAMS[type]
  132. this.initScope()
  133. }
  134. initScope () {
  135. R.forEachObjIndexed((value, key) => {
  136. if (!R.isNil(value.scope)) {
  137. this.params[key].scope = this.scope
  138. }
  139. }, this.params)
  140. }
  141. zoneChange (zoneId) {
  142. this.params.network.zone = zoneId
  143. }
  144. }
  145. /**
  146. * 根据表单拼装创建参数
  147. *
  148. * @export
  149. * @class GenCreateData
  150. */
  151. export class GenCreateData {
  152. constructor (fd, fi) {
  153. this.fd = fd
  154. this.fi = fi
  155. this.createType = this.fi.createType
  156. this.isPublic = this.createType === SERVER_TYPE.public
  157. this.isPrepaid = this.fd.resourceType === RESOURCE_TYPES_MAP.prepaid.key
  158. }
  159. /**
  160. * 拼装磁盘数据
  161. *
  162. * @param { Object } item // 磁盘数据
  163. * @param { String } type // 磁盘类型 sys | data
  164. * @param { Number } index // 序号
  165. * @returns { Object }
  166. * @memberof GenCreateData
  167. */
  168. genDisk (item, type, index) {
  169. const ret = {
  170. disk_type: type,
  171. index,
  172. backend: item.type === STORAGE_AUTO.key ? '' : item.type,
  173. size: item.size * 1024,
  174. }
  175. if (type === 'sys' && this.fd.imageType !== IMAGES_TYPE_MAP.iso.key) {
  176. ret.image_id = this.fd.image.key
  177. }
  178. if (type === 'sys' && this.fd.imageType === IMAGES_TYPE_MAP.iso.key) {
  179. ret.driver = 'ide'
  180. }
  181. if (item.schedtags) {
  182. ret.schedtags = item.schedtags
  183. }
  184. if (item.filetype) {
  185. ret.fs = item.filetype
  186. if (item.filetype !== 'swap') {
  187. ret.mountpoint = item.mountpoint
  188. }
  189. }
  190. if (item.snapshot_id) {
  191. ret.snapshot_id = item.snapshot_id
  192. }
  193. return ret
  194. }
  195. _genDisksArr () {
  196. const diskType = this.fd.systemDiskType.key
  197. const systemDisk = {
  198. type: diskType,
  199. size: this.fd.systemDiskSize,
  200. }
  201. if (this.fd.systemDiskSchedtag) {
  202. systemDisk.schedtags = [
  203. { id: this.fd.systemDiskSchedtag },
  204. ]
  205. if (this.fd.systemDiskPolicy && this.fd.systemDiskPolicy) {
  206. systemDisk.schedtags[0].strategy = this.fd.systemDiskPolicy
  207. }
  208. }
  209. const dataDisk = []
  210. R.forEachObjIndexed((value, key) => {
  211. const diskObj = {
  212. size: value,
  213. type: diskType,
  214. }
  215. if (this.fd.dataDiskFiletypes && this.fd.dataDiskFiletypes[key]) {
  216. diskObj.filetype = this.fd.dataDiskFiletypes[key]
  217. }
  218. if (this.fd.dataDiskMountPaths && this.fd.dataDiskMountPaths[key]) {
  219. diskObj.mountpoint = this.fd.dataDiskMountPaths[key]
  220. }
  221. if (this.fd.dataDiskSnapshots && this.fd.dataDiskSnapshots[key]) {
  222. diskObj.snapshot_id = this.fd.dataDiskSnapshots[key]
  223. }
  224. if (this.fd.dataDiskSchedtags && this.fd.dataDiskSchedtags[key]) {
  225. diskObj.schedtags = [
  226. { id: this.fd.dataDiskSchedtags[key] },
  227. ]
  228. if (this.fd.dataDiskPolicys && this.fd.dataDiskPolicys[key]) {
  229. diskObj.schedtags[0].strategy = this.fd.dataDiskPolicys[key]
  230. }
  231. }
  232. dataDisk.push(diskObj)
  233. }, this.fd.dataDiskSizes)
  234. const disks = { data: dataDisk, system: systemDisk }
  235. return disks
  236. }
  237. /**
  238. * 组装所有磁盘数据,包含系统盘及数据盘
  239. *
  240. * @returns { Array }
  241. * @memberof GenCreateData
  242. */
  243. genDisks () {
  244. const disks = this._genDisksArr()
  245. if (this.isPublic && this.isPrepaid) {
  246. return this.fd.spec.disks
  247. }
  248. const ret = [this.genDisk(disks.system, 'sys', 0)]
  249. for (let i = 0, len = disks.data.length; i < len; i++) {
  250. ret.push(this.genDisk(disks.data[i], 'data', i + 1))
  251. }
  252. return ret
  253. }
  254. /**
  255. * 组装所有网络数据
  256. *
  257. * @returns { Array }
  258. * @memberof GenCreateData
  259. */
  260. genNetworks () {
  261. let ret = [{ exit: false }]
  262. // 指定 IP 子网
  263. if (this.fd.networkType === NETWORK_OPTIONS_MAP.manual.key) {
  264. ret = []
  265. R.forEachObjIndexed((value, key) => {
  266. const obj = {
  267. network: value,
  268. }
  269. if (this.fd.networkIps) {
  270. const address = this.fd.networkIps[key]
  271. if (address) {
  272. obj.address = address
  273. }
  274. }
  275. ret.push(obj)
  276. }, this.fd.networks)
  277. }
  278. // 指定 调度标签
  279. if (this.fd.networkType === NETWORK_OPTIONS_MAP.schedtag.key) {
  280. ret = []
  281. R.forEachObjIndexed((value, key) => {
  282. const obj = {
  283. id: value,
  284. }
  285. const strategy = this.fd.networkPolicys[key]
  286. if (strategy) {
  287. obj.strategy = strategy
  288. }
  289. ret.push({
  290. schedtags: [obj],
  291. })
  292. }, this.fd.networkSchedtags)
  293. }
  294. return ret
  295. }
  296. /**
  297. * 获取配置的GPU数据
  298. *
  299. * @returns { Array }
  300. * @memberof GenCreateData
  301. */
  302. genDevices () {
  303. const ret = []
  304. for (let i = 0, len = this.fd.gpu.count; i < len; i++) {
  305. const regexp = /vendor=(.+):(.+)/
  306. const matched = this.fd.gpu.match(regexp)
  307. const model = matched[1]
  308. const vendor = matched[2]
  309. ret.push({
  310. model,
  311. vendor,
  312. })
  313. }
  314. return ret
  315. }
  316. /**
  317. * 获取管理员密码所提交的 key 与 value
  318. *
  319. * @returns { String }
  320. * @memberof GenCreateData
  321. */
  322. getLoginValueKey () {
  323. const ret = {}
  324. switch (this.fd.loginType) {
  325. case LOGIN_TYPES_MAP.keypair.key:
  326. ret.key = 'keypair'
  327. ret.value = this.fd.loginKeypair
  328. break
  329. case LOGIN_TYPES_MAP.image.key:
  330. ret.key = 'reset_password'
  331. ret.value = false
  332. break
  333. case LOGIN_TYPES_MAP.password.key:
  334. ret.key = 'password'
  335. ret.value = this.fd.loginPassword
  336. break
  337. default:
  338. break
  339. }
  340. return ret
  341. }
  342. /**
  343. * 获取调度策略所提交的 key 与 value
  344. *
  345. * @returns
  346. * @memberof GenCreateData
  347. */
  348. getSchedPolicyValueKey () {
  349. const ret = {}
  350. // 调度策略选择为 指定宿主机
  351. if (this.fd.schedPolicyType === SCHED_POLICY_OPTIONS_MAP.host.key) {
  352. ret.key = 'prefer_host'
  353. ret.value = this.fd.schedPolicyHost
  354. }
  355. // 调度策略选择为 调度标签
  356. if (this.fd.schedPolicyType === SCHED_POLICY_OPTIONS_MAP.schedtag.key) {
  357. ret.key = 'schedtags'
  358. ret.value = []
  359. R.forEachObjIndexed((value, key) => {
  360. ret.value.push({
  361. id: value,
  362. strategy: this.fd.policySchedtagPolicys[key],
  363. })
  364. }, this.policySchedtagSchedtags)
  365. }
  366. return ret
  367. }
  368. /**
  369. * 获取平台
  370. *
  371. * @returns { String }
  372. * @memberof GenCreateData
  373. */
  374. getHypervisor () {
  375. let ret = this.fd.hypervisor
  376. if (this.isPublic && !this.isPrepaid) {
  377. const provider = this.fd.sku.selected.provider
  378. if (provider) ret = provider.toLowerCase()
  379. }
  380. return ret
  381. }
  382. /**
  383. * 获取Region
  384. *
  385. * @returns { String }
  386. * @memberof GenCreateData
  387. */
  388. getPreferRegion () {
  389. let ret = this.fd.cloudregion.key
  390. if (this.isPublic && !this.isPrepaid) {
  391. const region = this.fd.sku.selected.cloudregion_id
  392. if (region) ret = region
  393. }
  394. return ret
  395. }
  396. /**
  397. * 获取Zone
  398. *
  399. * @returns { String }
  400. * @memberof GenCreateData
  401. */
  402. getPreferZone () {
  403. const ret = this.fd.zone && this.fd.zone.key
  404. return ret
  405. }
  406. /**
  407. * 获取CPU核数
  408. *
  409. * @returns { String }
  410. * @memberof GenCreateData
  411. */
  412. getCpuCount () {
  413. let ret = this.fd.vcpu
  414. if (this.isPublic && this.isPrepaid) {
  415. ret = this.fd.spec.vcpu_count
  416. }
  417. return ret
  418. }
  419. /**
  420. * 获取内存
  421. *
  422. * @returns { String }
  423. * @memberof GenCreateData
  424. */
  425. getMemSize () {
  426. let ret = this.fd.vmem
  427. if (this.isPublic && this.isPrepaid) {
  428. ret = this.fd.spec.vmem_size * 1024
  429. }
  430. return ret
  431. }
  432. /**
  433. * 组装所有的创建数据
  434. *
  435. * @returns { Object }
  436. * @memberof GenCreateData
  437. */
  438. all () {
  439. const data = {
  440. auto_start: true,
  441. generate_name: this.fd.name,
  442. hypervisor: this.getHypervisor(),
  443. __count__: this.fd.count,
  444. disks: this.genDisks(),
  445. nets: this.genNetworks(),
  446. prefer_region: this.getPreferRegion(),
  447. vcpu_count: this.getCpuCount(),
  448. vmem_size: this.getMemSize(),
  449. project_id: store.getters.userInfo.projectId,
  450. // project_id: this.fd.project.id || store.getters.userInfo.projectId,
  451. }
  452. if (this.fd.imageType === IMAGES_TYPE_MAP.iso.key) {
  453. data.cdrom = this.fd.image.data.id
  454. }
  455. // 非预付费资源池不会添加sku
  456. if (!this.isPrepaid) {
  457. data.sku = this.fd.sku.name
  458. }
  459. // 弹性IP
  460. if (this.isPublic) {
  461. if (this.fi.eipType === EIP_TYPES_MAP.new.key) {
  462. if (
  463. this.fd.eip_charge_type === EIP_CHARGE_TYPES_MAP.traffic.key ||
  464. this.fd.eip_charge_type === EIP_CHARGE_TYPES_MAP.bandwidth.key
  465. ) {
  466. data.eip_charge_type = this.fd.eip_charge_type
  467. data.eip_bw = this.fd.eip_bw
  468. }
  469. }
  470. // resource_type
  471. data.resource_type = this.fd.resourceType
  472. // 包年包月参数
  473. if (this.fi.billType === BILL_TYPES_MAP.package.key) {
  474. data.duration = this.fd.duration
  475. data.auto_prepaid_recycle = this.fd.auto_prepaid_recycle
  476. }
  477. }
  478. // gpu
  479. if (this.fd.gpuEnable) {
  480. data.isolated_devices = this.genDevices()
  481. }
  482. // 管理员密码非默认的情况下进行传参设置
  483. if (this.fd.loginType !== LOGIN_TYPES_MAP.random.key) {
  484. const loginValueKey = this.getLoginValueKey()
  485. data[loginValueKey.key] = loginValueKey.value
  486. }
  487. // 安全组
  488. if (this.fd.secgroupType === SECGROUP_OPTIONS_MAP.manual.key) {
  489. data.secgroup = this.fd.secgroup.id
  490. }
  491. // 如果设置了调度策略则拼装调度所需数据
  492. if (this.fd.schedPolicyType !== SCHED_POLICY_OPTIONS_MAP.default.key) {
  493. const schedPolicyValueKey = this.getSchedPolicyValueKey()
  494. data[schedPolicyValueKey.key] = schedPolicyValueKey.value
  495. }
  496. // 是否需要 拼装 高可用备份机
  497. if (this.fd.backupEnable) {
  498. data.backup = true
  499. data.prefer_backup_host = this.fd.backup
  500. }
  501. // zone
  502. const zoneId = this.getPreferZone()
  503. if (zoneId) {
  504. data.prefer_zone = zoneId
  505. }
  506. // 只有kvm支持启动方式
  507. if (this.fd.hypervisor === HYPERVISORS_MAP.kvm.key) {
  508. data.bios = this.fd.bios
  509. }
  510. return data
  511. }
  512. /**
  513. * 获取创建预测的错误信息
  514. *
  515. * @returns { Array }
  516. * @memberof GenCreateData
  517. */
  518. getForecastErrors (data) {
  519. const errors = []
  520. if (data.filtered_candidates && data.filtered_candidates.length > 0) {
  521. for (let i = 0, len = data.filtered_candidates.length; i < len; i++) {
  522. const item = data.filtered_candidates[i]
  523. const message = FORECAST_FILTERS_MAP[item.filter_name] || i18n.t('compute.text_1310', [item.filter_name])
  524. errors.push({
  525. message,
  526. children: item.reasons,
  527. })
  528. }
  529. } else {
  530. errors.push({
  531. message: i18n.t('compute.text_227'),
  532. })
  533. }
  534. return {
  535. errors,
  536. allow_count: data.allow_count,
  537. req_count: data.req_count,
  538. not_allow_reasons: data.not_allow_reasons,
  539. }
  540. }
  541. }