1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-19 13:29:41 +02:00

fix(kubeapi): fix ts api error handling [EE-5558] (#10488)

* fix(kubeapi): fix ts api error handling [EE-5558]

* use portainer errors for mapped functions

* don't parse long patch responses

* allow nested kube error that's thrown to bubble up

---------

Co-authored-by: testa113 <testa113>
This commit is contained in:
Ali 2023-10-23 20:52:40 +01:00 committed by GitHub
parent 6c55cac52a
commit 96ead31a8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 210 additions and 234 deletions

View file

@ -2,9 +2,11 @@ import { EventList } from 'kubernetes-types/core/v1';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
import axios, { parseAxiosError } from '@/portainer/services/axios'; import axios from '@/portainer/services/axios';
import { withError } from '@/react-tools/react-query'; import { withError } from '@/react-tools/react-query';
import { parseKubernetesAxiosError } from '../../axiosError';
async function getNamespaceEvents( async function getNamespaceEvents(
environmentId: EnvironmentId, environmentId: EnvironmentId,
namespace: string, namespace: string,
@ -21,7 +23,7 @@ async function getNamespaceEvents(
); );
return data.items; return data.items;
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, 'Unable to retrieve events'); throw parseKubernetesAxiosError(e, 'Unable to retrieve events');
} }
} }

View file

@ -13,6 +13,8 @@ import axios, { parseAxiosError } from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
import { isFulfilled } from '@/portainer/helpers/promise-utils'; import { isFulfilled } from '@/portainer/helpers/promise-utils';
import { parseKubernetesAxiosError } from '../axiosError';
import { getPod, getNamespacePods, patchPod } from './pod.service'; import { getPod, getNamespacePods, patchPod } from './pod.service';
import { filterRevisionsByOwnerUid, getNakedPods } from './utils'; import { filterRevisionsByOwnerUid, getNakedPods } from './utils';
import { import {
@ -29,22 +31,15 @@ export async function getApplicationsForCluster(
environmentId: EnvironmentId, environmentId: EnvironmentId,
namespaceNames?: string[] namespaceNames?: string[]
) { ) {
try { if (!namespaceNames) {
if (!namespaceNames) { return [];
return [];
}
const applications = await Promise.all(
namespaceNames.map((namespace) =>
getApplicationsForNamespace(environmentId, namespace)
)
);
return applications.flat();
} catch (e) {
throw parseAxiosError(
e as Error,
'Unable to retrieve applications for cluster'
);
} }
const applications = await Promise.all(
namespaceNames.map((namespace) =>
getApplicationsForNamespace(environmentId, namespace)
)
);
return applications.flat();
} }
// get a list of all Deployments, DaemonSets, StatefulSets and naked pods (https://portainer.atlassian.net/browse/CE-2) in one namespace // get a list of all Deployments, DaemonSets, StatefulSets and naked pods (https://portainer.atlassian.net/browse/CE-2) in one namespace
@ -52,34 +47,23 @@ async function getApplicationsForNamespace(
environmentId: EnvironmentId, environmentId: EnvironmentId,
namespace: string namespace: string
) { ) {
try { const [deployments, daemonSets, statefulSets, pods] = await Promise.all([
const [deployments, daemonSets, statefulSets, pods] = await Promise.all([ getApplicationsByKind<DeploymentList>(
getApplicationsByKind<DeploymentList>( environmentId,
environmentId, namespace,
namespace, 'Deployment'
'Deployment' ),
), getApplicationsByKind<DaemonSetList>(environmentId, namespace, 'DaemonSet'),
getApplicationsByKind<DaemonSetList>( getApplicationsByKind<StatefulSetList>(
environmentId, environmentId,
namespace, namespace,
'DaemonSet' 'StatefulSet'
), ),
getApplicationsByKind<StatefulSetList>( getNamespacePods(environmentId, namespace),
environmentId, ]);
namespace, // find all pods which are 'naked' (not owned by a deployment, daemonset or statefulset)
'StatefulSet' const nakedPods = getNakedPods(pods, deployments, daemonSets, statefulSets);
), return [...deployments, ...daemonSets, ...statefulSets, ...nakedPods];
getNamespacePods(environmentId, namespace),
]);
// find all pods which are 'naked' (not owned by a deployment, daemonset or statefulset)
const nakedPods = getNakedPods(pods, deployments, daemonSets, statefulSets);
return [...deployments, ...daemonSets, ...statefulSets, ...nakedPods];
} catch (e) {
throw parseAxiosError(
e as Error,
`Unable to retrieve applications in namespace '${namespace}'`
);
}
} }
// if not known, get the type of an application (Deployment, DaemonSet, StatefulSet or naked pod) by name // if not known, get the type of an application (Deployment, DaemonSet, StatefulSet or naked pod) by name
@ -92,72 +76,65 @@ export async function getApplication<
appKind?: AppKind, appKind?: AppKind,
yaml?: boolean yaml?: boolean
) { ) {
try { // if resourceType is known, get the application by type and name
// if resourceType is known, get the application by type and name if (appKind) {
if (appKind) { switch (appKind) {
switch (appKind) { case 'Deployment':
case 'Deployment': case 'DaemonSet':
case 'DaemonSet': case 'StatefulSet':
case 'StatefulSet': return getApplicationByKind<T>(
return await getApplicationByKind<T>( environmentId,
environmentId, namespace,
namespace, appKind,
appKind, name,
name, yaml
yaml );
); case 'Pod':
case 'Pod': return getPod(environmentId, namespace, name, yaml);
return await getPod(environmentId, namespace, name, yaml); default:
default: throw new Error('Unknown resource type');
throw new Error('Unknown resource type');
}
} }
// if resourceType is not known, get the application by name and return the first one that is fulfilled
const [deployment, daemonSet, statefulSet, pod] = await Promise.allSettled([
getApplicationByKind<Deployment>(
environmentId,
namespace,
'Deployment',
name,
yaml
),
getApplicationByKind<DaemonSet>(
environmentId,
namespace,
'DaemonSet',
name,
yaml
),
getApplicationByKind<StatefulSet>(
environmentId,
namespace,
'StatefulSet',
name,
yaml
),
getPod(environmentId, namespace, name, yaml),
]);
if (isFulfilled(deployment)) {
return deployment.value;
}
if (isFulfilled(daemonSet)) {
return daemonSet.value;
}
if (isFulfilled(statefulSet)) {
return statefulSet.value;
}
if (isFulfilled(pod)) {
return pod.value;
}
throw new Error('Unable to retrieve application');
} catch (e) {
throw parseAxiosError(
e as Error,
`Unable to retrieve application ${name} in namespace '${namespace}'`
);
} }
// if resourceType is not known, get the application by name and return the first one that is fulfilled
const [deployment, daemonSet, statefulSet, pod] = await Promise.allSettled([
getApplicationByKind<Deployment>(
environmentId,
namespace,
'Deployment',
name,
yaml
),
getApplicationByKind<DaemonSet>(
environmentId,
namespace,
'DaemonSet',
name,
yaml
),
getApplicationByKind<StatefulSet>(
environmentId,
namespace,
'StatefulSet',
name,
yaml
),
getPod(environmentId, namespace, name, yaml),
]);
if (isFulfilled(deployment)) {
return deployment.value;
}
if (isFulfilled(daemonSet)) {
return daemonSet.value;
}
if (isFulfilled(statefulSet)) {
return statefulSet.value;
}
if (isFulfilled(pod)) {
return pod.value;
}
throw new Error('Unable to retrieve application');
} }
export async function patchApplication( export async function patchApplication(
@ -167,44 +144,37 @@ export async function patchApplication(
name: string, name: string,
patch: ApplicationPatch patch: ApplicationPatch
) { ) {
try { switch (appKind) {
switch (appKind) { case 'Deployment':
case 'Deployment': return patchApplicationByKind<Deployment>(
return await patchApplicationByKind<Deployment>( environmentId,
environmentId, namespace,
namespace, appKind,
appKind, name,
name, patch
patch );
); case 'DaemonSet':
case 'DaemonSet': return patchApplicationByKind<DaemonSet>(
return await patchApplicationByKind<DaemonSet>( environmentId,
environmentId, namespace,
namespace, appKind,
appKind, name,
name, patch,
patch, 'application/strategic-merge-patch+json'
'application/strategic-merge-patch+json' );
); case 'StatefulSet':
case 'StatefulSet': return patchApplicationByKind<StatefulSet>(
return await patchApplicationByKind<StatefulSet>( environmentId,
environmentId, namespace,
namespace, appKind,
appKind, name,
name, patch,
patch, 'application/strategic-merge-patch+json'
'application/strategic-merge-patch+json' );
); case 'Pod':
case 'Pod': return patchPod(environmentId, namespace, name, patch);
return await patchPod(environmentId, namespace, name, patch); default:
default: throw new Error(`Unknown application kind ${appKind}`);
throw new Error(`Unknown application kind ${appKind}`);
}
} catch (e) {
throw parseAxiosError(
e as Error,
`Unable to patch application ${name} in namespace '${namespace}'`
);
} }
} }
@ -218,7 +188,7 @@ async function patchApplicationByKind<T extends Application>(
) { ) {
try { try {
const res = await axios.patch<T>( const res = await axios.patch<T>(
buildUrl(environmentId, namespace, `${appKind}s`, name), buildUrl(environmentId, namespace, `${appKind}s`, `${name}sd`),
patch, patch,
{ {
headers: { headers: {
@ -228,7 +198,7 @@ async function patchApplicationByKind<T extends Application>(
); );
return res; return res;
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, 'Unable to patch application'); throw parseKubernetesAxiosError(e, 'Unable to patch application');
} }
} }
@ -250,7 +220,7 @@ async function getApplicationByKind<
); );
return data; return data;
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, 'Unable to retrieve application'); throw parseKubernetesAxiosError(e, 'Unable to retrieve application');
} }
} }
@ -265,7 +235,10 @@ async function getApplicationsByKind<T extends ApplicationList>(
); );
return data.items as T['items']; return data.items as T['items'];
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, `Unable to retrieve ${appKind}s`); throw parseKubernetesAxiosError(
e,
`Unable to retrieve ${appKind}s in namespace '${namespace}'`
);
} }
} }
@ -350,7 +323,7 @@ export async function getReplicaSetList(
); );
return data; return data;
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, 'Unable to retrieve ReplicaSets'); throw parseKubernetesAxiosError(e, 'Unable to retrieve ReplicaSets');
} }
} }
@ -370,7 +343,10 @@ export async function getControllerRevisionList(
); );
return data; return data;
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, 'Unable to retrieve ControllerRevisions'); throw parseKubernetesAxiosError(
e,
'Unable to retrieve ControllerRevisions'
);
} }
} }

View file

@ -55,7 +55,7 @@ export async function getNamespaceHorizontalPodAutoscalers(
return autoScalarList.items; return autoScalarList.items;
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError( throw parseKubernetesAxiosError(
e as Error, e,
'Unable to retrieve horizontal pod autoscalers' 'Unable to retrieve horizontal pod autoscalers'
); );
} }
@ -81,7 +81,7 @@ export async function getNamespaceHorizontalPodAutoscaler<
return autoScalar; return autoScalar;
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError( throw parseKubernetesAxiosError(
e as Error, e,
'Unable to retrieve horizontal pod autoscaler' 'Unable to retrieve horizontal pod autoscaler'
); );
} }

View file

@ -3,6 +3,8 @@ import { Pod, PodList } from 'kubernetes-types/core/v1';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
import axios, { parseAxiosError } from '@/portainer/services/axios'; import axios, { parseAxiosError } from '@/portainer/services/axios';
import { parseKubernetesAxiosError } from '../axiosError';
import { ApplicationPatch } from './types'; import { ApplicationPatch } from './types';
export async function getNamespacePods( export async function getNamespacePods(
@ -21,7 +23,10 @@ export async function getNamespacePods(
); );
return data.items; return data.items;
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, 'Unable to retrieve pods'); throw parseKubernetesAxiosError(
e,
`Unable to retrieve pods in namespace '${namespace}'`
);
} }
} }
@ -40,7 +45,7 @@ export async function getPod<T extends Pod | string = Pod>(
); );
return data; return data;
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, 'Unable to retrieve pod'); throw parseKubernetesAxiosError(e, 'Unable to retrieve pod');
} }
} }
@ -61,7 +66,7 @@ export async function patchPod(
} }
); );
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, 'Unable to update pod'); throw parseAxiosError(e, 'Unable to update pod');
} }
} }
@ -73,7 +78,7 @@ export async function deletePod(
try { try {
return await axios.delete<Pod>(buildUrl(environmentId, namespace, name)); return await axios.delete<Pod>(buildUrl(environmentId, namespace, name));
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, 'Unable to delete pod'); throw parseKubernetesAxiosError(e as Error, 'Unable to delete pod');
} }
} }

View file

@ -24,6 +24,6 @@ export function kubernetesErrorParser(axiosError: AxiosError) {
* @param msg An optional error message to prepend. * @param msg An optional error message to prepend.
* @returns An error object with an error message and details. * @returns An error object with an error message and details.
*/ */
export function parseKubernetesAxiosError(err: Error, msg = '') { export function parseKubernetesAxiosError(err: unknown, msg = '') {
return parseAxiosError(err, msg, kubernetesErrorParser); return parseAxiosError(err, msg, kubernetesErrorParser);
} }

View file

@ -8,8 +8,7 @@ import {
UpdateEnvironmentPayload, UpdateEnvironmentPayload,
updateEnvironment, updateEnvironment,
} from '@/react/portainer/environments/queries/useUpdateEnvironmentMutation'; } from '@/react/portainer/environments/queries/useUpdateEnvironmentMutation';
import axios from '@/portainer/services/axios'; import axios, { parseAxiosError } from '@/portainer/services/axios';
import { parseKubernetesAxiosError } from '@/react/kubernetes/axiosError';
import { updateIngressControllerClassMap } from '../../ingressClass/useIngressControllerClassMap'; import { updateIngressControllerClassMap } from '../../ingressClass/useIngressControllerClassMap';
import { IngressControllerClassMap } from '../../ingressClass/types'; import { IngressControllerClassMap } from '../../ingressClass/types';
@ -72,9 +71,6 @@ async function patchStorageClass(
} }
); );
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError( throw parseAxiosError(e, `Unable to patch StorageClass ${name}`);
e as Error,
`Unable to patch StorageClass ${name}`
);
} }
} }

View file

@ -65,10 +65,7 @@ async function getStorageClasses(
); );
return storageClassList.items; return storageClassList.items;
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError( throw parseKubernetesAxiosError(e, 'Unable to retrieve Storage Classes');
e as Error,
'Unable to retrieve Storage Classes'
);
} }
} }

View file

@ -5,6 +5,8 @@ import axios from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
import { withError } from '@/react-tools/react-query'; import { withError } from '@/react-tools/react-query';
import { parseKubernetesAxiosError } from '../../axiosError';
const queryKeys = { const queryKeys = {
node: (environmentId: number, nodeName: string) => [ node: (environmentId: number, nodeName: string) => [
'environments', 'environments',
@ -22,10 +24,14 @@ const queryKeys = {
}; };
async function getNode(environmentId: EnvironmentId, nodeName: string) { async function getNode(environmentId: EnvironmentId, nodeName: string) {
const { data: node } = await axios.get<Node>( try {
`/endpoints/${environmentId}/kubernetes/api/v1/nodes/${nodeName}` const { data: node } = await axios.get<Node>(
); `/endpoints/${environmentId}/kubernetes/api/v1/nodes/${nodeName}`
return node; );
return node;
} catch (e) {
throw parseKubernetesAxiosError(e, 'Unable to get node details');
}
} }
export function useNodeQuery(environmentId: EnvironmentId, nodeName: string) { export function useNodeQuery(environmentId: EnvironmentId, nodeName: string) {
@ -33,20 +39,21 @@ export function useNodeQuery(environmentId: EnvironmentId, nodeName: string) {
queryKeys.node(environmentId, nodeName), queryKeys.node(environmentId, nodeName),
() => getNode(environmentId, nodeName), () => getNode(environmentId, nodeName),
{ {
...withError( ...withError('Unable to get node details'),
'Unable to get node details from the Kubernetes api',
'Failed to get node details'
),
} }
); );
} }
// getNodes is used to get a list of nodes using the kubernetes API // getNodes is used to get a list of nodes using the kubernetes API
async function getNodes(environmentId: EnvironmentId) { async function getNodes(environmentId: EnvironmentId) {
const { data: nodeList } = await axios.get<NodeList>( try {
`/endpoints/${environmentId}/kubernetes/api/v1/nodes` const { data: nodeList } = await axios.get<NodeList>(
); `/endpoints/${environmentId}/kubernetes/api/v1/nodes`
return nodeList.items; );
return nodeList.items;
} catch (e) {
throw parseKubernetesAxiosError(e, 'Unable to get nodes');
}
} }
// useNodesQuery is used to get an array of nodes using the kubernetes API // useNodesQuery is used to get an array of nodes using the kubernetes API

View file

@ -1,7 +1,6 @@
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import PortainerError from '@/portainer/error'; import axios, { parseAxiosError } from '@/portainer/services/axios';
import axios from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
import { withError } from '@/react-tools/react-query'; import { withError } from '@/react-tools/react-query';
@ -23,6 +22,6 @@ export async function getIsRBACEnabled(environmentId: EnvironmentId) {
); );
return data; return data;
} catch (e) { } catch (e) {
throw new PortainerError('Unable to check if RBAC is enabled.', e as Error); throw parseAxiosError(e, 'Unable to check if RBAC is enabled.');
} }
} }

View file

@ -1,16 +1,18 @@
import { IngressClassList } from 'kubernetes-types/networking/v1'; import { IngressClassList } from 'kubernetes-types/networking/v1';
import axios, { parseAxiosError } from '@/portainer/services/axios'; import axios from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
import { parseKubernetesAxiosError } from '../../axiosError';
export async function getAllIngressClasses(environmentId: EnvironmentId) { export async function getAllIngressClasses(environmentId: EnvironmentId) {
try { try {
const { const {
data: { items }, data: { items },
} = await axios.get<IngressClassList>(urlBuilder(environmentId)); } = await axios.get<IngressClassList>(urlBuilder(environmentId));
return items; return items;
} catch (error) { } catch (e) {
throw parseAxiosError(error as Error); throw parseKubernetesAxiosError(e, 'Unable to retrieve ingress classes');
} }
} }

View file

@ -1,8 +1,7 @@
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
import PortainerError from '@/portainer/error'; import axios, { parseAxiosError } from '@/portainer/services/axios';
import axios from '@/portainer/services/axios';
import { withError } from '@/react-tools/react-query'; import { withError } from '@/react-tools/react-query';
import { IngressControllerClassMap } from './types'; import { IngressControllerClassMap } from './types';
@ -61,7 +60,7 @@ export async function getIngressControllerClassMap({
); );
return controllerMaps; return controllerMaps;
} catch (e) { } catch (e) {
throw new PortainerError('Unable to get ingress controllers.', e as Error); throw parseAxiosError(e, 'Unable to get ingress controllers.');
} }
} }
@ -77,10 +76,7 @@ export async function updateIngressControllerClassMap(
>(buildUrl(environmentId, namespace), ingressControllerClassMap); >(buildUrl(environmentId, namespace), ingressControllerClassMap);
return controllerMaps; return controllerMaps;
} catch (e) { } catch (e) {
throw new PortainerError( throw parseAxiosError(e, 'Unable to update ingress controllers.');
'Unable to update ingress controllers.',
e as Error
);
} }
} }

View file

@ -5,11 +5,17 @@ import axios from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
import { withError } from '@/react-tools/react-query'; import { withError } from '@/react-tools/react-query';
import { parseKubernetesAxiosError } from '../axiosError';
async function getKubernetesEndpoints(environmentId: EnvironmentId) { async function getKubernetesEndpoints(environmentId: EnvironmentId) {
const { data: endpointsList } = await axios.get<EndpointsList>( try {
`/endpoints/${environmentId}/kubernetes/api/v1/endpoints` const { data: endpointsList } = await axios.get<EndpointsList>(
); `/endpoints/${environmentId}/kubernetes/api/v1/endpoints`
return endpointsList.items; );
return endpointsList.items;
} catch (e) {
throw parseKubernetesAxiosError(e, 'Unable to retrieve endpoints');
}
} }
export function useKubernetesEndpointsQuery( export function useKubernetesEndpointsQuery(

View file

@ -10,6 +10,7 @@ import {
} from '@/portainer/services/notifications'; } from '@/portainer/services/notifications';
import { isFulfilled, isRejected } from '@/portainer/helpers/promise-utils'; import { isFulfilled, isRejected } from '@/portainer/helpers/promise-utils';
import { pluralize } from '@/portainer/helpers/strings'; import { pluralize } from '@/portainer/helpers/strings';
import PortainerError from '@/portainer/error';
import { parseKubernetesAxiosError } from '../axiosError'; import { parseKubernetesAxiosError } from '../axiosError';
@ -127,10 +128,7 @@ async function getConfigMapsForCluster(
); );
return configMaps.flat(); return configMaps.flat();
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError( throw new PortainerError('Unable to retrieve ConfigMaps', e);
e as Error,
'Unable to retrieve ConfigMaps for cluster'
);
} }
} }
@ -142,10 +140,7 @@ async function getConfigMaps(environmentId: EnvironmentId, namespace: string) {
); );
return data.items; return data.items;
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError( throw parseKubernetesAxiosError(e, 'Unable to retrieve ConfigMaps');
e as Error,
'Unable to retrieve ConfigMaps'
);
} }
} }
@ -157,7 +152,7 @@ async function deleteConfigMap(
try { try {
await axios.delete(buildUrl(environmentId, namespace, name)); await axios.delete(buildUrl(environmentId, namespace, name));
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError(e as Error, 'Unable to remove ConfigMap'); throw parseKubernetesAxiosError(e, 'Unable to remove ConfigMap');
} }
} }

View file

@ -10,6 +10,7 @@ import {
} from '@/portainer/services/notifications'; } from '@/portainer/services/notifications';
import { isFulfilled, isRejected } from '@/portainer/helpers/promise-utils'; import { isFulfilled, isRejected } from '@/portainer/helpers/promise-utils';
import { pluralize } from '@/portainer/helpers/strings'; import { pluralize } from '@/portainer/helpers/strings';
import PortainerError from '@/portainer/error';
import { parseKubernetesAxiosError } from '../axiosError'; import { parseKubernetesAxiosError } from '../axiosError';
@ -123,10 +124,7 @@ async function getSecretsForCluster(
); );
return secrets.flat(); return secrets.flat();
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError( throw new PortainerError('Unable to retrieve secrets for cluster', e);
e as Error,
'Unable to retrieve secrets for cluster'
);
} }
} }
@ -138,7 +136,7 @@ async function getSecrets(environmentId: EnvironmentId, namespace: string) {
); );
return data.items; return data.items;
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError(e as Error, 'Unable to retrieve secrets'); throw parseKubernetesAxiosError(e, 'Unable to retrieve secrets');
} }
} }
@ -150,7 +148,7 @@ async function deleteSecret(
try { try {
await axios.delete(buildUrl(environmentId, namespace, name)); await axios.delete(buildUrl(environmentId, namespace, name));
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError(e as Error, 'Unable to remove secret'); throw parseKubernetesAxiosError(e, 'Unable to remove secret');
} }
} }

View file

@ -1,6 +1,8 @@
import axios, { parseAxiosError } from '@/portainer/services/axios'; import axios from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
import { parseKubernetesAxiosError } from '../axiosError';
interface SelfSubjectAccessReviewResponse { interface SelfSubjectAccessReviewResponse {
status: { status: {
allowed: boolean; allowed: boolean;
@ -43,8 +45,8 @@ export async function getSelfSubjectAccessReview(
); );
return accessReview; return accessReview;
} catch (e) { } catch (e) {
throw parseAxiosError( throw parseKubernetesAxiosError(
e as Error, e,
'Unable to retrieve self subject access review' 'Unable to retrieve self subject access review'
); );
} }

View file

@ -100,7 +100,7 @@ export async function getServices(
); );
return services; return services;
} catch (e) { } catch (e) {
throw parseAxiosError(e as Error, 'Unable to retrieve services'); throw parseAxiosError(e, 'Unable to retrieve services');
} }
} }
@ -120,7 +120,7 @@ export async function getNamespaceServices(
); );
return services.items; return services.items;
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError(e as Error, 'Unable to retrieve services'); throw parseKubernetesAxiosError(e, 'Unable to retrieve services');
} }
} }
@ -141,7 +141,7 @@ async function getService<T extends Service | string = Service>(
); );
return service; return service;
} catch (e) { } catch (e) {
throw parseKubernetesAxiosError(e as Error, 'Unable to retrieve service'); throw parseKubernetesAxiosError(e, 'Unable to retrieve service');
} }
} }

View file

@ -1,23 +1,18 @@
import { PersistentVolumeClaimList } from 'kubernetes-types/core/v1'; import { PersistentVolumeClaimList } from 'kubernetes-types/core/v1';
import axios, { parseAxiosError } from '@/portainer/services/axios'; import axios from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
import { parseKubernetesAxiosError } from '../axiosError';
export async function getPVCsForCluster( export async function getPVCsForCluster(
environmentId: EnvironmentId, environmentId: EnvironmentId,
namespaces: string[] namespaces: string[]
) { ) {
try { const pvcs = await Promise.all(
const pvcs = await Promise.all( namespaces.map((namespace) => getPVCs(environmentId, namespace))
namespaces.map((namespace) => getPVCs(environmentId, namespace)) );
); return pvcs.flat();
return pvcs.flat();
} catch (e) {
throw parseAxiosError(
e as Error,
'Unable to retrieve persistent volume claims for cluster'
);
}
} }
// get all persistent volume claims for a namespace // get all persistent volume claims for a namespace
@ -28,8 +23,8 @@ export async function getPVCs(environmentId: EnvironmentId, namespace: string) {
); );
return data.items; return data.items;
} catch (e) { } catch (e) {
throw parseAxiosError( throw parseKubernetesAxiosError(
e as Error, e,
'Unable to retrieve persistent volume claims' 'Unable to retrieve persistent volume claims'
); );
} }