2022-02-01 17:38:45 +00:00
|
|
|
import { useQueries, useQuery } from 'react-query';
|
|
|
|
import { useEffect } from 'react';
|
|
|
|
|
|
|
|
import * as notifications from '@/portainer/services/notifications';
|
|
|
|
import PortainerError from '@/portainer/error';
|
|
|
|
import { EnvironmentId } from '@/portainer/environments/types';
|
|
|
|
import { Option } from '@/portainer/components/form-components/Input/Select';
|
|
|
|
import { getResourceGroups } from '@/azure/services/resource-groups.service';
|
|
|
|
import { getSubscriptions } from '@/azure/services/subscription.service';
|
|
|
|
import { getContainerInstanceProvider } from '@/azure/services/provider.service';
|
|
|
|
import { ContainerInstanceFormValues, Subscription } from '@/azure/types';
|
2022-03-16 06:35:32 +00:00
|
|
|
import { parseAccessControlFormData } from '@/portainer/access-control/utils';
|
2022-02-01 17:38:45 +00:00
|
|
|
|
|
|
|
import {
|
|
|
|
getSubscriptionLocations,
|
|
|
|
getSubscriptionResourceGroups,
|
|
|
|
} from './utils';
|
|
|
|
|
|
|
|
export function useLoadFormState(
|
|
|
|
environmentId: EnvironmentId,
|
|
|
|
isUserAdmin: boolean
|
|
|
|
) {
|
|
|
|
const { subscriptions, isLoading: isLoadingSubscriptions } =
|
|
|
|
useSubscriptions(environmentId);
|
|
|
|
const { resourceGroups, isLoading: isLoadingResourceGroups } =
|
|
|
|
useResourceGroups(environmentId, subscriptions);
|
|
|
|
const { providers, isLoading: isLoadingProviders } = useProviders(
|
|
|
|
environmentId,
|
|
|
|
subscriptions
|
|
|
|
);
|
|
|
|
|
|
|
|
const subscriptionOptions =
|
|
|
|
subscriptions?.map((s) => ({
|
|
|
|
value: s.subscriptionId,
|
|
|
|
label: s.displayName,
|
|
|
|
})) || [];
|
|
|
|
|
|
|
|
const initSubscriptionId = getFirstValue(subscriptionOptions);
|
|
|
|
|
|
|
|
const subscriptionResourceGroups = getSubscriptionResourceGroups(
|
|
|
|
initSubscriptionId,
|
|
|
|
resourceGroups
|
|
|
|
);
|
|
|
|
|
|
|
|
const subscriptionLocations = getSubscriptionLocations(
|
|
|
|
initSubscriptionId,
|
|
|
|
providers
|
|
|
|
);
|
|
|
|
|
|
|
|
const initialValues: ContainerInstanceFormValues = {
|
|
|
|
name: '',
|
|
|
|
location: getFirstValue(subscriptionLocations),
|
|
|
|
subscription: initSubscriptionId,
|
|
|
|
resourceGroup: getFirstValue(subscriptionResourceGroups),
|
|
|
|
image: '',
|
|
|
|
os: 'Linux',
|
|
|
|
memory: 1,
|
|
|
|
cpu: 1,
|
|
|
|
ports: [{ container: '80', host: '80', protocol: 'TCP' }],
|
|
|
|
allocatePublicIP: true,
|
2022-03-16 06:35:32 +00:00
|
|
|
accessControl: parseAccessControlFormData(isUserAdmin),
|
2022-02-01 17:38:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
isUserAdmin,
|
|
|
|
initialValues,
|
|
|
|
subscriptions: subscriptionOptions,
|
|
|
|
resourceGroups,
|
|
|
|
providers,
|
|
|
|
isLoading:
|
|
|
|
isLoadingProviders || isLoadingResourceGroups || isLoadingSubscriptions,
|
|
|
|
};
|
|
|
|
|
|
|
|
function getFirstValue<T extends string | number>(arr: Option<T>[]) {
|
|
|
|
if (arr.length === 0) {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
return arr[0].value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function useSubscriptions(environmentId: EnvironmentId) {
|
|
|
|
const { data, isError, error, isLoading } = useQuery(
|
|
|
|
'azure.subscriptions',
|
|
|
|
() => getSubscriptions(environmentId)
|
|
|
|
);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (isError) {
|
|
|
|
notifications.error(
|
|
|
|
'Failure',
|
|
|
|
error as PortainerError,
|
|
|
|
'Unable to retrieve Azure resources'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}, [isError, error]);
|
|
|
|
|
|
|
|
return { subscriptions: data || [], isLoading };
|
|
|
|
}
|
|
|
|
|
|
|
|
function useResourceGroups(
|
|
|
|
environmentId: EnvironmentId,
|
|
|
|
subscriptions: Subscription[]
|
|
|
|
) {
|
|
|
|
const queries = useQueries(
|
|
|
|
subscriptions.map((subscription) => ({
|
|
|
|
queryKey: ['azure.resourceGroups', subscription.subscriptionId],
|
|
|
|
queryFn: () =>
|
|
|
|
getResourceGroups(environmentId, subscription.subscriptionId),
|
|
|
|
}))
|
|
|
|
);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const failedQuery = queries.find((q) => q.error);
|
|
|
|
if (failedQuery) {
|
|
|
|
notifications.error(
|
|
|
|
'Failure',
|
|
|
|
failedQuery.error as PortainerError,
|
|
|
|
'Unable to retrieve Azure resources'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}, [queries]);
|
|
|
|
|
|
|
|
return {
|
|
|
|
resourceGroups: Object.fromEntries(
|
|
|
|
queries.map((q, index) => [
|
|
|
|
subscriptions[index].subscriptionId,
|
|
|
|
q.data || [],
|
|
|
|
])
|
|
|
|
),
|
|
|
|
isLoading: queries.some((q) => q.isLoading),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function useProviders(
|
|
|
|
environmentId: EnvironmentId,
|
|
|
|
subscriptions: Subscription[]
|
|
|
|
) {
|
|
|
|
const queries = useQueries(
|
|
|
|
subscriptions.map((subscription) => ({
|
|
|
|
queryKey: [
|
|
|
|
'azure.containerInstanceProvider',
|
|
|
|
subscription.subscriptionId,
|
|
|
|
],
|
|
|
|
queryFn: () =>
|
|
|
|
getContainerInstanceProvider(
|
|
|
|
environmentId,
|
|
|
|
subscription.subscriptionId
|
|
|
|
),
|
|
|
|
}))
|
|
|
|
);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const failedQuery = queries.find((q) => q.error);
|
|
|
|
if (failedQuery) {
|
|
|
|
notifications.error(
|
|
|
|
'Failure',
|
|
|
|
failedQuery.error as PortainerError,
|
|
|
|
'Unable to retrieve Azure resources'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}, [queries]);
|
|
|
|
|
|
|
|
return {
|
|
|
|
providers: Object.fromEntries(
|
|
|
|
queries.map((q, index) => [subscriptions[index].subscriptionId, q.data])
|
|
|
|
),
|
|
|
|
isLoading: queries.some((q) => q.isLoading),
|
|
|
|
};
|
|
|
|
}
|