portainer/app/react/kubernetes/namespaces/queries.ts

60 lines
1.9 KiB
TypeScript
Raw Normal View History

import { useQuery } from 'react-query';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { error as notifyError } from '@/portainer/services/notifications';
import { withError } from '@/react-tools/react-query';
import {
getNamespaces,
getNamespace,
getSelfSubjectAccessReview,
} from './service';
import { Namespaces } from './types';
export function useNamespaces(
environmentId: EnvironmentId,
options?: { autoRefreshRate?: number }
) {
return useQuery(
['environments', environmentId, 'kubernetes', 'namespaces'],
async () => {
const namespaces = await getNamespaces(environmentId);
const namespaceNames = Object.keys(namespaces);
// use selfsubjectaccess reviews to avoid forbidden requests
const allNamespaceAccessReviews = await Promise.all(
namespaceNames.map((namespaceName) =>
getSelfSubjectAccessReview(environmentId, namespaceName)
)
);
const allowedNamespacesNames = allNamespaceAccessReviews
.filter((accessReview) => accessReview.status.allowed)
.map((accessReview) => accessReview.spec.resourceAttributes.namespace);
const allowedNamespaces = namespaceNames.reduce((acc, namespaceName) => {
if (allowedNamespacesNames.includes(namespaceName)) {
acc[namespaceName] = namespaces[namespaceName];
}
return acc;
}, {} as Namespaces);
return allowedNamespaces;
},
{
...withError('Unable to get namespaces.'),
refetchInterval() {
return options?.autoRefreshRate ?? false;
},
}
);
}
export function useNamespace(environmentId: EnvironmentId, namespace: string) {
return useQuery(
['environments', environmentId, 'kubernetes', 'namespaces', namespace],
() => getNamespace(environmentId, namespace),
{
onError: (err) => {
notifyError('Failure', err as Error, 'Unable to get namespace.');
},
}
);
}