From af5bf94b431cea91f424ec1b5dc038a22d25a954 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Mon, 6 May 2013 20:57:02 +0100 Subject: [PATCH] CLOUDSTACK-2319: fix "unable to add egress rules" in SecurityGroup Signed-off-by: Chip Childers --- .../network/security/SecurityGroupRules.java | 2 + .../security/SecurityGroupRulesVO.java | 15 +- .../dao/SecurityGroupRulesDaoImpl.java | 9 + ui/scripts/network.js | 297 +++++++++--------- 4 files changed, 168 insertions(+), 155 deletions(-) diff --git a/api/src/com/cloud/network/security/SecurityGroupRules.java b/api/src/com/cloud/network/security/SecurityGroupRules.java index d255e46fde5..4dbafd62e98 100644 --- a/api/src/com/cloud/network/security/SecurityGroupRules.java +++ b/api/src/com/cloud/network/security/SecurityGroupRules.java @@ -31,6 +31,8 @@ public interface SecurityGroupRules extends InternalIdentity { Long getRuleId(); + String getRuleUuid(); + int getStartPort(); int getEndPort(); diff --git a/core/src/com/cloud/network/security/SecurityGroupRulesVO.java b/core/src/com/cloud/network/security/SecurityGroupRulesVO.java index 82060efce12..c74152e453c 100644 --- a/core/src/com/cloud/network/security/SecurityGroupRulesVO.java +++ b/core/src/com/cloud/network/security/SecurityGroupRulesVO.java @@ -54,6 +54,9 @@ public class SecurityGroupRulesVO implements SecurityGroupRules { @Column(name = "id", table = "security_group_rule", insertable = false, updatable = false) private Long ruleId; + @Column(name = "uuid", table = "security_group_rule", insertable = false, updatable = false) + private String ruleUuid; + @Column(name = "start_port", table = "security_group_rule", insertable = false, updatable = false) private int startPort; @@ -75,7 +78,11 @@ public class SecurityGroupRulesVO implements SecurityGroupRules { public SecurityGroupRulesVO() { } - public SecurityGroupRulesVO(long id, String name, String description, Long domainId, Long accountId, Long ruleId, int startPort, int endPort, String protocol, Long allowedNetworkId, + public SecurityGroupRulesVO(long id) { + this.id = id; + } + + public SecurityGroupRulesVO(long id, String name, String description, Long domainId, Long accountId, Long ruleId, String ruleUuid, int startPort, int endPort, String protocol, Long allowedNetworkId, String allowedSourceIpCidr) { this.id = id; this.name = name; @@ -83,6 +90,7 @@ public class SecurityGroupRulesVO implements SecurityGroupRules { this.domainId = domainId; this.accountId = accountId; this.ruleId = ruleId; + this.ruleUuid = ruleUuid; this.startPort = startPort; this.endPort = endPort; this.protocol = protocol; @@ -120,6 +128,11 @@ public class SecurityGroupRulesVO implements SecurityGroupRules { return ruleId; } + @Override + public String getRuleUuid() { + return ruleUuid; + } + @Override public int getStartPort() { return startPort; diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java b/server/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java index f08ca05cd7a..18ef57fbcd8 100644 --- a/server/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java +++ b/server/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java @@ -84,4 +84,13 @@ public class SecurityGroupRulesDaoImpl extends GenericDaoBase sc = createSearchCriteria(); + sc.addAnd("ruleUuid", SearchCriteria.Op.EQ, uuid); + SecurityGroupRulesVO rule = findOneIncludingRemovedBy(sc); + SecurityGroupRulesVO newRule = new SecurityGroupRulesVO(rule.getRuleId()); + return newRule; + } } diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 9ba725a8574..6b310ce0e83 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -3981,13 +3981,12 @@ account: args.context.securityGroups[0].account }; - // TCP / ICMP if (args.data.icmptype && args.data.icmpcode) { // ICMP $.extend(data, { icmptype: args.data.icmptype, icmpcode: args.data.icmpcode }); - } else { // TCP + } else { // TCP/UDP $.extend(data, { startport: args.data.startport, endport: args.data.endport @@ -4081,121 +4080,142 @@ egressRules: { title: 'label.egress.rule', - custom: function(args) { - var context = args.context; + custom: cloudStack.uiCustom.securityRules({ + noSelect: true, + noHeaderActionsColumn: true, + fields: { + 'protocol': { + label: 'label.protocol', + select: function(args) { + args.$select.change(function() { + var $inputs = args.$form.find('th, td'); + var $icmpFields = $inputs.filter(function() { + var name = $(this).attr('rel'); - return $('
').multiEdit({ - context: context, - noSelect: true, - noHeaderActionsColumn: true, - fields: { - 'cidrlist': { edit: true, label: 'label.cidr' }, - 'protocol': { - label: 'label.protocol', - select: function(args) { - args.$select.change(function() { - var $inputs = args.$form.find('th, td'); - var $icmpFields = $inputs.filter(function() { - var name = $(this).attr('rel'); + return $.inArray(name, [ + 'icmptype', + 'icmpcode' + ]) > -1; + }); + var $otherFields = $inputs.filter(function() { + var name = $(this).attr('rel'); - return $.inArray(name, [ - 'icmptype', - 'icmpcode' - ]) > -1; - }); - var $otherFields = $inputs.filter(function() { - var name = $(this).attr('rel'); - - return name != 'cidrlist' && - name != 'icmptype' && - name != 'icmpcode' && - name != 'protocol' && - name != 'add-rule'; - }); - - if ($(this).val() == 'icmp') { - $icmpFields.show(); - $otherFields.hide(); - } else { - $icmpFields.hide(); - $otherFields.show(); - } + return name != 'icmptype' && + name != 'icmpcode' && + name != 'protocol' && + name != 'add-rule' && + name != 'cidr' && + name != 'accountname' && + name != 'securitygroup'; }); - args.response.success({ - data: [ - { name: 'tcp', description: 'TCP' }, - { name: 'udp', description: 'UDP' }, - { name: 'icmp', description: 'ICMP' } - ] - }); - } - }, - 'startport': { edit: true, label: 'label.start.port' }, - 'endport': { edit: true, label: 'label.end.port' }, - 'icmptype': { edit: true, label: 'ICMP.type', isHidden: true }, - 'icmpcode': { edit: true, label: 'ICMP.code', isHidden: true }, - 'add-rule': { - label: 'label.add', - addButton: true - } - }, - add: { - label: 'label.add', - action: function(args) { - var data = { - protocol: args.data.protocol, - cidrlist: args.data.cidrlist, - trafficType: 'Egress' - }; - - if (args.data.icmptype && args.data.icmpcode) { // ICMP - $.extend(data, { - icmptype: args.data.icmptype, - icmpcode: args.data.icmpcode - }); - } else { // TCP/UDP - $.extend(data, { - startport: args.data.startport, - endport: args.data.endport - }); - } - - // Get Source NAT IP - var sourceNATIP; - - $.ajax({ - url: createURL('listPublicIpAddresses'), - data: { - listAll: true, - associatednetworkid: args.context.networks[0].id - }, - async: false, - success: function(json) { - var ipAddresses = json.listpublicipaddressesresponse.publicipaddress; - - sourceNATIP = $.grep(ipAddresses, function(ipAddress) { - return ipAddress.issourcenat; - })[0]; + if ($(this).val() == 'icmp') { + $icmpFields.show(); + $otherFields.hide(); + } else { + $icmpFields.hide(); + $otherFields.show(); } }); - data.ipaddressid = sourceNATIP.id; + args.response.success({ + data: [ + { name: 'tcp', description: 'TCP' }, + { name: 'udp', description: 'UDP' }, + { name: 'icmp', description: 'ICMP' } + ] + }); + } + }, + 'startport': { edit: true, label: 'label.start.port' }, + 'endport': { edit: true, label: 'label.end.port' }, + 'icmptype': { edit: true, label: 'ICMP.type', isHidden: true }, + 'icmpcode': { edit: true, label: 'ICMP.code', isHidden: true }, + 'cidr': { edit: true, label: 'label.cidr', isHidden: true }, + 'accountname': { + edit: true, + label: 'label.account.and.security.group', + isHidden: true, + range: ['accountname', 'securitygroup'] + }, + 'add-rule': { + label: 'label.add', + addButton: true + } + }, + add: { + label: 'label.add', + action: function(args) { + var data = { + securitygroupid: args.context.securityGroups[0].id, + protocol: args.data.protocol, + domainid: args.context.securityGroups[0].domainid, + account: args.context.securityGroups[0].account + }; + if (args.data.icmptype && args.data.icmpcode) { // ICMP + $.extend(data, { + icmptype: args.data.icmptype, + icmpcode: args.data.icmpcode + }); + } else { // TCP/UDP + $.extend(data, { + startport: args.data.startport, + endport: args.data.endport + }); + } + + // CIDR / account + if (args.data.cidr) { + data.cidrlist = args.data.cidr; + } else { + data['usersecuritygrouplist[0].account'] = args.data.accountname; + data['usersecuritygrouplist[0].group'] = args.data.securitygroup; + } + + $.ajax({ + url: createURL('authorizeSecurityGroupEgress'), + data: data, + dataType: 'json', + async: true, + success: function(data) { + var jobId = data.authorizesecuritygroupegressresponse.jobid; + + args.response.success({ + _custom: { + jobId: jobId + }, + notification: { + label: 'label.add.egress.rule', + poll: pollAsyncJobResult + } + }); + } + }); + } + }, + actions: { + destroy: { + label: 'label.remove.rule', + action: function(args) { $.ajax({ - url: createURL('createFirewallRule'), - data: data, + url: createURL('revokeSecurityGroupEgress'), + data: { + domainid: args.context.securityGroups[0].domainid, + account: args.context.securityGroups[0].account, + id: args.context.multiRule[0].id + }, dataType: 'json', async: true, - success: function(json) { - var jobId = json.createfirewallruleresponse.jobid; + success: function(data) { + var jobID = data.revokesecuritygroupegress.jobid; args.response.success({ _custom: { - jobId: jobId + jobId: jobID }, notification: { - label: 'label.add.egress.rule', + label: 'label.remove.egress.rule', poll: pollAsyncJobResult } }); @@ -4205,60 +4225,29 @@ } }); } - }, - actions: { - destroy: { - label: 'label.remove.rule', - action: function(args) { - $.ajax({ - url: createURL('deleteFirewallRule'), - data: { - id: args.context.multiRule[0].id - }, - dataType: 'json', - async: true, - success: function(data) { - var jobID = data.deletefirewallruleresponse.jobid; - - args.response.success({ - _custom: { - jobId: jobID - }, - notification: { - label: 'label.remove.egress.rule', - poll: pollAsyncJobResult - } - }); - }, - error: function(json) { - args.response.error(parseXMLHttpResponse(json)); - } - }); - } - } - }, - ignoreEmptyFields: true, - dataProvider: function(args) { - $.ajax({ - url: createURL('listFirewallRules'), - data: { - listAll: true, - networkid: args.context.networks[0].id, - trafficType: 'Egress' - }, - dataType: 'json', - async: true, - success: function(json) { - var response = json.listfirewallrulesresponse.firewallrule; - - args.response.success({ - data: response - }); - } - }); } - }); - } + }, + ignoreEmptyFields: true, + dataProvider: function(args) { + $.ajax({ + url: createURL('listSecurityGroups'), + data: { + id: args.context.securityGroups[0].id + }, + dataType: 'json', + async: true, + success: function(data) { + args.response.success({ + data: $.map( + data.listsecuritygroupsresponse.securitygroup[0].egressrule ? + data.listsecuritygroupsresponse.securitygroup[0].egressrule : [], + ingressEgressDataMap + ) + }); + } + }); + } + }) } },