mirror of https://github.com/rancher/ui.git
279 lines
8.7 KiB
JavaScript
279 lines
8.7 KiB
JavaScript
import { alias, equal } from '@ember/object/computed';
|
|
import { get, set } from '@ember/object';
|
|
import Component from '@ember/component';
|
|
import NodeDriver from 'shared/mixins/node-driver';
|
|
import { ajaxPromise } from 'ember-api-store/utils/ajax-promise';
|
|
import layout from './template';
|
|
|
|
let RANCHER_TEMPLATE = 'Linux Ubuntu 14.04 LTS 64-bit';
|
|
let RANCHER_GROUP = 'rancher-machine';
|
|
let RANCHER_INGRESS_RULES = [
|
|
{
|
|
startport: 22,
|
|
endport: 22,
|
|
cidrlist: '0.0.0.0/0',
|
|
protocol: 'TCP'
|
|
},
|
|
{
|
|
icmptype: 8,
|
|
icmpcode: 0,
|
|
cidrlist: '0.0.0.0/0',
|
|
protocol: 'ICMP'
|
|
}
|
|
];
|
|
|
|
export default Component.extend(NodeDriver, {
|
|
layout,
|
|
driverName: 'exoscale',
|
|
model: null,
|
|
config: alias('model.exoscaleConfig'),
|
|
step: 1,
|
|
|
|
allDiskSizes : null,
|
|
allInstanceProfiles : null,
|
|
|
|
allSecurityGroups : null,
|
|
selectedSecurityGroup : null,
|
|
defaultSecurityGroup : null,
|
|
defaultSecurityGroupName : RANCHER_GROUP,
|
|
whichSecurityGroup : 'default',
|
|
isCustomSecurityGroup : equal('whichSecurityGroup','custom'),
|
|
exoscaleApi : 'api.exoscale.ch/compute',
|
|
|
|
bootstrap() {
|
|
const config = get(this,'globalStore').createRecord({
|
|
type: 'exoscaleConfig',
|
|
exoscaleApiKey: '',
|
|
exoscaleApiSecretKey: '',
|
|
diskSize: 50,
|
|
instanceProfile: 'small',
|
|
securityGroup: 'rancher-machine'
|
|
});
|
|
|
|
const model = get(this, 'model');
|
|
set(model, 'exoscaleConfig', config);
|
|
},
|
|
|
|
init() {
|
|
this._super();
|
|
|
|
const cur = get(this,'config.securityGroup');
|
|
if (cur === RANCHER_GROUP) {
|
|
this.setProperties({
|
|
whichSecurityGroup: 'default',
|
|
selectedSecurityGroup: null
|
|
});
|
|
} else {
|
|
this.setProperties({
|
|
whichSecurityGroup: 'custom',
|
|
selectedSecurityGroup: cur
|
|
});
|
|
}
|
|
},
|
|
|
|
actions: {
|
|
/* Login step */
|
|
exoscaleLogin() {
|
|
set(this,'errors', null);
|
|
set(this,'step', 2);
|
|
|
|
set(this,'config.exoscaleApiKey', (get(this,'config.exoscaleApiKey')||'').trim());
|
|
set(this,'config.exoscaleApiSecretKey', (get(this,'config.exoscaleApiSecretKey')||'').trim());
|
|
|
|
this.apiRequest('listSecurityGroups').then((res) => {
|
|
let groups = [];
|
|
let defaultGroup = null;
|
|
|
|
/* Retrieve the list of security groups. */
|
|
(res.listsecuritygroupsresponse.securitygroup || [])
|
|
.forEach((group) => {
|
|
let obj = {
|
|
id : group.id,
|
|
name : group.name,
|
|
description : group.description,
|
|
isDefault : group.name === get(this,'defaultSecurityGroupName')
|
|
};
|
|
|
|
groups.push(obj);
|
|
if (obj.isDefault && !defaultGroup) {
|
|
defaultGroup = obj;
|
|
}
|
|
});
|
|
|
|
/* Move to next step */
|
|
set(this,'step', 3);
|
|
set(this,'allSecurityGroups', groups);
|
|
set(this,'defaultSecurityGroup', defaultGroup);
|
|
set(this,'selectedSecurityGroup', get(this,'config.securityGroup') || get(this,'allSecurityGroups.firstObject.id'));
|
|
}, (err) => {
|
|
let errors = get(this,'errors')||[];
|
|
errors.pushObject(this.apiErrorMessage(err,
|
|
'listsecuritygroupsresponse',
|
|
'While requesting security groups',
|
|
'Authentication failure: please check the provided access credentials'
|
|
));
|
|
set(this,'errors', errors);
|
|
set(this,'step', 1);
|
|
});
|
|
},
|
|
|
|
/* Security group selection */
|
|
selectSecurityGroup() {
|
|
set(this,'errors',null);
|
|
|
|
/* When selecting a custom security group, we don't have to do anything more */
|
|
if (get(this,'isCustomSecurityGroup')) {
|
|
set(this,'config.securityGroup', get(this,'selectedSecurityGroup'));
|
|
this.fetchInstanceSettings();
|
|
return;
|
|
}
|
|
|
|
/* Otherwise, do we need to create the default security group? */
|
|
set(this,'config.securityGroup', get(this,'defaultSecurityGroupName'));
|
|
let group = get(this,'defaultSecurityGroup');
|
|
if (group) {
|
|
/* Already exists, we assume that it contains the appropriate rules */
|
|
set(this,'config.securityGroup', group.name);
|
|
this.fetchInstanceSettings();
|
|
return;
|
|
}
|
|
|
|
/* We need to create the security group */
|
|
set(this,'step', 4);
|
|
this.apiRequest('createSecurityGroup', {
|
|
name : get(this,'defaultSecurityGroupName'),
|
|
description : get(this,'settings.appName') + ' default security group'
|
|
}).then((res) => {
|
|
return async.eachSeries(RANCHER_INGRESS_RULES, (item, cb) => {
|
|
item.securitygroupid = res.createsecuritygroupresponse.securitygroup.id;
|
|
this.apiRequest('authorizeSecurityGroupIngress', item)
|
|
.then(() => {
|
|
return cb();
|
|
}, (err) => {
|
|
return cb(err);
|
|
});
|
|
}, (err) => {
|
|
if (err) {
|
|
let errors = get(this,'errors')||[];
|
|
errors.pushObject(this.apiErrorMessage(err,
|
|
'authorizesecuritygroupingressresponse',
|
|
'While setting default security group',
|
|
'Unable to configure the default security group'
|
|
));
|
|
set(this,'errors', errors);
|
|
set(this,'step', 3);
|
|
} else {
|
|
this.fetchInstanceSettings();
|
|
}
|
|
});
|
|
}, (err) => {
|
|
let errors = get(this,'errors')||[];
|
|
errors.pushObject(this.apiErrorMessage(err,
|
|
'createsecuritygroupresponse',
|
|
'While creating default security group',
|
|
'Unable to create the default security group'
|
|
));
|
|
set(this,'errors', errors);
|
|
set(this,'step', 3);
|
|
});
|
|
}
|
|
},
|
|
|
|
fetchInstanceSettings() {
|
|
set(this,'step', 5);
|
|
|
|
/* First, get a list of templates to get available disk sizes */
|
|
this.apiRequest('listTemplates', {
|
|
templatefilter : 'featured',
|
|
name : RANCHER_TEMPLATE
|
|
}).then((res) => {
|
|
set(this,'allDiskSizes',
|
|
res.listtemplatesresponse.template
|
|
.map((item) => Math.round(item.size / 1024 / 1024 / 1024))
|
|
.sort((a, b) => (a - b)).uniq()
|
|
);
|
|
|
|
/* Also get the instance types */
|
|
return this.apiRequest('listServiceOfferings', {
|
|
issystem: 'false'
|
|
}).then((res) => {
|
|
set(this,'allInstanceProfiles',
|
|
res.listserviceofferingsresponse.serviceoffering.sort((a, b) => {
|
|
if (a.memory < b.memory) {
|
|
return -1;
|
|
}
|
|
if (b.memory < a.memory) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}).map((item) => {
|
|
return { name: item.name, displaytext: item.displaytext }
|
|
}));
|
|
|
|
set(this,'step', 6);
|
|
}).catch((err) => {
|
|
let errors = get(this,'errors')||[];
|
|
errors.pushObject(this.apiErrorMessage(err,
|
|
'listserviceofferingsresponse',
|
|
'While getting list of instance types',
|
|
'Unable to get list of instance types'
|
|
));
|
|
set(this,'errors', errors);
|
|
set(this,'step', 3);
|
|
});
|
|
}).catch((err) => {
|
|
let errors = get(this,'errors')||[];
|
|
errors.pushObject(this.apiErrorMessage(err,
|
|
'listtemplatesresponse',
|
|
'While getting list of available images',
|
|
'Unable to get list of available images'
|
|
));
|
|
set(this,'errors', errors);
|
|
set(this,'step', 3);
|
|
});
|
|
},
|
|
|
|
apiErrorMessage(err, kind, prefix, def) {
|
|
let answer = (err.xhr || {}).responseJSON || {};
|
|
let text = (answer[kind] || {}).errortext;
|
|
if (text) {
|
|
return prefix + ": " + text;
|
|
} else {
|
|
return def;
|
|
}
|
|
},
|
|
|
|
apiRequest(command, params) {
|
|
let url = get(this,'app.proxyEndpoint') + '/' + this.exoscaleApi;
|
|
params = params || {};
|
|
params.command = command;
|
|
params.apiKey = get(this,'config.exoscaleApiKey');
|
|
params.response = 'json';
|
|
|
|
return ajaxPromise({url: url,
|
|
method: 'POST',
|
|
dataType: 'json',
|
|
data: params,
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'X-API-Headers-Restrict': 'Content-Length'
|
|
},
|
|
beforeSend: (xhr, settings) => {
|
|
// Append 'rancher:' to Content-Type
|
|
xhr.setRequestHeader('Content-Type',
|
|
'rancher:' + settings.contentType);
|
|
|
|
// Compute the signature
|
|
let qs = settings.data.split('&')
|
|
.map((q) => q.replace(/\+/g, '%20'))
|
|
.map(Function.prototype.call, String.prototype.toLowerCase)
|
|
.sort()
|
|
.join('&');
|
|
settings.data += '&signature=' + encodeURIComponent(AWS.util.crypto.hmac(
|
|
get(this,'config.exoscaleApiSecretKey'), qs, 'base64', 'sha1'));
|
|
return true;
|
|
},
|
|
}, true);
|
|
},
|
|
});
|