Updated Branches:
  refs/heads/autoscale f418db25d -> 93e7b86c4

Merge Autoscaler UI implemetation

This change includes the new dialog box for the CloudStack Autoscaler
implementation. It is accessible by a button ('Autoscaler') that
appears under each LB rule.

This also contains changes to the multiEdit widget to support features
required for Autoscaler:

-Fixes context/data passing to custom button widgets
-Fixes data retrieval for select fields


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/93e7b86c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/93e7b86c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/93e7b86c

Branch: refs/heads/autoscale
Commit: 93e7b86c46368ab29893d7926ea4652bc5d0e177
Parents: f418db2
Author: Brian Federle <[email protected]>
Authored: Mon Jul 30 11:29:43 2012 -0700
Committer: Brian Federle <[email protected]>
Committed: Mon Jul 30 11:29:43 2012 -0700

----------------------------------------------------------------------
 ui/css/cloudstack3.css             |  225 +++++++-
 ui/images/minus.png                |  Bin 0 -> 1544 bytes
 ui/index.jsp                       |    2 +
 ui/scripts/autoscaler.js           | 1043 +++++++++++++++++++++++++++++++
 ui/scripts/network.js              |  764 ++++++++++++-----------
 ui/scripts/ui-custom/autoscaler.js |  285 +++++++++
 ui/scripts/ui/widgets/multiEdit.js |   33 +-
 7 files changed, 1969 insertions(+), 383 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/93e7b86c/ui/css/cloudstack3.css
----------------------------------------------------------------------
diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index a60e480..65acf2b 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -9597,6 +9597,229 @@ div.panel.ui-dialog div.list-view div.fixed-header {
   overflow: auto;
 }
 
+/*Autoscaler*/
+.ui-dialog div.autoscaler {
+  overflow: auto;
+  max-height: 600px;
+}
+
+.ui-dialog div.autoscaler div.form-container div.form-item[rel=securityGroups] 
{
+  display: block;
+  width: 370px;
+  float: left;
+}
+
+.ui-dialog div.autoscaler div.form-container div.form-item[rel=diskOfferingId] 
{
+  display: inline-block;
+  width: 370px;
+  float: left;
+  position: relative;
+  margin-top: 1px;
+}
+
+.ui-dialog div.autoscaler div.form-container div.form-item[rel=minInstance] {
+  display: block;
+  width: 50%;
+  float: left;
+}
+
+.ui-dialog div.autoscaler div.form-container div.form-item[rel=maxInstance] {
+  display: inline-block;
+  width: 50%;
+  float: left;
+  left: -30px;
+  position: relative;
+}
+
+.ui-dialog div.autoscaler div.form-container div.form-item[rel=interval] {
+  display: block;
+  width: 50%;
+  float: left;
+}
+
+.ui-dialog div.autoscaler div.form-container div.form-item[rel=quietTime] {
+  display: inline-block;
+  width: 50%;
+  float: left;
+  left: -15px;
+  position: relative;
+}
+
+.ui-dialog div.autoscaler div.form-container div.form-item[rel=snmpCommunity] {
+  display: block;
+  width: 50%;
+  float: left;
+}
+
+.ui-dialog div.autoscaler div.form-container div.form-item[rel=snmpPort] {
+  display: inline-block;
+  width: 50%;
+  float: left;
+  left: -15px;
+  position: relative;
+}
+
+.ui-dialog div.autoscaler div.form-container div.value select {
+  width: 88%;
+  float: left;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy-title div.form-container {
+  height: 55px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy-title div.form-container {
+  height: 55px;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy div.multi-edit {
+  margin-top: 0px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit {
+  margin-top: 0px;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy-title {
+  color: #0055BB;
+  margin-left: -650px;
+  margin-top: 40px;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy-title label {
+  font-size: 13px;
+  margin-left: 200px;
+  margin-right: 10px;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy-title hr.policy-divider {
+  border-left: 1px none #38546D;
+  border-right: 1px none #16222C;
+  border-top: 1px none #38546D;
+  margin-bottom: 12px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy-title hr.policy-divider {
+  border-left: 1px none #38546D;
+  border-right: 1px none #16222C;
+  border-top: 1px none #38546D;
+  margin-bottom: 12px;
+}
+
+div.ui-dialog div.autoscaler div.field-group.bottom-fields hr.policy-divider {
+  border-left: 1px none #38546D;
+  border-right: 1px none #16222C;
+  border-top: 1px none #38546D;
+  margin-top: 15px;
+  margin-bottom: -1px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy-title label {
+  font-size: 13px;
+  margin-left: 170px;
+  margin-right: 10px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy-title {
+  color: #0055BB;
+  margin-left: -620px;
+  margin-top: 10px;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy-title div.form-container 
div.form-item div.value input[type=text] {
+  margin-left: 195px;
+  width: 30%;
+  margin-top: 1px;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy-title div.form-container 
div.form-item div.name {
+  margin-left: 390px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy-title div.form-container 
div.form-item div.value input[type=text] {
+  margin-left: 670px;
+  width: 30%;
+  margin-top: -16px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy-title div.form-container 
div.form-item div.name {
+  margin-left: 390px;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy div.multi-edit div.data 
div.data-body div.data-item {
+  margin-bottom: 0px;
+  margin-right: 22px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data 
div.data-body div.data-item {
+  margin-bottom: 0px;
+  margin-right: 22px;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy div.slide-label {
+  color: #A5A3A7;
+  font-size: 14px;
+  margin-bottom: 3px;
+  margin-left: 755px;
+  width: 12px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy div.slide-label {
+  color: #A5A3A7;
+  font-size: 14px;
+  margin-bottom: 3px;
+  margin-left: 755px;
+  width: 12px;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy div.hide {
+  background: #FFFFFF url("../images/minus.png") no-repeat 38% 59%;
+  border: 1px solid #D0D0D0;
+  border-radius: 9px 9px 9px 9px;
+  cursor: pointer;
+  float: right;
+  height: 15px;
+  margin: -20px 45px 0 11px;
+  width: 14px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy div.hide {
+  background: #FFFFFF url("../images/minus.png") no-repeat 31% 54%;
+  border: 1px solid #D0D0D0;
+  border-radius: 9px 9px 9px 9px;
+  cursor: pointer;
+  float: right;
+  height: 15px;
+  margin: -20px 45px 0 11px;
+  width: 14px;
+}
+
+div.ui-dialog div.autoscaler div.scale-up-policy div.expand {
+  background: #FFFFFF url("../images/sprites.png") repeat -541px -499px;
+  border: 1px solid #D0D0D0;
+  border-radius: 9px 9px 9px 9px;
+  cursor: pointer;
+  float: right;
+  height: 15px;
+  margin: -20px 45px 0 11px;
+  width: 14px;
+}
+
+div.ui-dialog div.autoscaler div.scale-down-policy div.expand {
+  background: #FFFFFF url("../images/sprites.png") repeat -541px -499px;
+  border: 1px solid #D0D0D0;
+  border-radius: 9px 9px 9px 9px;
+  cursor: pointer;
+  float: right;
+  height: 15px;
+  margin: -20px 45px 0 11px;
+  width: 14px;
+}
+
+div.ui-dialog div.autoscaler div.field-group div.form-container form 
div.form-item div.name label {
+  font-size: 11px;
+}
+
 /*Action icons*/
 .action.edit .icon {
   background-position: 1px -1px;
@@ -9970,4 +10193,4 @@ div.panel.ui-dialog div.list-view div.fixed-header {
 .label-hovered {
   cursor: pointer;
   color: blue !important;
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/93e7b86c/ui/images/minus.png
----------------------------------------------------------------------
diff --git a/ui/images/minus.png b/ui/images/minus.png
new file mode 100644
index 0000000..077db99
Binary files /dev/null and b/ui/images/minus.png differ

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/93e7b86c/ui/index.jsp
----------------------------------------------------------------------
diff --git a/ui/index.jsp b/ui/index.jsp
index 1ee8f0b..5488eb7 100644
--- a/ui/index.jsp
+++ b/ui/index.jsp
@@ -1636,6 +1636,8 @@
     <script type="text/javascript" 
src="scripts/ui-custom/projects.js?t=<%=now%>"></script>
     <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/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>
     <script type="text/javascript" 
src="scripts/installWizard.js?t=<%=now%>"></script>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/93e7b86c/ui/scripts/autoscaler.js
----------------------------------------------------------------------
diff --git a/ui/scripts/autoscaler.js b/ui/scripts/autoscaler.js
new file mode 100644
index 0000000..ff5c542
--- /dev/null
+++ b/ui/scripts/autoscaler.js
@@ -0,0 +1,1043 @@
+// 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) {
+  var scaleUpData = [];
+  var totalScaleUpCondition = 0;
+  var scaleDownData = [];
+  var totalScaleDownCondition = 0;
+
+  cloudStack.autoscaler = {
+    dataProvider: function(args) {
+      // Reset data
+      scaleUpData = [];
+      totalScaleUpCondition = 0;
+      scaleDownData = [];
+      totalScaleDownCondition = 0;
+
+      var sampleData = null;
+      /*
+       var sampleData = {
+       templateNames: '58d3f4b2-e847-4f93-993d-1ab1505129b6', //(will set this 
value to dropdown)
+       serviceOfferingId: '4aa823f3-27ec-46af-9e07-b023d7a7a6f1', //(will set 
this value to dropdown)
+       minInstance: 1,
+       maxInstance: 10,
+       scaleUpPolicy: {
+       id: 12345,
+       duration: 1000,
+       conditions: [
+       {
+       id: 1,
+       counterid: 'cpu',
+       relationaloperator: "GE",
+       threshold: 100
+       },
+       {
+       id: 2,
+       counterid: 'memory',
+       relationaloperator: "LT",
+       threshold: 200
+       }
+
+       ]
+       },
+       scaleDownPolicy: {
+       id: 6789,
+       duration: 500,
+       conditions: [
+       {
+       id: 1,
+       counterid: 'cpu',
+       relationaloperator: "LT",
+       threshold: 30
+       },
+       {
+       id: 2,
+       counterid: 'cpu',
+       relationaloperator: "LT",
+       threshold: 50
+       }
+
+       ]
+       },
+       interval: 200,
+       quietTime: 300,
+       destroyVMgracePeriod: null,
+       securityGroups: null, // (will set this value to dropdown)
+       diskOfferingId: 'a21c9aa4-ef7e-41dd-91eb-70b2182816b0', // (will set 
this value to dropdown)
+       snmpCommunity: 1,
+       snmpPort: 225,
+
+       isAdvanced: false // Set this to true if any advanced field data is 
present
+       };
+       */
+
+      args.response.success({ data: sampleData });
+    },
+
+    // --
+    // Add the following object blocks:
+    //
+    // topFields: { <standard createForm field format> }
+    // bottomFields: { <standard createForm field format> },
+    // scaleUpPolicy: { <standard multiEdit field format> },
+    // scaleDownPolicy: { <standard multiEdit field format> }
+    // --
+    //
+    forms: {
+      topFields: {
+        //**
+        //** Disabled due to UI issues
+        //**
+        // templateCategory: {
+        //   label: 'Template',
+        //   id: 'templatecategory',
+        //   select: function(args) {
+        //     args.response.success({
+        //       data: [
+        //         { id: 'all', description: _l('ui.listView.filters.all') },
+        //         { id: 'featured', description: _l('label.featured') },
+        //         { id: 'Community', description: 
_l('label.menu.community.templates') },
+        //         { id: 'self', description: _l('ui.listView.filters.mine') }
+        //       ]
+        //     });
+        //   }
+        // },
+        //**
+
+        templateNames: {
+          label: 'label.template',
+          id: 'templatename',
+          select: function(args) {
+            var templates;
+            var templateIdMap = {};
+            $.ajax({
+              url: createURL('listTemplates'),
+              data: {
+                templatefilter: 'featured',
+                zoneid: args.context.networks[0].zoneid
+              },
+              async: false,
+              success: function(json) {
+                templates = json.listtemplatesresponse.template;
+                if (templates == null)
+                  templates = [];
+                $(templates).each(function() {
+                  templateIdMap[this.id] = 1;
+                });
+              }
+            });
+
+            $.ajax({
+              url: createURL('listTemplates'),
+              data: {
+                templatefilter: 'community',
+                zoneid: args.context.networks[0].zoneid
+              },
+              async: false,
+              success: function(json) {
+                var items = json.listtemplatesresponse.template;
+                $(items).each(function() {
+                  if(!(this.id in templateIdMap)) {
+                    templates.push(this);
+                    templateIdMap[this.id] = 1;
+                  }
+                });
+              }
+            });
+
+            $.ajax({
+              url: createURL('listTemplates'),
+              data: {
+                templatefilter: 'selfexecutable',
+                zoneid: args.context.networks[0].zoneid
+              },
+              async: false,
+              success: function(json) {
+                var items = json.listtemplatesresponse.template;
+                $(items).each(function() {
+                  if(!(this.id in templateIdMap)) {
+                    templates.push(this);
+                    templateIdMap[this.id] = 1;
+                  }
+                });
+              }
+            });
+
+            args.response.success({
+              data: $.map(templates, function(template) {
+                return {
+                  id: template.id,
+                  description: template.name
+                };
+              })
+            });
+          }
+        },
+
+        serviceOfferingId: {
+          label: 'label.compute.offering',
+          select: function(args) {
+            $.ajax({
+              url: createURL("listServiceOfferings&issystem=false"),
+              dataType: "json",
+              async: true,
+              success: function(json) {
+                var serviceofferings = 
json.listserviceofferingsresponse.serviceoffering;
+                args.response.success({
+                  data: $.map(serviceofferings, function(serviceoffering) {
+                    return {
+                      id: serviceoffering.id,
+                      description: serviceoffering.name
+                    };
+                  })
+                });
+              }
+            });
+          }
+        },
+
+        minInstance: {
+          label: 'Min Instances',
+          defaultValue: '3',
+          validation: { required: true }
+        },
+
+        maxInstance: {
+          label: 'Max Instances',
+          defaultValue: '10',
+          validation: { required: true }
+        }
+      },
+
+      bottomFields: {
+        isAdvanced: { isBoolean: true, label: 'Show advanced settings' },
+        interval: {
+          label: 'Polling Interval (in sec)',
+          defaultValue: '30',
+          validation: { required: true }
+        },
+
+        quietTime: {
+          label: 'Quiet Time (in sec)',
+          defaultValue: '300',
+          validation: { required: true }
+        },
+
+        destroyVMgracePeriod: {
+          label: 'Destroy VM Grace Period',
+          defaultValue: '30',
+          isHidden:true,
+          dependsOn:'isAdvanced',
+          validation: { required: true }
+        },
+        securityGroups: {
+          label: 'label.menu.security.groups',
+          isHidden: true,
+          dependsOn: 'isAdvanced',
+          select: function(args) {
+            $.ajax({
+              url: createURL("listSecurityGroups&listAll=true"),
+              dataType: "json",
+              async: true,
+              success: function(json) {
+                var securitygroups = 
json.listsecuritygroupsresponse.securitygroup;
+                var items = [];
+                items.push({id: "", description: ""});
+                $(securitygroups).each(function(){
+                  items.push({id: this.id, description: this.name});
+                });
+                args.response.success({ data: items });
+              }
+            });
+          }
+        },
+
+        diskOfferingId: {
+          label: 'label.menu.disk.offerings',
+          isHidden: true,
+          dependsOn: 'isAdvanced',
+          select: function(args) {
+            $.ajax({
+              url: createURL("listDiskOfferings&listAll=true"),
+              dataType: "json",
+              async: true,
+              success: function(json) {
+                var diskofferings = 
json.listdiskofferingsresponse.diskoffering;
+                var items = [];
+                items.push({id: "", description: ""});
+                $(diskofferings).each(function(){
+                  items.push({id: this.id, description: this.name});
+                });
+                args.response.success({ data: items });
+              }
+            });
+          }
+        },
+
+        snmpCommunity: {
+          isHidden: true,
+          dependsOn: 'isAdvanced',
+          label: 'SNMP Community',
+          defaultValue: 'public',
+          validation: { required: true }
+        },
+
+        snmpPort: {
+          isHidden: true,
+          dependsOn: 'isAdvanced',
+          label: 'SNMP Port',
+          defaultValue: '161',
+          validation: { required: true }
+        },
+
+        username: {
+          isHidden: true,
+          dependsOn: 'isAdvanced',
+          label: 'User',
+          select: function(args) {
+            var items = [];
+            if(isAdmin() || isDomainAdmin()) {
+              $.ajax({
+                url: createURL('listUsers'),
+                data: {
+                  domainid: g_domainid,
+                  account: g_account
+                },
+                success: function(json) {
+                  var users = json.listusersresponse.user;
+                  $(users).each(function(){
+                    items.push({id: this.id, description: this.username});
+                  });
+                  args.response.success({ data:  items });
+                }
+              });
+            }
+            else { //regular user doesn't have access to listUers API call.
+              items.push({id: "", description: ""});
+            }
+          }
+        }
+      },
+      scaleUpPolicy: {
+        title: 'ScaleUp Policy',
+        label: 'SCALE UP POLICY',
+        noSelect: true,
+        noHeaderActionsColumn: true,
+        ignoreEmptyFields: true,
+        fields: {
+          'counterid': {
+            label: 'Counter',
+            select: function(args) {
+              $.ajax({
+                url: createURL("listCounters"),
+                dataType: "json",
+                async: true,
+                success: function(json) {
+                  var counters = json.counterresponse.counter;
+
+                  args.response.success({
+                    data: $.map(counters, function(counter) {
+                      return {
+                        name: counter.id,
+                        description: counter.name
+                      };
+                    })
+                  });
+                }
+              });
+            }
+          },
+          'relationaloperator': {
+            label: 'Operator',
+            select: function(args) {
+              args.response.success({
+                data: [
+                  { name: 'GT', description: 'greater-than' },
+                  { name: 'GE', description: 'greater-than or equals to' },
+                  { name: 'LT', description: 'less-than' },
+                  { name: 'LE', description: 'less-than or equals to' },
+                  { name: 'EQ', description: 'equals-to' }
+                ]
+              });
+            }
+          },
+          'threshold': { edit: true, label: 'Threshold' },
+          'add-scaleUpcondition': {
+            label: 'label.add',
+            addButton: true
+          }
+        },
+        add: {
+          label: 'label.add',
+          action: function(args) {
+            scaleUpData.push($.extend(args.data, {
+              index: totalScaleUpCondition
+            }));
+
+            totalScaleUpCondition++;
+            args.response.success();
+          }
+        },
+        actions: {
+          destroy: {
+            label: '',
+            action: function(args) {
+              scaleUpData = $.grep(scaleUpData, function(item) {
+                return item.index != args.context.multiRule[0].index;
+              });
+              totalScaleUpCondition--;
+              args.response.success();
+            }
+          }
+        },
+        dataProvider: function(args) {
+          var data = scaleUpData;
+          var $autoscaler = $('.ui-dialog .autoscaler');
+          var initialData = $autoscaler.data('autoscaler-scale-up-data');
+
+          if ($.isArray(initialData)) {
+            $(initialData).each(function() {
+              this.index = totalScaleUpCondition;
+              totalScaleUpCondition++;
+              scaleUpData.push(this);
+            });
+
+            $autoscaler.data('autoscaler-scale-up-data', null);
+          }
+
+          args.response.success({
+            data: scaleUpData
+          });
+        }
+        /*actions: {
+         destroy: {
+         label: '',
+         action: function(args) {
+         $.ajax({
+         url: createURL("deleteCondition&id=" + 
args.context.multiRule[0].counterid),
+         dataType: 'json',
+         async: true,
+         success: function(data) {
+         var jobId = data.deleteconditionresponse.jobid;
+
+         args.response.success({
+         _custom: {
+         jobId: jobId
+         }
+         });
+         }
+         });
+         }
+         }
+         },
+         ignoreEmptyFields: true,
+         dataProvider: function(args) {
+         $.ajax({
+         url: createURL('listConditions'),
+         dataType: 'json',
+         async: true,
+         success: function(data) {
+         args.response.success({
+         data: $.map(
+         data.listconditionsresponse.condition ?
+         data.listconditionsresponse.condition : [],
+         function(elem) {
+         return {
+         counterid: elem.id,
+         relationaloperator: elem.relationaloperator,
+         threshold: elem.threshold
+         };
+         }
+         )
+         });
+         }
+         });
+         }*/
+      },
+
+      scaleDownPolicy: {
+        title: 'ScaleDown Policy',
+        noSelect: true,
+        noHeaderActionsColumn: true,
+        ignoreEmptyFields: true,
+        fields: {
+          'counterid': {
+            label: 'Counter',
+            select: function(args) {
+              $.ajax({
+                url: createURL("listCounters"),
+                dataType: "json",
+                async: true,
+                success: function(json) {
+                  var counters = json.counterresponse.counter;
+
+                  args.response.success({
+                    data: $.map(counters, function(counter) {
+                      return {
+                        name: counter.id,
+                        description: counter.name
+                      };
+                    })
+                  });
+                }
+              });
+            }
+          },
+          'relationaloperator': {
+            label: 'Operator',
+            select: function(args) {
+              args.response.success({
+                data: [
+                  { name: 'GT', description: 'greater-than' },
+                  { name: 'GE', description: 'greater-than or equals to' },
+                  { name: 'LT', description: 'less-than' },
+                  { name: 'LE', description: 'less-than or equals to' },
+                  { name: 'EQ', description: 'equals-to' }
+                ]
+              });
+            }
+          },
+          'threshold': { edit: true, label: 'Threshold'},
+          'add-scaleDowncondition': {
+            label: 'label.add',
+            addButton: true
+          }
+        },
+        add: {
+          label: 'label.add',
+          action: function(args) {
+            scaleDownData.push($.extend(args.data, {
+              index: totalScaleDownCondition
+            }));
+            totalScaleDownCondition++;
+            args.response.success();
+          }
+        },
+        actions: {
+          destroy: {
+            label: '',
+            action: function(args) {
+              scaleDownData = $.grep(scaleDownData, function(item) {
+                return item.index != args.context.multiRule[0].index;
+              });
+              totalScaleDownCondition--;
+              args.response.success();
+            }
+          }
+        },
+        dataProvider: function(args) {
+          var data = scaleDownData;
+          var $autoscaler = $('.ui-dialog .autoscaler');
+          var initialData = $autoscaler.data('autoscaler-scale-down-data');
+
+          if ($.isArray(initialData)) {
+            $(initialData).each(function() {
+              this.index = totalScaleDownCondition;
+              totalScaleDownCondition++;
+              scaleDownData.push(this);
+            });
+
+            $autoscaler.data('autoscaler-scale-down-data', null);
+          }
+
+          args.response.success({
+            data: scaleDownData
+          });
+        }
+        /*
+         actions: {
+         destroy: {
+         label: '',
+         action: function(args) {
+         $.ajax({
+         url: createURL("deleteCondition&id=" + 
args.context.multiRule[0].counterid),
+         dataType: 'json',
+         async: true,
+         success: function(data) {
+         var jobId = data.deleteconditionresponse.jobid;
+
+         args.response.success({
+         _custom: {
+         jobId: jobId
+         }
+         });
+         }
+         });
+         }
+         }
+         },
+         ignoreEmptyFields: true,
+         dataProvider: function(args) {
+         $.ajax({
+         url: createURL('listConditions'),
+         dataType: 'json',
+         async: true,
+         success: function(data) {
+         args.response.success({
+         data: $.map(
+         data.listconditionsresponse.condition ?
+         data.listconditionsresponse.condition : [],
+         function(elem) {
+         return {
+         counterid: elem.id,
+         relationaloperator: elem.relationaloperator,
+         threshold: elem.threshold
+         };
+         }
+         )
+         });
+         }
+         });
+         }*/
+      }
+    },
+
+    actions: {
+      add: function(args) {
+        //validation (begin) *****
+        if(isAdmin() || isDomainAdmin()) { //only admin and domain-admin has 
access to listUers API
+          var havingApiKeyAndSecretKey = false;
+          $.ajax({
+            url: createURL('listUsers'),
+            data: {
+              id: args.data.username
+            },
+            async: false,
+            success: function(json) {
+              if(json.listusersresponse.user[0].apikey != null && 
json.listusersresponse.user[0].secretkey != null) {
+                havingApiKeyAndSecretKey = true;
+              }
+            }
+          });
+          if(havingApiKeyAndSecretKey == false) {
+            args.response.error('The selected user in advanced settings does 
not have API key or secret key');
+            return;
+          }
+        }
+
+        if(isAdmin()) { //only admin has access to listConfigurations API
+          var hasValidEndpointeUrl = false;
+          $.ajax({
+            url: createURL('listConfigurations'),
+            data: {
+              name: 'endpointe.url'
+            },
+            async: false,
+            success: function(json) {
+              if(json.listconfigurationsresponse.configuration != null) {
+                
if(json.listconfigurationsresponse.configuration[0].value.indexOf('localhost') 
== -1) {
+                  hasValidEndpointeUrl = true;
+                }
+              }
+            }
+          });
+          if(hasValidEndpointeUrl == false) {
+            args.response.error("Global setting endpointe.url has to be set to 
the Management Server's API end point");
+            return;
+          }
+        }
+        //validation (end) *****
+
+
+        var scaleVmProfileResponse = [];
+        var loadBalancerResponse  = [];
+        var scaleVmGroupResponse = [];
+        var scaleUpConditionIds = [];
+        var scaleDownConditionIds = [];
+
+        var scaleUp = function(args){
+          var scaleUpConditionIds = [];
+          $(scaleUpData).each(function(){
+            var data = {
+              counterid: this.counterid,
+              relationaloperator: this.relationaloperator,
+              threshold: this.threshold
+            };
+            $.ajax({
+              url: createURL('createCondition'),
+              data: data,
+              success: function(json) {
+                var createConditionIntervalID = setInterval(function() {
+                  $.ajax({
+                    url: createURL("queryAsyncJobResult&jobid=" + 
json.conditionresponse.jobid),
+                    dataType: "json",
+                    success: function(json) {
+                      var result = json.queryasyncjobresultresponse;
+                      if(result.jobstatus == 0) {
+                        return;
+                      }
+                      else {
+                        clearInterval(createConditionIntervalID);
+                        if(result.jobstatus == 1) {
+                          var item  = 
json.queryasyncjobresultresponse.jobresult.condition;
+                          scaleUpConditionIds.push(item.id);
+                          if (scaleUpConditionIds.length == 
scaleUpData.length) {
+                            var data = {
+                              action: 'scaleup',
+                              conditionids: scaleUpConditionIds.join(","),
+                              duration: args.data.scaleUpDuration,
+                              quiettime: args.data.quietTime
+                            };
+                            $.ajax({
+                              url: createURL('createAutoScalePolicy'),
+                              data: data,
+                              success: function(json) {
+                                var jobId = json.autoscalepolicyresponse.jobid;
+                                var createAutoScalePolicyInterval = 
setInterval(function(){
+                                  $.ajax({
+                                    url: 
createURL("queryAsyncJobResult&jobId="+jobId),
+                                    dataType: "json",
+                                    success: function(json) {
+                                      var result = 
json.queryasyncjobresultresponse;
+                                      if (result.jobstatus == 0) {
+                                        return; //Job has not completed
+                                      }
+                                      else {
+                                        
clearInterval(createAutoScalePolicyInterval);
+                                        if (result.jobstatus == 1) { 
//AutoScalePolicy successfully created
+                                          var item = 
result.jobresult.autoscalepolicy;
+                                          scaleDown($.extend(args, {
+                                            scaleUpPolicyResponse: item
+                                          }));
+                                        }
+                                        else if (result.jobstatus == 2) {
+                                          args.response.error({ message: 
_s(result.jobresult.errortext) });
+                                        }
+                                      }
+                                    }
+                                  });
+                                }, 3000);
+                              },
+                              error: function(XMLHttpResponse) {
+                                
args.response.error(parseXMLHttpResponse(XMLHttpResponse));
+                              }
+                            });
+                          }
+                        }
+                        else if(result.jobstatus == 2) {
+                          args.response.error({ message: 
_s(result.jobresult.errortext) });
+                        }
+                      }
+                    }
+                  });
+                }, 3000);
+              },
+              error: function(XMLHttpResponse) {
+                args.response.error(parseXMLHttpResponse(XMLHttpResponse));
+              }
+            });
+          });
+        };
+
+        var scaleDown = function(args){
+          var scaleDownConditionIds = [];
+          $(scaleDownData).each(function(){
+            var data = {
+              counterid: this.counterid,
+              relationaloperator: this.relationaloperator,
+              threshold: this.threshold
+            };
+            $.ajax({
+              url: createURL('createCondition'),
+              data: data,
+              success: function(json) {
+                var createConditionIntervalID = setInterval(function() {
+                  $.ajax({
+                    url: createURL("queryAsyncJobResult&jobid=" + 
json.conditionresponse.jobid),
+                    dataType: "json",
+                    success: function(json) {
+                      var result = json.queryasyncjobresultresponse;
+                      if(result.jobstatus == 0) {
+                        return;
+                      }
+                      else {
+                        clearInterval(createConditionIntervalID);
+                        if(result.jobstatus == 1) {
+                          var item  = 
json.queryasyncjobresultresponse.jobresult.condition;
+                          scaleDownConditionIds.push(item.id);
+                          if (scaleDownConditionIds.length == 
scaleDownData.length) {
+                            var data = {
+                              action: 'scaledown',
+                              conditionids: scaleDownConditionIds.join(","),
+                              duration: args.data.scaleDownDuration,
+                              quiettime: args.data.quietTime
+                            };
+                            $.ajax({
+                              url: createURL('createAutoScalePolicy'),
+                              data: data,
+                              success: function(json) {
+                                var jobId = json.autoscalepolicyresponse.jobid;
+                                var createAutoScalePolicyInterval = 
setInterval(function(){
+                                  $.ajax({
+                                    url: 
createURL("queryAsyncJobResult&jobId="+jobId),
+                                    dataType: "json",
+                                    success: function(json) {
+                                      var result = 
json.queryasyncjobresultresponse;
+                                      if (result.jobstatus == 0) {
+                                        return; //Job has not completed
+                                      }
+                                      else {
+                                        
clearInterval(createAutoScalePolicyInterval);
+                                        if (result.jobstatus == 1) { 
//AutoScalePolicy successfully created
+                                          var item = 
result.jobresult.autoscalepolicy;
+                                          createVmProfile($.extend(args, {
+                                            scaleDownPolicyResponse: item
+                                          }));
+                                        }
+                                        else if (result.jobstatus == 2) {
+                                          args.response.error({ message: 
_s(result.jobresult.errortext) });
+                                        }
+                                      }
+                                    }
+                                  });
+                                }, 3000);
+                              },
+                              error: function(XMLHttpResponse) {
+                                
args.response.error(parseXMLHttpResponse(XMLHttpResponse));
+                              }
+                            });
+                          }
+                        }
+                        else if(result.jobstatus == 2) {
+                          args.response.error({ message: 
_s(result.jobresult.errortext) });
+                        }
+                      }
+                    },
+                    error: function(XMLHttpResponse) {
+                      
args.response.error(parseXMLHttpResponse(XMLHttpResponse));
+                    }
+                  });
+                }, 3000);
+              }
+            });
+          });
+        };
+
+        var createVmProfile = function(args){
+          var array1 = [];
+          array1.push("&zoneid=" + args.context.networks[0].zoneid);
+          array1.push("&templateid=" + args.data.templateNames);
+          array1.push("&serviceofferingid=" + args.data.serviceOfferingId);
+          array1.push("&snmpcommunity=" + args.data.snmpCommunity);
+          array1.push("&snmpport=" + args.data.snmpPort);
+          array1.push("&destroyvmgraceperiod=" + 
args.data.destroyVMgracePeriod);
+
+          if(args.data.username != "")
+            array1.push("&autoscaleuserid=" + args.data.username);
+
+          var array2 = [];
+          if(args.data.diskOfferingId != "")
+            array2.push("diskofferingid=" + args.data.diskOfferingId);
+          if(args.data.securityGroups != ""){
+            if(array2.join("") != "")
+              array2.push("&securitygroupids=" + args.data.securityGroups);
+            else
+              array2.push("securitygroupids=" + args.data.securityGroups);
+          }
+          array2 = array2.join("");
+          if(array2 != "")
+            array1.push("&otherdeployparams=" + encodeURIComponent(array2));
+
+          $.ajax({
+            url: createURL('createAutoScaleVmProfile' + array1.join("")),
+            dataType: 'json',
+            async: true,
+            success: function(data) {
+              var jobId = data.autoscalevmprofileresponse.jobid;
+              var autoscaleVmProfileTimer = setInterval(function(){
+                $.ajax({
+                  url: createURL("queryAsyncJobResult&jobId="+jobId),
+                  dataType: "json",
+                  success: function(json) {
+                    var result = json.queryasyncjobresultresponse;
+                    if (result.jobstatus == 0) {
+                      return; //Job has not completed
+                    }
+                    else {
+                      clearInterval(autoscaleVmProfileTimer);
+                      if (result.jobstatus == 1) { //VM Profile successfully 
created
+                        scaleVmProfileResponse = 
result.jobresult.autoscalevmprofile;
+                        loadBalancer(args);
+                      }
+                      else if (result.jobstatus == 2) {
+                        args.response.error({message: 
_s(result.jobresult.errortext)});
+                      }
+                    }
+                  }
+                });
+              }, 3000);
+            },
+            error: function(XMLHttpResponse) {
+              args.response.error(parseXMLHttpResponse(XMLHttpResponse));
+            }
+          });
+        };
+
+        var loadBalancer = function(args){
+          var networkid;
+          if('vpc' in args.context) { //from VPC section
+            if(args.data.tier == null) {
+              cloudStack.dialog.notice({ message: 'Tier is required' });
+              return;
+            }
+            networkid = args.data.tier;
+          }
+          else if('networks' in args.context) {        //from Guest Network 
section
+            networkid = args.context.networks[0].id;
+          }
+          var data = {
+            algorithm: args.formData.algorithm,
+            name: args.formData.name,
+            privateport: args.formData.privateport,
+            publicport: args.formData.publicport,
+            openfirewall: false,
+            networkid: networkid,
+            publicipid: args.context.ipAddresses[0].id
+          };
+
+          $.ajax({
+            url: createURL('createLoadBalancerRule'),
+            dataType: 'json',
+            data: data,
+            async: true,
+            success: function(json) {
+              var jobId = json.createloadbalancerruleresponse.jobid;
+              var loadBalancerTimer = setInterval(function(){
+                $.ajax({
+                  url: createURL("queryAsyncJobResult&jobId="+jobId),
+                  dataType: "json",
+                  success: function(json) {
+                    var result = json.queryasyncjobresultresponse;
+                    if (result.jobstatus == 0) {
+                      return; //Job has not completed
+                    }
+                    else {
+                      clearInterval(loadBalancerTimer);
+                      if (result.jobstatus == 1) { //LoadBalancerRule 
successfully created
+                        loadBalancerResponse = result.jobresult.loadbalancer;
+                        autoScaleVmGroup(args);
+                      }
+                      else if (result.jobstatus == 2) {
+                        args.response.error({message: 
_s(result.jobresult.errortext)});
+                      }
+                    }
+                  }
+                });
+              }, 3000);
+            },
+            error: function(XMLHttpResponse) {
+              args.response.error(parseXMLHttpResponse(XMLHttpResponse));
+            }
+          });
+        };
+
+        var autoScaleVmGroup = function(args){
+          var array1 = [];
+          array1.push("&lbruleid=" + loadBalancerResponse.id);
+          array1.push("&minMembers=" + args.data.minInstance);
+          array1.push("&maxMembers=" + args.data.maxInstance );
+          array1.push("&vmprofileid=" + scaleVmProfileResponse.id);
+          array1.push("&interval=" + args.data.interval);
+          array1.push("&scaleuppolicyids=" + args.scaleUpPolicyResponse.id);
+          array1.push("&scaledownpolicyids=" + args.scaleDownPolicyResponse.id 
);
+          $.ajax({
+            url: createURL('createAutoScaleVmGroup' + array1.join("")),
+            dataType: 'json',
+            async: true,
+            success: function(json) {
+              var jobId = json.autoscalevmgroupresponse.jobid;
+              var scaleVmGroupTimer = setInterval(function(){
+                $.ajax({
+                  url: createURL("queryAsyncJobResult&jobId="+jobId),
+                  dataType: "json",
+                  success: function(json) {
+                    var result = json.queryasyncjobresultresponse;
+                    if (result.jobstatus == 0) {
+                      return; //Job has not completed
+                    }
+                    else {
+                      clearInterval(scaleVmGroupTimer);
+                      if (result.jobstatus == 1) { //autoscale Vm group 
successfully created
+                        scaleVmGroupResponse = 
result.jobresult.autoscalevmgroup;
+                        args.response.success();
+                      }
+                      else if (result.jobstatus == 2) {
+                        args.response.error({message: 
_s(result.jobresult.errortext)});
+                      }
+                    }
+                  }
+                });
+              }, 3000);
+            },
+            error: function(XMLHttpResponse) {
+              args.response.error(parseXMLHttpResponse(XMLHttpResponse));
+            }
+          });
+        };
+
+        scaleUp(args);
+
+        //setTimeout(function() { args.response.success(); }, 1000);
+        //setTimeout(function() { args.response.error('Error!'); }, 1000);
+      },
+      destroy: function(args) {
+        $.ajax({
+          url: createURL('')
+        });
+      }
+    },
+
+    dialog: function(args) {
+      return function(args) {
+        var context = args.context;
+
+        var $dialog= $('<div>');
+        $dialog.dialog ({
+          title: 'AutoScale Configuration Wizard',
+          closeonEscape: false,
+
+          draggable:true,
+          width:  825 ,
+          height :600,
+          buttons: {
+            'Cancel': function() {
+              $(this).dialog("close");
+              $('.overlay').remove();
+            },
+
+
+            'Apply': function() {
+              $(':ui-dialog').remove();
+              $('.overlay').remove();
+            }
+          }
+        }).closest('.ui-dialog').overlay();
+
+        $("buttons").each(function() {
+          $(this).attr('style','float: right');
+        });
+        var $field = $('<div>').addClass('field username');
+        var $input = $('<input>').attr({ name: 'username' });
+        var $inputLabel = $('<label>').html('Username');
+
+        $field.append($input, $inputLabel);
+        $field.appendTo($dialog);
+      }
+    }
+  }
+} (jQuery,cloudStack));

Reply via email to