Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add Sensor DE UI to webpage

  • Loading branch information...
commit f0b44153db220901abc2c348d6938e92bc0632b0 1 parent c0e0579
@oldpatricka oldpatricka authored
View
68 phantomweb/static/css/phantom_domain.css
@@ -1,3 +1,9 @@
+
+#loading
+{
+ height: 23px;
+}
+
#phantom_domain_content
{
display: table;
@@ -10,10 +16,50 @@
height: 25px;
}
+#phantom_domain_list_pane
+{
+ float: left;
+ position: relative;
+ overflow: hidden;
+ width: 12%%;
+ height: 410px;
+ margin: 4px;
+ margin-left: 0px;
+ margin-right: 1px;
+ padding-left: 0px;
+ padding-right: 0px;
+ padding-top: 0px;
+}
+
+#phantom_domain_list_domains
+{
+ height: 400px;
+ overflow: hidden;
+ padding: 4px;
+ margin: -5px -20px -5px -5px;
+}
+
+#phantom_domain_button_add_div
+{
+ padding-top: 0;
+}
+
+#phantom_domain_button_add
+{
+ width: 100%;
+ margin-left: auto;
+ margin-right: auto;
+}
+
#phantom_domain_main_combined_pane
{
float: left;
position: relative;
+ width: 38%;
+}
+
+.phantom_domain_de_pref {
+ display: none;
}
.phantom_domain_section_div
@@ -34,7 +80,7 @@
.phantom_domain_label
{
display: inline-block;
- width: 40%;
+ width: 45%;
}
.phantom_domain_value
@@ -67,7 +113,8 @@
#phantom_domain_details_pane
{
position: relative;
- float: right;
+ float: left;
+ width: 41%;
}
#phantom_domain_details_filter_div
@@ -84,26 +131,21 @@
.phantom_domain_form_pane
{
border: solid;
- border-color: black;
+ border-color: #AAA;
border-width: 1px;
padding: 10px;
- margin: 4px;
height: 400px;
- width: 45%;
- margin-left: 5px;
- margin-right: 5px;
+ margin: 4px;
+ margin-left: 0px;
+ margin-right: 1px;
}
.phantom_domain_control_buttons
{
- margin-left: 75px;
+ margin-left: auto;
+ margin-right: auto;
}
-#phantom_domain_list_domains
-{
- width: 400px;
- height: 200px;
-}
.phantom_domain_combo
{
View
354 phantomweb/static/js/phantom_domain.js
@@ -1,39 +1,78 @@
var g_domain_data = {};
var g_launch_config_names = {};
var g_domain_details = {};
+var g_decision_engines_by_name = {'Sensor': 'sensor', 'Multi Cloud': 'multicloud'};
+var g_decision_engines_by_type = {'sensor': 'Sensor', 'multicloud': 'Multi Cloud'};
+var DEFAULT_DECISION_ENGINE = 'Multi Cloud';
-function phantom_domain_buttons(enabled) {
+$(document).ready(function() {
+
+ $("#phantom_domain_main_combined_pane_inner").hide();
+
+ $("#phantom_domain_de_choice").val(DEFAULT_DECISION_ENGINE)
+ phantom_select_de(DEFAULT_DECISION_ENGINE);
+
+ phantom_domain_load();
+
+ $("body").click(function() {
+ phantom_domain_noncontext_mouse_down();
+ })
+
+ $("#phantom_domain_update_button").click(function() {
+ phantom_domain_update_click();
+ })
+
+ $("#phantom_domain_de_choice").change(function() {
+ phantom_select_de($("#phantom_domain_de_choice").val());
+ });
- var component_array = [
- "#phantom_domain_name_input",
- "#phantom_domain_size_input",
- "#phantom_domain_lc_choice",
- "#phantom_domain_button_start",
- "#phantom_domain_button_resize",
- "#phantom_domain_button_terminate",
- "#phantom_domain_button_list_choices",
- "#phantom_domain_filter_list",
- "#phantom_domain_update_button",
- "#phantom_domain_instance_details",
- "#phantom_domain_list_domains"
- ];
+ $("#phantom_domain_button_add").click(function() {
+ phantom_add_domain_click();
+ });
+
+ $("#phantom_domain_list_domains").change(function() {
+ phantom_domain_select_domain();
+ });
+
+ $("#phantom_domain_list_domains option").click(function() {
+ phantom_domain_select_domain();
+ });
+
+ $("#phantom_domain_button_start").click(function() {
+ phantom_domain_start_click();
+ });
+
+ $("#phantom_domain_button_resize").click(function() {
+ phantom_domain_resize_click();
+ });
+
+ $("#phantom_domain_button_terminate").click(function() {
+ phantom_domain_terminate_click();
+ });
+});
+
+
+function phantom_domain_buttons(enabled) {
if (enabled) {
- for (var comp in component_array) {
- comp = component_array[comp];
- $(comp).removeAttr("disabled", "disabled");
- }
+ $("input, select").removeAttr("disabled");
$('#phantom_domain_loading_image').hide();
}
else {
- for (var comp in component_array) {
- comp = component_array[comp];
- $(comp).attr("disabled", "disabled");
- }
+ $("input, select").attr("disabled", true);
$('#phantom_domain_loading_image').show();
}
}
+function phantom_add_domain_click() {
+ var new_domain_name = prompt("Enter a new domain name:");
+ g_domain_data[new_domain_name] = {};
+ phantom_domain_load_domain_names();
+
+ $("#phantom_domain_list_domains").val(new_domain_name);
+ phantom_domain_select_domain();
+}
+
function phantom_domain_load_lc_names() {
$("#phantom_domain_lc_choice").empty();
@@ -45,12 +84,41 @@ function phantom_domain_load_lc_names() {
}
function phantom_domain_load_domain_names() {
+ var previously_selected_domain = $("#phantom_domain_list_domains").val();
$("#phantom_domain_list_domains").empty();
for(var domain_name in g_domain_data) {
var new_opt = $('<option>', {'name': domain_name, value: domain_name, text: domain_name});
$("#phantom_domain_list_domains").append(new_opt);
}
+
+ $("#phantom_domain_list_domains").val(previously_selected_domain);
+}
+
+function phantom_domain_load_de_names() {
+ $("#phantom_domain_de_choice").empty();
+
+ for(var decision_engine in g_decision_engines_by_name) {
+ var new_opt = $('<option>', {'name': decision_engine, value: decision_engine, text: decision_engine});
+ $("#phantom_domain_de_choice").append(new_opt);
+ }
+}
+
+function phantom_select_de(decision_engine) {
+ var current_de = $("#phantom_domain_de_choice").val();
+
+ if (decision_engine === "Sensor") {
+ $("#phantom_domain_de_choice").val("Sensor");
+ $(".phantom_domain_de_pref").hide().filter("#phantom_domain_sensor_preferences").show();
+ $("#phantom_domain_sensor_preferences").show();
+ }
+ else if (decision_engine === "Multi Cloud") {
+ $("#phantom_domain_de_choice").val("Multi Cloud");
+ $(".phantom_domain_de_pref").hide().filter("#phantom_domain_multicloud_preferences").show();
+ }
+ else {
+ console.log("Don't know de type: " + decision_engine);
+ }
}
function phantom_domain_load_internal() {
@@ -63,6 +131,7 @@ function phantom_domain_load_internal() {
phantom_domain_load_lc_names();
phantom_domain_load_domain_names();
+ phantom_domain_load_de_names();
phantom_domain_buttons(true);
};
@@ -85,23 +154,78 @@ function phantom_domain_load() {
}
}
-
+// TODO: refactor for DRY with resize
function phantom_domain_start_click_internal() {
var url = make_url('api/domain/start');
var lc_name = $("#phantom_domain_lc_choice").val();
- var domain_name = $("#phantom_domain_name_input").val();
+ var domain_name = $("#phantom_domain_name_label").text();
+ var de_name = g_decision_engines_by_name[$("#phantom_domain_de_choice").val()];
+
+ // Multicloud attrs
var vm_count = $("#phantom_domain_size_input").val();
+ // Sensor attrs
+ var metric = $("#phantom_domain_metric_input").val();
+ var cooldown = $("#phantom_domain_cooldown_input").val();
+ var minimum_vms = $("#phantom_domain_minimum_input").val();
+ var maximum_vms = $("#phantom_domain_maximum_input").val();
+ var scale_up_threshold = $("#phantom_domain_scale_up_threshold_input").val();
+ var scale_up_vms = $("#phantom_domain_scale_up_n_vms_input").val();
+ var scale_down_threshold = $("#phantom_domain_scale_down_threshold_input").val();
+ var scale_down_vms = $("#phantom_domain_scale_down_n_vms_input").val();
+
var error_msg = undefined;
- if(lc_name == undefined || lc_name == "" || lc_name == null) {
+ if (lc_name == undefined || lc_name == "" || lc_name == null) {
error_msg = "You must select a launch configuration name";
}
- if(domain_name == undefined || domain_name == "" || domain_name == null) {
+ if (domain_name == undefined || domain_name == "" || domain_name == null) {
error_msg = "You must specify a domain name";
}
- if(vm_count == undefined || vm_count == "" || vm_count == null) {
- error_msg = "You must specify a total number of vms";
+
+ var data = {"name": domain_name, "lc_name": lc_name, "de_name": de_name};
+
+ if (de_name == "multicloud") {
+ if (! vm_count) {
+ error_msg = "You must specify a total number of vms";
+ }
+
+ data["vm_count"] = vm_count;
+ }
+ else if (de_name == "sensor") {
+ if (! metric) {
+ error_msg = "You must specify a metric";
+ }
+ if (! cooldown) {
+ error_msg = "You must specify a cooldown";
+ }
+ if (! minimum_vms) {
+ error_msg = "You must specify a minimum number of vms";
+ }
+ if (! maximum_vms) {
+ error_msg = "You must specify a maximum number of vms";
+ }
+ if (! scale_up_threshold) {
+ error_msg = "You must specify a scale up threshold";
+ }
+ if (! scale_up_vms) {
+ error_msg = "You must specify a number of vms to scale up by";
+ }
+ if (! scale_down_threshold) {
+ error_msg = "You must specify a scale down threshold";
+ }
+ if (! scale_down_vms) {
+ error_msg = "You must specify a number of vms to scale down by";
+ }
+
+ data["sensor_metric"] = metric;
+ data["sensor_cooldown"] = cooldown;
+ data["sensor_minimum_vms"] = minimum_vms;
+ data["sensor_maximum_vms"] = maximum_vms;
+ data["sensor_scale_up_threshold"] = scale_up_threshold;
+ data["sensor_scale_up_vms"] = scale_up_vms;
+ data["sensor_scale_down_threshold"] = scale_down_threshold;
+ data["sensor_scale_down_vms"] = scale_down_vms;
}
if (error_msg != undefined) {
@@ -109,10 +233,12 @@ function phantom_domain_start_click_internal() {
return;
}
- var data = {'name': domain_name, "lc_name": lc_name, "vm_count": vm_count}
-
var success_func = function(obj) {
phantom_domain_load_internal();
+ $("#phantom_domain_start_buttons").hide();
+ $("#phantom_domain_running_buttons").show();
+ $("#phantom_domain_list_domains").val(domain_name);
+ phantom_domain_details_internal();
}
var error_func = function(obj, message) {
@@ -134,38 +260,92 @@ function phantom_domain_start_click() {
}
function phantom_domain_resize_click_internal() {
- var url = make_url('api/domain/resize');
- var domain_name = $("#phantom_domain_name_input").val();
- var new_size = $("#phantom_domain_size_input").val();
+ var url = make_url('api/domain/resize');
+ var lc_name = $("#phantom_domain_lc_choice").val();
+ var domain_name = $("#phantom_domain_name_label").text();
+ var de_name = g_decision_engines_by_name[$("#phantom_domain_de_choice").val()];
- var error_msg = undefined;
+ // Multicloud attrs
+ var vm_count = $("#phantom_domain_size_input").val();
+
+ // Sensor attrs
+ var metric = $("#phantom_domain_metric_input").val();
+ var cooldown = $("#phantom_domain_cooldown_input").val();
+ var minimum_vms = $("#phantom_domain_minimum_input").val();
+ var maximum_vms = $("#phantom_domain_maximum_input").val();
+ var scale_up_threshold = $("#phantom_domain_scale_up_threshold_input").val();
+ var scale_up_vms = $("#phantom_domain_scale_up_n_vms_input").val();
+ var scale_down_threshold = $("#phantom_domain_scale_down_threshold_input").val();
+ var scale_down_vms = $("#phantom_domain_scale_down_n_vms_input").val();
+
+ var error_msg = undefined;
- if(domain_name == undefined || domain_name == "" || domain_name == null) {
+ if (! lc_name) {
+ error_msg = "You must select a launch configuration name";
+ }
+ if (! domain_name) {
error_msg = "You must specify a domain name";
- }
- if(new_size == undefined || new_size == "" || new_size == null) {
- error_msg = "You must specify a new size";
- }
- if (error_msg != undefined) {
- alert(error_msg);
- return;
- }
-
- var data = {'name': domain_name, 'vm_count': new_size}
-
- var success_func = function(obj) {
- $("#phantom_domain_size_input").val("");
- phantom_domain_load_internal();
- }
-
- var error_func = function(obj, message) {
- alert(message);
- phantom_domain_buttons(true);
- }
-
- phantom_domain_buttons(false);
- phantomAjaxPost(url, data, success_func, error_func);
+ }
+ var data = {"name": domain_name, "lc_name": lc_name, "de_name": de_name};
+
+ if (de_name == "multicloud") {
+ if (! vm_count) {
+ error_msg = "You must specify a total number of vms";
+ }
+
+ data["vm_count"] = vm_count;
+ }
+ else if (de_name == "sensor") {
+ if (! metric) {
+ error_msg = "You must specify a metric";
+ }
+ if (! cooldown) {
+ error_msg = "You must specify a cooldown";
+ }
+ if (! minimum_vms) {
+ error_msg = "You must specify a minimum number of vms";
+ }
+ if (! maximum_vms) {
+ error_msg = "You must specify a maximum number of vms";
+ }
+ if (! scale_up_threshold) {
+ error_msg = "You must specify a scale up threshold";
+ }
+ if (! scale_up_vms) {
+ error_msg = "You must specify a number of vms to scale up by";
+ }
+ if (! scale_down_threshold) {
+ error_msg = "You must specify a scale down threshold";
+ }
+ if (! scale_down_vms) {
+ error_msg = "You must specify a number of vms to scale down by";
+ }
+
+ data["sensor_metric"] = metric;
+ data["sensor_cooldown"] = cooldown;
+ data["sensor_minimum_vms"] = minimum_vms;
+ data["sensor_maximum_vms"] = maximum_vms;
+ data["sensor_scale_up_threshold"] = scale_up_threshold;
+ data["sensor_scale_up_vms"] = scale_up_vms;
+ data["sensor_scale_down_threshold"] = scale_down_threshold;
+ data["sensor_scale_down_vms"] = scale_down_vms;
+ }
+
+ var success_func = function(obj) {
+ //("#phantom_domain_size_input").val("");
+ //$("#phantom_domain_list_domains").val(domain_name);
+ phantom_domain_load_internal();
+ //phantom_domain_select_domain();
+ }
+
+ var error_func = function(obj, message) {
+ alert(message);
+ phantom_domain_buttons(true);
+ }
+
+ phantom_domain_buttons(false);
+ phantomAjaxPost(url, data, success_func, error_func);
}
function phantom_domain_resize_click() {
@@ -179,13 +359,13 @@ function phantom_domain_resize_click() {
function phantom_domain_terminate_click_internal() {
var url = make_url('api/domain/terminate');
- var domain_name = $("#phantom_domain_name_input").val();
+ var domain_name = $("#phantom_domain_name_label").text();
var error_msg = undefined;
if(domain_name == undefined || domain_name == "" || domain_name == null) {
error_msg = "You must specify a domain name";
- }
+ }
if (error_msg != undefined) {
alert(error_msg);
return;
@@ -194,10 +374,13 @@ function phantom_domain_terminate_click_internal() {
var data = {'name': domain_name}
var success_func = function(obj) {
- $("#phantom_domain_name_input").val("");
+ delete g_domain_data[domain_name];
+ $("#phantom_domain_name_label").text("");
$("#phantom_domain_lc_choice").val("");
$("#phantom_domain_size_input").val("");
- phantom_domain_load_internal();
+ $("#phantom_domain_list_domains option[name*=" + domain_name + "]").remove();
+ phantom_domain_deselect_domain();
+ phantom_domain_buttons(true);
}
var error_func = function(obj, message) {
@@ -220,14 +403,45 @@ function phantom_domain_terminate_click() {
}
function phantom_domain_select_domain_internal() {
+
var domain_name = $("#phantom_domain_list_domains").val();
+ if (!domain_name) {
+ return;
+ }
+
+ $("#phantom_domain_main_combined_pane_inner").show();
+ $("#phantom_domain_instance_details").empty();
var domain_data = g_domain_data[domain_name];
- $("#phantom_domain_name_input").val(domain_name);
- $("#phantom_domain_size_input").val(domain_data.vm_size);
- $("#phantom_domain_lc_choice").val(domain_data.lc_name);
+ $("#phantom_domain_name_label").text(domain_name);
+
+ if (Object.keys(domain_data).length == 0) {
+ phantom_select_de(DEFAULT_DECISION_ENGINE);
+ $("#phantom_domain_start_buttons").show();
+ $("#phantom_domain_running_buttons").hide();
+ }
+ else {
- phantom_domain_details_internal();
+ $("#phantom_domain_lc_choice").val(domain_data.lc_name);
+ $("#phantom_domain_start_buttons").hide();
+ $("#phantom_domain_running_buttons").show();
+ phantom_select_de(g_decision_engines_by_type[domain_data.de_name]);
+
+ if (domain_data.de_name == "multicloud") {
+ $("#phantom_domain_size_input").val(domain_data.vm_size);
+ }
+ else if (domain_data.de_name == "sensor") {
+ $("#phantom_domain_metric_input").val(domain_data.metric);
+ $("#phantom_domain_cooldown_input").val(domain_data.sensor_cooldown);
+ $("#phantom_domain_minimum_input").val(domain_data.sensor_minimum_vms);
+ $("#phantom_domain_maximum_input").val(domain_data.sensor_maximum_vms);
+ $("#phantom_domain_scale_up_threshold_input").val(domain_data.sensor_scale_up_threshold);
+ $("#phantom_domain_scale_up_n_vms_input").val(domain_data.sensor_scale_up_vms);
+ $("#phantom_domain_scale_down_threshold_input").val(domain_data.sensor_scale_down_threshold);
+ $("#phantom_domain_scale_down_n_vms_input").val(domain_data.sensor_scale_down_vms);
+ }
+ phantom_domain_details_internal();
+ }
}
@@ -240,6 +454,12 @@ function phantom_domain_select_domain() {
}
}
+function phantom_domain_deselect_domain() {
+ $("#phantom_domain_main_combined_pane_inner").show();
+ $("#phantom_domain_instance_details").empty();
+ $("#phantom_domain_main_combined_pane_inner").hide();
+}
+
function phantom_domain_update_click() {
try {
phantom_domain_details_internal();
@@ -312,7 +532,7 @@ function sensor_data_to_string(sensor_data) {
function phantom_domain_details_internal() {
- var domain_name = $("#phantom_domain_list_domains").val();
+ var domain_name = $("#phantom_domain_name_label").text();
var url = make_url("api/domain/details");
var data = {'name': domain_name};
View
112 phantomweb/templates/phantom_domain.html
@@ -14,7 +14,7 @@
<script src="/static/js/phantom_common.js"></script>
<script src="/static/js/phantom_domain.js"></script>
{% endblock %}
-{% block bodytag %}onload="phantom_domain_load();" onclick="phantom_domain_noncontext_mouse_down();"{% endblock %}
+{% block bodytag %}{% endblock %}
{% block nimbus_body %}
<div id="phantom_instance_context_menu_div">
@@ -28,53 +28,91 @@
<div class="phantom_headings">
<label id="phantom_domain_heading_label" >Domains</label>
</div>
- <div>
+ <div id="loading">
<img src="/static/images/loading4.gif" id="phantom_domain_loading_image"/>
</div>
- <div id="phantom_domain_main_combined_pane" class="phantom_domain_form_pane">
- <label class="phantom_area_header">Domain Options</label>
- <div class="phantom_domain_section_div phantom_domain_row">
- <label for="phantom_domain_name_input" class="phantom_domain_label">Domain Name:</label>
- <input type='text' id="phantom_domain_name_input" class="phantom_domain_value"/>
+ <div id="phantom_domain_list_pane" class="phantom_domain_form_pane">
+ <div class="phantom_domain_section_div phantom_domain_row" id="phantom_domain_button_add_div" >
+ <input type="button" id="phantom_domain_button_add" class="phantom_domain_button" value="Add Domain" />
</div>
- <div class="phantom_domain_section_div phantom_domain_row">
- <label for="phantom_domain_size_input" class="phantom_domain_label">Size:</label>
- <input type='text' id="phantom_domain_size_input" class="phantom_domain_value"/>
- </div>
+ <select id="phantom_domain_list_domains" class="phantom_domain_value phantom_domain_combo" size="20" >
+ </select>
+ </div>
- <div class="phantom_domain_section_div phantom_domain_row" >
- <label class="phantom_domain_label" id="phantom_domain_lc_div">Launch Configuration</label>
- <select id="phantom_domain_lc_choice" class="phantom_domain_value phantom_domain_combo">
- </select>
- </div>
+ <div id="phantom_domain_main_combined_pane" class="phantom_domain_form_pane">
+ <div id="phantom_domain_main_combined_pane_inner">
+ <label class="phantom_area_header">Configuration for <span id="phantom_domain_name_label"></span></label>
- <div id="phantom_domain_button_div" class="phantom_domain_row phantom_domain_section_div">
- <table class="phantom_domain_control_buttons">
- <tr>
- <td>
- <input type="button" id="phantom_domain_button_start" class="phantom_domain_button" value="Start" onclick="phantom_domain_start_click()"/>
- </td>
- <td>
- <input type="button" id="phantom_domain_button_resize" class="phantom_domain_button" value="Resize" onclick="phantom_domain_resize_click()"/>
- </td>
- <td>
- <input type="button" id="phantom_domain_button_terminate" class="phantom_domain_button" value="Terminate" onclick="phantom_domain_terminate_click()"/>
- </td>
- </tr>
- </table>
- </div>
+ <div class="phantom_domain_section_div phantom_domain_row" >
+ <label class="phantom_domain_label" id="phantom_domain_lc_div">Launch Configuration</label>
+ <select id="phantom_domain_lc_choice" class="phantom_domain_value phantom_domain_combo">
+ </select>
+ </div>
- <div class="phantom_domain_section_div">
- <select size="5" id="phantom_domain_list_domains" class="phantom_domain_row" onchange="phantom_domain_select_domain()">
- </select>
- </div>
+ <div class="phantom_domain_section_div phantom_domain_row" >
+ <label class="phantom_domain_label" id="phantom_domain_de_div">Decision Engine:</label>
+ <select id="phantom_domain_de_choice" class="phantom_domain_value phantom_domain_combo">
+ </select>
+ </div>
+
+ <div class="phantom_domain_de_pref phantom_domain_section_div phantom_domain_row" id="phantom_domain_multicloud_preferences">
+ <label for="phantom_domain_size_input" class="phantom_domain_label">Size:</label>
+ <input type='text' id="phantom_domain_size_input" class="phantom_domain_value"/>
+ </div>
+ <div class="phantom_domain_de_pref phantom_domain_section_div phantom_domain_row" id="phantom_domain_sensor_preferences">
+ <label for="phantom_domain_metric_input" class="phantom_domain_label">Metric:</label>
+ <input type='text' id="phantom_domain_metric_input" class="phantom_domain_value"/>
+
+ <label for="phantom_domain_cooldown_input" class="phantom_domain_label">Cooldown (s):</label>
+ <input type='text' id="phantom_domain_cooldown_input" class="phantom_domain_value"/>
+
+ <label for="phantom_domain_minimum_input" class="phantom_domain_label">Minimum:</label>
+ <input type='text' id="phantom_domain_minimum_input" class="phantom_domain_value"/>
+
+ <label for="phantom_domain_maximum_input" class="phantom_domain_label">Maximum:</label>
+ <input type='text' id="phantom_domain_maximum_input" class="phantom_domain_value"/>
+
+ <label for="phantom_domain_scale_up_threshold_input" class="phantom_domain_label">Scale Up Threshold:</label>
+ <input type='text' id="phantom_domain_scale_up_threshold_input" class="phantom_domain_value"/>
+
+ <label for="phantom_domain_scale_up_n_vms_input" class="phantom_domain_label">Scale Up By:</label>
+ <input type='text' id="phantom_domain_scale_up_n_vms_input" class="phantom_domain_value"/>
+
+ <label for="phantom_domain_scale_down_threshold_input" class="phantom_domain_label">Scale Down Threshold:</label>
+ <input type='text' id="phantom_domain_scale_down_threshold_input" class="phantom_domain_value"/>
+
+ <label for="phantom_domain_scale_down_n_vms_input" class="phantom_domain_label">Scale Down By:</label>
+ <input type='text' id="phantom_domain_scale_down_n_vms_input" class="phantom_domain_value"/>
+ </div>
+
+
+ <div id="phantom_domain_button_div" class="phantom_domain_row phantom_domain_section_div">
+ <table class="phantom_domain_control_buttons" id="phantom_domain_start_buttons">
+ <tr>
+ <td>
+ <input type="button" id="phantom_domain_button_start" class="phantom_domain_button" value="Start"/>
+ </td>
+ </tr>
+ </table>
+ <table class="phantom_domain_control_buttons" id="phantom_domain_running_buttons">
+ <tr>
+ <td>
+ <input type="button" id="phantom_domain_button_resize" class="phantom_domain_button" value="Update"/>
+ </td>
+ <td>
+ <input type="button" id="phantom_domain_button_terminate" class="phantom_domain_button" value="Terminate"/>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
</div>
<div id="phantom_domain_details_pane" class="phantom_domain_form_pane">
- <label id="phantom_domain_details_name" class="phantom_area_header">Domain details.</label>
+ <label id="phantom_domain_details_name" class="phantom_area_header">Details</label>
<div id="phantom_domain_details_filter_div">
<label id="phantom_domain_filter_list_label">Show:</label>
<select name="phantom_domain_filter_list" id="phantom_domain_filter_list">
@@ -86,7 +124,7 @@
<option>TERMINATING</option>
<option>FAILED</option>
</select>
- <input type="button" id="phantom_domain_update_button" class="phantom_domain_button" value="Update" onclick="phantom_domain_update_click()"/>
+ <input type="button" id="phantom_domain_update_button" class="phantom_domain_button" value="Refresh"/>
</div>
<div id="phantom_domain_details_list_div">
<ul id="phantom_domain_instance_details">
View
25 phantomweb/util.py
@@ -114,6 +114,7 @@ class UserObjectMySQL(UserObject):
def __init__(self, username):
+ self.username = username
phantom_info_objects = PhantomInfoDB.objects.all()
if not phantom_info_objects:
raise PhantomWebException('The service is mis-configured. Please contact your sysadmin')
@@ -128,9 +129,12 @@ def __init__(self, username):
self._user_dbobject = self._authz.get_user_object_by_display_name(username)
if not self._user_dbobject:
raise PhantomWebException('The user %s is not associated with cloud user database. Please contact your sysadmin' % (username))
+ self.access_key = self._user_dbobject.access_key
ssl = self.rabbit_info.rabbitssl
self._dashi_conn = DashiCeiConnection(self.rabbit_info.rabbithost, self.rabbit_info.rabbituser, self.rabbit_info.rabbitpassword, exchange=self.rabbit_info.rabbitexchange, timeout=60, port=self.rabbit_info.rabbitport, ssl=ssl)
+ self.epum = EPUMClient(self._dashi_conn)
+ self.dtrs = DTRSClient(self._dashi_conn)
self._load_clouds()
@@ -139,14 +143,29 @@ def close(self):
self._authz.close()
def has_phantom_data(self):
- return True
+ return True
def describe_domain(self, username, domain):
# TODO: this should eventually be part of the REST API
- epum_client = EPUMClient(self._dashi_conn)
- describe = epum_client.describe_domain(domain, caller=username)
+ describe = self.epum.describe_domain(domain, caller=username)
return describe
+ def get_all_groups(self):
+ domain_names = self.epum.list_domains(caller=self.access_key)
+ domains = []
+ for domain in domain_names:
+ domain_description = self.epum.describe_domain(domain, caller=self.access_key)
+ domains.append(domain_description)
+ return domains
+
+ def get_all_lcs(self):
+ dt_names = self.dtrs.list_dts(self.access_key)
+ dts = []
+ for dt_name in dt_names:
+ dt = self.dtrs.describe_dt(self.access_key, dt_name)
+ dts.append(dt)
+ return dts
+
def load_clouds(self):
self._load_clouds()
View
234 phantomweb/workload.py
@@ -18,6 +18,11 @@
# at some point this should come from some sort of DB
g_instance_types = ["m1.small", "m1.large", "m1.xlarge"]
+g_engine_to_phantom_de_map = {
+ "epu.decisionengine.impls.phantom_multi_site_overflow.PhantomMultiSiteOverflowEngine": "multicloud",
+ "epu.decisionengine.impls.sensor.SensorEngine": "sensor",
+ }
+
PHANTOM_REGION = 'phantom'
#
@@ -74,6 +79,35 @@ def _get_all_domains(phantom_con):
return return_asgs
+def _get_all_domains_dashi(userobj):
+
+ asgs = userobj.get_all_groups()
+
+ return_asgs = {}
+ for a in asgs:
+ engine_conf = a.get('config', {}).get('engine_conf', {})
+ engine_class = a.get('config', {}).get('general', {}).get('engine_class')
+
+ ent = {}
+ ent['name'] = a['name']
+ ent['de_name'] = g_engine_to_phantom_de_map.get(engine_class)
+ ent['vm_size'] = engine_conf.get('domain_desired_size')
+
+ ent['lc_name'] = engine_conf.get('dtname')
+ ent['metric'] = engine_conf.get('metric')
+ ent['sensor_cooldown'] = engine_conf.get('cooldown_period')
+ ent['sensor_minimum_vms'] = engine_conf.get('minimum_vms')
+ ent['sensor_maximum_vms'] = engine_conf.get('maximum_vms')
+ ent['sensor_scale_up_threshold'] = engine_conf.get('scale_up_threshold')
+ ent['sensor_scale_up_vms'] = engine_conf.get('scale_up_n_vms')
+ ent['sensor_scale_down_threshold'] = engine_conf.get('scale_down_threshold')
+ ent['sensor_scale_down_vms'] = engine_conf.get('scale_down_n_vms')
+
+ return_asgs[a['name']] = ent
+
+ return return_asgs
+
+
@LogEntryDecorator
def _get_phantom_con(userobj):
url = userobj.phantom_info.phantom_url
@@ -85,8 +119,57 @@ def _get_phantom_con(userobj):
con.host = uparts.hostname
return con
+def sensor_tags_from_de_params(phantom_con, domain_name, de_params):
+
+ policy_name_key = 'PHANTOM_DEFINITION'
+ policy_name = 'sensor_engine'
+ policy_tag = Tag(connection=phantom_con, key=policy_name_key, value=policy_name, resource_id=domain_name)
+
+ metric_key = 'metric'
+ metric = de_params.get('sensor_metric')
+
+ cooldown_key = 'cooldown_period'
+ cooldown = de_params.get('sensor_cooldown')
+ scale_up_threshold_key = 'scale_up_threshold'
+ scale_up_threshold = de_params.get('sensor_scale_up_threshold')
+ scale_up_vms_key = 'scale_up_n_vms'
+ scale_up_vms = de_params.get('sensor_scale_up_vms')
+ scale_down_threshold_key = 'scale_down_threshold'
+ scale_down_threshold = de_params.get('sensor_scale_down_threshold')
+ scale_down_vms_key = 'scale_down_n_vms'
+ scale_down_vms = de_params.get('sensor_scale_down_vms')
+
+ # TODO: This is hardcoded for this sync, should be exposed in the UI
+ sample_function_key = 'sample_function'
+ sample_function = 'Average'
+ sensor_type_key = 'sensor_type'
+ sensor_type = 'cloudwatch'
+
+ metric_tag = Tag(connection=phantom_con, key=metric_key, value=metric, resource_id=domain_name)
+ sample_function_tag = Tag(connection=phantom_con, key=sample_function_key, value=sample_function, resource_id=domain_name)
+ sensor_type_tag = Tag(connection=phantom_con, key=sensor_type_key, value=sensor_type, resource_id=domain_name)
+ cooldown_tag = Tag(connection=phantom_con, key=cooldown_key, value=cooldown, resource_id=domain_name)
+ scale_up_threshold_tag = Tag(connection=phantom_con, key=scale_up_threshold_key, value=scale_up_threshold, resource_id=domain_name)
+ scale_up_vms_tag = Tag(connection=phantom_con, key=scale_up_vms_key, value=scale_up_vms, resource_id=domain_name)
+ scale_down_threshold_tag = Tag(connection=phantom_con, key=scale_down_threshold_key, value=scale_down_threshold, resource_id=domain_name)
+ scale_down_vms_tag = Tag(connection=phantom_con, key=scale_down_vms_key, value=scale_down_vms, resource_id=domain_name)
+
+ tags = []
+ tags.append(policy_tag)
+ tags.append(metric_tag)
+ tags.append(sample_function_tag)
+ tags.append(sensor_type_tag)
+ tags.append(cooldown_tag)
+ tags.append(scale_up_threshold_tag)
+ tags.append(scale_up_vms_tag)
+ tags.append(scale_down_threshold_tag)
+ tags.append(scale_down_vms_tag)
+
+ return tags
+
+
@LogEntryDecorator
-def _start_domain(phantom_con, domain_name, lc_name, vm_count, host_list_str, a_cloudname):
+def _start_domain(phantom_con, domain_name, lc_name, de_name, de_params, host_list_str, a_cloudname):
shoe_horn = "%s@%s" % (lc_name, a_cloudname)
try:
@@ -98,31 +181,50 @@ def _start_domain(phantom_con, domain_name, lc_name, vm_count, host_list_str, a_
lc = lc[0]
- policy_name_key = 'PHANTOM_DEFINITION'
- policy_name = 'error_overflow_n_preserving'
- ordered_clouds_key = 'clouds'
- n_preserve_key = 'n_preserve'
- n_preserve = vm_count
+ tags = []
- policy_tag = Tag(connection=phantom_con, key=policy_name_key, value=policy_name, resource_id=domain_name)
- clouds_tag = Tag(connection=phantom_con, key=ordered_clouds_key, value=host_list_str, resource_id=domain_name)
- npreserve_tag = Tag(connection=phantom_con, key=n_preserve_key, value=n_preserve, resource_id=domain_name)
+ if de_name == 'multicloud':
+ policy_name_key = 'PHANTOM_DEFINITION'
+ policy_name = 'error_overflow_n_preserving'
+ ordered_clouds_key = 'clouds'
+ n_preserve_key = 'n_preserve'
+ n_preserve = de_params.get('vm_count')
- # TODO: This is hardcoded for this sync, should be exposed in the UI
- metric_key = 'metric'
- metric = 'CPUUtilization'
- sample_function_key = 'sample_function'
- sample_function = 'Average'
- sensor_type_key = 'sensor_type'
- sensor_type = 'cloudwatch'
+ policy_tag = Tag(connection=phantom_con, key=policy_name_key, value=policy_name, resource_id=domain_name)
+ clouds_tag = Tag(connection=phantom_con, key=ordered_clouds_key, value=host_list_str, resource_id=domain_name)
+ npreserve_tag = Tag(connection=phantom_con, key=n_preserve_key, value=n_preserve, resource_id=domain_name)
- metric_tag = Tag(connection=phantom_con, key=metric_key, value=metric, resource_id=domain_name)
- sample_function_tag = Tag(connection=phantom_con, key=sample_function_key, value=sample_function, resource_id=domain_name)
- sensor_type_tag = Tag(connection=phantom_con, key=sensor_type_key, value=sensor_type, resource_id=domain_name)
+ tags.append(policy_tag)
+ tags.append(clouds_tag)
+ tags.append(npreserve_tag)
+
+ min_size = de_params.get('vm_count')
+ max_size = de_params.get('vm_count')
+
+ # TODO: This is hardcoded for this sync, should be exposed in the UI
+ metric_key = 'metric'
+ metric = 'CPUUtilization'
+ sample_function_key = 'sample_function'
+ sample_function = 'Average'
+ sensor_type_key = 'sensor_type'
+ sensor_type = 'cloudwatch'
+
+ metric_tag = Tag(connection=phantom_con, key=metric_key, value=metric, resource_id=domain_name)
+ sample_function_tag = Tag(connection=phantom_con, key=sample_function_key, value=sample_function, resource_id=domain_name)
+ sensor_type_tag = Tag(connection=phantom_con, key=sensor_type_key, value=sensor_type, resource_id=domain_name)
- tags = [policy_tag, clouds_tag, npreserve_tag, metric_tag, sample_function_tag, sensor_type_tag]
+ tags.append(metric_tag)
+ tags.append(sample_function_tag)
+ tags.append(sensor_type_tag)
- asg = boto.ec2.autoscale.group.AutoScalingGroup(launch_config=lc, connection=phantom_con, group_name=domain_name, availability_zones=["us-east-1"], min_size=vm_count, max_size=vm_count, tags=tags)
+ elif de_name == 'sensor':
+
+ min_size = de_params.get('sensor_minimum_vms')
+ max_size = de_params.get('sensor_maximum_vms')
+
+ tags = tags + sensor_tags_from_de_params(phantom_con, domain_name, de_params)
+
+ asg = boto.ec2.autoscale.group.AutoScalingGroup(launch_config=lc, connection=phantom_con, group_name=domain_name, availability_zones=["us-east-1"], min_size=min_size, max_size=max_size, tags=tags)
phantom_con.create_auto_scaling_group(asg)
@PhantomWebDecorator
@@ -439,9 +541,9 @@ def phantom_lc_delete(request_params, userobj):
@PhantomWebDecorator
@LogEntryDecorator
def phantom_domain_load(request_params, userobj):
- phantom_con = _get_phantom_con(userobj)
- domains = _get_all_domains(phantom_con)
+ phantom_con = _get_phantom_con(userobj)
+ domains = _get_all_domains_dashi(userobj)
all_lc_dict = _get_all_launch_configurations(phantom_con, userobj._user_dbobject.access_key)
lc_names = []
@@ -458,14 +560,40 @@ def phantom_domain_load(request_params, userobj):
@PhantomWebDecorator
@LogEntryDecorator
def phantom_domain_start(request_params, userobj):
- params = ['name', "lc_name", "vm_count", ]
- for p in params:
+ sensor_params = ["sensor_metric", "sensor_cooldown", "sensor_minimum_vms",
+ "sensor_maximum_vms", "sensor_scale_up_threshold", "sensor_scale_up_vms",
+ "sensor_scale_down_threshold", "sensor_scale_down_vms"]
+ multicloud_params = ["vm_count",]
+ mandatory_params = ['name', "lc_name", "de_name"]
+ for p in mandatory_params:
if p not in request_params:
raise PhantomWebException('Missing parameter %s' % (p))
domain_name = request_params["name"]
lc_name = request_params["lc_name"]
- vm_count = request_params["vm_count"]
-
+ de_name = request_params["de_name"]
+
+ de_params = {}
+ if de_name == "sensor":
+ for p in sensor_params:
+ if p not in request_params:
+ raise PhantomWebException('Missing parameter %s' % (p))
+
+ de_params["sensor_metric"] = request_params["sensor_metric"]
+ de_params["sensor_cooldown"] = request_params["sensor_cooldown"]
+ de_params["sensor_minimum_vms"] = request_params["sensor_minimum_vms"]
+ de_params["sensor_maximum_vms"] = request_params["sensor_maximum_vms"]
+ de_params["sensor_scale_up_threshold"] = request_params["sensor_scale_up_threshold"]
+ de_params["sensor_scale_up_vms"] = request_params["sensor_scale_up_vms"]
+ de_params["sensor_scale_down_threshold"] = request_params["sensor_scale_down_threshold"]
+ de_params["sensor_scale_down_vms"] = request_params["sensor_scale_down_vms"]
+
+ elif de_name == "multicloud":
+ for p in multicloud_params:
+ if p not in request_params:
+ g_general_log.debug("%s not in %s" % (p, request_params))
+ raise PhantomWebException('Missing parameter %s' % (p))
+
+ de_params["vm_count"] = request_params["vm_count"]
lc_db_object = LaunchConfigurationDB.objects.filter(name=lc_name, username=userobj._user_dbobject.access_key)
if not lc_db_object or len(lc_db_object) < 1:
@@ -487,7 +615,7 @@ def phantom_domain_start(request_params, userobj):
phantom_con = _get_phantom_con(userobj)
- _start_domain(phantom_con, domain_name, lc_name, vm_count, ordered_hosts, a_cloudname)
+ _start_domain(phantom_con, domain_name, lc_name, de_name, de_params, ordered_hosts, a_cloudname)
response_dict = {}
return response_dict
@@ -495,24 +623,64 @@ def phantom_domain_start(request_params, userobj):
@PhantomWebDecorator
@LogEntryDecorator
def phantom_domain_resize(request_params, userobj):
- params = ['name', "vm_count"]
- for p in params:
+ sensor_params = ["sensor_metric", "sensor_cooldown", "sensor_minimum_vms",
+ "sensor_maximum_vms", "sensor_scale_up_threshold", "sensor_scale_up_vms",
+ "sensor_scale_down_threshold", "sensor_scale_down_vms"]
+ multicloud_params = ["vm_count",]
+ mandatory_params = ['name', "de_name"]
+ for p in mandatory_params:
if p not in request_params:
raise PhantomWebException('Missing parameter %s' % (p))
+ domain_name = request_params["name"]
+ de_name = request_params["de_name"]
+
+ de_params = {}
+ if de_name == "sensor":
+ g_general_log.debug("PDA: updating sensor")
+ for p in sensor_params:
+ if p not in request_params:
+ raise PhantomWebException('Missing parameter %s' % (p))
+
+ de_params["sensor_metric"] = request_params["sensor_metric"]
+ de_params["sensor_cooldown"] = request_params["sensor_cooldown"]
+ de_params["sensor_minimum_vms"] = request_params["sensor_minimum_vms"]
+ de_params["sensor_maximum_vms"] = request_params["sensor_maximum_vms"]
+ de_params["sensor_scale_up_threshold"] = request_params["sensor_scale_up_threshold"]
+ de_params["sensor_scale_up_vms"] = request_params["sensor_scale_up_vms"]
+ de_params["sensor_scale_down_threshold"] = request_params["sensor_scale_down_threshold"]
+ de_params["sensor_scale_down_vms"] = request_params["sensor_scale_down_vms"]
+
+ elif de_name == "multicloud":
+ g_general_log.debug("PDA: updating multicloud")
+ for p in multicloud_params:
+ if p not in request_params:
+ g_general_log.debug("%s not in %s" % (p, request_params))
+ raise PhantomWebException('Missing parameter %s' % (p))
+
+ de_params["vm_count"] = request_params["vm_count"]
+
domain_name = request_params["name"]
- new_size = request_params["vm_count"]
+ new_size = request_params.get("vm_count")
try:
phantom_con = _get_phantom_con(userobj)
+
+ tags = sensor_tags_from_de_params(phantom_con, domain_name, de_params)
+ phantom_con.create_or_update_tags(tags)
+
asg = phantom_con.get_all_groups(names=[domain_name,])
if not asg:
raise PhantomWebException("domain %s not found" % (domain_name))
asg = asg[0]
- asg.set_capacity(new_size)
+
+ if new_size is not None:
+ asg.set_capacity(new_size)
+
except PhantomWebException:
raise
except Exception, ex:
+ g_general_log.exception("Error in resize")
raise PhantomWebException(str(ex))
response_dict = {}
return response_dict
@@ -594,8 +762,8 @@ def phantom_domain_details(request_params, userobj):
# TODO: this should support multiple metrics in the next sync
metrics = userobj.describe_domain(userobj._user_dbobject.access_key, domain_name)
instance_metrics = {}
- metric = metrics.get('config', {}).get('engine_conf', {}).get('metric')
if metrics is not None:
+ metric = metrics.get('config', {}).get('engine_conf', {}).get('metric')
for instance in metrics.get('instances', []):
instance_metrics[instance.get('iaas_id')] = metric, instance.get('sensor_data')
Please sign in to comment.
Something went wrong with that request. Please try again.