mirror of https://github.com/rancher/ui.git
329 lines
9.3 KiB
JavaScript
329 lines
9.3 KiB
JavaScript
import Component from '@ember/component'
|
|
import ClusterDriver from 'shared/mixins/cluster-driver';
|
|
import { equal, alias, or } from '@ember/object/computed';
|
|
import { get, set, computed, observer } from '@ember/object';
|
|
import { satisfies } from 'shared/utils/parse-version';
|
|
import { sortVersions } from 'shared/utils/sort';
|
|
import { inject as service } from '@ember/service';
|
|
import { validateEndpoint } from 'shared/utils/util';
|
|
import C from 'shared/utils/constants';
|
|
import layout from './template';
|
|
import { resolve } from 'rsvp';
|
|
|
|
export default Component.extend(ClusterDriver, {
|
|
layout,
|
|
globalStore: service(),
|
|
settings: service(),
|
|
growl: service(),
|
|
intl: service(),
|
|
|
|
configField: 'rancherKubernetesEngineConfig',
|
|
|
|
model: null,
|
|
|
|
initialVersion: null,
|
|
loading: false,
|
|
isNew: equal('mode', 'new'),
|
|
isEdit: equal('mode', 'edit'),
|
|
notView: or('isNew', 'isEdit'),
|
|
clusterState: alias('model.originalCluster.state'),
|
|
|
|
networkChoices: [
|
|
{ label: 'clusterNew.rke.network.flannel', value: 'flannel' },
|
|
{ label: 'clusterNew.rke.network.calico', value: 'calico' },
|
|
{ label: 'clusterNew.rke.network.canal', value: 'canal' },
|
|
],
|
|
|
|
authChoices: [
|
|
{ label: 'clusterNew.rke.auth.x509', value: 'x509' },
|
|
],
|
|
|
|
ingressChoices: [
|
|
{ label: 'clusterNew.rke.ingress.nginx', value: 'nginx' },
|
|
{ label: 'clusterNew.rke.ingress.none', value: 'none' },
|
|
],
|
|
|
|
registry: 'default',
|
|
registryUrl: null,
|
|
registryUser: null,
|
|
registryPass: null,
|
|
|
|
init() {
|
|
this._super();
|
|
|
|
const globalStore = get(this, 'globalStore');
|
|
const counts = {};
|
|
|
|
set(this, 'existingNodes', globalStore.all('node'));
|
|
globalStore.findAll('node').then((all) => {
|
|
all.forEach((node) => {
|
|
const id = get(node,'clusterId');
|
|
counts[id] = (counts[id]||0) + 1;
|
|
});
|
|
|
|
this.notifyPropertyChange('initialNodeCounts');
|
|
});
|
|
|
|
set(this, 'initialNodeCounts', counts);
|
|
|
|
set(this, 'initialVersion', get(this, 'cluster.rancherKubernetesEngineConfig.kubernetesVersion'));
|
|
|
|
const config = get(this, 'cluster.rancherKubernetesEngineConfig');
|
|
if ( config && get(config, 'privateRegistries.length') > 0 ) {
|
|
const registry = get(config, 'privateRegistries.firstObject');
|
|
set(this, 'registry', 'custom');
|
|
set(this, 'registryUrl', get(registry, 'url'));
|
|
set(this, 'registryUser', get(registry, 'user'));
|
|
set(this, 'registryPass', get(registry, 'password'));
|
|
}
|
|
},
|
|
|
|
didInsertElement() {
|
|
if ( ! get(this,'cluster.rancherKubernetesEngineConfig') ) {
|
|
const globalStore = get(this, 'globalStore');
|
|
let config = globalStore.createRecord({
|
|
type: 'rancherKubernetesEngineConfig',
|
|
ignoreDockerVersion: true,
|
|
kubernetesVersion: get(this, `settings.${C.SETTING.VERSION_K8S_DEFAULT}`),
|
|
authentication: globalStore.createRecord({
|
|
type: 'authnConfig',
|
|
strategy: 'x509',
|
|
}),
|
|
network: globalStore.createRecord({
|
|
type: 'networkConfig',
|
|
plugin: 'canal',
|
|
}),
|
|
ingress: globalStore.createRecord({
|
|
type: 'ingressConfig',
|
|
provider: 'nginx',
|
|
}),
|
|
services: globalStore.createRecord({
|
|
type: 'rkeConfigServices',
|
|
kubeApi: globalStore.createRecord({
|
|
type: 'kubeAPIService',
|
|
podSecurityPolicy: false,
|
|
}),
|
|
etcd: globalStore.createRecord({
|
|
type: 'etcdService',
|
|
extraArgs: {
|
|
'heartbeat-interval': 500,
|
|
'election-timeout': 5000
|
|
},
|
|
}),
|
|
}),
|
|
});
|
|
set(this, 'cluster.rancherKubernetesEngineConfig', config);
|
|
}
|
|
|
|
if ( get(this, 'isNew') ) {
|
|
this.driverDidChange();
|
|
}
|
|
},
|
|
|
|
driverDidChange: observer('nodeWhich', function () {
|
|
if ( !get(this, 'isNew') ) {
|
|
return;
|
|
}
|
|
|
|
const config = get(this, 'cluster.rancherKubernetesEngineConfig');
|
|
|
|
if ( get(config, 'cloudProvider') ){
|
|
delete config.cloudProvider;
|
|
}
|
|
}),
|
|
|
|
didReceiveAttrs() {
|
|
if ( get(this,'isEdit') ) {
|
|
this.loadToken();
|
|
}
|
|
},
|
|
|
|
actions: {
|
|
setNodePoolErrors(errors) {
|
|
set(this, 'nodePoolErrors', errors);
|
|
},
|
|
},
|
|
|
|
willSave() {
|
|
if ( get(this, 'registry') === 'custom' ) {
|
|
const registry = {
|
|
url: get(this, 'registryUrl'),
|
|
user: get(this, 'registryUser'),
|
|
password: get(this, 'registryPass'),
|
|
}
|
|
|
|
set(this, 'config.privateRegistries', [registry]);
|
|
}
|
|
|
|
return this._super(...arguments);
|
|
},
|
|
|
|
validate() {
|
|
this._super(...arguments);
|
|
const errors = get(this,'errors')||[];
|
|
|
|
if ( !get(this, 'isCustom') ) {
|
|
errors.pushObjects(get(this, 'nodePoolErrors'));
|
|
}
|
|
|
|
if ( get(this, 'config.services.kubeApi.podSecurityPolicy') &&
|
|
!get(this, 'cluster.defaultPodSecurityPolicyTemplateId') ) {
|
|
errors.push(get(this, 'intl').t('clusterNew.psp.required'));
|
|
}
|
|
|
|
set(this, 'errors', errors);
|
|
return errors.length === 0;
|
|
},
|
|
|
|
doneSaving() {
|
|
if ( get(this, 'isCustom') ) {
|
|
if ( get(this, 'isEdit') ) {
|
|
this.sendAction('close');
|
|
} else {
|
|
this.loadToken();
|
|
}
|
|
} else {
|
|
this.sendAction('close');
|
|
}
|
|
|
|
return resolve();
|
|
},
|
|
|
|
loadToken() {
|
|
const cluster = get(this,'cluster');
|
|
set(this, 'step', 2);
|
|
set(this, 'loading', true);
|
|
return cluster.getOrCreateToken().then((token) => {
|
|
if ( this.isDestroyed || this.isDestroying ) {
|
|
return;
|
|
}
|
|
set(this, 'token', token);
|
|
set(this, 'loading', false);
|
|
}).catch((err) => {
|
|
if ( this.isDestroyed || this.isDestroying ) {
|
|
return;
|
|
}
|
|
|
|
get(this,'growl').fromError('Error getting command', err);
|
|
set(this, 'loading', false);
|
|
});
|
|
},
|
|
|
|
versionChanged: observer('config.kubernetesVersion','versionChoices.[]', function() {
|
|
const versions = get(this, 'versionChoices')||[];
|
|
const current = get(this, 'config.kubernetesVersion');
|
|
const exists = versions.findBy('value', current);
|
|
if ( !exists ) {
|
|
set(this, 'config.kubernetesVersion', versions[0].value);
|
|
}
|
|
}),
|
|
|
|
versionChoices: computed('initialVersion', `settings.${C.SETTING.VERSIONS_K8S}`, 'config.kubernetesVersion', function() {
|
|
const versions = JSON.parse(get(this, `settings.${C.SETTING.VERSIONS_K8S}`)||'{}');
|
|
|
|
if ( !versions ) {
|
|
return [];
|
|
}
|
|
|
|
const initialVersion = get(this, 'initialVersion');
|
|
let oldestSupportedVersion = '>=1.8.0';
|
|
if ( initialVersion ) {
|
|
oldestSupportedVersion = '>=' + initialVersion;
|
|
}
|
|
|
|
let out = Object.keys(versions);
|
|
|
|
out = out.filter((v) => {
|
|
const str = v.replace(/-.*/,'');
|
|
return satisfies(str, oldestSupportedVersion);
|
|
});
|
|
|
|
if (get(this, 'editing') && !out.includes(initialVersion) ) {
|
|
out.unshift(initialVersion);
|
|
}
|
|
|
|
return sortVersions(out).reverse().map((v) => {
|
|
return {value: v}
|
|
});
|
|
}),
|
|
|
|
isAddressValid: computed('address', function() {
|
|
return get(this, 'address') === undefined || get(this, 'address.length') === 0 || validateEndpoint(get(this, 'address'));
|
|
}),
|
|
|
|
isInternalAddressValid: computed('internalAddress', function() {
|
|
return get(this, 'internalAddress') === undefined || get(this, 'internalAddress.length') === 0 || validateEndpoint(get(this, 'internalAddress'));
|
|
}),
|
|
|
|
// Custom stuff
|
|
isCustom: equal('nodeWhich','custom'),
|
|
existingNodes: null,
|
|
initialNodeCounts: null,
|
|
step: 1,
|
|
token: null,
|
|
labels: null,
|
|
etcd: false,
|
|
controlplane: false,
|
|
worker: true,
|
|
|
|
newNodeCount: computed('initialNodeCounts','cluster.id','existingNodes.@each.clusterId', function() {
|
|
let clusterId = get(this,'cluster.id');
|
|
let orig = get(this, 'initialNodeCounts')[clusterId] || 0;
|
|
let cur = get(this, 'existingNodes').filterBy('clusterId', clusterId).length
|
|
|
|
if ( cur < orig ) {
|
|
orig = cur;
|
|
set (get(this,'initialNodeCounts'), clusterId, cur)
|
|
}
|
|
|
|
return cur - orig;
|
|
}),
|
|
|
|
networkDidChange: observer('config.network.plugin', function () {
|
|
const plugin = get(this, 'config.network.plugin');
|
|
if (plugin === 'flannel') {
|
|
set(this, 'config.network.flannelNetworkProvider', {});
|
|
set(this, 'config.network.calicoNetworkProvider', null);
|
|
} else if (plugin === 'calico') {
|
|
set(this, 'config.network.calicoNetworkProvider', {});
|
|
set(this, 'config.network.flannelNetworkProvider', null);
|
|
} else {
|
|
set(this, 'config.network.calicoNetworkProvider', null);
|
|
set(this, 'config.network.flannelNetworkProvider', null);
|
|
}
|
|
}),
|
|
|
|
command: computed(`settings.${C.SETTING.AGENT_IMAGE}`, 'labels', 'token.nodeCommand', 'etcd', 'controlplane', 'worker', 'address', 'internalAddress', function() {
|
|
let out = get(this, 'token.nodeCommand');
|
|
|
|
if ( !out ) {
|
|
return;
|
|
}
|
|
|
|
const address = get(this, 'address');
|
|
if(address) {
|
|
out += ` --address ${address}`;
|
|
}
|
|
|
|
const internalAddress = get(this, 'internalAddress');
|
|
if(internalAddress) {
|
|
out += ` --internal-address ${internalAddress}`;
|
|
}
|
|
|
|
const roles = ['etcd','controlplane','worker'];
|
|
for ( let i = 0, k ; i < roles.length ; i++ ) {
|
|
k = roles[i];
|
|
if ( get(this,k) ) {
|
|
out += ` --${k}`;
|
|
}
|
|
}
|
|
|
|
const labels = get(this, 'labels')||{};
|
|
Object.keys(labels).forEach((key) => {
|
|
out += ` --label ${key}=${labels[key]}`;
|
|
});
|
|
|
|
return out;
|
|
}),
|
|
});
|