dashboard/shell/models/management.cattle.io.nodepo...

198 lines
4.3 KiB
JavaScript

import { CAPI, MANAGEMENT, NORMAN } from '@shell/config/types';
import { sortBy } from '@shell/utils/sort';
import HybridModel from '@shell/plugins/steve/hybrid-class';
import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
const RKE1_ALLOWED_ACTIONS = [
'goToViewYaml',
'download',
'viewInApi'
];
export default class MgmtNodePool extends HybridModel {
get _availableActions() {
const out = super._availableActions;
return out.filter((a) => a.divider || RKE1_ALLOWED_ACTIONS.includes(a.action));
}
get nodeTemplateId() {
return (this.spec?.nodeTemplateName || '').replace(/:/, '/');
}
get nodeTemplate() {
return this.$getters['byId'](MANAGEMENT.NODE_TEMPLATE, this.nodeTemplateId);
}
get provider() {
return this.nodeTemplate?.provider;
}
get providerName() {
return this.nodeTemplate?.nameDisplay;
}
get providerDisplay() {
return this.nodeTemplate?.providerDisplay;
}
get providerLocation() {
return this.nodeTemplate?.providerLocation;
}
get providerSize() {
return this.nodeTemplate?.providerSize;
}
get provisioningCluster() {
return this.$getters['all'](CAPI.RANCHER_CLUSTER).find((c) => c.name === this.spec.clusterName);
}
get doneOverride() {
return {
name: 'c-cluster-product-resource-namespace-id',
params: {
resource: CAPI.RANCHER_CLUSTER,
namespace: this.provisioningCluster?.namespace,
id: this.spec.clusterName
}
};
}
get scale() {
return this.norman.quantity;
}
scalePool(delta) {
this.norman.quantity += delta;
if ( this.scaleTimer ) {
clearTimeout(this.scaleTimer);
}
this.scaleTimer = setTimeout(() => {
try {
this.norman.save();
} catch (error) {
this.$dispatch('growl/fromError', {
title: 'Error scaling pool',
error
}, { root: true });
}
}, 1000);
}
get nodes() {
const nodePoolName = this.id.replace('/', ':');
return this.$getters['all'](MANAGEMENT.NODE).filter((node) => node.spec.nodePoolName === nodePoolName);
}
get nodeSummary() {
// Use three buckets of states rather than actual states.
// These are used in `stateParts` which is show in the same context as `stateParts` for machine deployments (rke2 pools))
// Using actual states here would look strange when against bucket states for RKE2
const res = {
pending: 0,
unavailable: 0,
ready: 0,
};
if (!this.nodes) {
return res;
}
return this.nodes.reduce((res, n) => {
if (n.metadata.state.error ) {
res.unavailable++;
} else if (n.metadata.state.transitioning) {
res.pending++;
} else if (n.state !== 'active') {
res.unavailable++;
} else {
res.ready++;
}
return res;
}, { ...res });
}
get desired() {
return this.spec?.quantity || 0;
}
get pending() {
return this.nodeSummary.pending;
}
get ready() {
return this.nodeSummary.ready;
}
get unavailable() {
return this.nodeSummary.unavailable;
}
get stateParts() {
const out = [
{
label: 'Pending',
color: 'bg-info',
textColor: 'text-info',
value: this.pending,
sort: 1,
},
{
label: 'Unavailable',
color: 'bg-error',
textColor: 'text-error',
value: this.unavailable,
sort: 3,
},
{
label: 'Ready',
color: 'bg-success',
textColor: 'text-success',
value: this.ready,
sort: 4,
},
].filter((x) => x.value > 0);
return sortBy(out, 'sort:desc');
}
get norman() {
const id = this.id.replace('/', ':');
return this.$rootGetters['rancher/byId'](NORMAN.NODE_POOL, id);
}
get canDelete() {
return this.norman?.hasLink('remove');
}
get canUpdate() {
return this.norman?.hasLink('update');
}
get isControlPlane() {
return this.spec?.controlPlane === true;
}
get isEtcd() {
return this.spec?.etcd === true;
}
canScaleDownPool() {
if (!this.isEtcd && !this.isControlPlane) {
return true;
}
return notOnlyOfRole(this, this?.provisioningCluster?.nodes);
}
remove() {
return this.norman?.remove();
}
}