/* Copyright (C) 2017 Cloudbase Solutions SRL This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ // @flow import { observable, action } from 'mobx' import type { Endpoint, Validation, StorageBackend } from '../types/Endpoint' import notificationStore from './NotificationStore' import EndpointSource from '../sources/EndpointSource' export const passwordFields = ['password', 'private_key_passphrase'] const updateEndpoint = (endpoint, endpoints) => endpoints.map(e => { if (e.id === endpoint.id) { return { ...endpoint } } return { ...e } }) class EndpointStore { @observable endpoints: Endpoint[] = [] @observable loading = false @observable loading = false @observable connectionInfo: ?$PropertyType = null @observable connectionsInfo: Endpoint[] = [] @observable validation: ?Validation = null @observable validating = false @observable updating = false @observable adding = false @observable connectionInfoLoading = false @observable connectionsInfoLoading = false @observable storageBackends: StorageBackend[] = [] @observable storageLoading: boolean = false @action getEndpoints(options?: { showLoading: boolean }) { if (options && options.showLoading) { this.loading = true } return EndpointSource.getEndpoints().then(endpoints => { this.endpoints = endpoints this.loading = false }).catch(() => { this.loading = false }) } @action delete(endpoint: Endpoint) { return EndpointSource.delete(endpoint).then(() => { this.endpoints = this.endpoints.filter(e => e.id !== endpoint.id) }) } @action getConnectionInfo(endpoint: Endpoint) { this.connectionInfoLoading = true return EndpointSource.getConnectionInfo(endpoint).then(connectionInfo => { this.setConnectionInfo(connectionInfo) }).catch(() => { this.connectionInfoLoading = false return Promise.reject() }) } @action getConnectionsInfo(endpointsData: Endpoint[]): Promise { this.connectionsInfoLoading = true return EndpointSource.getConnectionsInfo(endpointsData).then(endpoints => { this.connectionsInfoLoading = false this.connectionsInfo = endpoints }).catch(() => { this.connectionsInfoLoading = false }) } @action duplicate(opts: { shouldSwitchProject: boolean, onSwitchProject: () => Promise, endpoints: Endpoint[], }): Promise { let endpoints = [] return Promise.all(opts.endpoints.map(endpoint => { return EndpointSource.getConnectionInfo(endpoint).then(connectionInfo => { endpoints.push({ ...endpoint, connection_info: connectionInfo, name: `${endpoint.name}${!opts.shouldSwitchProject ? ' (copy)' : ''}`, }) }) })).then(() => { if (opts.shouldSwitchProject) { return opts.onSwitchProject() } return Promise.resolve() }).then(() => { return Promise.all(endpoints.map(endpoint => { return EndpointSource.add(endpoint, true) }).map((p: Promise) => p.catch(e => e))) .then((results: (Endpoint | { status: string, data?: { description: string } })[]) => { let internalServerErrors = results.filter(r => r.status && r.status === 500) if (internalServerErrors.length > 0) { notificationStore.alert(`There was a problem duplicating ${internalServerErrors.length} endpoint${internalServerErrors.length > 1 ? 's' : ''}`, 'error') } let forbiddenErrors = results.filter(r => r.status && r.status === 403) if (forbiddenErrors.length > 0 && forbiddenErrors[0].data && forbiddenErrors[0].data.description) { notificationStore.alert(String(forbiddenErrors[0].data.description), 'error') } }) }).catch(e => { if (e.data && e.data.description) { notificationStore.alert(e.data.description, 'error') } }) } @action setConnectionInfo(connectionInfo: $PropertyType) { this.connectionInfo = connectionInfo this.connectionInfoLoading = false } @action validate(endpoint: Endpoint) { this.validating = true return EndpointSource.validate(endpoint).then(validation => { this.validation = validation this.validating = false }).catch(() => { this.validating = false this.validation = { valid: false, message: '' } }) } @action clearValidation() { this.validating = false this.validation = null } @action update(endpoint: Endpoint) { this.endpoints = updateEndpoint(endpoint, this.endpoints) this.connectionInfo = { ...endpoint.connection_info } this.updating = true return EndpointSource.update(endpoint).then(updatedEndpoint => { this.endpoints = updateEndpoint(updatedEndpoint, this.endpoints) this.connectionInfo = { ...updatedEndpoint.connection_info } this.updating = false }) } @action clearConnectionInfo() { this.connectionInfo = null } @action add(endpoint: Endpoint) { this.adding = true return EndpointSource.add(endpoint).then(addedEndpoint => { this.endpoints = [ addedEndpoint, ...this.endpoints, ] this.connectionInfo = addedEndpoint.connection_info this.adding = false }).catch(() => { this.adding = false }) } @action loadStorage(endpointId: string, data: any): Promise { this.storageBackends = [] this.storageLoading = true return EndpointSource.loadStorage(endpointId, data).then(storage => { this.storageBackends = storage.storage_backends this.storageLoading = false }).catch(ex => { this.storageLoading = false throw ex }) } } export default new EndpointStore()