1
0
Fork 0
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

This commit is contained in:
LP B 2024-06-10 20:54:31 +02:00 committed by GitHub
parent 4ba16f1b04
commit 6a8e6734f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
212 changed files with 4439 additions and 3281 deletions

View file

@ -0,0 +1,12 @@
import { EnvironmentId } from '@/react/portainer/environments/types';
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
import { ServiceId } from '../types';
export function buildUrl(
endpointId: EnvironmentId,
id?: ServiceId,
action?: string
) {
return buildDockerProxyUrl(endpointId, 'services', id, action);
}

View file

@ -1,11 +1,15 @@
import { EnvironmentId } from '@/react/portainer/environments/types';
import { queryKeys as dockerQueryKeys } from '../../queries/utils';
import { Filters } from '../types';
export const queryKeys = {
list: (environmentId: EnvironmentId) =>
[...dockerQueryKeys.root(environmentId), 'services'] as const,
filters: (environmentId: EnvironmentId, filters: Filters = {}) =>
[...queryKeys.list(environmentId), filters] as const,
service: (environmentId: EnvironmentId, id: string) =>
[...queryKeys.list(environmentId), id] as const,
};

View file

@ -0,0 +1,54 @@
import { Service } from 'docker-types/generated/1.41';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios, { parseAxiosError } from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types';
import {
mutationOptions,
withError,
withInvalidate,
} from '@/react-tools/react-query';
import { ServiceUpdateConfig } from '../types';
import { withRegistryAuthHeader } from '../../proxy/queries/utils';
import { buildUrl } from './build-url';
import { queryKeys } from './query-keys';
export function useCreateServiceMutation(environmentId: EnvironmentId) {
const queryClient = useQueryClient();
return useMutation(
createService,
mutationOptions(
withInvalidate(queryClient, [queryKeys.list(environmentId)]),
withError('Unable to create service')
)
);
}
export async function createService({
environmentId,
config,
registryId,
}: {
environmentId: EnvironmentId;
config: ServiceUpdateConfig;
registryId?: number;
}) {
try {
const { data } = await axios.post<Service>(
buildUrl(environmentId, 'create'),
config,
{
headers: {
version: '1.29', // https://github.com/orgs/portainer/discussions/9407#discussioncomment-6559219
...withRegistryAuthHeader(registryId),
},
}
);
return data;
} catch (e) {
throw parseAxiosError(e, 'Unable to create service');
}
}

View file

@ -0,0 +1,35 @@
import { useQuery } from '@tanstack/react-query';
import { Service } from 'docker-types/generated/1.41';
import axios, { parseAxiosError } from '@/portainer/services/axios';
import { withGlobalError } from '@/react-tools/react-query';
import { ServiceId } from '@/react/docker/services/types';
import { queryKeys } from '@/react/docker/services/queries/query-keys';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { buildUrl } from '@/react/docker/services/queries/build-url';
export function useService(environmentId: EnvironmentId, serviceId: ServiceId) {
return useQuery(
queryKeys.service(environmentId, serviceId),
() => getService(environmentId, serviceId),
{
enabled: !!serviceId,
...withGlobalError('Unable to retrieve service'),
}
);
}
export async function getService(
environmentId: EnvironmentId,
serviceId: ServiceId
) {
try {
const { data } = await axios.get<Service>(
buildUrl(environmentId, serviceId)
);
return data;
} catch (e) {
throw parseAxiosError(e, 'Unable to get service');
}
}

View file

@ -0,0 +1,33 @@
import _ from 'lodash';
import axios, { parseAxiosError } from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { buildUrl } from '@/react/docker/services/queries/build-url';
import { ServiceId } from '@/react/docker/services/types';
type ServiceLogsParams = {
stdout?: boolean;
stderr?: boolean;
timestamps?: boolean;
since?: number;
tail?: number;
};
export async function getServiceLogs(
environmentId: EnvironmentId,
serviceId: ServiceId,
params?: ServiceLogsParams
): Promise<string> {
try {
const { data } = await axios.get<string>(
buildUrl(environmentId, serviceId, 'logs'),
{
params: _.pickBy(params),
}
);
return data;
} catch (e) {
throw parseAxiosError(e, 'Unable to get service logs');
}
}

View file

@ -0,0 +1,36 @@
import { useQuery } from '@tanstack/react-query';
import { Service } from 'docker-types/generated/1.41';
import axios, { parseAxiosError } from '@/portainer/services/axios';
import { withGlobalError } from '@/react-tools/react-query';
import { queryKeys } from '@/react/docker/services/queries/query-keys';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { buildUrl } from '@/react/docker/services/queries/build-url';
import { Filters } from '../types';
import { withFiltersQueryParam } from '../../proxy/queries/utils';
export function useServices(environmentId: EnvironmentId, filters?: Filters) {
return useQuery(
queryKeys.filters(environmentId, filters),
() => getServices(environmentId, filters),
{
...withGlobalError('Unable to retrieve services'),
}
);
}
export async function getServices(
environmentId: EnvironmentId,
filters?: Filters
) {
try {
const { data } = await axios.get<Service[]>(buildUrl(environmentId), {
params: withFiltersQueryParam(filters),
});
return data;
} catch (e) {
throw parseAxiosError(e, 'Unable to get services');
}
}

View file

@ -1,36 +1,33 @@
import {
TaskSpec,
ServiceSpec,
ServiceUpdateResponse,
} from 'docker-types/generated/1.41';
import { ServiceUpdateResponse } from 'docker-types/generated/1.41';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios, { parseAxiosError } from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { mutationOptions, withError } from '@/react-tools/react-query';
import {
mutationOptions,
withError,
withInvalidate,
} from '@/react-tools/react-query';
import { encodeRegistryCredentials } from '../../images/queries/encodeRegistryCredentials';
import { urlBuilder } from '../axios/urlBuilder';
import { ServiceUpdateConfig } from '../types';
import { withRegistryAuthHeader } from '../../proxy/queries/utils';
import { buildUrl } from './build-url';
import { queryKeys } from './query-keys';
export function useUpdateServiceMutation() {
export function useUpdateServiceMutation(environmentId: EnvironmentId) {
const queryClient = useQueryClient();
return useMutation(
updateService,
mutationOptions(
{
onSuccess(data, { environmentId }) {
return queryClient.invalidateQueries(queryKeys.list(environmentId));
},
},
withInvalidate(queryClient, [queryKeys.list(environmentId)]),
withError('Unable to update service')
)
);
}
async function updateService({
export async function updateService({
environmentId,
serviceId,
config,
@ -47,20 +44,17 @@ async function updateService({
}) {
try {
const { data } = await axios.post<ServiceUpdateResponse>(
urlBuilder(environmentId, serviceId, 'update'),
buildUrl(environmentId, serviceId, 'update'),
config,
{
params: {
rollback,
version,
},
...(registryId
? {
headers: {
'X-Registry-Id': encodeRegistryCredentials(registryId),
},
}
: {}),
headers: {
version: '1.29', // https://github.com/orgs/portainer/discussions/9407#discussioncomment-6559219
...withRegistryAuthHeader(registryId),
},
}
);
return data;
@ -68,13 +62,3 @@ async function updateService({
throw parseAxiosError(e, 'Unable to update service');
}
}
export interface ServiceUpdateConfig {
Name: string;
Labels: Record<string, string>;
TaskTemplate: TaskSpec;
Mode: ServiceSpec['Mode'];
UpdateConfig: ServiceSpec['UpdateConfig'];
Networks: ServiceSpec['Networks'];
EndpointSpec: ServiceSpec['EndpointSpec'];
}