Skip to content

flux: Fix overview page fetching resource classes #223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 18 additions & 11 deletions flux/src/helpers/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import {
SectionBox,
ShowHideLabel,
} from '@kinvolk/headlamp-plugin/lib/components/common';
import K8s from '@kinvolk/headlamp-plugin/lib/k8s';
import Event from '@kinvolk/headlamp-plugin/lib/K8s/event';
import { KubeObject, KubeObjectClass } from '@kinvolk/headlamp-plugin/lib/lib/k8s/cluster';
import { localeDate, timeAgo } from '@kinvolk/headlamp-plugin/lib/Utils';
import React from 'react';
import React, { useEffect } from 'react';
import Table from '../common/Table';
import { PluralName } from './pluralName';

Expand Down Expand Up @@ -196,29 +197,35 @@ export function NameLink(resourceClass: KubeObjectClass) {
),
};
}
export function useFluxCheck(sourceCRDs) {
export function useFluxCheck() {
const [crds] = K8s.ResourceClasses.CustomResourceDefinition.useList();
const [fluxCRDs, setFluxCrds] = React.useState([]);
useEffect(() => {
if (!crds) return;
setFluxCrds(crds?.filter(crd => crd.metadata.name.includes('fluxcd.')));
}, [crds]);
const [gitRepoCRD, allCrdsSuccessful] = React.useMemo(() => {
const gitRepoCRD = sourceCRDs.find(
crd => crd?.metadata?.name === 'gitrepositories.source.toolkit.fluxcd.io'
const gitRepoCRD = fluxCRDs.find(
crd => crd?.jsonData?.metadata?.name === 'gitrepositories.source.toolkit.fluxcd.io'
);
const allCrdsSuccessful = sourceCRDs.every(crd => {
const allCrdsSuccessful = fluxCRDs.every(crd => {
if (!crd) return true;
const conditions = crd.status?.conditions || [];
const conditions = crd?.jsonData.status?.conditions || [];
// Check if any condition has status "True"
const isSuccess = conditions.some(cond => cond.status === 'True');
return isSuccess;
});

return [gitRepoCRD, allCrdsSuccessful];
}, sourceCRDs);
}, [fluxCRDs]);

const fluxCheck = React.useMemo(() => {
const partOfLabel = 'app.kubernetes.io/part-of';
const kustomizeLabel = 'kustomize.toolkit.fluxcd.io';
const version = gitRepoCRD?.metadata.labels?.['app.kubernetes.io/version'] ?? '';
const name = gitRepoCRD?.metadata.labels?.[kustomizeLabel + '/name'] ?? '';
const namespace = gitRepoCRD?.metadata.labels?.[kustomizeLabel + '/namespace'] ?? '';
const partOf = gitRepoCRD?.metadata.labels?.[partOfLabel] ?? '';
const version = gitRepoCRD?.jsonData?.metadata.labels?.['app.kubernetes.io/version'] ?? '';
const name = gitRepoCRD?.jsonData?.metadata.labels?.[kustomizeLabel + '/name'] ?? '';
const namespace = gitRepoCRD?.jsonData?.metadata.labels?.[kustomizeLabel + '/namespace'] ?? '';
const partOf = gitRepoCRD?.jsonData?.metadata.labels?.[partOfLabel] ?? '';

return {
version,
Expand Down
164 changes: 44 additions & 120 deletions flux/src/overview/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Icon } from '@iconify/react';
import { K8s } from '@kinvolk/headlamp-plugin/lib';
import { apiFactory } from '@kinvolk/headlamp-plugin/lib/ApiProxy';
import {
Link,
NameValueTable,
Expand All @@ -14,81 +13,42 @@ import { useTheme } from '@mui/material/styles';
import React, { useEffect } from 'react';
import SourceLink from '../common/Link';
import Table from '../common/Table';
import { helmReleaseClass } from '../helm-releases/HelmReleaseList';
import { useFluxCheck } from '../helpers';
import { IMAGE_AUTOMATION_BETA_VERSION } from '../image-automation/ImageAutomationList';
import {
imagePolicyClass,
imageRepositoriesClass,
imageUpdateAutomationClass,
} from '../image-automation/ImageAutomationList';
import { kustomizationClass } from '../kustomizations/KustomizationList';
import { providerNotificationClass } from '../notifications/NotificationList';
import { alertNotificationClass } from '../notifications/NotificationList';
import { receiverNotificationClass } from '../notifications/NotificationList';
import {
bucketRepositoryClass,
gitRepositoryClass,
helmChartClass,
helmRepositoryClass,
ociRepositoryClass,
} from '../sources/SourceList';

export function FluxOverview() {
const [kustomizations] = K8s.ResourceClasses.CustomResourceDefinition.useGet(
'kustomizations.kustomize.toolkit.fluxcd.io'
);
const [helmReleases] = K8s.ResourceClasses.CustomResourceDefinition.useGet(
'helmreleases.helm.toolkit.fluxcd.io'
);
const [gitRepoCRD] = K8s.ResourceClasses.CustomResourceDefinition.useGet(
'gitrepositories.source.toolkit.fluxcd.io'
);
const [ociRepos] = K8s.ResourceClasses.CustomResourceDefinition.useGet(
'ocirepositories.source.toolkit.fluxcd.io'
);
const [bucketRepos] = K8s.ResourceClasses.CustomResourceDefinition.useGet(
'buckets.source.toolkit.fluxcd.io'
);
const [helmRepos] = K8s.ResourceClasses.CustomResourceDefinition.useGet(
'helmrepositories.source.toolkit.fluxcd.io'
);
const [helmCharts] = K8s.ResourceClasses.CustomResourceDefinition.useGet(
'helmcharts.source.toolkit.fluxcd.io'
);

const [alerts] = K8s.ResourceClasses.CustomResourceDefinition.useGet(
'alerts.notification.toolkit.fluxcd.io'
);
const [providers] = K8s.ResourceClasses.CustomResourceDefinition.useGet(
'providers.notification.toolkit.fluxcd.io'
);
const [receivers] = K8s.ResourceClasses.CustomResourceDefinition.useGet(
'receivers.notification.toolkit.fluxcd.io'
);

const CRD = React.useMemo(() => {
const CRD = K8s.ResourceClasses.CustomResourceDefinition;
const isVersionAvailable = CRD.apiEndpoint.apiInfo.find(
apiInfo => apiInfo.version === IMAGE_AUTOMATION_BETA_VERSION
);
if (!isVersionAvailable) {
CRD.apiEndpoint = apiFactory(
...CRD.apiEndpoint.apiInfo.map(apiInfo => {
const params = [];
params.push(apiInfo.group);
params.push(apiInfo.version);
params.push(apiInfo.resource);
return params;
}),
['apiextensions.k8s.io', IMAGE_AUTOMATION_BETA_VERSION, 'customresourcedefinitions']
);
}

return CRD;
}, []);

const [imageRepository] = CRD.useGet('imagerepositories.image.toolkit.fluxcd.io');
const [imageUpdateAutomation] = CRD.useGet('imageupdateautomations.image.toolkit.fluxcd.io');
const [imagePolicy] = CRD.useGet('imagepolicies.image.toolkit.fluxcd.io');

const fluxCheck = useFluxCheck([
gitRepoCRD,
ociRepos,
bucketRepos,
helmRepos,
helmCharts,
kustomizations,
alerts,
providers,
receivers,
imageRepository,
imageUpdateAutomation,
imagePolicy,
]);
const kustomizationResourceClass = kustomizationClass();
const helmReleaseResourceClass = helmReleaseClass();
const gitRepoResourceClass = gitRepositoryClass();
const ociRepoResourceClass = ociRepositoryClass();
const bucketRepoResourceClass = bucketRepositoryClass();
const helmRepoResourceClass = helmRepositoryClass();
const helmChartResourceClass = helmChartClass();
const alertsResourceClass = alertNotificationClass();
const providersResourceClass = providerNotificationClass();
const receiversResourceClass = receiverNotificationClass();

const imageUpdateAutomationResourceClass = imageUpdateAutomationClass();
const imagePolicyResourceClass = imagePolicyClass();
const imageRepositoryResourceClass = imageRepositoriesClass();

const fluxCheck = useFluxCheck();

const [pods] = K8s.ResourceClasses.Pod.useList({
namespace: fluxCheck.namespace,
Expand Down Expand Up @@ -121,46 +81,6 @@ export function FluxOverview() {
);
}, [pods]);

const kustomizationResourceClass = React.useMemo(() => {
return kustomizations?.makeCRClass();
}, [kustomizations]);

const helmReleaseResourceClass = React.useMemo(() => {
return helmReleases?.makeCRClass();
}, [helmReleases]);

const gitRepoResourceClass = React.useMemo(() => {
return gitRepoCRD?.makeCRClass();
}, [gitRepoCRD]);

const ociRepoResourceClass = React.useMemo(() => {
return ociRepos?.makeCRClass();
}, [ociRepos]);

const bucketRepoResourceClass = React.useMemo(() => {
return bucketRepos?.makeCRClass();
}, [bucketRepos]);

const helmRepoResourceClass = React.useMemo(() => {
return helmRepos?.makeCRClass();
}, [helmRepos]);

const helmChartResourceClass = React.useMemo(() => {
return helmCharts?.makeCRClass();
}, [helmCharts]);

const imageRepositoryClass = React.useMemo(() => {
return imageRepository?.makeCRClass();
}, [imageRepository]);

const imageUpdateAutomationClass = React.useMemo(() => {
return imageUpdateAutomation?.makeCRClass();
}, [imageUpdateAutomation]);

const imagePolicyClass = React.useMemo(() => {
return imagePolicy?.makeCRClass();
}, [imagePolicy]);

return (
<>
<SectionBox title="Flux Overview">
Expand Down Expand Up @@ -199,23 +119,27 @@ export function FluxOverview() {
{helmChartResourceClass && <FluxOverviewChart resourceClass={helmChartResourceClass} />}
</Box>
<Box width="300px" m={2}>
{alerts && <FluxOverviewChart resourceClass={alerts.makeCRClass()} />}
{alertsResourceClass && <FluxOverviewChart resourceClass={alertsResourceClass} />}
</Box>
<Box width="300px" m={2}>
{providers && <FluxOverviewChart resourceClass={providers.makeCRClass()} />}
{providersResourceClass && <FluxOverviewChart resourceClass={providersResourceClass} />}
</Box>
<Box width="300px" m={2}>
{receivers && <FluxOverviewChart resourceClass={receivers.makeCRClass()} />}
{receiversResourceClass && <FluxOverviewChart resourceClass={receiversResourceClass} />}
</Box>
<Box width="300px" m={2}>
{imageRepositoryClass && <FluxOverviewChart resourceClass={imageRepositoryClass} />}
{imageRepositoryResourceClass && (
<FluxOverviewChart resourceClass={imageRepositoryResourceClass} />
)}
</Box>
<Box width="300px" m={2}>
{imagePolicyClass && <FluxOverviewChart resourceClass={imagePolicyClass} />}
{imagePolicyResourceClass && (
<FluxOverviewChart resourceClass={imagePolicyResourceClass} />
)}
</Box>
<Box width="300px" m={2}>
{imageUpdateAutomationClass && (
<FluxOverviewChart resourceClass={imageUpdateAutomationClass} />
{imageUpdateAutomationResourceClass && (
<FluxOverviewChart resourceClass={imageUpdateAutomationResourceClass} />
)}
</Box>
</Box>
Expand Down