mirror of https://github.com/rancher/ui.git
222 lines
5.6 KiB
JavaScript
222 lines
5.6 KiB
JavaScript
import Component from '@ember/component';
|
|
import layout from './template';
|
|
import { get, set, computed, observer } from '@ember/object';
|
|
import { inject as service } from '@ember/service';
|
|
import { all as PromiseAll } from 'rsvp';
|
|
|
|
const headers = [
|
|
{
|
|
name: 'hostnamePrefix',
|
|
sort: ['hostnamePrefix', 'id'],
|
|
translationKey: 'clusterNew.rke.nodes.hostnamePrefix',
|
|
scope: 'embedded',
|
|
},
|
|
{
|
|
name: 'count',
|
|
sort: ['quantity', 'displayName.id'],
|
|
translationKey: 'clusterNew.rke.nodes.count',
|
|
width: 120,
|
|
},
|
|
{
|
|
name: 'nodeTemplate',
|
|
sort: ['nodeTemplate.displayName', 'nodeTemplate.id'],
|
|
translationKey: 'clusterNew.rke.nodes.template',
|
|
},
|
|
{
|
|
name: 'etcd',
|
|
sort: false,
|
|
translationKey: 'clusterNew.rke.role.header.etcd',
|
|
classNames: ['text-center'],
|
|
width: 120,
|
|
},
|
|
{
|
|
name: 'controlplane',
|
|
sort: false,
|
|
translationKey: 'clusterNew.rke.role.header.controlplane',
|
|
classNames: ['text-center'],
|
|
width: 120,
|
|
},
|
|
{
|
|
name: 'worker',
|
|
sort: false,
|
|
translationKey: 'clusterNew.rke.role.header.worker',
|
|
scope: 'embedded',
|
|
classNames: ['text-center'],
|
|
width: 120,
|
|
},
|
|
{
|
|
name: 'remove',
|
|
sort: false,
|
|
classNames: ['text-center'],
|
|
width: 50,
|
|
}
|
|
];
|
|
|
|
export default Component.extend({
|
|
layout,
|
|
headers,
|
|
globalStore: service(),
|
|
modalService: service('modal'),
|
|
intl: service(),
|
|
|
|
cluster: null,
|
|
nodeTemplates: null,
|
|
driver: null, // docker-machine driver
|
|
|
|
originalPools: null,
|
|
nodePools: null,
|
|
errors: null,
|
|
|
|
init() {
|
|
this._super(...arguments);
|
|
const originalPools = (get(this,'cluster.nodePools')||[]).slice();
|
|
set(this, 'originalPools', originalPools);
|
|
set(this, 'nodePools', originalPools.slice().map(p => p.clone()));
|
|
|
|
if ( get(this, 'mode') === 'new' && get(originalPools, 'length') === 0 ) {
|
|
get(this, 'nodePools').pushObject(get(this, 'globalStore').createRecord({
|
|
type: 'nodePool',
|
|
quantity: 1,
|
|
}));
|
|
}
|
|
this.sendAction('registerHook', this.savePools.bind(this), 'savePools');
|
|
},
|
|
|
|
didReceiveAttrs() {
|
|
this.validate();
|
|
},
|
|
|
|
actions: {
|
|
addPool() {
|
|
let nodePools = get(this, 'nodePools');
|
|
|
|
let templateId = null;
|
|
const lastNode = nodePools[nodePools.length-1];
|
|
if ( lastNode ) {
|
|
templateId = get(lastNode, 'nodeTemplateId');
|
|
}
|
|
|
|
nodePools.pushObject(get(this, 'globalStore').createRecord({
|
|
type: 'nodePool',
|
|
nodeTemplateId: templateId
|
|
}));
|
|
},
|
|
|
|
removePool(pool) {
|
|
get(this, 'nodePools').removeObject(pool);
|
|
},
|
|
|
|
addNodeTemplate(node) {
|
|
get(this,'modalService').toggleModal('modal-edit-node-template', {
|
|
nodeTemplate: null,
|
|
driver: get(this, 'driver'),
|
|
onAdd: function(nodeTemplate) {
|
|
set(node, 'nodeTemplateId', get(nodeTemplate, 'id'));
|
|
},
|
|
});
|
|
},
|
|
},
|
|
|
|
savePools: function() {
|
|
if (this.isDestroyed || this.isDestroying || get(this, 'driver') === 'custom' ) {
|
|
return;
|
|
}
|
|
|
|
const nodePools = get(this, 'nodePools');
|
|
const original = get(this, 'originalPools');
|
|
|
|
const remove = [];
|
|
original.forEach((pool) => {
|
|
if ( !nodePools.includes(pool) ) {
|
|
// Remove
|
|
remove.push(pool);
|
|
}
|
|
});
|
|
|
|
const clusterId = get(this, 'cluster.id');
|
|
nodePools.forEach((pool) => {
|
|
set(pool, 'clusterId', clusterId);
|
|
});
|
|
|
|
|
|
return PromiseAll(nodePools.map(x => x.save())).then(() => {
|
|
return PromiseAll(remove.map(x => x.delete())).then(() => {
|
|
return get(this, 'cluster');
|
|
});
|
|
});
|
|
},
|
|
|
|
filteredNodeTemplates: computed('driver','nodeTemplates.@each.{state,driver}', function() {
|
|
const driver = get(this, 'driver');
|
|
let templates = get(this, 'nodeTemplates').filterBy('state','active').filterBy('driver', driver);
|
|
return templates;
|
|
}),
|
|
|
|
_nodeCountFor(role) {
|
|
let count = 0;
|
|
(get(this, 'nodePools')||[]).filterBy(role,true).forEach((pool) => {
|
|
let more = get(pool, 'quantity');
|
|
if ( more ) {
|
|
more = parseInt(more, 10);
|
|
}
|
|
|
|
count += more;
|
|
});
|
|
|
|
return count;
|
|
},
|
|
|
|
etcdOk: computed('nodePools.@each.{quantity,etcd}', function() {
|
|
let count = this._nodeCountFor('etcd');
|
|
return count === 1 || count === 3 || count === 5
|
|
}),
|
|
|
|
controlPlaneOk: computed('nodePools.@each.{quantity,controlPlane}', function() {
|
|
let count = this._nodeCountFor('controlPlane');
|
|
return count >= 1;
|
|
}),
|
|
|
|
workerOk: computed('nodePools.@each.{quantity,worker}', function() {
|
|
let count = this._nodeCountFor('worker');
|
|
return count >= 1;
|
|
}),
|
|
|
|
driverChanged: observer('driver', function() {
|
|
const driver = get(this, 'driver');
|
|
|
|
get(this, 'nodePools').forEach((pool) => {
|
|
const tpl = get(pool, 'nodeTemplate');
|
|
if ( tpl && get(tpl, 'driver') !== driver ) {
|
|
set(pool, 'nodeTemplateId', null);
|
|
}
|
|
});
|
|
}),
|
|
|
|
validate: observer('etcdOk','controlPlaneOk','workerOk','nodePools.@each.{quantity,hostnamePrefix,nodeTemplateId}', function() {
|
|
const intl = get(this, 'intl');
|
|
|
|
const errors = [];
|
|
if ( !get(this, 'etcdOk') ) {
|
|
errors.push(intl.t('clusterNew.rke.errors.etcd'));
|
|
}
|
|
|
|
if ( !get(this, 'controlPlaneOk') ) {
|
|
errors.push(intl.t('clusterNew.rke.errors.controlPlane'));
|
|
}
|
|
|
|
if ( !get(this, 'workerOk') ) {
|
|
errors.push(intl.t('clusterNew.rke.errors.worker'));
|
|
}
|
|
|
|
get(this,'nodePools').forEach((pool) => {
|
|
// ClusterId is required but not known yet
|
|
if ( !get(pool, 'clusterId') ) {
|
|
set(pool, 'clusterId', '__later__');
|
|
}
|
|
errors.pushObjects(pool.validationErrors());
|
|
});
|
|
|
|
this.sendAction('setNodePoolErrors', errors);
|
|
}),
|
|
});
|