dashboard/models/fleet.cattle.io.gitrepo.js

288 lines
6.5 KiB
JavaScript

import { convert, matching, convertSelectorObj } from '@/utils/selector';
import jsyaml from 'js-yaml';
import { escapeHtml } from '@/utils/string';
import { FLEET } from '@/config/types';
import { FLEET as FLEET_ANNOTATIONS } from '@/config/labels-annotations';
import { addObjects, findBy, insertAt } from '@/utils/array';
import { set } from '@/utils/object';
function quacksLikeAHash(str) {
if ( str.match(/^[a-f0-9]{40,}$/i) ) {
return true;
}
return false;
}
export default {
applyDefaults() {
return () => {
const spec = this.spec || {};
const meta = this.metadata || {};
meta.namespace = this.$rootGetters['workspace'];
spec.repo = spec.repo || '';
if ( !spec.branch && !spec.revision ) {
spec.branch = 'master';
}
spec.paths = spec.paths || [];
spec.clientSecretName = spec.clientSecretName || null;
set(this, 'spec', spec);
set(this, 'metadata', meta);
};
},
_availableActions() {
const out = this._standardActions;
insertAt(out, 0, {
action: 'pause',
label: 'Pause',
icon: 'icon icon-pause',
bulkable: true,
enabled: !!this.links.update && !this.spec?.paused
});
insertAt(out, 1, {
action: 'unpause',
label: 'Unpause',
icon: 'icon icon-play',
bulkable: true,
enabled: !!this.links.update && this.spec?.paused === true
});
insertAt(out, 2, {
action: 'forceUpdate',
label: 'Force Update',
icon: 'icon icon-refresh',
bulkable: true,
enabled: !!this.links.update
});
insertAt(out, 3, { divider: true });
return out;
},
pause() {
this.spec.paused = true;
this.save();
},
unpause() {
this.spec.paused = false;
this.save();
},
state() {
if ( this.spec?.paused === true ) {
return 'paused';
}
return this.metadata?.state?.name || 'unknown';
},
forceUpdate() {
const now = this.spec.forceSyncGeneration || 1;
this.spec.forceSyncGeneration = now + 1;
this.save();
},
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.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;
},
github() {
const match = this.spec.repo.match(/^https?:\/\/github\.com\/(.*?)(\.git)?\/*$/);
if ( match ) {
return match[1];
}
return false;
},
repoIcon() {
if ( this.github ) {
return 'icon icon-github';
}
},
repoDisplay() {
let repo = this.spec.repo;
repo = repo.replace(/.git$/, '');
repo = repo.replace(/^https:\/\//, '');
repo = repo.replace(/\/+$/, '');
if ( this.github ) {
return this.github;
}
return repo;
},
commitDisplay() {
const spec = this.spec;
const hash = this.status?.commit?.substr(0, 7);
if ( !spec || !spec.repo ) {
return;
}
if ( spec.revision && quacksLikeAHash(spec.revision) ) {
return spec.revision.substr(0, 7);
} else if ( spec.revision ) {
return spec.revision;
} else if ( spec.branch ) {
return spec.branch + (hash ? ` @ ${ hash }` : '');
}
return hash;
},
clusterInfo() {
const ready = this.status?.readyClusters || 0;
const total = this.status?.desiredReadyClusters || 0;
return {
ready,
unready: total - ready,
total,
};
},
targetInfo() {
let mode = null;
let cluster = null;
let clusterGroup = null;
let advanced = null;
const targets = this.spec.targets || [];
advanced = jsyaml.safeDump(targets);
if ( advanced === '[]\n' ) {
advanced = `# - name:
# clusterSelector:
# matchLabels:
# foo: bar
# matchExpressions:
# - key: foo
# op: In
# values: [bar, baz]
# clusterGroup: foo
# clusterGroupSelector:
# matchLabels:
# foo: bar
# matchExpressions:
# - key: foo
# op: In
# values: [bar, baz]
`;
}
if ( this.metadata.namespace === 'fleet-local' ) {
mode = 'local';
} else if ( !targets.length ) {
mode = 'none';
} else if ( targets.length === 1) {
const target = targets[0];
if ( target.clusterGroup ) {
clusterGroup = target.clusterGroup;
if ( !mode ) {
mode = 'clusterGroup';
}
}
if ( target.clusterSelector ) {
if ( Object.keys(target.clusterSelector).length === 0 ) {
mode = 'all';
} else {
const expressions = convert(target.clusterSelector.matchLabels, target.clusterSelector.matchExpressions);
if ( expressions.length === 1 &&
expressions[0].key === FLEET_ANNOTATIONS.CLUSTER_NAME &&
expressions[0].operator === 'In' &&
expressions[0].values.length === 1
) {
cluster = expressions[0].values[0];
if ( !mode ) {
mode = 'cluster';
}
}
}
}
}
if ( !mode ) {
mode = 'advanced';
}
return {
mode,
modeDisplay: this.t(`fleet.gitRepo.targetDisplay."${ mode }"`),
cluster,
clusterGroup,
advanced
};
},
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');
}
},
};