mirror of
https://github.com/portainer/portainer.git
synced 2025-08-02 20:35:25 +02:00
feat(app): limit the docker API version supported by the frontend (#11855)
Some checks are pending
ci / build_images (map[arch:amd64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
ci / build_images (map[arch:arm platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:arm64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:ppc64le platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:s390x platform:linux version:]) (push) Waiting to run
ci / build_manifests (push) Blocked by required conditions
/ triage (push) Waiting to run
Lint / Run linters (push) Waiting to run
Test / test-client (push) Waiting to run
Test / test-server (map[arch:amd64 platform:linux]) (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
Test / test-server (map[arch:arm64 platform:linux]) (push) Waiting to run
Some checks are pending
ci / build_images (map[arch:amd64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
ci / build_images (map[arch:arm platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:arm64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:ppc64le platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:s390x platform:linux version:]) (push) Waiting to run
ci / build_manifests (push) Blocked by required conditions
/ triage (push) Waiting to run
Lint / Run linters (push) Waiting to run
Test / test-client (push) Waiting to run
Test / test-server (map[arch:amd64 platform:linux]) (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
Test / test-server (map[arch:arm64 platform:linux]) (push) Waiting to run
This commit is contained in:
parent
4ba16f1b04
commit
6a8e6734f3
212 changed files with 4439 additions and 3281 deletions
|
@ -1,20 +0,0 @@
|
|||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
|
||||
import { buildUrl as buildDockerUrl } from '../../proxy/queries/build-url';
|
||||
import { NetworkId } from '../types';
|
||||
|
||||
export function buildUrl(
|
||||
environmentId: EnvironmentId,
|
||||
{ id, action }: { id?: NetworkId; action?: string } = {}
|
||||
) {
|
||||
let baseUrl = 'networks';
|
||||
if (id) {
|
||||
baseUrl += `/${id}`;
|
||||
}
|
||||
|
||||
if (action) {
|
||||
baseUrl += `/${action}`;
|
||||
}
|
||||
|
||||
return buildDockerUrl(environmentId, baseUrl);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
|
||||
import { queryKeys as dockerQueryKeys } from '../../queries/utils';
|
||||
import { NetworkId } from '../types';
|
||||
|
||||
import { NetworksQuery } from './types';
|
||||
|
||||
|
@ -9,4 +10,6 @@ export const queryKeys = {
|
|||
[...dockerQueryKeys.root(environmentId), 'networks'] as const,
|
||||
list: (environmentId: EnvironmentId, query: NetworksQuery) =>
|
||||
[...queryKeys.base(environmentId), 'list', query] as const,
|
||||
item: (environmentId: EnvironmentId, id: NetworkId) =>
|
||||
[...queryKeys.base(environmentId), id] as const,
|
||||
};
|
||||
|
|
|
@ -10,9 +10,8 @@ import {
|
|||
} from '@/react-tools/react-query';
|
||||
|
||||
import { queryKeys as dockerQueryKeys } from '../../queries/utils';
|
||||
import { addNodeHeader } from '../../proxy/addNodeHeader';
|
||||
|
||||
import { buildUrl } from './buildUrl';
|
||||
import { withAgentTargetHeader } from '../../proxy/queries/utils';
|
||||
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
|
||||
|
||||
interface ConnectContainerPayload {
|
||||
Container: string;
|
||||
|
@ -40,6 +39,9 @@ interface ConnectContainer {
|
|||
nodeName?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw docker API proxy
|
||||
*/
|
||||
export async function connectContainer({
|
||||
environmentId,
|
||||
containerId,
|
||||
|
@ -56,13 +58,11 @@ export async function connectContainer({
|
|||
};
|
||||
}
|
||||
|
||||
const headers = addNodeHeader(nodeName);
|
||||
|
||||
try {
|
||||
await axios.post(
|
||||
buildUrl(environmentId, { id: networkId, action: 'connect' }),
|
||||
buildDockerProxyUrl(environmentId, 'networks', networkId, 'connect'),
|
||||
payload,
|
||||
{ headers }
|
||||
{ headers: { ...withAgentTargetHeader(nodeName) } }
|
||||
);
|
||||
} catch (err) {
|
||||
throw parseAxiosError(err, 'Unable to connect container');
|
|
@ -0,0 +1,91 @@
|
|||
import { Network } from 'docker-types/generated/1.41';
|
||||
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
|
||||
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
|
||||
import {
|
||||
withAgentManagerOperationHeader,
|
||||
withAgentTargetHeader,
|
||||
} from '../../proxy/queries/utils';
|
||||
|
||||
type MacvlanConfigOnly = {
|
||||
ConfigOnly: true;
|
||||
Internal: false;
|
||||
Attachable: false;
|
||||
Options: {
|
||||
parent: string; // parent network card
|
||||
};
|
||||
};
|
||||
|
||||
type MacvlanConfigFrom = {
|
||||
ConfigFrom: {
|
||||
Network: string;
|
||||
};
|
||||
Scope: 'swarm' | 'local';
|
||||
};
|
||||
|
||||
type NetworkConfigBase = {
|
||||
Name: Required<Network>['Name'];
|
||||
CheckDuplicate?: boolean;
|
||||
Driver?: string;
|
||||
Internal?: boolean;
|
||||
Attachable?: boolean;
|
||||
Ingress?: boolean;
|
||||
IPAM?: Network['IPAM'];
|
||||
EnableIPv6?: boolean;
|
||||
Options?: Network['Options'];
|
||||
Labels?: Network['Labels'];
|
||||
};
|
||||
|
||||
/**
|
||||
* This type definition of NetworkConfig doesnt enforce the usage of only one type of the union
|
||||
* and not a mix of fields of the unionised types.
|
||||
* e.g. the following is valid for TS while it is not for the Docker API
|
||||
*
|
||||
* const config: NetworkConfig = {
|
||||
* Name: 'my-network', // shared
|
||||
* ConfigOnly: true, // MacvlanConfigOnly
|
||||
* Scope: 'swarm', // MacvlanConfigFrom
|
||||
* }
|
||||
*
|
||||
*/
|
||||
type NetworkConfig =
|
||||
| NetworkConfigBase
|
||||
| (NetworkConfigBase & MacvlanConfigOnly)
|
||||
| (NetworkConfigBase & MacvlanConfigFrom);
|
||||
|
||||
type CreateOptions = {
|
||||
nodeName?: string;
|
||||
agentManagerOperation?: boolean;
|
||||
};
|
||||
|
||||
type CreateNetworkResponse = {
|
||||
Id: string;
|
||||
Warning: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Raw docker API proxy
|
||||
*/
|
||||
export async function createNetwork(
|
||||
environmentId: EnvironmentId,
|
||||
networkConfig: NetworkConfig,
|
||||
{ nodeName, agentManagerOperation }: CreateOptions = {}
|
||||
) {
|
||||
try {
|
||||
const { data } = await axios.post<CreateNetworkResponse>(
|
||||
buildDockerProxyUrl(environmentId, 'networks', 'create'),
|
||||
networkConfig,
|
||||
{
|
||||
headers: {
|
||||
...withAgentTargetHeader(nodeName),
|
||||
...withAgentManagerOperationHeader(agentManagerOperation),
|
||||
},
|
||||
}
|
||||
);
|
||||
return data;
|
||||
} catch (err) {
|
||||
throw parseAxiosError(err, 'Unable to create network');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
import {
|
||||
mutationOptions,
|
||||
withError,
|
||||
withInvalidate,
|
||||
} from '@/react-tools/react-query';
|
||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
|
||||
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
|
||||
import { NetworkId } from '../types';
|
||||
|
||||
import { queryKeys } from './queryKeys';
|
||||
|
||||
export function useDeleteNetwork(environmentId: EnvironmentId) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation(
|
||||
({ networkId }: { networkId: NetworkId }) =>
|
||||
deleteNetwork(environmentId, networkId),
|
||||
mutationOptions(
|
||||
withInvalidate(queryClient, [queryKeys.base(environmentId)]),
|
||||
withError('Unable to remove network')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw docker API proxy
|
||||
* @param environmentId
|
||||
* @param networkId
|
||||
* @returns
|
||||
*/
|
||||
export async function deleteNetwork(
|
||||
environmentId: EnvironmentId,
|
||||
networkId: NetworkId
|
||||
) {
|
||||
try {
|
||||
await axios.delete(
|
||||
buildDockerProxyUrl(environmentId, 'networks', networkId)
|
||||
);
|
||||
return networkId;
|
||||
} catch (err) {
|
||||
throw parseAxiosError(err, 'Unable to remove network');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import {
|
||||
mutationOptions,
|
||||
withError,
|
||||
withInvalidate,
|
||||
} from '@/react-tools/react-query';
|
||||
|
||||
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
|
||||
import { ContainerId } from '../../containers/types';
|
||||
import { NetworkId } from '../types';
|
||||
|
||||
import { queryKeys } from './queryKeys';
|
||||
|
||||
export function useDisconnectContainer({
|
||||
environmentId,
|
||||
networkId,
|
||||
}: {
|
||||
environmentId: EnvironmentId;
|
||||
networkId: NetworkId;
|
||||
}) {
|
||||
const client = useQueryClient();
|
||||
|
||||
return useMutation(
|
||||
({ containerId }: { containerId: ContainerId }) =>
|
||||
disconnectContainer(environmentId, networkId, containerId),
|
||||
mutationOptions(
|
||||
withInvalidate(client, [queryKeys.item(environmentId, networkId)]),
|
||||
withError('Unable to disconnect container from network')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw docker API proxy
|
||||
* @param environmentId
|
||||
* @param networkId
|
||||
* @param containerId
|
||||
* @returns
|
||||
*/
|
||||
export async function disconnectContainer(
|
||||
environmentId: EnvironmentId,
|
||||
networkId: NetworkId,
|
||||
containerId: ContainerId
|
||||
) {
|
||||
try {
|
||||
await axios.post(
|
||||
buildDockerProxyUrl(environmentId, 'networks', networkId, 'disconnect'),
|
||||
{
|
||||
Container: containerId,
|
||||
Force: false,
|
||||
}
|
||||
);
|
||||
return { networkId, environmentId };
|
||||
} catch (err) {
|
||||
throw parseAxiosError(err, 'Unable to disconnect container from network');
|
||||
}
|
||||
}
|
52
app/react/docker/networks/queries/useNetwork.ts
Normal file
52
app/react/docker/networks/queries/useNetwork.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { withGlobalError } from '@/react-tools/react-query';
|
||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
|
||||
import { DockerNetwork, NetworkId } from '../types';
|
||||
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
|
||||
import { withAgentTargetHeader } from '../../proxy/queries/utils';
|
||||
|
||||
import { queryKeys } from './queryKeys';
|
||||
|
||||
export function useNetwork(
|
||||
environmentId: EnvironmentId,
|
||||
networkId: NetworkId,
|
||||
{ nodeName }: { nodeName?: string } = {}
|
||||
) {
|
||||
return useQuery(
|
||||
[...queryKeys.item(environmentId, networkId), { nodeName }],
|
||||
() => getNetwork(environmentId, networkId, { nodeName }),
|
||||
{
|
||||
...withGlobalError('Unable to get network'),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw docker API proxy
|
||||
* @param environmentId
|
||||
* @param networkId
|
||||
* @param param2
|
||||
* @returns
|
||||
*/
|
||||
export async function getNetwork(
|
||||
environmentId: EnvironmentId,
|
||||
networkId: NetworkId,
|
||||
{ nodeName }: { nodeName?: string } = {}
|
||||
) {
|
||||
try {
|
||||
const { data: network } = await axios.get<DockerNetwork>(
|
||||
buildDockerProxyUrl(environmentId, 'networks', networkId),
|
||||
{
|
||||
headers: {
|
||||
...withAgentTargetHeader(nodeName),
|
||||
},
|
||||
}
|
||||
);
|
||||
return network;
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, 'Unable to retrieve network details');
|
||||
}
|
||||
}
|
|
@ -3,8 +3,9 @@ import { useQuery } from '@tanstack/react-query';
|
|||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||
|
||||
import { buildUrl } from '../../proxy/queries/build-url';
|
||||
import { DockerNetwork } from '../types';
|
||||
import { withFiltersQueryParam } from '../../proxy/queries/utils';
|
||||
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
|
||||
|
||||
import { queryKeys } from './queryKeys';
|
||||
import { NetworksQuery } from './types';
|
||||
|
@ -29,17 +30,18 @@ export function useNetworks<T = Array<DockerNetwork>>(
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw docker API proxy
|
||||
*/
|
||||
export async function getNetworks(
|
||||
environmentId: EnvironmentId,
|
||||
{ local, swarm, swarmAttachable, filters }: NetworksQuery
|
||||
) {
|
||||
try {
|
||||
const { data } = await axios.get<Array<DockerNetwork>>(
|
||||
buildUrl(environmentId, 'networks'),
|
||||
filters && {
|
||||
params: {
|
||||
filters,
|
||||
},
|
||||
buildDockerProxyUrl(environmentId, 'networks'),
|
||||
{
|
||||
params: { ...withFiltersQueryParam(filters) },
|
||||
}
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue