OptionsSchemaPlugin.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. Copyright (C) 2017 Cloudbase Solutions SRL
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. // @flow
  15. import type { Field } from '../../../types/Field'
  16. import type { DestinationOption, StorageMap } from '../../../types/Endpoint'
  17. import type { WizardData } from '../../../types/WizardData'
  18. import { executionOptions } from '../../../config'
  19. const migrationImageOsTypes = ['windows', 'linux']
  20. export const defaultFillFieldValues = (field: Field, option: DestinationOption) => {
  21. if (field.type === 'string') {
  22. field.enum = [...option.values]
  23. if (option.config_default) {
  24. field.default = typeof option.config_default === 'string' ? option.config_default : option.config_default.id
  25. }
  26. }
  27. if (field.type === 'array') {
  28. field.enum = [...option.values]
  29. }
  30. }
  31. export const defaultFillMigrationImageMapValues = (field: Field, option: DestinationOption): boolean => {
  32. if (field.name === 'migr_image_map') {
  33. field.properties = migrationImageOsTypes.map(os => {
  34. let values = option.values
  35. .filter(v => v.os_type === os || v.os_type === 'unknown')
  36. .sort((v1, v2) => {
  37. if (v1.os_type === 'unknown' && v2.os_type !== 'unknown') {
  38. return 1
  39. } else if (v1.os_type !== 'unknown' && v2.os_type === 'unknown') {
  40. return -1
  41. }
  42. return 0
  43. })
  44. let unknownIndex = values.findIndex(v => v.os_type === 'unknown')
  45. if (unknownIndex > -1 && values.filter(v => v.os_type === 'unknown').length < values.length) {
  46. values.splice(unknownIndex, 0, { separator: true })
  47. }
  48. return {
  49. name: `${os}_os_image`,
  50. type: 'string',
  51. enum: values,
  52. }
  53. })
  54. return true
  55. }
  56. return false
  57. }
  58. export const defaultGetDestinationEnv = (data: WizardData): any => {
  59. let env = {}
  60. let specialOptions = ['execute_now', 'separate_vm', 'skip_os_morphing', 'default_storage']
  61. .concat(executionOptions.map(o => o.name))
  62. .concat(migrationImageOsTypes.map(o => `${o}_os_image`))
  63. if (data.options) {
  64. Object.keys(data.options).forEach(optionName => {
  65. if (specialOptions.find(o => o === optionName) || !data.options || data.options[optionName] == null) {
  66. return
  67. }
  68. if (optionName.indexOf('/') > 0) {
  69. let parentName = optionName.substr(0, optionName.lastIndexOf('/'))
  70. if (!env[parentName]) {
  71. env[parentName] = {}
  72. }
  73. env[parentName][optionName.substr(optionName.lastIndexOf('/') + 1)] = data.options ? data.options[optionName] : null
  74. } else {
  75. env[optionName] = data.options ? data.options[optionName] : null
  76. }
  77. })
  78. }
  79. return env
  80. }
  81. export const defaultGetMigrationImageMap = (data: WizardData) => {
  82. let env = {}
  83. if (data.options) {
  84. migrationImageOsTypes.forEach(os => {
  85. if (data.options && data.options[`${os}_os_image`]) {
  86. if (!env.migr_image_map) {
  87. env.migr_image_map = {}
  88. }
  89. env.migr_image_map[os] = data.options[`${os}_os_image`]
  90. }
  91. })
  92. }
  93. return env
  94. }
  95. export default class OptionsSchemaParser {
  96. static fillFieldValues(field: Field, options: DestinationOption[]) {
  97. let option = options.find(f => f.name === field.name)
  98. if (!option) {
  99. return
  100. }
  101. if (!defaultFillMigrationImageMapValues(field, option)) {
  102. defaultFillFieldValues(field, option)
  103. }
  104. }
  105. static getDestinationEnv(data: WizardData) {
  106. let env = {
  107. ...defaultGetDestinationEnv(data),
  108. ...defaultGetMigrationImageMap(data),
  109. }
  110. return env
  111. }
  112. static getNetworkMap(data: WizardData) {
  113. let payload = {}
  114. if (data.networks && data.networks.length) {
  115. data.networks.forEach(mapping => {
  116. payload[mapping.sourceNic.network_name] = mapping.targetNetwork.id
  117. })
  118. }
  119. return payload
  120. }
  121. static getStorageMap(data: WizardData, storageMap: StorageMap[]) {
  122. let payload = {}
  123. if (data.options && data.options.default_storage) {
  124. payload.default = data.options.default_storage
  125. }
  126. storageMap.forEach(mapping => {
  127. if (mapping.target.id === null) {
  128. return
  129. }
  130. if (mapping.type === 'backend') {
  131. if (!payload.backend_mappings) {
  132. payload.backend_mappings = []
  133. }
  134. payload.backend_mappings.push({
  135. source: mapping.source.storage_backend_identifier,
  136. destination: mapping.target.name,
  137. })
  138. } else {
  139. if (!payload.disk_mappings) {
  140. payload.disk_mappings = []
  141. }
  142. payload.disk_mappings.push({
  143. disk_id: mapping.source.id.toString(),
  144. destination: mapping.target.name,
  145. })
  146. }
  147. })
  148. return payload
  149. }
  150. }