Skip to content
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

Improve Fleet performance #12896

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
43 changes: 13 additions & 30 deletions shell/components/fleet/FleetRepos.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@ import FleetIntro from '@shell/components/fleet/FleetIntro';

import {
AGE,
STATE,
NAME,
FLEET_SUMMARY,
FLEET_REPO,
FLEET_REPO_TARGET,
FLEET_REPO_CLUSTERS_READY,
FLEET_REPO_CLUSTER_SUMMARY,
FLEET_REPO_PER_CLUSTER_STATE

FLEET_REPO_CLUSTERS_READY,
FLEET_REPO_PER_CLUSTER_STATE,
FLEET_REPO_TARGET,
FLEET_SUMMARY,
NAME,
STATE,
} from '@shell/config/table-headers';
import { STATES_ENUM } from '@shell/plugins/dashboard-store/resource-class';

// i18n-ignore repoDisplay
export default {
Expand Down Expand Up @@ -77,40 +75,25 @@ export default {

headers() {
// Cluster summary is only shown in the cluster view
const fleetClusterSummary = {
const summary = this.isClusterView ? [{
...FLEET_REPO_CLUSTER_SUMMARY,
formatterOpts: {
// Fleet uses labels to identify clusters
clusterLabel: this.clusterId
},
};
formatterOpts: { clusterId: this.clusterId },
}] : [FLEET_REPO_CLUSTERS_READY, FLEET_SUMMARY];

// if hasPerClusterState then use the repo state
const fleetPerClusterState = {
const state = this.isClusterView ? {
...FLEET_REPO_PER_CLUSTER_STATE,
value: (row) => {
const statePerCluster = row.clusterResourceStatus?.find((c) => {
return c.clusterLabel === this.clusterId;
});

return statePerCluster ? statePerCluster?.status?.displayStatus : STATES_ENUM.ACTIVE;
},
};
value: (repo) => repo.clusterState(this.clusterId),
} : STATE;

const summary = this.isClusterView ? [fleetClusterSummary] : [FLEET_REPO_CLUSTERS_READY, FLEET_SUMMARY];

const state = this.isClusterView ? fleetPerClusterState : STATE;

const out = [
return [
state,
NAME,
FLEET_REPO,
FLEET_REPO_TARGET,
...summary,
AGE
];

return out;
},
},
methods: {
Expand Down
4 changes: 2 additions & 2 deletions shell/components/formatter/FleetClusterSummaryGraph.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default {
required: true
},

clusterLabel: {
clusterId: {
type: String,
required: true
}
Expand All @@ -22,6 +22,6 @@ export default {
<template>
<FleetSummaryGraph
:row="row"
:clusterLabel="clusterLabel"
:clusterId="clusterId"
/>
</template>
13 changes: 6 additions & 7 deletions shell/components/formatter/FleetSummaryGraph.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default {
required: true
},

clusterLabel: {
clusterId: {
type: String,
required: false,
default: null,
Expand All @@ -23,10 +23,8 @@ export default {

computed: {
summary() {
if (this.clusterLabel) {
return this.row.clusterResourceStatus.find((x) => {
return x.clusterLabel === this.clusterLabel;
})?.status.resourceCounts || {};
if (this.clusterId) {
return this.row.statusResourceCountsForCluster(this.clusterId);
}

return this.row.status?.resourceCounts || {};
Expand All @@ -37,7 +35,8 @@ export default {
},

stateParts() {
const keys = Object.keys(this.summary).filter((x) => !x.startsWith('desired'));
const summary = this.summary;
const keys = Object.keys(summary).filter((x) => !x.startsWith('desired'));

const out = keys.map((key) => {
const textColor = colorForState(key);
Expand All @@ -46,7 +45,7 @@ export default {
label: ucFirst(key),
color: textColor.replace(/text-/, 'bg-'),
textColor,
value: this.summary[key],
value: summary[key],
sort: stateSort(textColor, key),
};
}).filter((x) => x.value > 0);
Expand Down
6 changes: 3 additions & 3 deletions shell/detail/fleet.cattle.io.cluster.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ export default {
},

async fetch() {
const clusterId = this.value?.metadata?.labels[FLEET_LABELS.CLUSTER_NAME];
const managementClusterId = this.value?.metadata?.labels[FLEET_LABELS.CLUSTER_NAME];
const hash = await allHash({
rancherCluster: this.$store.dispatch('management/find', {
type: MANAGEMENT.CLUSTER,
id: clusterId
id: managementClusterId
}),
repos: this.$store.dispatch('management/findAll', { type: FLEET.GIT_REPO }),
workspaces: this.$store.dispatch('management/findAll', { type: FLEET.WORKSPACE }),
Expand All @@ -53,7 +53,7 @@ export default {
return this.value.bundleDeployments;
},
clusterId() {
return this.value?.metadata?.labels[FLEET_LABELS.CLUSTER_NAME];
return this.value.id;
},

repos() {
Expand Down
11 changes: 0 additions & 11 deletions shell/models/fleet.cattle.io.bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,6 @@ import { FLEET } from '@shell/config/types';
import { convertSelectorObj, matching } from '@shell/utils/selector';

export default class FleetBundle extends SteveModel {
get deploymentInfo() {
const ready = this.status?.summary?.ready || 0;
const total = this.status?.summary?.desiredReady || 0;

return {
ready,
unready: total - ready,
total
};
}

get lastUpdateTime() {
return this.status?.conditions?.[0].lastUpdateTime;
}
Expand Down
102 changes: 52 additions & 50 deletions shell/models/fleet.cattle.io.gitrepo.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { addObject, addObjects, findBy, insertAt } from '@shell/utils/array';
import { set } from '@shell/utils/object';
import SteveModel from '@shell/plugins/steve/steve-class';
import {
colorForState, mapStateToEnum, primaryDisplayStatusFromCount, stateDisplay, stateSort
colorForState, mapStateToEnum, primaryDisplayStatusFromCount, stateDisplay, STATES_ENUM, stateSort,
} from '@shell/plugins/dashboard-store/resource-class';
import { NAME } from '@shell/config/product/explorer';
import FleetUtils from '@shell/utils/fleet';
Expand All @@ -20,6 +20,21 @@ function quacksLikeAHash(str) {
return false;
}

function normalizeStateCounts(data) {
if (!data || data === {}) {
return {
total: 0,
states: {},
};
}
const { desiredReady, ...rest } = data ;

return {
total: desiredReady,
states: rest,
};
}

export default class GitRepo extends SteveModel {
applyDefaults() {
const spec = this.spec || {};
Expand Down Expand Up @@ -305,18 +320,7 @@ export default class GitRepo extends SteveModel {
}

get bundles() {
const all = this.$getters['all'](FLEET.BUNDLE);

return all.filter((bundle) => bundle.repoName === this.name &&
bundle.namespace === this.namespace &&
bundle.namespacedName.startsWith(`${ this.namespace }:${ this.name }`));
}

/**
* Bundles with state of active
*/
get bundlesReady() {
return this.bundles?.filter((bundle) => bundle.state === 'active');
return this.$getters['matching'](FLEET.BUNDLE, { 'fleet.cattle.io/repo-name': this.name }, this.namespace);
}

get bundleDeployments() {
Expand All @@ -325,6 +329,37 @@ export default class GitRepo extends SteveModel {
return bds.filter((bd) => bd.metadata?.labels?.['fleet.cattle.io/repo-name'] === this.name);
}

get allBundlesStatuses() {
const { nonReadyResources, ...bundlesSummary } = this.status?.summary || {};

return normalizeStateCounts(bundlesSummary);
}

get allResourceStatuses() {
return normalizeStateCounts(this.status?.resourceCounts || {});
}

statusResourceCountsForCluster(clusterId) {
if (!this.targetClusters.some((c) => c.id === clusterId)) {
return {};
}

return this.bundleDeployments
.filter((bd) => FleetUtils.clusterIdFromBundleDeploymentLabels(bd.metadata?.labels) === clusterId)
.map((bd) => FleetUtils.resourcesFromBundleDeploymentStatus(bd.status))
.flat()
.map((r) => r.state)
.reduce((prev, state) => {
if (!prev[state]) {
prev[state] = 0;
}
prev[state]++;
prev.desiredReady++;

return prev;
}, { desiredReady: 0 });
}

get resourcesStatuses() {
const bundleDeployments = this.bundleDeployments || [];
const clusters = (this.targetClusters || []).reduce((res, c) => {
Expand Down Expand Up @@ -357,7 +392,7 @@ export default class GitRepo extends SteveModel {
name: `c-cluster-product-resource${ r.namespace ? '-namespace' : '' }-id`,
params: {
product: NAME,
cluster: c.metadata.labels[FLEET_ANNOTATIONS.CLUSTER_NAME],
cluster: c.metadata.labels[FLEET_ANNOTATIONS.CLUSTER_NAME], // explorer uses the "management" Cluster name, which differs from the Fleet Cluster name
resource: type,
namespace: r.namespace,
id: r.name,
Expand Down Expand Up @@ -385,7 +420,6 @@ export default class GitRepo extends SteveModel {
creationTimestamp: r.createdAt,

// other properties
clusterLabel: c.metadata.labels[FLEET_ANNOTATIONS.CLUSTER_NAME],
stateBackground: color,
stateDisplay: display,
stateSort: stateSort(color, display),
Expand All @@ -408,42 +442,10 @@ export default class GitRepo extends SteveModel {
};
}

get clusterResourceStatus() {
const clusterStatuses = this.resourcesStatuses.reduce((prev, curr) => {
const { clusterId, clusterLabel, state } = curr;

if (!prev[clusterId]) {
prev[clusterId] = {
clusterLabel,
resourceCounts: { [state]: 0, desiredReady: 0 }

};
}

if (!prev[clusterId].resourceCounts[state]) {
prev[clusterId].resourceCounts[state] = 0;
}

prev[clusterId].resourceCounts[state] += 1;
prev[clusterId].resourceCounts.desiredReady += 1;

return prev;
}, {});

const values = Object.keys(clusterStatuses).map((key) => {
const { clusterLabel, resourceCounts } = clusterStatuses[key];

return {
clusterId: key,
clusterLabel, // FLEET LABEL
status: {
displayStatus: primaryDisplayStatusFromCount(resourceCounts),
resourceCounts: { ...resourceCounts }
}
};
});
clusterState(clusterId) {
const resourceCounts = this.statusResourceCountsForCluster(clusterId);

return values;
return primaryDisplayStatusFromCount(resourceCounts) || STATES_ENUM.ACTIVE;
}

get clustersList() {
Expand Down
Loading
Loading