EndpointStore.js 7.2 KB

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