Skip to content

Commit

Permalink
Topology, fetch build config data when necessary
Browse files Browse the repository at this point in the history
  • Loading branch information
jeff-phillips-18 committed Nov 9, 2020
1 parent eac92a3 commit fb36344
Show file tree
Hide file tree
Showing 30 changed files with 296 additions and 189 deletions.
Expand Up @@ -18,7 +18,6 @@ describe('usePluginsOverviewTabSection', () => {
item = {
revisions: sampleKnativeRevisions.data,
obj: knativeServiceObj,
buildConfigs: [],
} as OverviewItem;
});

Expand Down
1 change: 1 addition & 0 deletions frontend/packages/console-shared/src/hooks/index.ts
Expand Up @@ -6,6 +6,7 @@ export * from './scroll';
export * from './plugins-overview-tab-section';
export * from './debounce';
export * from './select-list';
export * from './useBuildConfigsWatcher';
export * from './usePodsWatcher';
export * from './useQueryParams';
export * from './version';
Expand Down
@@ -0,0 +1,53 @@
import * as React from 'react';
import { CronJobKind, K8sResourceKind } from '@console/internal/module/k8s';
import { useK8sWatchResources } from '@console/internal/components/utils/k8s-watch-hook';
import { getBuildConfigsForCronJob, getBuildConfigsForResource } from '../utils';
import { BuildConfigOverviewItem } from '../types';

export const useBuildConfigsWatcher = (
resource: K8sResourceKind,
): { loaded: boolean; loadError: string; buildConfigs: BuildConfigOverviewItem[] } => {
const [loaded, setLoaded] = React.useState<boolean>(false);
const [loadError, setLoadError] = React.useState<string>('');
const [buildConfigs, setBuildConfigs] = React.useState<BuildConfigOverviewItem[]>();
const { namespace } = resource.metadata;
const watchedResources = React.useMemo(
() => ({
buildConfigs: {
isList: true,
kind: 'BuildConfig',
namespace,
},
builds: {
isList: true,
kind: 'Build',
namespace,
},
}),
[namespace],
);

const resources = useK8sWatchResources(watchedResources);

React.useEffect(() => {
const errorKey = Object.keys(resources).find((key) => resources[key].loadError);
if (errorKey) {
setLoadError(resources[errorKey].loadError);
return;
}
setLoadError(null);
if (
Object.keys(resources).length > 0 &&
Object.keys(resources).every((key) => resources[key].loaded)
) {
const resourceBuildConfigs =
resource.kind === 'CronJob'
? getBuildConfigsForCronJob(resource as CronJobKind, resources)
: getBuildConfigsForResource(resource, resources);
setBuildConfigs(resourceBuildConfigs);
setLoaded(true);
}
}, [resource, resources]);

return { loaded, loadError, buildConfigs };
};
4 changes: 1 addition & 3 deletions frontend/packages/console-shared/src/types/resource.ts
Expand Up @@ -6,7 +6,7 @@ import {
RouteKind,
} from '@console/internal/module/k8s';
import { DEPLOYMENT_STRATEGY } from '../constants';
import { OverviewItemAlerts, PodControllerOverviewItem } from './pod';
import { PodControllerOverviewItem } from './pod';
import { ClusterServiceVersionKind } from '@console/operator-lifecycle-manager';
import { Alert } from '@console/internal/components/monitoring/types';

Expand All @@ -26,8 +26,6 @@ export type BuildConfigOverviewItem = K8sResourceKind & {
};

export type OverviewItem<T = K8sResourceKind> = {
alerts?: OverviewItemAlerts;
buildConfigs: BuildConfigOverviewItem[];
current?: PodControllerOverviewItem;
isRollingOut?: boolean;
obj: T;
Expand Down
Expand Up @@ -69,8 +69,6 @@ expect.extend({
});

enum Keys {
ALERTS = 'alerts',
BC = 'buildConfigs',
CURRENT = 'current',
ROLLINGOUT = 'isRollingOut',
OBJ = 'obj',
Expand All @@ -85,8 +83,8 @@ enum Keys {
KSROUTES = 'ksroutes',
}

const podKeys = [Keys.ALERTS, Keys.OBJ, Keys.ROUTES, Keys.SERVICE, Keys.STATUS];
const dsAndSSKeys = [...podKeys, Keys.BC, Keys.PODS];
const podKeys = [Keys.OBJ, Keys.ROUTES, Keys.SERVICE, Keys.STATUS];
const dsAndSSKeys = [...podKeys, Keys.PODS];
const dcKeys = [...dsAndSSKeys, Keys.CURRENT, Keys.ROLLINGOUT, Keys.PREVIOUS];
const knativeKeys = [...dcKeys, Keys.REVISIONS, Keys.KNATIVECONFIGS, Keys.KSROUTES];

Expand Down Expand Up @@ -164,7 +162,6 @@ describe('TransformResourceData', () => {
expect(transformedData[0][Keys.CURRENT]).toBeUndefined();
expect(transformedData[0][Keys.PREVIOUS]).toBeUndefined();
expect(transformedData[0][Keys.ROLLINGOUT]).toBeUndefined();
expect(transformedData[0][Keys.BC]).toHaveLength(0);
});

it('should create DaemonSets Items for a provided ds', () => {
Expand All @@ -189,7 +186,6 @@ describe('TransformResourceData', () => {
expect(transformedData[0][Keys.CURRENT]).toBeUndefined();
expect(transformedData[0][Keys.PREVIOUS]).toBeUndefined();
expect(transformedData[0][Keys.ROLLINGOUT]).toBeUndefined();
expect(transformedData[0][Keys.BC]).toHaveLength(0);
});

it('should return only pods and not replication controllers for a given resource', () => {
Expand All @@ -212,7 +208,6 @@ describe('TransformResourceData', () => {
expect(transformedData[0][Keys.CURRENT]).toBeUndefined();
expect(transformedData[0][Keys.PREVIOUS]).toBeUndefined();
expect(transformedData[0][Keys.ROLLINGOUT]).toBeUndefined();
expect(transformedData[0][Keys.BC]).toHaveLength(0);
});

it('should create CronJob Items', () => {
Expand All @@ -221,7 +216,6 @@ describe('TransformResourceData', () => {
expect(transformedData[0][Keys.CURRENT]).toBeUndefined();
expect(transformedData[0][Keys.PREVIOUS]).toBeUndefined();
expect(transformedData[0][Keys.ROLLINGOUT]).toBeUndefined();
expect(transformedData[0][Keys.BC]).toHaveLength(1);
expect(transformedData[0][Keys.JOBS]).toHaveLength(2);
expect(transformedData[0][Keys.PODS]).toHaveLength(2);
});
Expand Down
107 changes: 10 additions & 97 deletions frontend/packages/console-shared/src/utils/resource-utils.ts
Expand Up @@ -55,57 +55,6 @@ type ResourceItem = {

export type ResourceUtil = (obj: K8sResourceKind, props: any) => ResourceItem | undefined;

export const getResourcePausedAlert = (resource: K8sResourceKind): OverviewItemAlerts => {
if (!resource.spec.paused) {
return {};
}
return {
[`${resource.metadata.uid}--Paused`]: {
severity: 'info',
message: `${resource.metadata.name} is paused.`,
},
};
};

export const getBuildAlerts = (buildConfigs: BuildConfigOverviewItem[]): OverviewItemAlerts => {
const buildAlerts = {};
const addAlert = (build: K8sResourceKind, buildPhase: string) =>
_.set(buildAlerts, `${build.metadata.uid}--build${buildPhase}`, {
severity: `build${buildPhase}`,
message: _.get(build, ['status', 'message'], buildPhase),
});

_.each(buildConfigs, (bc) => {
let seenComplete = false;
// Requires builds to be sorted by most recent first.
_.each(bc.builds, (build: K8sResourceKind) => {
const buildPhase = _.get(build, ['status', 'phase']);
switch (buildPhase) {
case 'Complete':
seenComplete = true;
break;
case 'Failed':
case 'Error':
if (!seenComplete) {
// show failure/error
addAlert(build, buildPhase);
}
break;
case 'New':
case 'Pending':
case 'Running':
// show new/pending/running
addAlert(build, buildPhase);
break;
default:
break;
}
});
});

return buildAlerts;
};

export const getOwnedResources = <T extends K8sResourceKind>(
obj: K8sResourceKind,
resources: T[],
Expand Down Expand Up @@ -678,25 +627,15 @@ export const getOverviewItemsForResource = (
current?: PodControllerOverviewItem,
previous?: PodControllerOverviewItem,
isRollingOut?: boolean,
customPods?: PodKind[],
additionalAlerts?: OverviewItemAlerts,
customBuildConfigs?: BuildConfigOverviewItem[],
) => {
const monitoringAlerts = isMonitorable
? getWorkloadMonitoringAlerts(obj, resources?.monitoringAlerts)
: undefined;
const buildConfigs = customBuildConfigs || getBuildConfigsForResource(obj, resources);
const services = getServicesForResource(obj, resources);
const routes = getRoutesForServices(services, resources);
const pods = customPods ?? getPodsForResource(obj, resources);
const alerts = {
...(additionalAlerts ?? combinePodAlerts(pods)),
...getBuildAlerts(buildConfigs),
};
const pods = getPodsForResource(obj, resources);
const status = resourceStatus(obj, current, isRollingOut);
const overviewItems = {
alerts,
buildConfigs,
const overviewItem: OverviewItem = {
obj,
pods,
routes,
Expand All @@ -712,41 +651,32 @@ export const getOverviewItemsForResource = (
if (utils) {
return utils.reduce((acc, util) => {
return { ...acc, ...util(obj, resources) };
}, overviewItems);
}, overviewItem);
}
return overviewItems;
return overviewItem;
};

export const createDeploymentConfigItem = (
deploymentConfig: K8sResourceKind,
resources: any,
utils?: ResourceUtil[],
): OverviewItem => {
const { mostRecentRC, visibleReplicationControllers } = getReplicationControllersForResource(
const { visibleReplicationControllers } = getReplicationControllersForResource(
deploymentConfig,
resources,
);
const [current, previous] = visibleReplicationControllers;
const isRollingOut = getRolloutStatus(deploymentConfig, current, previous);
const buildConfigs = getBuildConfigsForResource(deploymentConfig, resources);
const services = getServicesForResource(deploymentConfig, resources);
const routes = getRoutesForServices(services, resources);
const rolloutAlerts = mostRecentRC ? getReplicationControllerAlerts(mostRecentRC) : {};
const alerts = {
...getResourcePausedAlert(deploymentConfig),
...getBuildAlerts(buildConfigs),
...rolloutAlerts,
};
const status = resourceStatus(deploymentConfig, current, isRollingOut);
const pods = [..._.get(current, 'pods', []), ..._.get(previous, 'pods', [])];
const monitoringAlerts = getWorkloadMonitoringAlerts(
deploymentConfig,
resources?.monitoringAlerts,
);
const hpas = resources?.hpas?.data?.filter(doesHpaMatch(deploymentConfig));
const overviewItems = {
alerts,
buildConfigs,
const overviewItem: OverviewItem = {
current,
hpas,
isRollingOut,
Expand All @@ -763,9 +693,9 @@ export const createDeploymentConfigItem = (
if (utils) {
return utils.reduce((acc, util) => {
return { ...acc, ...util(deploymentConfig, resources) };
}, overviewItems);
}, overviewItem);
}
return overviewItems;
return overviewItem;
};

export const createDeploymentConfigItems = (
Expand All @@ -787,21 +717,14 @@ export const createDeploymentItem = (
const replicaSets = getReplicaSetsForResource(deployment, resources);
const [current, previous] = replicaSets;
const isRollingOut = !!current && !!previous;
const buildConfigs = getBuildConfigsForResource(deployment, resources);
const services = getServicesForResource(deployment, resources);
const routes = getRoutesForServices(services, resources);
const alerts = {
...getResourcePausedAlert(deployment),
...getBuildAlerts(buildConfigs),
};
const status = resourceStatus(deployment, current, isRollingOut);
const pods = [..._.get(current, 'pods', []), ..._.get(previous, 'pods', [])];
const monitoringAlerts = getWorkloadMonitoringAlerts(deployment, resources?.monitoringAlerts);
const hpas = resources?.hpas?.data?.filter(doesHpaMatch(deployment));
const overviewItem = {
const overviewItem: OverviewItem = {
obj: deployment,
alerts,
buildConfigs,
current,
hpas,
isRollingOut,
Expand Down Expand Up @@ -837,25 +760,18 @@ export const createCronJobItem = (
resources: any,
utils?: ResourceUtil[],
): OverviewItem => {
const buildConfigs = getBuildConfigsForCronJob(cronJob, resources);
const jobs = getJobsForCronJob(cronJob, resources);
const pods = jobs?.reduce((acc, job) => {
acc.push(...getPodsForResource(job, resources));
return acc;
}, []);
const alerts = {
...combinePodAlerts(pods),
...getBuildAlerts(buildConfigs),
};
const status = resourceStatus(cronJob);
const isMonitorable = isKindMonitorable(CronJobModel);
const monitoringAlerts = isMonitorable
? getWorkloadMonitoringAlerts(cronJob, resources?.monitoringAlerts)
: undefined;
const overviewItem = {
alerts,
const overviewItem: OverviewItem = {
obj: cronJob,
buildConfigs,
pods,
jobs,
status,
Expand Down Expand Up @@ -909,7 +825,6 @@ export const createPodItem = (pod: PodKind, resources: any): OverviewItem => {
if (!_.isEmpty(owners) || phase === 'Succeeded' || phase === 'Failed') {
return null;
}
const alerts = getPodAlerts(pod);
const services = getServicesForResource(pod, resources);
const routes = getRoutesForServices(services, resources);
const status = podStatus(pod as PodKind);
Expand All @@ -919,9 +834,7 @@ export const createPodItem = (pod: PodKind, resources: any): OverviewItem => {
: undefined;

return {
alerts,
obj: pod,
buildConfigs: null,
routes,
services,
status,
Expand Down
Expand Up @@ -23,7 +23,6 @@ describe('Monitoring Tab', () => {
},
},
},
buildConfigs: [],
routes: [],
services: [],
},
Expand Down
Expand Up @@ -10,7 +10,6 @@ describe('Pipeline sidebar overview', () => {
beforeEach(() => {
props = {
item: {
buildConfigs: [],
obj: {},
routes: [],
services: [],
Expand Down
Expand Up @@ -19,7 +19,7 @@ import { Decorator } from './Decorator';
import PodSet, { podSetInnerRadius } from './PodSet';
import BuildDecorator from './build-decorators/BuildDecorator';
import { BaseNode } from './BaseNode';
import { getCheURL, getEditURL } from '../../topology-utils';
import { getCheURL, getEditURL, getTopologyResourceObject } from '../../topology-utils';
import { useDisplayFilters, getFilterById, SHOW_POD_COUNT_FILTER_ID } from '../../filters';
import MonitoringAlertsDecorator from './MonitoringAlertsDecorator';
import './WorkloadNode.scss';
Expand Down Expand Up @@ -55,6 +55,7 @@ const ObservedWorkloadNode: React.FC<WorkloadNodeProps> = ({
const cheURL = getCheURL(consoleLinks);
const { width, height } = element.getDimensions();
const workloadData = element.getData().data;
const resourceObj = getTopologyResourceObject(element.getData());
const filters = useDisplayFilters();
const size = Math.min(width, height);
const { donutStatus, editURL, vcsURI, vcsRef } = workloadData;
Expand Down Expand Up @@ -119,6 +120,7 @@ const ObservedWorkloadNode: React.FC<WorkloadNodeProps> = ({
</Tooltip>
),
<BuildDecorator
resource={resourceObj}
key="build"
workloadData={workloadData}
x={cx - radius + decoratorRadius * 0.7}
Expand Down

0 comments on commit fb36344

Please sign in to comment.