EndpointStore.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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 { observable, action } from 'mobx'
  16. import type { Endpoint, Validation, StorageBackend } from '../types/Endpoint'
  17. import notificationStore from './NotificationStore'
  18. import EndpointSource from '../sources/EndpointSource'
  19. export const passwordFields = ['password', 'private_key_passphrase', 'secret_access_key']
  20. const updateEndpoint = (endpoint, endpoints) => endpoints.map(e => {
  21. if (e.id === endpoint.id) {
  22. return { ...endpoint }
  23. }
  24. return { ...e }
  25. })
  26. class EndpointStore {
  27. @observable endpoints: Endpoint[] = []
  28. @observable loading = false
  29. @observable loading = false
  30. @observable connectionInfo: ?$PropertyType<Endpoint, 'connection_info'> = null
  31. @observable connectionsInfo: Endpoint[] = []
  32. @observable validation: ?Validation = null
  33. @observable validating = false
  34. @observable updating = false
  35. @observable adding = false
  36. @observable connectionInfoLoading = false
  37. @observable connectionsInfoLoading = false
  38. @observable storageBackends: StorageBackend[] = []
  39. @observable storageLoading: boolean = false
  40. @observable storageConfigDefault: string = ''
  41. @action getEndpoints(options?: { showLoading?: boolean, skipLog?: boolean }) {
  42. if (options && options.showLoading) {
  43. this.loading = true
  44. }
  45. return EndpointSource.getEndpoints(options && options.skipLog).then(endpoints => {
  46. this.endpoints = endpoints
  47. this.loading = false
  48. }).catch(() => {
  49. this.loading = false
  50. })
  51. }
  52. @action delete(endpoint: Endpoint) {
  53. return EndpointSource.delete(endpoint).then(() => {
  54. this.endpoints = this.endpoints.filter(e => e.id !== endpoint.id)
  55. })
  56. }
  57. @action getConnectionInfo(endpoint: Endpoint) {
  58. this.connectionInfoLoading = true
  59. return EndpointSource.getConnectionInfo(endpoint).then(connectionInfo => {
  60. this.setConnectionInfo(connectionInfo)
  61. }).catch(() => {
  62. this.connectionInfoLoading = false
  63. return Promise.reject()
  64. })
  65. }
  66. @action getConnectionsInfo(endpointsData: Endpoint[]): Promise<void> {
  67. this.connectionsInfoLoading = true
  68. return EndpointSource.getConnectionsInfo(endpointsData).then(endpoints => {
  69. this.connectionsInfoLoading = false
  70. this.connectionsInfo = endpoints
  71. }).catch(() => {
  72. this.connectionsInfoLoading = false
  73. })
  74. }
  75. @action duplicate(opts: {
  76. shouldSwitchProject: boolean,
  77. onSwitchProject: () => Promise<void>,
  78. endpoints: Endpoint[],
  79. }): Promise<void> {
  80. let endpoints = []
  81. return Promise.all(opts.endpoints.map(endpoint => {
  82. return EndpointSource.getConnectionInfo(endpoint).then(connectionInfo => {
  83. endpoints.push({
  84. ...endpoint,
  85. connection_info: connectionInfo,
  86. name: `${endpoint.name}${!opts.shouldSwitchProject ? ' (copy)' : ''}`,
  87. })
  88. })
  89. })).then(() => {
  90. if (opts.shouldSwitchProject) {
  91. return opts.onSwitchProject()
  92. }
  93. return Promise.resolve()
  94. }).then(() => {
  95. return Promise.all(endpoints.map(endpoint => {
  96. return EndpointSource.add(endpoint, true)
  97. }).map((p: Promise<any>) => p.catch(e => e)))
  98. .then((results: (Endpoint | { status: string, data?: { description: string } })[]) => {
  99. let internalServerErrors = results.filter(r => r.status && r.status === 500)
  100. if (internalServerErrors.length > 0) {
  101. notificationStore.alert(`There was a problem duplicating ${internalServerErrors.length} endpoint${internalServerErrors.length > 1 ? 's' : ''}`, 'error')
  102. }
  103. let forbiddenErrors = results.filter(r => r.status && r.status === 403)
  104. if (forbiddenErrors.length > 0 && forbiddenErrors[0].data && forbiddenErrors[0].data.description) {
  105. notificationStore.alert(String(forbiddenErrors[0].data.description), 'error')
  106. }
  107. })
  108. }).catch(e => {
  109. if (e.data && e.data.description) {
  110. notificationStore.alert(e.data.description, 'error')
  111. }
  112. })
  113. }
  114. @action setConnectionInfo(connectionInfo: $PropertyType<Endpoint, 'connection_info'>) {
  115. this.connectionInfo = connectionInfo
  116. this.connectionInfoLoading = false
  117. }
  118. @action validate(endpoint: Endpoint) {
  119. this.validating = true
  120. return EndpointSource.validate(endpoint).then(validation => {
  121. this.validation = validation
  122. this.validating = false
  123. }).catch(() => {
  124. this.validating = false
  125. this.validation = { valid: false, message: '' }
  126. })
  127. }
  128. @action clearValidation() {
  129. this.validating = false
  130. this.validation = null
  131. }
  132. @action update(endpoint: Endpoint) {
  133. this.endpoints = updateEndpoint(endpoint, this.endpoints)
  134. this.connectionInfo = { ...endpoint.connection_info }
  135. this.updating = true
  136. return EndpointSource.update(endpoint).then(updatedEndpoint => {
  137. this.endpoints = updateEndpoint(updatedEndpoint, this.endpoints)
  138. this.connectionInfo = { ...updatedEndpoint.connection_info }
  139. this.updating = false
  140. }).catch(e => {
  141. this.updating = false
  142. throw e
  143. })
  144. }
  145. @action clearConnectionInfo() {
  146. this.connectionInfo = null
  147. }
  148. @action add(endpoint: Endpoint) {
  149. this.adding = true
  150. return EndpointSource.add(endpoint).then(addedEndpoint => {
  151. this.endpoints = [
  152. addedEndpoint,
  153. ...this.endpoints,
  154. ]
  155. this.connectionInfo = addedEndpoint.connection_info
  156. this.adding = false
  157. }).catch(e => {
  158. this.adding = false
  159. throw e
  160. })
  161. }
  162. @action loadStorage(endpointId: string, data: any): Promise<void> {
  163. this.storageBackends = []
  164. this.storageLoading = true
  165. return EndpointSource.loadStorage(endpointId, data).then(storage => {
  166. this.storageBackends = storage.storage_backends
  167. this.storageConfigDefault = storage.config_default || ''
  168. this.storageLoading = false
  169. }).catch(ex => {
  170. this.storageLoading = false
  171. throw ex
  172. })
  173. }
  174. }
  175. export default new EndpointStore()