/* 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 . */ import { observable, action, runInAction } from 'mobx' import type { UpdateData, MigrationItem, MigrationItemDetails, MigrationItemOptions, UserScriptData, } from '../@types/MainItem' import type { Field } from '../@types/Field' import type { Endpoint } from '../@types/Endpoint' import type { InstanceScript } from '../@types/Instance' import MigrationSource from '../sources/MigrationSource' import apiCaller from '../utils/ApiCaller' class MigrationStore { @observable migrations: MigrationItem[] = [] @observable migrationDetails: MigrationItemDetails | null = null @observable loading: boolean = true @observable detailsLoading: boolean = true migrationsLoaded: boolean = false @action async getMigrations(options?: { showLoading?: boolean, skipLog?: boolean }) { if ((options && options.showLoading) || !this.migrationsLoaded) { this.loading = true } try { const migrations = await MigrationSource.getMigrations(options && options.skipLog) runInAction(() => { this.migrations = migrations this.loading = false this.migrationsLoaded = true }) } catch (ex) { runInAction(() => { this.loading = false }) throw ex } } getDefaultSkipOsMorphing(migration: MigrationItemDetails | null) { const tasks = migration && migration.tasks if (tasks && !tasks.find(t => t.task_type === 'OS_MORPHING')) { return true } return null } @action async recreateFullCopy(migration: MigrationItemOptions) { return MigrationSource.recreateFullCopy(migration) } @action async recreate( migration: MigrationItemDetails, sourceEndpoint: Endpoint, destEndpoint: Endpoint, updateData: UpdateData, defaultStorage: { value: string | null, busType?: string | null }, updatedDefaultStorage: { value: string | null, busType?: string | null } | undefined, replicationCount: number | null | undefined, ): Promise { const migrationResult = await MigrationSource.recreate({ sourceEndpoint, destEndpoint, migration, instanceNames: migration.instances, sourceEnv: migration.source_environment, updatedSourceEnv: updateData.source, destEnv: migration.destination_environment, updatedDestEnv: updateData.destination, storageMappings: migration.storage_mappings, updatedStorageMappings: updateData.storage, defaultStorage, updatedDefaultStorage, networkMappings: migration.network_map, updatedNetworkMappings: updateData.network, defaultSkipOsMorphing: this.getDefaultSkipOsMorphing(migration), replicationCount, uploadedScripts: updateData.uploadedScripts, removedScripts: updateData.removedScripts, }) return migrationResult } @action async getMigration( migrationId: string, options?: { showLoading?: boolean, skipLog?: boolean }, ) { if (options && options.showLoading) { this.detailsLoading = true } try { const migration = await MigrationSource.getMigration(migrationId, options && options.skipLog) runInAction(() => { this.migrationDetails = migration this.migrations = this.migrations.map(m => (m.id === migration.id ? migration : m)) }) } finally { runInAction(() => { this.detailsLoading = false }) } } @action async cancel(migrationId: string, force?: boolean | null) { await MigrationSource.cancel(migrationId, force) } @action async delete(migrationId: string) { await MigrationSource.delete(migrationId) runInAction(() => { this.migrations = this.migrations.filter(r => r.id !== migrationId) }) } @action async migrateReplica( replicaId: string, options: Field[], uploadedUserScripts: InstanceScript[], removedUserScripts: InstanceScript[], userScriptData: UserScriptData | null | undefined, minionPoolMappings: { [instance: string]: string }, ) { const migration = await MigrationSource.migrateReplica( replicaId, options, uploadedUserScripts, removedUserScripts, userScriptData, minionPoolMappings, ) runInAction(() => { this.migrations = [ migration, ...this.migrations, ] }) return migration } @action cancelMigrationDetails() { if (this.migrationDetails) { apiCaller.cancelRequests(this.migrationDetails.id) } this.detailsLoading = false } @action clearDetails() { this.detailsLoading = true this.migrationDetails = null } } export default new MigrationStore()