2
0

ConnectionSchemaPlugin.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. import LabelDictionary from '../../../utils/LabelDictionary'
  15. import Utils from '../../../utils/ObjectUtils'
  16. import type { Schema, SchemaProperties, SchemaDefinitions } from '../../../@types/Schema'
  17. import type { Field } from '../../../@types/Field'
  18. import { Endpoint } from '../../../@types/Endpoint'
  19. export const defaultSchemaToFields = (
  20. schema: SchemaProperties,
  21. schemaDefinitions?: SchemaDefinitions | null,
  22. dictionaryKey?: string,
  23. ): any[] => {
  24. if (!schema.properties) {
  25. return []
  26. }
  27. const fields = Object.keys(schema.properties).map(fieldName => {
  28. let properties: any = schema.properties[fieldName]
  29. if (typeof properties.$ref === 'string' && schemaDefinitions) {
  30. const definitionName = properties.$ref.substr(properties.$ref.lastIndexOf('/') + 1)
  31. properties = schemaDefinitions[definitionName]
  32. return {
  33. name: fieldName,
  34. type: properties.type ? properties.type : '',
  35. properties: properties.properties
  36. ? defaultSchemaToFields(properties, null, dictionaryKey) : [],
  37. }
  38. } if (properties.type === 'object' && properties.properties && Object.keys(properties.properties).length) {
  39. return {
  40. name: fieldName,
  41. type: 'object',
  42. properties: defaultSchemaToFields(properties, null, dictionaryKey),
  43. }
  44. }
  45. const name = fieldName
  46. LabelDictionary.pushToCache({ name, title: properties.title, description: properties.description }, dictionaryKey || '')
  47. return {
  48. ...properties,
  49. name,
  50. required: schema.required && schema.required.find(k => k === fieldName) ? true : fieldName === 'username' || fieldName === 'password',
  51. }
  52. })
  53. return fields
  54. }
  55. export const connectionSchemaToFields = (schema: SchemaProperties) => {
  56. const fields = defaultSchemaToFields(schema)
  57. const sortPriority: any = { username: 1, password: 2 }
  58. fields.sort((a, b) => {
  59. if (sortPriority[a.name] && sortPriority[b.name]) {
  60. return sortPriority[a.name] - sortPriority[b.name]
  61. }
  62. if (sortPriority[a.name] || (a.required && !b.required)) {
  63. return -1
  64. }
  65. if (sortPriority[b.name] || (!a.required && b.required)) {
  66. return 1
  67. }
  68. return a.name.localeCompare(b.name)
  69. })
  70. return fields
  71. }
  72. export const generateField = (fieldBuilderProps: any) => {
  73. const field = { ...fieldBuilderProps }
  74. if (!field.type) {
  75. field.type = 'string'
  76. }
  77. if (!field.required) {
  78. field.required = false
  79. }
  80. field.default = undefined
  81. return field
  82. }
  83. export const generateBaseFields = () => [
  84. generateField({ name: 'name', title: 'Name', required: true }),
  85. generateField({
  86. name: 'mapped_regions',
  87. title: 'Coriolis Regions',
  88. type: 'array',
  89. noItemsMessage: 'No regions available',
  90. noSelectionMessage: 'Choose regions',
  91. description: `Optional list of one or more Coriolis Regions the Endpoint should be mapped to.
  92. Mapping this Endpoint to a set of Regions will mean that any operations related to the Endpoint will be executed on Coriolis services which are marked as being in the same Region.
  93. (e.g. running DRaaS operations with some Coriolis services running on a private source platform and some on a public target).
  94. Can be left unselected for all-in-one Coriolis installations or when the source/target platform is accessible by the whole Coriolis deployment.`,
  95. }),
  96. generateField({ name: 'description', title: 'Description' }),
  97. ]
  98. export const fieldsToPayload = (data: { [prop: string]: any }, schema: SchemaProperties) => {
  99. const info: any = {}
  100. const usableSchema: any = schema
  101. Object.keys(usableSchema.properties).forEach(fieldName => {
  102. if (data[fieldName] && typeof data[fieldName] !== 'object') {
  103. info[fieldName] = Utils.trim(fieldName, data[fieldName])
  104. } else if (typeof usableSchema.properties[fieldName] === 'object') {
  105. const properties = usableSchema.properties[fieldName]
  106. && usableSchema.properties[fieldName].properties
  107. if (properties) {
  108. Object.keys(properties).forEach(fn => {
  109. const fullFn = `${fieldName}/${fn}`
  110. if (data[fullFn] != null) {
  111. if (!info[fieldName]) {
  112. info[fieldName] = {}
  113. }
  114. info[fieldName][fn] = Utils.trim(fn, data[fullFn])
  115. }
  116. })
  117. }
  118. } else if (
  119. !data[fieldName]
  120. && usableSchema.required && usableSchema.required.find((f: string) => f === fieldName)
  121. && usableSchema.properties[fieldName].default
  122. ) {
  123. info[fieldName] = usableSchema.properties[fieldName].default
  124. }
  125. })
  126. return info
  127. }
  128. export default class ConnectionSchemaParser {
  129. static parseSchemaToFields(schema: Schema): Field[] {
  130. let fields = connectionSchemaToFields(schema.oneOf[0])
  131. fields = [
  132. ...generateBaseFields(),
  133. ...fields,
  134. ]
  135. return fields
  136. }
  137. static parseConnectionInfoToPayload(data: { [prop: string]: any }, schema: any) {
  138. const schemaRoot = schema.oneOf ? schema.oneOf[0] : schema
  139. const connection_info = fieldsToPayload(data, schemaRoot)
  140. const dataSecretRef = data.secret_ref || data['connection_info/secret_ref']
  141. if (dataSecretRef) {
  142. connection_info.secret_ref = dataSecretRef
  143. }
  144. return connection_info
  145. }
  146. static parseConnectionResponse(endpoint: Endpoint) {
  147. return endpoint
  148. }
  149. }