Fix permissions loading

Signed-off-by: Dominika Zemanovicova <dzemanov@redhat.com>
This commit is contained in:
Dominika Zemanovicova
2025-01-09 19:34:56 +01:00
parent 2f993dfc9c
commit 7d7497785f
6 changed files with 160 additions and 188 deletions
@@ -24,8 +24,8 @@ import {
useKubernetesClusterError,
} from '../KubernetesClusterErrorContext/KubernetesClusterErrorContext';
import { WarningPanel } from '@backstage/core-components';
import { useKubernetesClustersPermission } from '../../hooks/useKubernetesClustersPermission';
import { kubernetesClustersPermission } from '@backstage/plugin-kubernetes-common';
import { RequirePermission } from '@backstage/plugin-permission-react';
const ContentGrid = () => {
const { error } = useKubernetesClusterError();
@@ -59,17 +59,20 @@ const ContentGrid = () => {
* @public
*/
export const KubernetesClusterContent = () => {
const hasKubernetesClustersPermission = useKubernetesClustersPermission();
return !hasKubernetesClustersPermission ? (
<WarningPanel
title="Permission required"
message={`To view Kubernetes objects, contact your administrator to give you the
'${kubernetesClustersPermission.name}' permission.`}
/>
) : (
<KubernetesClusterErrorProvider>
<ContentGrid />
</KubernetesClusterErrorProvider>
return (
<RequirePermission
permission={kubernetesClustersPermission}
errorPage={
<WarningPanel
title="Permission required"
message={`To view Kubernetes objects, contact your administrator to give you the
'${kubernetesClustersPermission.name}' permission.`}
/>
}
>
<KubernetesClusterErrorProvider>
<ContentGrid />
</KubernetesClusterErrorProvider>
</RequirePermission>
);
};
@@ -1,26 +0,0 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { kubernetesClustersPermission } from '@backstage/plugin-kubernetes-common';
import { usePermission } from '@backstage/plugin-permission-react';
export const useKubernetesClustersPermission = () => {
const kubernetesClustersPermissionResult = usePermission({
permission: kubernetesClustersPermission,
});
return kubernetesClustersPermissionResult.allowed;
};
+81 -97
View File
@@ -28,18 +28,14 @@ import {
import {
DetectedError,
detectErrors,
kubernetesClustersPermission,
kubernetesResourcesPermission,
} from '@backstage/plugin-kubernetes-common';
import {
Content,
EmptyState,
Page,
Progress,
WarningPanel,
} from '@backstage/core-components';
import { useKubernetesClustersPermission } from './hooks/useKubernetesClustersPermission';
import { useKubernetesResourcesPermission } from './hooks/useKubernetesResourcesPermission';
import { RequireKubernetesPermissions } from './RequireKubernetesPermissions';
type KubernetesContentProps = {
entity: Entity;
@@ -51,27 +47,11 @@ export const KubernetesContent = ({
entity,
refreshIntervalMs,
}: KubernetesContentProps) => {
const hasKubernetesClustersPermission = useKubernetesClustersPermission();
const hasKubernetesResourcesPermission = useKubernetesResourcesPermission();
const { kubernetesObjects, error } = useKubernetesObjects(
entity,
refreshIntervalMs,
);
if (!hasKubernetesClustersPermission || !hasKubernetesResourcesPermission) {
return (
<Page themeId="tool">
<Content>
<WarningPanel
title="Permission required"
message={`To view Kubernetes objects, contact your administrator to give you the
'${kubernetesClustersPermission.name}' and '${kubernetesResourcesPermission.name}' permission.`}
/>
</Content>
</Page>
);
}
const clusters = kubernetesObjects?.items.map(item => item.cluster) ?? [];
const clustersWithErrors =
@@ -83,89 +63,93 @@ export const KubernetesContent = ({
: new Map<string, DetectedError[]>();
return (
<DetectedErrorsContext.Provider value={[...detectedErrors.values()].flat()}>
<Page themeId="tool">
<Content>
{kubernetesObjects === undefined && error === undefined && (
<Progress />
)}
<RequireKubernetesPermissions>
<DetectedErrorsContext.Provider
value={[...detectedErrors.values()].flat()}
>
<Page themeId="tool">
<Content>
{kubernetesObjects === undefined && error === undefined && (
<Progress />
)}
{/* errors retrieved from the kubernetes clusters */}
{clustersWithErrors.length > 0 && (
<Grid container spacing={3} direction="column">
<Grid item>
<ErrorPanel
entityName={entity.metadata.name}
clustersWithErrors={clustersWithErrors}
/>
{/* errors retrieved from the kubernetes clusters */}
{clustersWithErrors.length > 0 && (
<Grid container spacing={3} direction="column">
<Grid item>
<ErrorPanel
entityName={entity.metadata.name}
clustersWithErrors={clustersWithErrors}
/>
</Grid>
</Grid>
</Grid>
)}
)}
{/* other errors */}
{error !== undefined && (
<Grid container spacing={3} direction="column">
<Grid item>
<ErrorPanel
entityName={entity.metadata.name}
errorMessage={error}
/>
{/* other errors */}
{error !== undefined && (
<Grid container spacing={3} direction="column">
<Grid item>
<ErrorPanel
entityName={entity.metadata.name}
errorMessage={error}
/>
</Grid>
</Grid>
</Grid>
)}
)}
{kubernetesObjects && (
<Grid container spacing={3} direction="column">
<Grid item>
<ErrorReporting
detectedErrors={detectedErrors}
clusters={clusters}
/>
</Grid>
<Grid item>
<Typography variant="h3">Your Clusters</Typography>
</Grid>
<Grid item container>
{kubernetesObjects?.items.length <= 0 && (
<Grid
container
justifyContent="space-around"
direction="row"
alignItems="center"
spacing={2}
>
<Grid item xs={8}>
<EmptyState
missing="data"
title="No Kubernetes resources"
description={`No resources on any known clusters for ${entity.metadata.name}`}
/>
</Grid>
</Grid>
)}
{kubernetesObjects?.items.length > 0 &&
kubernetesObjects?.items.map((item, i) => {
const podsWithErrors = new Set<string>(
detectedErrors
.get(item.cluster.name)
?.filter(de => de.sourceRef.kind === 'Pod')
.map(de => de.sourceRef.name),
);
return (
<Grid item key={i} xs={12}>
<Cluster
clusterObjects={item}
podsWithErrors={podsWithErrors}
{kubernetesObjects && (
<Grid container spacing={3} direction="column">
<Grid item>
<ErrorReporting
detectedErrors={detectedErrors}
clusters={clusters}
/>
</Grid>
<Grid item>
<Typography variant="h3">Your Clusters</Typography>
</Grid>
<Grid item container>
{kubernetesObjects?.items.length <= 0 && (
<Grid
container
justifyContent="space-around"
direction="row"
alignItems="center"
spacing={2}
>
<Grid item xs={8}>
<EmptyState
missing="data"
title="No Kubernetes resources"
description={`No resources on any known clusters for ${entity.metadata.name}`}
/>
</Grid>
);
})}
</Grid>
)}
{kubernetesObjects?.items.length > 0 &&
kubernetesObjects?.items.map((item, i) => {
const podsWithErrors = new Set<string>(
detectedErrors
.get(item.cluster.name)
?.filter(de => de.sourceRef.kind === 'Pod')
.map(de => de.sourceRef.name),
);
return (
<Grid item key={i} xs={12}>
<Cluster
clusterObjects={item}
podsWithErrors={podsWithErrors}
/>
</Grid>
);
})}
</Grid>
</Grid>
</Grid>
)}
</Content>
</Page>
</DetectedErrorsContext.Provider>
)}
</Content>
</Page>
</DetectedErrorsContext.Provider>
</RequireKubernetesPermissions>
);
};
@@ -0,0 +1,63 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { ReactNode } from 'react';
import {
kubernetesClustersPermission,
kubernetesResourcesPermission,
} from '@backstage/plugin-kubernetes-common';
import { usePermission } from '@backstage/plugin-permission-react';
import { Content, Page, WarningPanel } from '@backstage/core-components';
export type RequireKubernetesPermissionProps = {
children: ReactNode;
};
export function RequireKubernetesPermissions(
props: RequireKubernetesPermissionProps,
): JSX.Element | null {
const kubernetesClustersPermissionResult = usePermission({
permission: kubernetesClustersPermission,
});
const kubernetesResourcesPermissionResult = usePermission({
permission: kubernetesResourcesPermission,
});
if (
kubernetesClustersPermissionResult.loading ||
kubernetesResourcesPermissionResult.loading
) {
return null;
}
if (
kubernetesClustersPermissionResult.allowed &&
kubernetesResourcesPermissionResult.allowed
) {
return <>{props.children}</>;
}
return (
<Page themeId="tool">
<Content>
<WarningPanel
title="Permission required"
message={`To view Kubernetes objects, contact your administrator to give you the
'${kubernetesClustersPermission.name}' and '${kubernetesResourcesPermission.name}' permission.`}
/>
</Content>
</Page>
);
}
@@ -1,26 +0,0 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { kubernetesClustersPermission } from '@backstage/plugin-kubernetes-common';
import { usePermission } from '@backstage/plugin-permission-react';
export const useKubernetesClustersPermission = () => {
const kubernetesClustersPermissionResult = usePermission({
permission: kubernetesClustersPermission,
});
return kubernetesClustersPermissionResult.allowed;
};
@@ -1,26 +0,0 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { kubernetesResourcesPermission } from '@backstage/plugin-kubernetes-common';
import { usePermission } from '@backstage/plugin-permission-react';
export const useKubernetesResourcesPermission = () => {
const kubernetesResourcesPermissionResult = usePermission({
permission: kubernetesResourcesPermission,
});
return kubernetesResourcesPermissionResult.allowed;
};