ui/lib/global-admin/addon/clusters/new/rke/controller.js

243 lines
6.9 KiB
JavaScript

import Controller from '@ember/controller';
// import { copy } from '@ember/object/internals';
import { get, set } from '@ember/object';
import { inject as service } from '@ember/service';
import { computed,observer } from '@ember/object';
import { alias } from '@ember/object/computed';
import NewOrEdit from 'ui/mixins/new-or-edit';
import EmberObject from '@ember/object';
import { reject, all as PromiseAll } from 'rsvp';
const RKECONFIGNODE_DEFAULT = {
role: null,
type: 'rkeConfigHost',
machineId: null,
};
const headersAll = [
{
name: 'state',
sort: ['sortState','displayName'],
searchField: 'displayState',
translationKey: 'generic.state',
scope: 'embedded',
width: 120,
},
{
name: 'name',
sort: ['displayName','id'],
searchField: 'displayName',
translationKey: 'generic.name',
scope: 'embedded',
},
{
name: 'etcd',
sort: false,
searchField: null,
translationKey: 'clustersPage.addPage.rke.new.headers.labels.etcd',
},
{
name: 'controlplane',
sort: false,
searchField: null,
translationKey: 'clustersPage.addPage.rke.new.headers.labels.control',
},
{
name: 'worker',
sort: false,
searchField: null,
translationKey: 'clustersPage.addPage.rke.new.headers.labels.worker',
scope: 'embedded',
},
];
const workerHeaders = headersAll.filter((x) => x.scope === 'embedded');
const NETWORK = [
{label: 'clustersPage.addPage.rke.new.options.network.flannel', value: 'flannel'},
{label: 'clustersPage.addPage.rke.new.options.network.calico', value: 'calico'},
{label: 'clustersPage.addPage.rke.new.options.network.canal', value: 'canal'},
];
const AUTH = [
{label: 'clustersPage.addPage.rke.new.options.auth.x509', value: 'x509'},
];
const M_CONFIG = {
type: 'clusterRoleTemplateBinding',
clusterId: '',
name: '',
subjectKind: '',
subjectName: '',
roleTemplateId: '',
};
export default Controller.extend(NewOrEdit, {
modal: service('modal'),
clusterStore: service(),
globalStore: service(),
loading: null,
newHost: null,
canSave: null,
primaryResource: alias('model.cluster'),
memberArray: alias('model.cluster.clusterRoleTemplateBindings'),
memberConfig: M_CONFIG,
config: alias('primaryResource.rancherKubernetesEngineConfig'),
scope: null,
headersAll: headersAll,
workerHeaders: workerHeaders,
sortBy: 'name',
searchText: '',
authChoices: AUTH,
networkChoices: NETWORK,
countMap: null,
secPolicy: alias('primaryResource.defaultPodSecurityPolicyTemplateId'),
init() {
this._super(...arguments);
this.setProperties({
loading: false,
canSave: true,
scope: 'dedicated',
countMap: {
etcd: 0,
controlplane: 0,
worker: 0,
},
});
},
etcdSafe: computed('countMap.etcd', function() {
const count = get(this, 'countMap.etcd');
return count === 1 || count === 3 || count === 5;
}),
cpSafe: computed('countMap.controlplane', function() {
return get(this, 'countMap.controlplane') >= 1;
}),
workerSafe: computed('countMap.worker', function() {
return get(this, 'countMap.worker') >= 1;
}),
countState: observer('config.nodes.[]', function() {
let nodes = (get(this, 'config.nodes') || []);
let countMap = {
etcd: 0,
controlplane: 0,
worker: 0,
};
nodes.forEach((host) => {
get(host, 'role').forEach((role) => {
countMap[role]++;
});
});
set(this, 'countMap', countMap);
}),
scopeChanged: observer('scope', function() {
let config = get(this, 'config');
set(config, 'nodes', []);
}),
actions: {
addHost() {
get(this, 'modal').toggleModal('modal-add-cluster', {
templates: get(this, 'model.machineTemplates'),
nodes: get(this, 'model.nodes'),
drivers: get(this, 'model.machineDrivers'),
});
},
cancel(prev) {
this.send('goToPrevious',prev);
},
addRole(host, type) {
let clusterStore = get(this, 'clusterStore');
let neu = EmberObject.create(RKECONFIGNODE_DEFAULT);
let config = get(this, 'config');
let nodes = ( get(config, 'nodes') || [] ).slice();
let match = nodes.findBy('machineId', get(host, 'id'));
if (match) {
let roles = get(match, 'role');
// exists now check roles
if (roles.includes(type)) {
// remove
roles.removeObject(type);
//last one? remove that as well
if (roles.length === 0) {
nodes.removeObject(match);
}
} else {
//add new role
roles.addObject(type);
}
} else {
neu.setProperties({
role: [type],
type: 'rkeConfigHost',
machineId: get(host, 'id')
// user: 'root',
// ssh: '123',
});
neu = clusterStore.createRecord(neu);
nodes.addObject(neu);
}
set(config, 'nodes', nodes); //so the countState observer updates
}
},
doneSaving() {
return this.setMembers(this.get('primaryResource'));
},
setMembers(cluster) {
const clusterId = cluster.id; // TODO cluster does not have an ID
const members = this.get('memberArray');
const promises = [];
// TODO - wait for setMembers API suppot.
return this.get('globalStore').findAll('clusterRoleTemplateBinding', { forceReload: true })
.then(( bindings ) => {
const currentBindings = bindings.filter(b => b.clusterId === clusterId);
members.forEach(( member ) => {
const found = currentBindings.any(( m ) => {
return m.subjectName === member.subjectName &&
m.clusterId === member.clusterId &&
m.subjectKind === member.subjectKind;
});
if (!found) {
member.clusterId = clusterId;
const promise = this.get('globalStore').rawRequest({
url: 'clusterroletemplatebinding',
method: 'POST',
data: member,
});
promises.push(promise);
}
});
currentBindings.forEach(( currentMember ) => {
const found = members.any(( m ) =>{
return m.subjectName === currentMember.subjectName &&
m.clusterId === currentMember.clusterId &&
m.subjectKind === currentMember.subjectKind;
});
if (!found) {
const promise = this.get('globalStore').rawRequest({
url: `clusterroletemplatebinding/${currentMember.id}`,
method: 'DELETE',
});
promises.push(promise);
}
});
return PromiseAll(promises).then((/* resp */) => {
this.transitionToRoute('clusters.index');
}).catch((error) => {
return reject(error.body.message);
});
});
},
});