dashboard/shell/models/fleet.cattle.io.bundle.js

133 lines
4.4 KiB
JavaScript

import { escapeHtml, ucFirst } from '@shell/utils/string';
import SteveModel from '@shell/plugins/steve/steve-class';
import { addObject, addObjects, findBy } from '@shell/utils/array';
import { FLEET } from '@shell/config/types';
import { FLEET as FLEET_ANNOTATIONS } from '@shell/config/labels-annotations';
import { convertSelectorObj, matching } from '@shell/utils/selector';
export default class FleetBundle extends SteveModel {
get lastUpdateTime() {
return this.status?.conditions?.[0].lastUpdateTime;
}
get repoName() {
const labels = this.metadata?.labels || {};
return labels[FLEET_ANNOTATIONS.REPO_NAME];
}
get helmName() {
const labels = this.metadata?.labels || {};
return labels[FLEET_ANNOTATIONS.HELM_NAME];
}
get appSourceName() {
return this.helmName || this.repoName;
}
get targetClusters() {
const workspace = this.$getters['byId'](
FLEET.WORKSPACE,
this.metadata.namespace
);
const clusters = workspace?.clusters || [];
const groups = workspace?.clusterGroups || [];
const out = [];
if (workspace.id === 'fleet-local') {
const local = findBy(groups, 'id', 'fleet-local/default');
if (local) {
return local.targetClusters;
}
return [];
}
for (const tgt of this.spec.targets) {
if (tgt.clusterName) {
const cluster = findBy(clusters, 'metadata.name', tgt.clusterName);
if (cluster) {
addObject(out, cluster);
}
} else if (tgt.clusterGroup) {
const group = findBy(groups, {
'metadata.namespace': this.metadata.namespace,
'metadata.name': tgt.clusterGroup
});
if (group) {
addObjects(out, group.targetClusters);
}
} else if (tgt.clusterGroupSelector) {
const expressions = convertSelectorObj(tgt.clusterGroupSelector);
const matchingGroups = matching(groups, expressions);
for (const group of matchingGroups) {
addObjects(out, group.targetClusters);
}
} else if (tgt.clusterSelector) {
const expressions = convertSelectorObj(tgt.clusterSelector);
const matchingClusters = matching(clusters, expressions);
addObjects(out, matchingClusters);
}
}
return out;
}
get stateDescription() {
const error = this.stateObj?.error || false;
const message = this.stateObj?.message;
return error ? ucFirst(message) : '';
}
get stateObj() {
const errorState = this.status?.conditions?.find((item) => {
const { error, message } = item;
const errState = !!error;
/**
* error.trainsitioning = true when error applied. So checking non existance of tranistioning is not enough.
* {
* "error": true,
* "lastUpdateTime": "2022-03-03T08:28:15Z",
* "message": "ErrApplied(1) [Cluster test-do/c-b5rsv: rendered manifests contain a resource that already exists. Unable to continue with install: Service \"frontend\" in namespace \"fleet-mc-helm-kustomize-example\" exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error: key \"meta.helm.sh/release-name\" must equal \"sf-mchk-multi-cluster-helm-kustomize\": current value is \"test-bug-multi-cluster-helm-kustomize\"]; NotReady(1) [Cluster test-do/c-5fhtx]; deployment.apps fleet-mc-helm-kustomize-example/redis-master [progressing] Deployment does not have minimum availability., Available: 0/1; deployment.apps shavin/frontend extra; deployment.apps shavin/redis-master extra; deployment.apps shavin/redis-slave extra; service.v1 shavin/frontend extra",
* "status": "False",
* "transitioning": true,
* "type": "Ready"
* },
*/
const hasErrorMessage =
message?.toLowerCase().includes('errapplied') ||
message?.toLowerCase().includes('error');
return errState && hasErrorMessage;
});
if (errorState) {
errorState.name = errorState.message?.toLowerCase().includes('errapplied') ? 'errapplied' : 'error';
return errorState;
}
return { ...this.metadata.state };
}
get groupByLabel() {
const name = this.metadata.namespace;
if (name) {
return this.$rootGetters['i18n/t']('resourceTable.groupLabel.workspace', { name: escapeHtml(name) });
} else {
return this.$rootGetters['i18n/t'](
'resourceTable.groupLabel.notInAWorkspace'
);
}
}
}