ui/lib/nodes/addon/components/node-driver/driver-packet/component.js

200 lines
4.8 KiB
JavaScript

import { hash } from 'rsvp';
import { on } from '@ember/object/evented';
import {
get, set, setProperties, computed, observer
} from '@ember/object';
import { isEmpty } from '@ember/utils';
import { alias } from '@ember/object/computed';
import Component from '@ember/component';
import NodeDriver from 'shared/mixins/node-driver';
import fetch from 'ember-api-store/utils/fetch';
import layout from './template';
const OS_WHITELIST = ['centos_7', 'coreos_stable', 'ubuntu_14_04', 'ubuntu_16_04', 'rancher'];
const PLAN_BLACKLIST = ['baremetal_2a']; // quick wheres james spader?
const DEFAULTS = {
os: 'ubuntu_16_04',
facilityCode: 'ewr1',
plan: 'baremetal_0',
billingCycle: 'hourly',
}
export default Component.extend(NodeDriver, {
layout,
driverName: 'packet',
facilityChoices: null,
planChoices: null,
osChoices: null,
step: 1,
config: alias('model.packetConfig'),
init() {
this._super(...arguments);
setProperties(this, {
facilityChoices: [],
planChoices: [],
osChoices: [],
allOS: [],
});
},
actions: {
authPacket(savedCB) {
let promises = {
plans: this.apiRequest('plans'),
opSys: this.apiRequest('operating-systems'),
facilities: this.apiRequest('facilities'),
};
hash(promises).then((hash) => {
let osChoices = this.parseOSs(hash.opSys.operating_systems);
let selectedPlans = this.parsePlans(osChoices.findBy('slug', 'ubuntu_14_04'), hash.plans.plans);
let config = get(this, 'config');
setProperties(this, {
allOS: osChoices,
allPlans: hash.plans.plans,
step: 2,
facilityChoices: hash.facilities.facilities,
osChoices,
planChoices: selectedPlans,
});
setProperties(config, DEFAULTS);
savedCB(true);
}, (err) => {
let errors = get(this, 'errors') || [];
errors.push(`${ err.statusText }: ${ err.body.message }`);
set(this, 'errors', errors);
savedCB(false);
});
},
},
planChoiceDetails: computed('config.plan', function() {
let planSlug = get(this, 'config.plan');
let plan = get(this, 'allPlans').findBy('slug', planSlug);
return plan;
}),
facilityObserver: on('init', observer('config.facility', function() {
let facilities = get(this, 'facilityChoices');
let slug = get(this, 'config.facility');
let facility = facilities.findBy('code', slug);
let plans = get(this, 'allPlans');
let out = [];
if (plans && facility) {
plans.forEach((plan) => {
plan.available_in.forEach((fac) => {
let facId = fac.href.split('/')[fac.href.split('/').length - 1];
if (facility.id === facId) {
out.push(plan);
}
})
});
set(this, 'planChoices', out);
}
})),
bootstrap() {
let store = get(this, 'globalStore');
let config = store.createRecord({
type: 'packetConfig',
projectId: '',
apiKey: '',
});
const model = get(this, 'model');
set(model, 'packetConfig', config);
},
apiRequest(command, opt, out) {
opt = opt || {};
let url = `${ get(this, 'app.proxyEndpoint') }/`;
if ( opt.url ) {
url += opt.url.replace(/^http[s]?\/\//, '');
} else {
url += `${ 'api.packet.net' }/${ command }`;
}
return fetch(url, {
headers: {
'Accept': 'application/json',
'X-Auth-Token': get(this, 'config.apiKey'),
},
}).then((res) => {
let body = res.body;
if ( out ) {
out[command].pushObjects(body[command]);
} else {
out = body;
}
// De-paging
if ( body && body.links && body.links.pages && body.links.pages.next ) {
opt.url = body.links.pages.next;
return this.apiRequest(command, opt, out).then(() => {
return out;
});
} else {
return out;
}
});
},
parseOSs(osList) {
return osList.filter((os) => {
if (OS_WHITELIST.includes(os.slug) && !isEmpty(os.provisionable_on)) {
return os;
}
});
},
parsePlans(os, plans) {
let out = [];
os.provisionable_on.forEach((loc) => {
let plan = plans.findBy('slug', loc);
if (plan && !PLAN_BLACKLIST.includes(loc)) {
out.push(plan);
}
});
return out;
},
validate() {
let errors = get(this, 'model').validationErrors();
if (!get(this, 'config.projectId') ) {
errors.push('Project ID is required');
}
if (!get(this, 'config.apiKey') ) {
errors.push('API Key is requried');
}
if ( errors.length ) {
set(this, 'errors', errors.uniq());
return false;
}
return true;
},
});