Commit 27ec75c8 authored by Ioannis Tsafaras's avatar Ioannis Tsafaras
Browse files

Merge pull request #270 from gouzouni625/disable-dropdown-options

Bug No3: Drop-down lists with projects and quotas
parents de05dc1b fd3e4ed0
......@@ -19,7 +19,7 @@ module.exports = function(defaults) {
// please specify an object with the list of modules as keys
// along with the exports of each module as its value.
app.import(app.bowerDirectory + '/AdminLTE/plugins/jQuery/jQuery-2.1.4.min.js');
app.import(app.bowerDirectory + '/AdminLTE/plugins/jQuery/jQuery-2.2.0.min.js');
app.import(app.bowerDirectory + '/AdminLTE/plugins/jQueryUI/jquery-ui.min.js');
app.import(app.bowerDirectory + '/handlebars/handlebars.js');
//app.import(app.bowerDirectory + '/bootstrap/dist/js/bootstrap.js');
......
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
create(newLambdaInstance) {
newLambdaInstance.set('instanceName', this.get('instanceName'));
newLambdaInstance.set('masterName', this.get('masterName'));
newLambdaInstance.set('slaves', this.$("input[name='slaves']")[0].value);
newLambdaInstance.set('projectName', this.$("select[name='okeanos_project']")[0].value);
newLambdaInstance.set('VCPUsMaster', this.$("select[name='vcpus_master']")[0].value);
newLambdaInstance.set('VCPUsSlave', this.$("select[name='vcpus_slave']")[0].value);
newLambdaInstance.set('RamMaster', this.$("select[name='ram_master']")[0].value);
newLambdaInstance.set('RamSlave', this.$("select[name='ram_slave']")[0].value);
newLambdaInstance.set('DiskMaster', this.$("select[name='disk_master']")[0].value);
newLambdaInstance.set('DiskSlave', this.$("select[name='disk_slave']")[0].value);
var requestedPublicKeys = [];
var options = this.$("select[name='public_key_name']")[0].options;
for(var i = 0;i < options.length;i++){
if(options[i].selected){
requestedPublicKeys.push(options[i].value);
}
}
newLambdaInstance.set('publicKeyName', requestedPublicKeys);
var kafkaOutputTopics, kafkaInputTopics;
var kafkaInputTopicsString = this.get('kafkaInputTopics');
if (kafkaInputTopicsString) {
kafkaInputTopics = kafkaInputTopicsString.replace(/\s+/g, '').split(',');
}
var kafkaOutputTopicsString = this.get('kafkaOutputTopics');
if (kafkaOutputTopicsString) {
kafkaOutputTopics = kafkaOutputTopicsString.replace(/\s+/g, '').split(',');
}
var duplicateTopic = false;
if (kafkaInputTopics && kafkaOutputTopics) {
kafkaInputTopics.forEach(function (inputTopic) {
if (kafkaOutputTopics.indexOf(inputTopic) !== -1) {
duplicateTopic = true;
}
});
}
if (duplicateTopic) {
this.set('duplicate_message', 'Apache Kafka input and output topics must be different!');
this.set('duplicate', true);
document.getElementById('inputTopics').focus();
}
else {
newLambdaInstance.set('kafkaInputTopics', kafkaInputTopics);
newLambdaInstance.set('kafkaOutputTopics', kafkaOutputTopics);
this.sendAction('saveAction', newLambdaInstance);
}
},
close_alert: function()
{
this.set('duplicate', false);
},
}
});
import Ember from "ember";
export default Ember.Controller.extend({
selectedProjectName: null,
selectedProjectVMs: null,
selectedProjectCPUs: null,
selectedProjectRAM: [],
selectedProjectDisk: [],
selectedNumberOfSlaves: null,
selectedMasterNodeCPUs: null,
selectedSlaveNodeCPUs: null,
selectedMasterNodeRAM: null,
selectedSlaveNodeRAM: null,
selectedMasterNodeDisk: null,
selectedSlaveNodeDisk: null,
masterNodeCPUValues: [],
slaveNodeCPUValues: [],
masterNodeRAMValues: [],
slaveNodeRAMValues: [],
masterNodeDiskValues: [],
slaveNodeDiskValues: [],
minQuotasPerVM: {'cpus': 2, 'ram': 2048, 'disk': 10},
minQuotasPerProject: {
'vms': 2,
'cpus': 4,
'ram': {'bytes': 4294967296, 'megaBytes': 4096},
'disk': {'bytes': 21474836480, 'gigaBytes': 20},
'floatingIPs': 1,
'privateNetworks': 1
},
enoughQuotas: false,
submitButtonDisabled: false,
masterCPUsSelectDisabled: false,
masterRAMSelectDisabled: false,
masterDiskSelectDisabled: false,
slaveCPUsSelectDisabled: false,
slaveRAMSelectDisabled: false,
slaveDiskSelectDisabled: false,
actions: {
saveLambdaInstance: function(newLambdaInstance){
var self = this;
newLambdaInstance.save().then(function(){
self.transitionToRoute('lambda-instance', newLambdaInstance.get('id')).catch(function() {
self.transitionToRoute('lambda-instances.index').then(function(newRoute) {
newRoute.controller.set('message', 'Your lambda instance creation will begin shortly.');
newRoute.controller.set('request', true);
newRoute.controller.send('start_stop');
newLambdaInstance.set('instanceName', this.get('instanceName'));
newLambdaInstance.set('masterName', this.get('masterName'));
newLambdaInstance.set('slaves', Ember.$("input[name='slaves']")[0].value);
newLambdaInstance.set('projectName', Ember.$("select[name='okeanos_project']")[0].value);
newLambdaInstance.set('VCPUsMaster', Ember.$("select[name='vcpus_master']")[0].value);
newLambdaInstance.set('VCPUsSlave', Ember.$("select[name='vcpus_slave']")[0].value);
newLambdaInstance.set('RamMaster', Ember.$("select[name='ram_master']")[0].value);
newLambdaInstance.set('RamSlave', Ember.$("select[name='ram_slave']")[0].value);
newLambdaInstance.set('DiskMaster', Ember.$("select[name='disk_master']")[0].value);
newLambdaInstance.set('DiskSlave', Ember.$("select[name='disk_slave']")[0].value);
var requestedPublicKeys = [];
var options = Ember.$("select[name='public_key_name']")[0].options;
for(var i = 0;i < options.length;i++){
if(options[i].selected){
requestedPublicKeys.push(options[i].value);
}
}
newLambdaInstance.set('publicKeyName', requestedPublicKeys);
var kafkaOutputTopics, kafkaInputTopics;
var kafkaInputTopicsString = this.get('kafkaInputTopics');
if (kafkaInputTopicsString) {
kafkaInputTopics = kafkaInputTopicsString.replace(/\s+/g, '').split(',');
}
var kafkaOutputTopicsString = this.get('kafkaOutputTopics');
if (kafkaOutputTopicsString) {
kafkaOutputTopics = kafkaOutputTopicsString.replace(/\s+/g, '').split(',');
}
var duplicateTopic = false;
if (kafkaInputTopics && kafkaOutputTopics) {
kafkaInputTopics.forEach(function (inputTopic) {
if (kafkaOutputTopics.indexOf(inputTopic) !== -1) {
duplicateTopic = true;
}
});
}
if (duplicateTopic) {
this.set('duplicate_message', 'Apache Kafka input and output topics must be different!');
this.set('duplicate', true);
document.getElementById('inputTopics').focus();
}
else {
newLambdaInstance.set('kafkaInputTopics', kafkaInputTopics);
newLambdaInstance.set('kafkaOutputTopics', kafkaOutputTopics);
var self = this;
newLambdaInstance.save().then(function(){
self.transitionToRoute('lambda-instance', newLambdaInstance.get('id')).catch(function() {
self.transitionToRoute('lambda-instances.index').then(function(newRoute) {
newRoute.controller.set('message', 'Your lambda instance creation will begin shortly.');
newRoute.controller.set('request', true);
newRoute.controller.send('start_stop');
});
});
});
}
},
close_alert: function()
{
this.set('duplicate', false);
},
selectFromDropDownList: function(variable, event){
if(variable === "selectedProjectName"){
this.set(variable, event.target.value);
}
else{
this.set(variable, parseInt(event.target.value));
}
this.calculateDropDownListValues();
}
},
calculateDropDownListValues: function(){
var model = this.get('model');
// Get the quotas of the selected project. Each project inside the model has the minimum
// quotas needed for the creation of a Lambda Instance since those that didn't, were removed
// from the router.
var selectedProjectName = this.get('selectedProjectName');
for(var i = 0, n = model.userOkeanosProjects.get('length');i < n;i++){
var currentProject = model.userOkeanosProjects.objectAt(i);
if(currentProject.get('name').localeCompare(selectedProjectName) === 0){
this.set('selectedProjectVMs', currentProject.get('vm'));
this.set('selectedProjectCPUs', currentProject.get('cpu'));
this.set('selectedProjectRAM', {'megaBytes': currentProject.get('ram') / 1048576});
this.set('selectedProjectDisk', {'gigaBytes': currentProject.get('disk') / 1073741824});
break;
}
}
// Set the selected number of slaves to a proper value.
if(this.get('selectedNumberOfSlaves') <= 0){
this.set('selectedNumberOfSlaves', 1);
}
else if(this.get('selectedNumberOfSlaves') >= this.get('selectedProjectVMs')){
this.set('selectedNumberOfSlaves', this.get('selectedProjectVMs') - 1);
}
var selectedNumberOfSlaves = this.get('selectedNumberOfSlaves');
var masterNodeCPUValues = this.get('masterNodeCPUValues');
var slaveNodeCPUValues = this.get('slaveNodeCPUValues');
var masterNodeRAMValues = this.get('masterNodeRAMValues');
var slaveNodeRAMValues = this.get('slaveNodeRAMValues');
var masterNodeDiskValues = this.get('masterNodeDiskValues');
var slaveNodeDiskValues = this.get('slaveNodeDiskValues');
var availableCPUs = this.get('selectedProjectCPUs');
var availableRAM = this.get('selectedProjectRAM')['megaBytes'];
var availableDisk = this.get('selectedProjectDisk')['gigaBytes'];
var leastCPUsForSlaves = selectedNumberOfSlaves * slaveNodeCPUValues.objectAt(0).get('value');
var leastRAMForSlaves = selectedNumberOfSlaves * slaveNodeRAMValues.objectAt(0).get('value');
var leastDiskForSlaves = selectedNumberOfSlaves * slaveNodeDiskValues.objectAt(0).get('value');
var maxCPUsForMaster = availableCPUs - leastCPUsForSlaves;
var maxRAMForMaster = availableRAM - leastRAMForSlaves;
var maxDiskForMaster = availableDisk - leastDiskForSlaves;
var controller = this;
masterNodeCPUValues.forEach(function(item){
item.set('enabled', item.get('value') <= maxCPUsForMaster);
// Check if the selectedMasterNodeCPUs value has become disabled.
if(item.get('value') === controller.get('selectedMasterNodeCPUs') && !item.get('enabled')){
controller.set('selectedMasterNodeCPUs', masterNodeCPUValues[0]['value']);
}
});
if(masterNodeCPUValues.isEvery('enabled', false)){
this.set('masterCPUsSelectDisabled', true);
Ember.run.schedule('render', function task(){
Ember.$("select[name='vcpus_master']")[0].selectedIndex = -1;
});
}
else{
if(this.get('masterCPUsSelectDisabled')){
Ember.run.schedule('render', function task(){
Ember.$("select[name='vcpus_master']")[0].selectedIndex = 0;
});
}
this.set('masterCPUsSelectDisabled', false);
}
masterNodeRAMValues.forEach(function(item){
item.set('enabled', item.get('value') <= maxRAMForMaster);
// Check if the selectedMasterNodeRAM value has become disabled.
if(item.get('value') === controller.get('selectedMasterNodeRAM') && !item.get('enabled')){
controller.set('selectedMasterNodeRAM', masterNodeRAMValues[0]['value']);
}
});
if(masterNodeRAMValues.isEvery('enabled', false)){
this.set('masterRAMSelectDisabled', true);
Ember.run.schedule('render', function task(){
Ember.$("select[name='ram_master']")[0].selectedIndex = -1;
});
}
else{
if(this.get('masterRAMSelectDisabled')){
Ember.run.schedule('render', function task(){
Ember.$("select[name='ram_master']")[0].selectedIndex = 0;
});
}
this.set('masterRAMSelectDisabled', false);
}
masterNodeDiskValues.forEach(function(item){
item.set('enabled', item.get('value') <= maxDiskForMaster);
// Check if the selectedMasterNodeDisk value has become disabled.
if(item.get('value') === controller.get('selectedMasterNodeDisk') && !item.get('enabled')){
controller.set('selectedMasterNodeDisk', masterNodeDiskValues[0]['value']);
}
});
if(masterNodeDiskValues.isEvery('enabled', false)){
this.set('masterDiskSelectDisabled', true);
Ember.run.schedule('render', function task(){
Ember.$("select[name='disk_master']")[0].selectedIndex = -1;
});
}
else{
if(this.get('masterDiskSelectDisabled')){
Ember.run.schedule('render', function task(){
Ember.$("select[name='disk_master']")[0].selectedIndex = 0;
});
}
this.set('masterDiskSelectDisabled', false);
}
var maxCPUsForSlave = (availableCPUs - this.get('selectedMasterNodeCPUs')) / selectedNumberOfSlaves;
var maxRAMForSlave = (availableRAM - this.get('selectedMasterNodeRAM')) / selectedNumberOfSlaves;
var maxDiskForSlave = (availableDisk - this.get('selectedMasterNodeDisk')) / selectedNumberOfSlaves;
slaveNodeCPUValues.forEach(function(item){
item.set('enabled', item.get('value') <= maxCPUsForSlave);
// Check if the selectedSlaveNodeCPUs value has becomed disabled.
if(item.get('value') === controller.get('selectedSlaveNodeCPUs') && !item.get('enabled')){
controller.set('selectedSlaveNodeCPUs', slaveNodeCPUValues[0]['value']);
}
});
if(slaveNodeCPUValues.isEvery('enabled', false)){
this.set('slaveCPUsSelectDisabled', true);
Ember.run.schedule('render', function task(){
Ember.$("select[name='vcpus_slave']")[0].selectedIndex = -1;
});
}
else{
if(this.get('slaveCPUsSelectDisabled')){
Ember.run.schedule('render', function task(){
Ember.$("select[name='vcpus_slave']")[0].selectedIndex = 0;
});
}
this.set('slaveCPUsSelectDisabled', false);
}
slaveNodeRAMValues.forEach(function(item){
item.set('enabled', item.get('value') <= maxRAMForSlave);
// Check if the selectedSlaveNodeRAM value has becomed disabled.
if(item.get('value') === controller.get('selectedSlaveNodeRAM') && !item.get('enabled')){
controller.set('selectedSlaveNodeRAM', slaveNodeRAMValues[0]['value']);
}
});
if(slaveNodeRAMValues.isEvery('enabled', false)){
this.set('slaveRAMSelectDisabled', true);
Ember.run.schedule('render', function task(){
Ember.$("select[name='ram_slave']")[0].selectedIndex = -1;
});
}
else{
if(this.get('slaveRAMSelectDisabled')){
Ember.run.schedule('render', function task(){
Ember.$("select[name='ram_slave']")[0].selectedIndex = 0;
});
}
this.set('slaveRAMSelectDisabled', false);
}
slaveNodeDiskValues.forEach(function(item){
item.set('enabled', item.get('value') <= maxDiskForSlave);
// Check if the selectedSlaveNodeDisk value has become disabled.
if(item.get('value') === controller.get('selectedSlaveNodeDisk') && !item.get('enabled')){
controller.set('selectedSlaveNodeDisk', slaveNodeDiskValues[0]['value']);
}
});
if(slaveNodeDiskValues.isEvery('enabled', false)){
this.set('slaveDiskSelectDisabled', true);
Ember.run.schedule('render', function task(){
Ember.$("select[name='disk_slave']")[0].selectedIndex = -1;
});
}
else{
if(this.get('slaveDiskSelectDisabled')){
Ember.run.schedule('render', function task(){
Ember.$("select[name='disk_slave']")[0].selectedIndex = 0;
});
}
this.set('slaveDiskSelectDisabled', false);
}
this.set('submitButtonDisabled', (
this.get('masterCPUsSelectDisabled') || this.get('masterRAMSelectDisabled') ||
this.get('masterDiskSelectDisabled') || this.get('slaveCPUsSelectDisabled') ||
this.get('slaveRAMSelectDisabled') || this.get('slaveDiskSelectDisabled')
)
);
}
});
......@@ -6,6 +6,7 @@ var UploadController = Ember.Controller.extend({
outOfSpace: false,
userHasEnteredData: false,
submitDisabled: false,
enoughQuotas: false,
actions : {
upload: function() {
......
......@@ -2,7 +2,7 @@ import Ember from "ember";
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model() {
model: function() {
return Ember.RSVP.hash({
newLambdaInstance: this.store.createRecord('create-lambda-instance', {}),
userPublicKeys: this.store.findAll('user-public-key'),
......@@ -11,15 +11,106 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
});
},
afterModel: function(model) {
// After the models are loaded, check each project's quotas. If a least one project
// has enough quotas to create a Lambda Instance, set enoughQuotas to true.
// Delete every project that doesn't have the quotas to create the smallest Lambda
// Instance.
var controller = this.controllerFor('create-lambda-instance');
var minQuotasPerProject = controller.get('minQuotasPerProject');
controller.set('enoughQuotas', false);
for (var i = 0;i < model.userOkeanosProjects.get('length');i++){
if (model.userOkeanosProjects.objectAt(i).get('vm') >= 2 &&
model.userOkeanosProjects.objectAt(i).get('cpu') >= 4 &&
model.userOkeanosProjects.objectAt(i).get('ram') >= 4294967296 &&
model.userOkeanosProjects.objectAt(i).get('disk') >= 21474836480 &&
model.userOkeanosProjects.objectAt(i).get('floating_ip') >= 1 &&
model.userOkeanosProjects.objectAt(i).get('private_network') >= 1) {
this.controllerFor('create-lambda-instance').set('enoughQuotas', true);
if (model.userOkeanosProjects.objectAt(i).get('vm') >= minQuotasPerProject['vms'] &&
model.userOkeanosProjects.objectAt(i).get('cpu') >= minQuotasPerProject['cpus'] &&
model.userOkeanosProjects.objectAt(i).get('ram') >= minQuotasPerProject['ram']['bytes'] &&
model.userOkeanosProjects.objectAt(i).get('disk') >= minQuotasPerProject['disk']['bytes'] &&
model.userOkeanosProjects.objectAt(i).get('floating_ip') >= minQuotasPerProject['floatingIPs'] &&
model.userOkeanosProjects.objectAt(i).get('private_network') >= minQuotasPerProject['privateNetworks']) {
if(!controller.get('enoughQuotas')){
controller.set('enoughQuotas', true);
}
}
else{
model.userOkeanosProjects.objectAt(i).deleteRecord();
}
}
},
setupController: function(controller, model){
this._super(controller, model);
if(model.userOkeanosProjects.get('length') > 0){
var minQuotasPerProject = controller.get('minQuotasPerProject');
var selectedProject = model.userOkeanosProjects.objectAt(0);
controller.set('selectedProjectName', selectedProject.get('name'));
controller.set('selectedProjectVMs', selectedProject.get('vm'));
controller.set('selectedProjectCPUs', selectedProject.get('cpu'));
controller.set('selectedProjectRAM', {'megaBytes': selectedProject.get('ram') / 1048576});
controller.set('selectedProjectDisk', {'gigaBytes': selectedProject.get('disk') / 1073741824});
controller.set('selectedNumberOfSlaves', minQuotasPerProject['vms'] - 1);
var minQuotasPerVM = controller.get('minQuotasPerVM');
var masterNodeCPUValues = controller.get('masterNodeCPUValues');
var slaveNodeCPUValues = controller.get('slaveNodeCPUValues');
var masterNodeRAMValues = controller.get('masterNodeRAMValues');
var slaveNodeRAMValues = controller.get('slaveNodeRAMValues');
var masterNodeDiskValues = controller.get('masterNodeDiskValues');
var slaveNodeDiskValues = controller.get('slaveNodeDiskValues');
var n = model.VMParameterValues.get('length');
for(var i = 0;i < n;i++){
var cpus = model.VMParameterValues.objectAt(i).get('vcpus');
for(var j = 0, m = cpus.get('length');j < m;j++){
if(cpus[j] >= minQuotasPerVM['cpus']){
masterNodeCPUValues.pushObject(Ember.Object.create({'value': parseInt(cpus[j]), 'enabled': true}));
slaveNodeCPUValues.pushObject(Ember.Object.create({'value': parseInt(cpus[j]), 'enabled': true}));
}
}
var ram = model.VMParameterValues.objectAt(i).get('ram');
for(j = 0, m = ram.get('length');j < m;j++){
if(ram[j] >= minQuotasPerVM['ram']){
masterNodeRAMValues.pushObject(Ember.Object.create({'value': parseInt(ram[j]), 'enabled': true}));
slaveNodeRAMValues.pushObject(Ember.Object.create({'value': parseInt(ram[j]), 'enabled': true}));
}
}
var disk = model.VMParameterValues.objectAt(i).get('disk');
for(j = 0, m = disk.get('length');j < m;j++){
if(disk[j] >= minQuotasPerVM['disk']){
masterNodeDiskValues.pushObject(Ember.Object.create({'value': parseInt(disk[j]), 'enabled': true}));
slaveNodeDiskValues.pushObject(Ember.Object.create({'value': parseInt(disk[j]), 'enabled': true}));
}
}
}
var compareFunction = function(a, b){
return a['value'] > b['value'];
};
masterNodeCPUValues.sort(compareFunction);
slaveNodeCPUValues.sort(compareFunction);
masterNodeRAMValues.sort(compareFunction);
slaveNodeRAMValues.sort(compareFunction);
masterNodeDiskValues.sort(compareFunction);
slaveNodeDiskValues.sort(compareFunction);
controller.set('selectedMasterNodeCPUs', masterNodeCPUValues[0]['value']);
controller.set('selectedSlaveNodeCPUs', slaveNodeCPUValues[0]['value']);
controller.set('selectedMasterNodeRAM', masterNodeRAMValues[0]['value']);
controller.set('selectedSlaveNodeRAM', slaveNodeRAMValues[0]['value']);
controller.set('selectedMasterNodeDisk', masterNodeDiskValues[0]['value']);
controller.set('selectedSlaveNodeDisk', slaveNodeDiskValues[0]['value']);
}
}
});
......@@ -17,6 +17,26 @@ var UploadRoute = Ember.Route.extend(AuthenticatedRouteMixin, {
}
},
},
afterModel: function(model) {
// After the models are loaded, check each project's quotas. If a least one project
// has enough quotas to upload a Lambda Application, set enoughQuotas to true.