mirror of https://github.com/apache/cloudstack.git
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
This commit is contained in:
parent
6f3df699d1
commit
bbfb13a1d9
|
|
@ -10663,6 +10663,229 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
|
|||
border-color: inherit;
|
||||
}
|
||||
|
||||
/*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;
|
||||
|
|
@ -11045,4 +11268,3 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
|
|||
cursor: pointer;
|
||||
color: #0000FF !important;
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -1638,6 +1638,8 @@ under the License.
|
|||
<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>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -56,7 +56,7 @@
|
|||
var allowedActions = args.context.actions;
|
||||
var disallowedActions = [];
|
||||
var item = args.context.item;
|
||||
var status = item.state;
|
||||
var status = item.state;
|
||||
|
||||
if (status == 'Destroyed' ||
|
||||
status == 'Releasing' ||
|
||||
|
|
@ -65,9 +65,70 @@
|
|||
status == 'Allocating' ||
|
||||
item.account == 'system' ||
|
||||
item.issystem == true ) {
|
||||
return [];
|
||||
return [];
|
||||
}
|
||||
|
||||
if(item.networkOfferingConserveMode == false) {
|
||||
/*
|
||||
(1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added.
|
||||
*/
|
||||
if (item.issourcenat == true){
|
||||
disallowedActions.push('enableStaticNAT');
|
||||
disallowedActions.push('enableVPN');
|
||||
}
|
||||
|
||||
/*
|
||||
(2) If IP is non-SourceNat, show StaticNat/VPN/PortForwarding/LoadBalancer at first.
|
||||
1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer.
|
||||
2. Once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer.
|
||||
3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer.
|
||||
4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding.
|
||||
*/
|
||||
else { //item.issourcenat == false
|
||||
if (item.isstaticnat) { //1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer.
|
||||
disallowedActions.push('enableVPN');
|
||||
}
|
||||
if (item.vpnenabled) { //2. Once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer.
|
||||
disallowedActions.push('enableStaticNAT');
|
||||
}
|
||||
|
||||
//3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer.
|
||||
$.ajax({
|
||||
url: createURL('listPortForwardingRules'),
|
||||
data: {
|
||||
ipaddressid: item.id,
|
||||
listAll: true
|
||||
},
|
||||
dataType: 'json',
|
||||
async: false,
|
||||
success: function(json) {
|
||||
var rules = json.listportforwardingrulesresponse.portforwardingrule;
|
||||
if(rules != null && rules.length > 0) {
|
||||
disallowedActions.push('enableVPN');
|
||||
disallowedActions.push('enableStaticNAT');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding.
|
||||
$.ajax({
|
||||
url: createURL('listLoadBalancerRules'),
|
||||
data: {
|
||||
publicipid: item.id,
|
||||
listAll: true
|
||||
},
|
||||
dataType: 'json',
|
||||
async: false,
|
||||
success: function(json) {
|
||||
var rules = json.listloadbalancerrulesresponse.loadbalancerrule;
|
||||
if(rules != null && rules.length > 0) {
|
||||
disallowedActions.push('enableVPN');
|
||||
disallowedActions.push('enableStaticNAT');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(item.networkOfferingConserveMode == false) {
|
||||
/*
|
||||
(1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added.
|
||||
|
|
@ -163,7 +224,7 @@
|
|||
securityGroups: function(args) {
|
||||
var allowedActions = [];
|
||||
var isSecurityGroupOwner = isAdmin() || isDomainAdmin() ||
|
||||
args.context.item.account == args.context.users[0].account;
|
||||
args.context.item.account == args.context.users[0].account;
|
||||
|
||||
if (isSecurityGroupOwner &&
|
||||
args.context.item.state != 'Destroyed' &&
|
||||
|
|
@ -532,7 +593,7 @@
|
|||
data: data,
|
||||
async: false,
|
||||
success: function(data) {
|
||||
args.response.success({
|
||||
args.response.success({
|
||||
data: data.listnetworksresponse.network
|
||||
});
|
||||
},
|
||||
|
|
@ -692,7 +753,7 @@
|
|||
fields: {
|
||||
cleanup: {
|
||||
label: 'label.clean.up',
|
||||
isBoolean: true
|
||||
isBoolean: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -702,7 +763,7 @@
|
|||
}
|
||||
},
|
||||
action: function(args) {
|
||||
var array1 = [];
|
||||
var array1 = [];
|
||||
array1.push("&cleanup=" + (args.data.cleanup == "on"));
|
||||
$.ajax({
|
||||
url: createURL("restartNetwork&id=" + args.context.networks[0].id + array1.join("")),
|
||||
|
|
@ -953,10 +1014,10 @@
|
|||
|
||||
tags: cloudStack.api.tags({ resourceType: 'Network', contextId: 'networks' }),
|
||||
|
||||
|
||||
dataProvider: function(args) {
|
||||
$.ajax({
|
||||
url: createURL("listNetworks&id=" + args.context.networks[0].id + "&listAll=true"), //pass "&listAll=true" to "listNetworks&id=xxxxxxxx" for now before API gets fixed.
|
||||
|
||||
dataProvider: function(args) {
|
||||
$.ajax({
|
||||
url: createURL("listNetworks&id=" + args.context.networks[0].id + "&listAll=true"), //pass "&listAll=true" to "listNetworks&id=xxxxxxxx" for now before API gets fixed.
|
||||
data: { listAll: true },
|
||||
dataType: "json",
|
||||
async: true,
|
||||
|
|
@ -1048,6 +1109,13 @@
|
|||
action: cloudStack.lbStickyPolicy.dialog()
|
||||
}
|
||||
},
|
||||
'autoScale': {
|
||||
label: 'AutoScale',
|
||||
custom: {
|
||||
buttonLabel: 'label.configure',
|
||||
action: cloudStack.uiCustom.autoscaler(cloudStack.autoscaler)
|
||||
}
|
||||
},
|
||||
'add-vm': {
|
||||
label: 'label.add.vms',
|
||||
addButton: true
|
||||
|
|
@ -1475,7 +1543,7 @@
|
|||
},
|
||||
enableStaticNAT: {
|
||||
label: 'label.action.enable.static.NAT',
|
||||
|
||||
|
||||
action: {
|
||||
noAdd: true,
|
||||
custom: cloudStack.uiCustom.enableStaticNAT({
|
||||
|
|
@ -1549,7 +1617,7 @@
|
|||
$.extend(data, {
|
||||
account: args.context.ipAddresses[0].account,
|
||||
domainid: args.context.ipAddresses[0].domainid
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
|
|
@ -1762,7 +1830,7 @@
|
|||
issourcenat: { label: 'label.source.nat', converter: cloudStack.converters.toBooleanText },
|
||||
isstaticnat: { label: 'label.static.nat', converter: cloudStack.converters.toBooleanText },
|
||||
issystem: { label: 'label.is.system', converter: cloudStack.converters.toBooleanText }, //(basic zone only)
|
||||
purpose: { label: 'label.purpose' }, //(basic zone only) When an IP is system-generated, the purpose it serves can be Lb or static nat.
|
||||
purpose: { label: 'label.purpose' }, //(basic zone only) When an IP is system-generated, the purpose it serves can be Lb or static nat.
|
||||
virtualmachinedisplayname: { label: 'label.vm.name' },
|
||||
domain: { label: 'label.domain' },
|
||||
account: { label: 'label.account' },
|
||||
|
|
@ -1770,7 +1838,7 @@
|
|||
vlanname: { label: 'label.vlan' }
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
tags: cloudStack.api.tags({ resourceType: 'PublicIpAddress', contextId: 'ipAddresses' }),
|
||||
|
||||
dataProvider: function(args) {
|
||||
|
|
@ -1887,12 +1955,7 @@
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(args.context.ipAddresses[0].networkOfferingConserveMode == false) {
|
||||
/*
|
||||
(1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added.
|
||||
*/
|
||||
if (args.context.ipAddresses[0].issourcenat){
|
||||
});
|
||||
if(havingFirewallService == false) { //firewall is not supported in IP from VPC section (because ACL has already supported in tier from VPC section)
|
||||
disallowedActions.push("firewall");
|
||||
}
|
||||
|
|
@ -2150,111 +2213,111 @@
|
|||
|
||||
vmDetails: cloudStack.sections.instances.listView.detailView,
|
||||
|
||||
|
||||
//"NAT Port Range" multiEdit screen for StaticNAT is obsolete in cloudstack 3.0 because createIpForwardingRule/deleteIpForwardingRule/listIpForwardingRules API are obsolete in cloudstack 3.0.
|
||||
//cloudstack 3.0 is using createFirewallRule/listFirewallRules/deleteFirewallRule API for both staticNAT and non-staticNAT .
|
||||
/*
|
||||
staticNAT: {
|
||||
noSelect: true,
|
||||
fields: {
|
||||
'protocol': {
|
||||
label: 'label.protocol',
|
||||
select: function(args) {
|
||||
args.response.success({
|
||||
data: [
|
||||
{ name: 'tcp', description: 'TCP' },
|
||||
{ name: 'udp', description: 'UDP' }
|
||||
]
|
||||
});
|
||||
}
|
||||
},
|
||||
'startport': { edit: true, label: 'label.start.port' },
|
||||
'endport': { edit: true, label: 'label.end.port' },
|
||||
'add-rule': {
|
||||
label: 'label.add.rule',
|
||||
addButton: true
|
||||
}
|
||||
},
|
||||
add: {
|
||||
label: 'label.add',
|
||||
action: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('createIpForwardingRule'),
|
||||
data: $.extend(args.data, {
|
||||
ipaddressid: args.context.ipAddresses[0].id
|
||||
}),
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
args.response.success({
|
||||
_custom: {
|
||||
jobId: data.createipforwardingruleresponse.jobid
|
||||
},
|
||||
notification: {
|
||||
label: 'label.add.static.nat.rule',
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(data) {
|
||||
args.response.error(parseXMLHttpResponse(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
destroy: {
|
||||
label: 'label.remove.rule',
|
||||
action: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('deleteIpForwardingRule'),
|
||||
data: {
|
||||
id: args.context.multiRule[0].id
|
||||
},
|
||||
dataType: 'json',
|
||||
async: true,
|
||||
success: function(data) {
|
||||
var jobID = data.deleteipforwardingruleresponse.jobid;
|
||||
args.response.success({
|
||||
_custom: {
|
||||
jobId: jobID
|
||||
},
|
||||
notification: {
|
||||
label: 'label.remove.static.nat.rule',
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(data) {
|
||||
args.response.error(parseXMLHttpResponse(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
dataProvider: function(args) {
|
||||
setTimeout(function() {
|
||||
$.ajax({
|
||||
url: createURL('listIpForwardingRules'),
|
||||
data: {
|
||||
listAll: true,
|
||||
ipaddressid: args.context.ipAddresses[0].id
|
||||
},
|
||||
dataType: 'json',
|
||||
async: true,
|
||||
success: function(data) {
|
||||
args.response.success({
|
||||
data: data.listipforwardingrulesresponse.ipforwardingrule
|
||||
});
|
||||
},
|
||||
error: function(data) {
|
||||
args.response.error(parseXMLHttpResponse(data));
|
||||
}
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
*/
|
||||
|
||||
|
||||
//"NAT Port Range" multiEdit screen for StaticNAT is obsolete in cloudstack 3.0 because createIpForwardingRule/deleteIpForwardingRule/listIpForwardingRules API are obsolete in cloudstack 3.0.
|
||||
//cloudstack 3.0 is using createFirewallRule/listFirewallRules/deleteFirewallRule API for both staticNAT and non-staticNAT .
|
||||
/*
|
||||
staticNAT: {
|
||||
noSelect: true,
|
||||
fields: {
|
||||
'protocol': {
|
||||
label: 'label.protocol',
|
||||
select: function(args) {
|
||||
args.response.success({
|
||||
data: [
|
||||
{ name: 'tcp', description: 'TCP' },
|
||||
{ name: 'udp', description: 'UDP' }
|
||||
]
|
||||
});
|
||||
}
|
||||
},
|
||||
'startport': { edit: true, label: 'label.start.port' },
|
||||
'endport': { edit: true, label: 'label.end.port' },
|
||||
'add-rule': {
|
||||
label: 'label.add.rule',
|
||||
addButton: true
|
||||
}
|
||||
},
|
||||
add: {
|
||||
label: 'label.add',
|
||||
action: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('createIpForwardingRule'),
|
||||
data: $.extend(args.data, {
|
||||
ipaddressid: args.context.ipAddresses[0].id
|
||||
}),
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
args.response.success({
|
||||
_custom: {
|
||||
jobId: data.createipforwardingruleresponse.jobid
|
||||
},
|
||||
notification: {
|
||||
label: 'label.add.static.nat.rule',
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(data) {
|
||||
args.response.error(parseXMLHttpResponse(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
destroy: {
|
||||
label: 'label.remove.rule',
|
||||
action: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('deleteIpForwardingRule'),
|
||||
data: {
|
||||
id: args.context.multiRule[0].id
|
||||
},
|
||||
dataType: 'json',
|
||||
async: true,
|
||||
success: function(data) {
|
||||
var jobID = data.deleteipforwardingruleresponse.jobid;
|
||||
args.response.success({
|
||||
_custom: {
|
||||
jobId: jobID
|
||||
},
|
||||
notification: {
|
||||
label: 'label.remove.static.nat.rule',
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(data) {
|
||||
args.response.error(parseXMLHttpResponse(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
dataProvider: function(args) {
|
||||
setTimeout(function() {
|
||||
$.ajax({
|
||||
url: createURL('listIpForwardingRules'),
|
||||
data: {
|
||||
listAll: true,
|
||||
ipaddressid: args.context.ipAddresses[0].id
|
||||
},
|
||||
dataType: 'json',
|
||||
async: true,
|
||||
success: function(data) {
|
||||
args.response.success({
|
||||
data: data.listipforwardingrulesresponse.ipforwardingrule
|
||||
});
|
||||
},
|
||||
error: function(data) {
|
||||
args.response.error(parseXMLHttpResponse(data));
|
||||
}
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
*/
|
||||
|
||||
|
||||
// Load balancing rules
|
||||
loadBalancing: {
|
||||
|
|
@ -2282,7 +2345,7 @@
|
|||
$.extend(data, {
|
||||
account: args.context.ipAddresses[0].account,
|
||||
domainid: args.context.ipAddresses[0].domainid
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
|
|
@ -2379,6 +2442,14 @@
|
|||
action: cloudStack.lbStickyPolicy.dialog()
|
||||
}
|
||||
},
|
||||
'autoScale': {
|
||||
label: 'AutoScale',
|
||||
custom: {
|
||||
buttonLabel: 'label.configure',
|
||||
action: cloudStack.uiCustom.autoscaler(cloudStack.autoscaler)
|
||||
}
|
||||
},
|
||||
|
||||
'add-vm': {
|
||||
label: 'label.add.vms',
|
||||
addButton: true
|
||||
|
|
@ -2500,7 +2571,7 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
destroy: {
|
||||
|
|
@ -2596,10 +2667,10 @@
|
|||
|
||||
$.ajax({
|
||||
url: createURL('listLoadBalancerRules'),
|
||||
data: {
|
||||
publicipid: args.context.ipAddresses[0].id,
|
||||
listAll: true
|
||||
},
|
||||
data: {
|
||||
publicipid: args.context.ipAddresses[0].id,
|
||||
listAll: true
|
||||
},
|
||||
dataType: 'json',
|
||||
async: true,
|
||||
success: function(data) {
|
||||
|
|
@ -2623,7 +2694,7 @@
|
|||
},
|
||||
success: function(json) {
|
||||
var stickyPolicy = json.listlbstickinesspoliciesresponse.stickinesspolicies ?
|
||||
json.listlbstickinesspoliciesresponse.stickinesspolicies[0].stickinesspolicy : null;
|
||||
json.listlbstickinesspoliciesresponse.stickinesspolicies[0].stickinesspolicy : null;
|
||||
|
||||
if (stickyPolicy && stickyPolicy.length) {
|
||||
stickyPolicy = stickyPolicy[0];
|
||||
|
|
@ -2659,7 +2730,7 @@
|
|||
id: item.id
|
||||
},
|
||||
success: function(data) {
|
||||
lbInstances = data.listloadbalancerruleinstancesresponse.loadbalancerruleinstance ?
|
||||
lbInstances = data.listloadbalancerruleinstancesresponse.loadbalancerruleinstance ?
|
||||
data.listloadbalancerruleinstancesresponse.loadbalancerruleinstance : [];
|
||||
},
|
||||
error: function(data) {
|
||||
|
|
@ -2673,7 +2744,10 @@
|
|||
_maxLength: {
|
||||
name: 7
|
||||
},
|
||||
sticky: stickyData
|
||||
sticky: stickyData,
|
||||
autoScale: {
|
||||
lbRuleID: item.id
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -2776,7 +2850,7 @@
|
|||
$.extend(data, {
|
||||
account: args.context.ipAddresses[0].account,
|
||||
domainid: args.context.ipAddresses[0].domainid
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
|
|
@ -2921,7 +2995,7 @@
|
|||
},
|
||||
dataProvider: function(args) {
|
||||
var $multi = args.$multi;
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: createURL('listPortForwardingRules'),
|
||||
data: {
|
||||
|
|
@ -2939,7 +3013,7 @@
|
|||
|
||||
$(portForwardingData).each(function() {
|
||||
var item = this;
|
||||
|
||||
|
||||
item._itemName = '_displayName';
|
||||
|
||||
$.ajax({
|
||||
|
|
@ -3048,9 +3122,9 @@
|
|||
$.ajax({
|
||||
url: createURL('addVpnUser'),
|
||||
data: $.extend(args.data, {
|
||||
domainid: args.context.ipAddresses[0].domainid,
|
||||
account: args.context.ipAddresses[0].account
|
||||
}),
|
||||
domainid: args.context.ipAddresses[0].domainid,
|
||||
account: args.context.ipAddresses[0].account
|
||||
}),
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
args.response.success({
|
||||
|
|
@ -3407,7 +3481,7 @@
|
|||
success: function(data) {
|
||||
args.response.success({
|
||||
data: $.map(
|
||||
data.listsecuritygroupsresponse.securitygroup[0].ingressrule ?
|
||||
data.listsecuritygroupsresponse.securitygroup[0].ingressrule ?
|
||||
data.listsecuritygroupsresponse.securitygroup[0].ingressrule : [],
|
||||
ingressEgressDataMap
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,285 @@
|
|||
// 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.autoscaler = function(args) {
|
||||
// Place outer args here as local variables
|
||||
// i.e, -- var dataProvider = args.dataProvider
|
||||
var forms = $.extend(true, {}, args.forms);
|
||||
var topfields = forms.topFields;
|
||||
var bottomfields = forms.bottomFields;
|
||||
var scaleuppolicy = forms.scaleUpPolicy;
|
||||
var scaledownpolicy = forms.scaleDownPolicy;
|
||||
var dataProvider = cloudStack.autoscaler.dataProvider;
|
||||
|
||||
return function(args) {
|
||||
var context = args.data ?
|
||||
$.extend(true, {}, args.context, {
|
||||
lbRules: [args.data]
|
||||
}) : args.context;
|
||||
var formData = args.formData;
|
||||
var $autoscalerDialog = $('<div>').addClass('autoscaler');
|
||||
var $topFields = $('<div>').addClass('field-group top-fields');
|
||||
var $bottomFields = $('<div>').addClass('field-group bottom-fields');
|
||||
var $scaleUpPolicy = $('<div>').addClass('scale-up-policy');
|
||||
var $slideScaleUp = $('<div></div>').addClass('expand');
|
||||
var $hideScaleUp = $('<div></div>').addClass('hide');
|
||||
var $scaleUpLabel= $('<div>Show</div>').addClass('slide-label');
|
||||
var $scaleUpHideLabel=$('<div>Hide</div>').addClass('slide-label');
|
||||
var $scaleDownHideLabel=$('<div>Hide</div>').addClass('slide-label');
|
||||
var $scaleDownLabel=$('<div>Show</div>').addClass('slide-label');
|
||||
var $slideScaleDown = $('<div></div>').addClass('expand');
|
||||
var $hideScaleDown = $('<div></div>').addClass('hide');
|
||||
var $scaleUpDivider = $('<hr></hr>').addClass('policy-divider');
|
||||
var $scaleDownDivider = $('<hr></hr>').addClass('policy-divider');
|
||||
var $bottomFieldDivider = $('<hr></hr>').addClass('policy-divider');
|
||||
var $scaleDownPolicy = $('<div>').addClass('scale-down-policy');
|
||||
var $scaleUpPolicyTitle = $('<div>').addClass('scale-up-policy-title')
|
||||
.html("Scale Up Policy");
|
||||
var $scaleDownPolicyTitle = $('<div>').addClass('scale-down-policy-title')
|
||||
.html("Scale Down Policy");
|
||||
var topFieldForm, $topFieldForm,
|
||||
bottomFieldForm, $bottomFieldForm,
|
||||
scaleUpPolicyTitleForm, $scaleUpPolicyTitleForm,
|
||||
scaleDownPolicyTitleForm, $scaleDownPolicyTitleForm,
|
||||
scaleUpPolicyForm, scaleDownPolicyForm;
|
||||
|
||||
var renderDialogContent = function(args) {
|
||||
var data = args.data ? args.data : {};
|
||||
|
||||
// Setup default values, in case where existing data is present
|
||||
var setDefaultFields = function(fieldID, field) {
|
||||
var fieldData = data[fieldID];
|
||||
|
||||
if (fieldData && !field.isBoolean) {
|
||||
field.defaultValue = fieldData;
|
||||
} else {
|
||||
field.isChecked = fieldData;
|
||||
}
|
||||
};
|
||||
$.each(topfields, setDefaultFields);
|
||||
$.each(bottomfields, setDefaultFields);
|
||||
|
||||
// Create and append top fields
|
||||
// -- uses create form to generate fields
|
||||
topFieldForm = cloudStack.dialog.createForm({
|
||||
context: context,
|
||||
noDialog: true, // Don't render a dialog, just return $formContainer
|
||||
form: {
|
||||
title: '',
|
||||
fields: topfields
|
||||
}
|
||||
});
|
||||
$topFieldForm = topFieldForm.$formContainer;
|
||||
$topFieldForm.appendTo($topFields);
|
||||
|
||||
scaleUpPolicyTitleForm = cloudStack.dialog.createForm({
|
||||
context: context,
|
||||
noDialog: true,
|
||||
form: {
|
||||
title: '',
|
||||
fields: {
|
||||
scaleUpDuration: { label: 'Duration', validation: { required: true } }
|
||||
}
|
||||
}
|
||||
});
|
||||
$scaleUpPolicyTitleForm = scaleUpPolicyTitleForm.$formContainer;
|
||||
$scaleUpPolicyTitleForm.appendTo($scaleUpPolicyTitle);
|
||||
|
||||
|
||||
scaleDownPolicyTitleForm = cloudStack.dialog.createForm({
|
||||
context: context,
|
||||
noDialog: true,
|
||||
form: {
|
||||
title: '',
|
||||
fields: {
|
||||
scaleDownDuration: { label: 'Duration', validation: { required: true } }
|
||||
}
|
||||
}
|
||||
});
|
||||
$scaleDownPolicyTitleForm = scaleDownPolicyTitleForm.$formContainer;
|
||||
$scaleDownPolicyTitleForm.appendTo($scaleDownPolicyTitle);
|
||||
|
||||
// Make multi-edits
|
||||
//
|
||||
// Scale up policy
|
||||
if (data.scaleUpPolicy && $.isArray(data.scaleUpPolicy.conditions)) {
|
||||
$autoscalerDialog.data('autoscaler-scale-up-data',
|
||||
data.scaleUpPolicy.conditions);
|
||||
}
|
||||
|
||||
if (data.scaleUpPolicy && data.scaleUpPolicy.duration) {
|
||||
$scaleUpPolicyTitleForm.find('input[name=scaleUpDuration]').val(
|
||||
data.scaleUpPolicy.duration
|
||||
);
|
||||
}
|
||||
|
||||
scaleuppolicy.context = context;
|
||||
scaleUpPolicyForm = $scaleUpPolicy.multiEdit(scaleuppolicy);
|
||||
|
||||
// Scale down policy
|
||||
if (data.scaleDownPolicy && $.isArray(data.scaleDownPolicy.conditions)) {
|
||||
$autoscalerDialog.data('autoscaler-scale-down-data',
|
||||
data.scaleDownPolicy.conditions);
|
||||
}
|
||||
|
||||
if (data.scaleDownPolicy && data.scaleDownPolicy.duration) {
|
||||
$scaleDownPolicyTitleForm.find('input[name=scaleDownDuration]').val(
|
||||
data.scaleDownPolicy.duration
|
||||
);
|
||||
}
|
||||
|
||||
scaledownpolicy.context = context;
|
||||
scaleDownPolicyForm = $scaleDownPolicy.multiEdit(scaledownpolicy);
|
||||
|
||||
// Create and append bottom fields
|
||||
bottomFieldForm = cloudStack.dialog.createForm({
|
||||
context: context,
|
||||
noDialog: true, // Don't render a dialog, just return $formContainer
|
||||
form: {
|
||||
title: '',
|
||||
fields: bottomfields
|
||||
}
|
||||
});
|
||||
$bottomFieldForm = bottomFieldForm.$formContainer;
|
||||
$bottomFieldForm.appendTo($bottomFields);
|
||||
|
||||
// Append main div elements
|
||||
$autoscalerDialog.append(
|
||||
$topFields,
|
||||
$scaleUpPolicyTitle,
|
||||
$scaleUpPolicy,
|
||||
$scaleDownPolicyTitle,
|
||||
$scaleDownPolicy,
|
||||
$bottomFields
|
||||
);
|
||||
|
||||
// Render dialog
|
||||
//$autoscalerDialog.find('.form-item[rel=templateNames] label').hide();
|
||||
/* Duration Fields*/
|
||||
//$('div.ui-dialog div.autoscaler').find('div.scale-up-policy-title').append("<br></br>").append($inputLabel = $('<label>').html('Duration').attr({left:'200'})).append($('<input>').attr({ name: 'username' }));
|
||||
//$('div.ui-dialog div.autoscaler').find('div.scale-down-policy-title').append("<br></br>").append($inputLabel = $('<label>').html('Duration').attr({left:'200'})).append($('<input>').attr({ name: 'username' }));
|
||||
|
||||
/*Dividers*/
|
||||
$autoscalerDialog.find('div.scale-up-policy-title').prepend($scaleUpDivider);
|
||||
$autoscalerDialog.find('div.scale-down-policy-title').prepend($scaleDownDivider);
|
||||
$autoscalerDialog.find('div.field-group.bottom-fields').prepend($bottomFieldDivider);
|
||||
|
||||
/* Hide effects for multi-edit table*/
|
||||
$autoscalerDialog.find('div.scale-up-policy').prepend($hideScaleUp);
|
||||
$autoscalerDialog.find('div.scale-down-policy ').prepend($hideScaleDown);
|
||||
$autoscalerDialog.find('div.scale-up-policy').prepend($scaleUpHideLabel);
|
||||
$autoscalerDialog.find('div.scale-down-policy').prepend($scaleDownHideLabel);
|
||||
|
||||
/*Toggling the labels and data-item table - SCALE UP POLICY*/
|
||||
$autoscalerDialog.find('div.scale-up-policy div.hide').click(function() {
|
||||
$autoscalerDialog.find('div.scale-up-policy div.multi-edit div.data-item').slideToggle();
|
||||
$scaleUpLabel = $autoscalerDialog.find('div.scale-up-policy div.slide-label').replaceWith($scaleUpLabel);
|
||||
});
|
||||
|
||||
/*Toggling the images */
|
||||
$('div.ui-dialog div.autoscaler div.scale-up-policy div.hide').click(function() {
|
||||
$(this).toggleClass('expand hide');
|
||||
});
|
||||
|
||||
$('div.ui-dialog div.autoscaler div.scale-down-policy div.hide').click(function() {
|
||||
$(this).toggleClass('expand hide');
|
||||
});
|
||||
|
||||
/*Toggling the labels and data-item table - SCALE DOWN POLICY*/
|
||||
$('div.ui-dialog div.autoscaler div.scale-down-policy div.hide').click(function() {
|
||||
$('div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data div.data-item').slideToggle();
|
||||
$scaleDownLabel = $('div.ui-dialog div.autoscaler div.scale-down-policy div.slide-label').replaceWith($scaleDownLabel);
|
||||
});
|
||||
|
||||
$('div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data div.expand').click(function() { $('div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data div.data-item').slideToggle(); });
|
||||
|
||||
$autoscalerDialog.dialog('option', 'position', 'center');
|
||||
$autoscalerDialog.dialog('option', 'height', 'auto');
|
||||
};
|
||||
|
||||
var $loading = $('<div>').addClass('loading-overlay').appendTo($autoscalerDialog);
|
||||
$autoscalerDialog.dialog({
|
||||
title: 'AutoScale Configuration Wizard',
|
||||
width: 825,
|
||||
height: 600,
|
||||
draggable: true,
|
||||
closeonEscape: false,
|
||||
overflow:'auto',
|
||||
open:function() {
|
||||
$("button").each(function(){
|
||||
$(this).attr("style", "left: 600px; position: relative; margin-right: 5px; ");
|
||||
});
|
||||
},
|
||||
buttons: [
|
||||
{
|
||||
text: _l('label.cancel'),
|
||||
'class': 'cancel',
|
||||
click: function() {
|
||||
$autoscalerDialog.dialog('destroy');
|
||||
$('.overlay').remove();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: _l('Apply'),
|
||||
'class': 'ok',
|
||||
click: function() {
|
||||
var data = cloudStack.serializeForm($('.ui-dialog .autoscaler form'));
|
||||
|
||||
$loading.appendTo($autoscalerDialog);
|
||||
cloudStack.autoscaler.actions.add({
|
||||
formData: formData,
|
||||
context: context,
|
||||
data: data,
|
||||
response: {
|
||||
success: function() {
|
||||
$loading.remove();
|
||||
$autoscalerDialog.dialog('destroy');
|
||||
$autoscalerDialog.closest(':ui-dialog').remove();
|
||||
$('.overlay').remove();
|
||||
cloudStack.dialog.notice({
|
||||
message: 'Autoscaler configured successfully.'
|
||||
});
|
||||
},
|
||||
error: function(message) {
|
||||
cloudStack.dialog.notice({ message: message });
|
||||
$loading.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
||||
}).closest('.ui-dialog').overlay();
|
||||
|
||||
dataProvider({
|
||||
context: context,
|
||||
response: {
|
||||
success: function(args) {
|
||||
$loading.remove();
|
||||
renderDialogContent(args);
|
||||
|
||||
if (args.data && args.data.isAdvanced) {
|
||||
$autoscalerDialog.find('input[type=checkbox]').trigger('click');
|
||||
$autoscalerDialog.find('input[type=checkbox]').attr('checked', 'checked');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
}(jQuery, cloudStack));
|
||||
|
|
@ -129,13 +129,20 @@
|
|||
$td.attr('title', data[fieldName]);
|
||||
}
|
||||
} else if (field.select) {
|
||||
$td.append($('<span>').html(_s(
|
||||
// Get matching option text
|
||||
$multi.find('select').filter(function() {
|
||||
return $(this).attr('name') == fieldName;
|
||||
}).find('option').filter(function() {
|
||||
return $(this).val() == data[fieldName];
|
||||
}).html())));
|
||||
// Get matching option text
|
||||
var $matchingSelect = $multi.find('select')
|
||||
.filter(function() {
|
||||
return $(this).attr('name') == fieldName;
|
||||
});
|
||||
var $matchingOption = $matchingSelect.find('option')
|
||||
.filter(function() {
|
||||
return $(this).val() == data[fieldName];
|
||||
});
|
||||
|
||||
var matchingValue = $matchingOption.size() ?
|
||||
$matchingOption.html() : data[fieldName];
|
||||
|
||||
$td.append($('<span>').html(_s(matchingValue)));
|
||||
} else if (field.addButton && !options.noSelect) {
|
||||
if (options.multipleAdd) {
|
||||
$addButton.click(function() {
|
||||
|
|
@ -180,9 +187,14 @@
|
|||
if ($td.hasClass('disabled')) return false;
|
||||
|
||||
var $button = $(this);
|
||||
var context = $.extend(true, {},
|
||||
options.context ?
|
||||
options.context : cloudStack.context, {
|
||||
multiRules: [data]
|
||||
});
|
||||
|
||||
field.custom.action({
|
||||
context: options.context ? options.context : cloudStack.context,
|
||||
context: context,
|
||||
data: $td.data('multi-custom-data'),
|
||||
$item: $td,
|
||||
response: {
|
||||
|
|
@ -814,6 +826,7 @@
|
|||
var formData = getMultiData($multi);
|
||||
|
||||
field.custom.action({
|
||||
formData: formData,
|
||||
context: context,
|
||||
data: $td.data('multi-custom-data'),
|
||||
response: {
|
||||
|
|
@ -1024,7 +1037,7 @@
|
|||
}
|
||||
|
||||
// Get existing data
|
||||
getData();
|
||||
setTimeout(function() { getData(); });
|
||||
|
||||
var fullRefreshEvent = function(event) {
|
||||
if ($multi.is(':visible')) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue