import { useQuery } from 'react-query'; import { Plugin, PluginInterfaceType, PluginsInfo, } from 'docker-types/generated/1.41'; import axios, { parseAxiosError } from '@/portainer/services/axios'; import { EnvironmentId } from '@/react/portainer/environments/types'; import { queryKeys } from '../../queries/utils/root'; import { buildDockerProxyUrl } from './buildDockerProxyUrl'; import { useInfo } from './useInfo'; const pluginTypeToVersionMap: { [k in keyof PluginsInfo]: string } = { Volume: 'docker.volumedriver/1.0', Network: 'docker.networkdriver/1.0', Log: 'docker.logdriver/1.0', }; export async function getPlugins(environmentId: EnvironmentId) { try { const { data } = await axios.get>( buildDockerProxyUrl(environmentId, 'plugins') ); return data; } catch (e) { throw parseAxiosError(e as Error, 'Unable to retrieve plugins'); } } function usePlugins( environmentId: EnvironmentId, { enabled }: { enabled?: boolean } = {} ) { return useQuery( queryKeys.plugins(environmentId), () => getPlugins(environmentId), { enabled } ); } export function useServicePlugins( environmentId: EnvironmentId, systemOnly: boolean, pluginType: keyof PluginsInfo ) { const systemPluginsQuery = useInfo(environmentId, (info) => info.Plugins); const pluginsQuery = usePlugins(environmentId, { enabled: !systemOnly }); return { data: aggregateData( systemPluginsQuery.data, pluginsQuery.data, systemOnly, pluginType ), isLoading: systemPluginsQuery.isLoading || pluginsQuery.isLoading, }; } /** * @private Exported only for AngularJS `PluginService` factory `app/docker/services/pluginService.js` */ export function aggregateData( systemPluginsData: PluginsInfo | undefined, pluginsData: Plugin[] | undefined, systemOnly: boolean, pluginType: keyof PluginsInfo ) { if (!systemPluginsData) { return null; } const systemPlugins = systemPluginsData[pluginType] || []; if (systemOnly) { return systemPlugins; } const plugins = pluginsData ?.filter( (plugin) => plugin.Enabled && // docker has an error in their types, so we need to cast to unknown first // see https://docs.docker.com/engine/api/v1.41/#tag/Plugin/operation/PluginList plugin.Config.Interface.Types.includes( pluginTypeToVersionMap[pluginType] as unknown as PluginInterfaceType ) ) .map((plugin) => plugin.Name) || []; return [...systemPlugins, ...plugins]; } export function useLoggingPlugins( environmentId: EnvironmentId, systemOnly: boolean ) { return useServicePlugins(environmentId, systemOnly, 'Log'); } export function useVolumePlugins( environmentId: EnvironmentId, systemOnly: boolean ) { return useServicePlugins(environmentId, systemOnly, 'Volume'); } export function useNetworkPlugins( environmentId: EnvironmentId, systemOnly: boolean ) { return useServicePlugins(environmentId, systemOnly, 'Network'); }