Merge branch 'master' into Health-Check-UI
Conflicts:
ui/css/cloudstack3.css
diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index 7381715..7410568 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -1763,6 +1763,37 @@
}
.detail-group .main-groups table td.value .view-all:hover {
+ background-position: 100% -431px;
+ }
+
+/*List-view: subselect dropdown*/
+.list-view .subselect {
+ width: 116px;
+ display: block;
+ float: left;
+ background: url(../images/bg-gradients.png) 0px -42px;
+ padding: 0;
+ margin: 8px 0 1px 7px;
+ clear: both;
+ border: 1px solid #A8A7A7;
+ /*+border-radius:4px;*/
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ -khtml-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.list-view .subselect span {
+ margin: 4px 0 0 12px;
+}
+
+.list-view .subselect select {
+ width: 85%;
+ margin: 5px 0 4px;
+ font-size: 10px;
+}
+
+.detail-group .main-groups table td.value .view-all:hover {
background-position: 100% -431px;
}
@@ -7743,9 +7774,27 @@
margin: 0 22px 0 0;
}
+ /** Fix long table overflow*/
+.detail-view .multi-edit {
+ width: 100%;
+}
+
+.detail-view .multi-edit table {
+ width: 97%;
+ max-width: inherit;
+}
+
+.detail-view .multi-edit table tr th,
+.detail-view .multi-edit table tr td {
+ width: 87px !important;
+ min-width: 87px !important;
+ max-width: 87px !important;
+}
+
+
/** Header fields*/
.multi-edit .header-fields {
- position: relative;
+ position: relative;
/*+placement:shift 14px 11px;*/
position: relative;
left: 14px;
@@ -10561,6 +10610,33 @@
width: 65px;
}
+/*HEALTH CHECK */
+
+div.ui-dialog div.health-check div.health-check-description {
+color: #808080;
+}
+
+div.ui-dialog div.health-check div.form-container form div.form-item {
+width:58% margin-left:116px; margin-top:-16px; margin-bottom:30px; }
+
+div.ui-dialog div.health-check div.health-check-config-title {
+float:left;
+color: #808080;
+font-size:17px;
+margin-left:15px;
+}
+
+div.ui-dialog div.health-check div.health-check-advanced-title {
+float:left;
+color: #808080;
+font-size:17px;
+margin-left:15px;
+margin-top:-70px;
+}
+
+
+
+
/*Autoscaler*/
.ui-dialog div.autoscaler {
overflow: auto;
diff --git a/ui/index.jsp b/ui/index.jsp
index d1e6bfa..3b8f378 100644
--- a/ui/index.jsp
+++ b/ui/index.jsp
@@ -1645,6 +1645,7 @@
<script type="text/javascript" src="scripts/cloudStack.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/lbStickyPolicy.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/ui-custom/autoscaler.js?t=<%=now%>"></script>
+ <script type="text/javascript" src="scripts/ui-custom/healthCheck.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/autoscaler.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/ui-custom/zoneChart.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/ui-custom/dashboard.js?t=<%=now%>"></script>
diff --git a/ui/scripts/network.js b/ui/scripts/network.js
index 15ead8c..65be302 100755
--- a/ui/scripts/network.js
+++ b/ui/scripts/network.js
@@ -2609,6 +2609,17 @@
action: cloudStack.lbStickyPolicy.dialog()
}
},
+
+ 'health-check':{
+ label:'Health Check',
+ custom:{
+ requireValidation: true ,
+ buttonLabel:'Configure',
+ action:cloudStack.uiCustom.healthCheck()
+
+ }
+ },
+
'autoScale': {
label: 'AutoScale',
custom: {
diff --git a/ui/scripts/ui-custom/healthCheck.js b/ui/scripts/ui-custom/healthCheck.js
new file mode 100644
index 0000000..c4c84e5
--- /dev/null
+++ b/ui/scripts/ui-custom/healthCheck.js
@@ -0,0 +1,342 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+(function($, cloudStack) {
+
+ cloudStack.uiCustom.healthCheck = function(args) {
+
+ // Place outer args here as local variables
+ // i.e, -- var dataProvider = args.dataProvider
+
+ return function(args){
+ if(args.context.multiRules == undefined) { //LB rule is not created yet
+ cloudStack.dialog.notice({ message: _l('Health Check can only be configured on a created LB rule') });
+ return;
+ }
+
+ var formData = args.formData;
+ var forms = $.extend(true, {}, args.forms);
+ var topFieldForm, bottomFieldForm , $topFieldForm , $bottomFieldForm;
+ var topfields = forms.topFields;
+
+ var $healthCheckDesc = $('<div>Your load balancer will automatically perform health checks on your cloudstack instances and only route traffic to instances that pass the health check </div>').addClass('health-check-description');
+ var $healthCheckConfigTitle = $('<div><br><br>Configuration Options :</div>').addClass('health-check-config-title');
+ var $healthCheckAdvancedTitle = $('<div><br><br> Advanced Options : </div>').addClass('health-check-advanced-title');
+
+ var $healthCheckDialog = $('<div>').addClass('health-check');
+ $healthCheckDialog.append($healthCheckDesc);
+ $healthCheckDialog.append($healthCheckConfigTitle);
+ var $loadingOnDialog = $('<div>').addClass('loading-overlay');
+
+ var policyObj = null;
+ var pingpath1 = '/';
+ var responsetimeout1 = '2';
+ var healthinterval1 = '5';
+ var healthythreshold1 = '2';
+ var unhealthythreshold1 = '1';
+
+ $.ajax({
+ url: createURL('listLBHealthCheckPolicies'),
+ data: {
+ lbruleid: args.context.multiRules[0].id
+ },
+ async: false,
+ success: function(json) {
+ if(json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0] != undefined) {
+ policyObj = json.listlbhealthcheckpoliciesresponse.healthcheckpolicies[0].healthcheckpolicy[0];
+ pingpath1 = policyObj.pingpath; //API bug: API doesn't return it
+ responsetimeout1 = policyObj.responsetime;
+ healthinterval1 = policyObj.healthcheckinterval;
+ healthythreshold1 = policyObj.healthcheckthresshold;
+ unhealthythreshold1 = policyObj.unhealthcheckthresshold;
+ }
+ }
+ });
+
+ topFieldForm = cloudStack.dialog.createForm({
+ context: args.context,
+ noDialog: true, // Don't render a dialog, just return $formContainer
+ form: {
+ title: '',
+ fields:{
+ pingpath: {label: 'Ping Path', docID:'helpAccountUsername' , validation: {required: false}, defaultValue: pingpath1}
+ }
+ }
+ });
+
+ $topFieldForm = topFieldForm.$formContainer;
+ $topFieldForm.appendTo($healthCheckDialog);
+
+ $healthCheckDialog.append($healthCheckAdvancedTitle);
+
+ bottomFieldForm = cloudStack.dialog.createForm ({
+ context:args.context,
+ noDialog:true,
+ form:{
+ title:'',
+ fields:{
+ responsetimeout: {label: 'Response Timeout (in sec)' , validation:{required:false}, defaultValue: responsetimeout1},
+ healthinterval: {label: 'Health Check Interval (in sec)', validation:{required:false}, defaultValue: healthinterval1},
+ healthythreshold: {label: 'Healthy Threshold', validation: {required:false}, defaultValue: healthythreshold1},
+ unhealthythreshold: {label: 'Unhealthy Threshold' , validation: { required:false}, defaultValue: unhealthythreshold1}
+ }
+ }
+ });
+
+ $bottomFieldForm = bottomFieldForm.$formContainer;
+ $bottomFieldForm.appendTo($healthCheckDialog);
+
+
+ var buttons = [
+ {
+ text: _l('label.cancel'),
+ 'class': 'cancel',
+ click: function() {
+ $healthCheckDialog.dialog('destroy');
+ $('.overlay').remove();
+ }
+ }
+ ];
+
+ if(policyObj == null) { //policy is not created yet
+ buttons.push(
+ {
+ text: _l('Create'),
+ 'class': 'ok',
+ click: function() {
+ $loadingOnDialog.appendTo($healthCheckDialog);
+ var formData = cloudStack.serializeForm($healthCheckDialog.find('form'));
+ var data = {
+ lbruleid: args.context.multiRules[0].id,
+ pingpath: formData.pingpath,
+ responsetimeout: formData.responsetimeout,
+ intervaltime: formData.healthinterval,
+ healthythreshold: formData.healthythreshold,
+ unhealthythreshold: formData.unhealthythreshold
+ };
+
+ $.ajax({
+ url: createURL('createLBHealthCheckPolicy'),
+ data: data,
+ success: function(json) {
+ var jobId = json.createlbhealthcheckpolicyresponse.jobid;
+ var createLBHealthCheckPolicyIntervalId = setInterval(function(){
+ $.ajax({
+ url: createURL('queryAsyncJobResult'),
+ data: {
+ jobid: jobId
+ },
+ success: function(json) {
+ var result = json.queryasyncjobresultresponse;
+ if (result.jobstatus == 0) {
+ return; //Job has not completed
+ }
+ else {
+ clearInterval(createLBHealthCheckPolicyIntervalId);
+
+ if (result.jobstatus == 1) {
+ cloudStack.dialog.notice({ message: _l('Health Check Policy has been created') });
+ $loadingOnDialog.remove();
+ $healthCheckDialog.dialog('destroy');
+ $('.overlay').remove();
+ }
+ else if (result.jobstatus == 2) {
+ cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });
+ $loadingOnDialog.remove();
+ $healthCheckDialog.dialog('destroy');
+ $('.overlay').remove();
+ }
+ }
+ }
+ });
+ }, g_queryAsyncJobResultInterval);
+ }
+ });
+ }
+ }
+ );
+ }
+ else { //policy exists already
+ buttons.push(
+ //Update Button (begin) - call delete API first, then create API
+ {
+ text: _l('Update'),
+ 'class': 'ok',
+ click: function() {
+ $loadingOnDialog.appendTo($healthCheckDialog);
+
+ $.ajax({
+ url: createURL('deleteLBHealthCheckPolicy'),
+ data: {
+ id : policyObj.id
+ },
+ success: function(json) {
+ var jobId = json.deletelbhealthcheckpolicyresponse.jobid;
+ var deleteLBHealthCheckPolicyIntervalId = setInterval(function(){
+ $.ajax({
+ url: createURL('queryAsyncJobResult'),
+ data: {
+ jobid: jobId
+ },
+ success: function(json) {
+ var result = json.queryasyncjobresultresponse;
+ if (result.jobstatus == 0) {
+ return; //Job has not completed
+ }
+ else {
+ clearInterval(deleteLBHealthCheckPolicyIntervalId);
+
+ if (result.jobstatus == 1) {
+ var formData = cloudStack.serializeForm($healthCheckDialog.find('form'));
+ var data = {
+ lbruleid: args.context.multiRules[0].id,
+ pingpath: formData.pingpath,
+ responsetimeout: formData.responsetimeout,
+ intervaltime: formData.healthinterval,
+ healthythreshold: formData.healthythreshold,
+ unhealthythreshold: formData.unhealthythreshold
+ };
+
+ $.ajax({
+ url: createURL('createLBHealthCheckPolicy'),
+ data: data,
+ success: function(json) {
+ var jobId = json.createlbhealthcheckpolicyresponse.jobid;
+ var createLBHealthCheckPolicyIntervalId = setInterval(function(){
+ $.ajax({
+ url: createURL('queryAsyncJobResult'),
+ data: {
+ jobid: jobId
+ },
+ success: function(json) {
+ var result = json.queryasyncjobresultresponse;
+ if (result.jobstatus == 0) {
+ return; //Job has not completed
+ }
+ else {
+ clearInterval(createLBHealthCheckPolicyIntervalId);
+
+ if (result.jobstatus == 1) {
+ cloudStack.dialog.notice({ message: _l('Health Check Policy has been updated') });
+ $loadingOnDialog.remove();
+ $healthCheckDialog.dialog('destroy');
+ $('.overlay').remove();
+ }
+ else if (result.jobstatus == 2) {
+ cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });
+ $loadingOnDialog.remove();
+ $healthCheckDialog.dialog('destroy');
+ $('.overlay').remove();
+ }
+ }
+ }
+ });
+ }, g_queryAsyncJobResultInterval);
+ }
+ });
+ }
+ else if (result.jobstatus == 2) {
+ cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });
+ $loadingOnDialog.remove();
+ $healthCheckDialog.dialog('destroy');
+ $('.overlay').remove();
+ }
+ }
+ }
+ });
+ }, g_queryAsyncJobResultInterval);
+ }
+ });
+ }
+ }
+ //Update Button (end)
+ ,
+ //Delete Button (begin) - call delete API
+ {
+ text: _l('Delete'),
+ 'class': 'delete',
+ click: function() {
+ $loadingOnDialog.appendTo($healthCheckDialog);
+
+ $.ajax({
+ url: createURL('deleteLBHealthCheckPolicy'),
+ data: {
+ id : policyObj.id
+ },
+ success: function(json) {
+ var jobId = json.deletelbhealthcheckpolicyresponse.jobid;
+ var deleteLBHealthCheckPolicyIntervalId = setInterval(function(){
+ $.ajax({
+ url: createURL('queryAsyncJobResult'),
+ data: {
+ jobid: jobId
+ },
+ success: function(json) {
+ var result = json.queryasyncjobresultresponse;
+ if (result.jobstatus == 0) {
+ return; //Job has not completed
+ }
+ else {
+ clearInterval(deleteLBHealthCheckPolicyIntervalId);
+
+ if (result.jobstatus == 1) {
+ cloudStack.dialog.notice({ message: _l('Health Check Policy has been deleted') });
+ $loadingOnDialog.remove();
+ $healthCheckDialog.dialog('destroy');
+ $('.overlay').remove();
+ }
+ else if (result.jobstatus == 2) {
+ cloudStack.dialog.notice({ message: _s(result.jobresult.errortext) });
+ $loadingOnDialog.remove();
+ $healthCheckDialog.dialog('destroy');
+ $('.overlay').remove();
+ }
+ }
+ }
+ });
+ }, g_queryAsyncJobResultInterval);
+ }
+ });
+ }
+ }
+ //Delete Button (end)
+ );
+ }
+
+ $healthCheckDialog.dialog({
+ title: 'Health Check Wizard',
+ width: 600,
+ height: 600,
+ draggable: true,
+ closeonEscape: false,
+ overflow:'auto',
+ open:function() {
+ $("button").each(function(){
+ $(this).attr("style", "left: 400px; position: relative; margin-right: 5px; ");
+ });
+
+ $('.ui-dialog .delete').css('left','140px');
+
+ },
+ buttons: buttons
+ }).closest('.ui-dialog').overlay();
+
+ }
+ }
+ }(jQuery, cloudStack));
+
+
diff --git a/ui/scripts/ui/widgets/toolTip.js b/ui/scripts/ui/widgets/toolTip.js
index af6c2aa..6967acc 100644
--- a/ui/scripts/ui/widgets/toolTip.js
+++ b/ui/scripts/ui/widgets/toolTip.js
@@ -156,7 +156,7 @@
// Fix overlay
setTimeout(function() {
- $('.tooltip-box').zIndex($(':ui-dialog').zIndex() + 1); });
+ $('.tooltip-box').zIndex($(':ui-dialog').zIndex() + 10); });
};