portainer/app/react/common/stacks/ItemView/StackDuplicationForm/useMigrateStackMutation.ts

102 lines
2.1 KiB
TypeScript

import { useMutation } from '@tanstack/react-query';
import { getSwarm } from '@/react/docker/proxy/queries/useSwarm';
import { EnvironmentId } from '@/react/portainer/environments/types';
import axios, { parseAxiosError } from '@/portainer/services/axios';
import { StackType } from '../../types';
import { buildStackUrl } from '../../queries/buildUrl';
export function useMigrateStackMutation() {
return useMutation({
mutationFn: routeMigrationRequest,
});
}
export function routeMigrationRequest({
stackType,
id,
fromEnvId,
targetEnvId,
name,
fromSwarmId,
}: {
stackType: StackType;
fromSwarmId?: string;
id: number;
fromEnvId: EnvironmentId;
targetEnvId: EnvironmentId;
name?: string;
}) {
if (stackType === StackType.DockerSwarm) {
return migrateSwarmStack({ id, fromEnvId, targetEnvId, name, fromSwarmId });
}
return migrateStack({ id, fromEnvId, targetEnvId, name });
}
export async function migrateSwarmStack({
id,
fromEnvId,
targetEnvId,
fromSwarmId,
name,
}: {
id: number;
fromEnvId: EnvironmentId;
targetEnvId: EnvironmentId;
fromSwarmId?: string;
name?: string;
}) {
if (!fromSwarmId) {
throw new Error('Original Swarm ID is required to migrate a Swarm stack');
}
const targetSwarm = await getSwarm(targetEnvId);
if (fromSwarmId === targetSwarm.ID) {
throw new Error(
'Target environment is located in the same Swarm cluster as the current environment'
);
}
return migrateStack({
id,
fromEnvId,
targetEnvId,
name,
targetSwarmId: targetSwarm.ID,
});
}
export async function migrateStack({
id,
fromEnvId,
targetEnvId,
name,
targetSwarmId,
}: {
id: number;
fromEnvId: EnvironmentId;
targetEnvId: EnvironmentId;
name?: string;
targetSwarmId?: string;
}) {
try {
return await axios.post(
buildStackUrl(id, 'migrate'),
{
EndpointID: targetEnvId,
Name: name,
SwarmID: targetSwarmId,
},
{
params: {
endpointId: fromEnvId,
},
}
);
} catch (err) {
throw parseAxiosError(err);
}
}