diff --git a/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java b/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java index e6a4ea4646a..56c5d82a6e5 100644 --- a/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java @@ -63,8 +63,8 @@ import com.cloud.agent.api.ReadyAnswer; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; -import com.cloud.agent.api.SecurityIngressRuleAnswer; -import com.cloud.agent.api.SecurityIngressRulesCmd; +import com.cloud.agent.api.SecurityGroupRuleAnswer; +import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; @@ -234,8 +234,8 @@ public class FakeComputingResource extends ServerResourceBase implements ServerR return execute((GetStorageStatsCommand) cmd); } else if (cmd instanceof ModifyStoragePoolCommand) { return execute((ModifyStoragePoolCommand) cmd); - } else if (cmd instanceof SecurityIngressRulesCmd) { - return execute((SecurityIngressRulesCmd) cmd); + } else if (cmd instanceof SecurityGroupRulesCmd) { + return execute((SecurityGroupRulesCmd) cmd); } else if (cmd instanceof StartCommand ) { return execute((StartCommand) cmd); } else if (cmd instanceof CleanupNetworkRulesCmd) { @@ -257,9 +257,9 @@ public class FakeComputingResource extends ServerResourceBase implements ServerR return new Answer(cmd); } - private Answer execute(SecurityIngressRulesCmd cmd) { - s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", numrules=" + cmd.getRuleSet().length); - return new SecurityIngressRuleAnswer(cmd); + private Answer execute(SecurityGroupRulesCmd cmd) { + s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ",ingress numrules=" + cmd.getIngressRuleSet().length + ",egress numrules=" + cmd.getEgressRuleSet().length); + return new SecurityGroupRuleAnswer(cmd); } private Answer execute(ModifyStoragePoolCommand cmd) { diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java index d434f1181ef..95fe2970c1a 100644 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java @@ -120,8 +120,8 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; -import com.cloud.agent.api.SecurityIngressRuleAnswer; -import com.cloud.agent.api.SecurityIngressRulesCmd; +import com.cloud.agent.api.SecurityGroupRuleAnswer; +import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; @@ -913,8 +913,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((CreateStoragePoolCommand) cmd); } else if (cmd instanceof ModifyStoragePoolCommand) { return execute((ModifyStoragePoolCommand) cmd); - } else if (cmd instanceof SecurityIngressRulesCmd) { - return execute((SecurityIngressRulesCmd) cmd); + } else if (cmd instanceof SecurityGroupRulesCmd) { + return execute((SecurityGroupRulesCmd) cmd); } else if (cmd instanceof DeleteStoragePoolCommand) { return execute((DeleteStoragePoolCommand) cmd); } else if (cmd instanceof FenceCommand ) { @@ -1568,7 +1568,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return answer; } - private Answer execute(SecurityIngressRulesCmd cmd) { + private Answer execute(SecurityGroupRulesCmd cmd) { String vif = null; String brname = null; try { @@ -1577,7 +1577,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vif = nics.get(0).getDevName(); brname = nics.get(0).getBrName(); } catch (LibvirtException e) { - return new SecurityIngressRuleAnswer(cmd, false, e.toString()); + return new SecurityGroupRuleAnswer(cmd, false, e.toString()); } boolean result = add_network_rules(cmd.getVmName(), @@ -1589,10 +1589,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (!result) { s_logger.warn("Failed to program network rules for vm " + cmd.getVmName()); - return new SecurityIngressRuleAnswer(cmd, false, "programming network rules failed"); + return new SecurityGroupRuleAnswer(cmd, false, "programming network rules failed"); } else { - s_logger.debug("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", numrules=" + cmd.getRuleSet().length); - return new SecurityIngressRuleAnswer(cmd); + s_logger.debug("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ",ingress numrules=" + cmd.getIngressRuleSet().length + ",egress numrules=" + cmd.getEgressRuleSet().length); + return new SecurityGroupRuleAnswer(cmd); } } diff --git a/api/src/com/cloud/agent/api/SecurityEgressRuleAnswer.java b/api/src/com/cloud/agent/api/SecurityEgressRuleAnswer.java deleted file mode 100644 index 1b0d33326c1..00000000000 --- a/api/src/com/cloud/agent/api/SecurityEgressRuleAnswer.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package com.cloud.agent.api; - -public class SecurityEgressRuleAnswer extends Answer { - Long logSequenceNumber = null; - Long vmId = null; - - protected SecurityEgressRuleAnswer() { - } - - public SecurityEgressRuleAnswer(SecurityEgressRulesCmd cmd) { - super(cmd); - this.logSequenceNumber = cmd.getSeqNum(); - this.vmId = cmd.getVmId(); - } - - public SecurityEgressRuleAnswer(SecurityEgressRulesCmd cmd, boolean result, String detail) { - super(cmd, result, detail); - this.logSequenceNumber = cmd.getSeqNum(); - this.vmId = cmd.getVmId(); - } - - public Long getLogSequenceNumber() { - return logSequenceNumber; - } - - public Long getVmId() { - return vmId; - } - -} diff --git a/api/src/com/cloud/agent/api/SecurityEgressRulesCmd.java b/api/src/com/cloud/agent/api/SecurityEgressRulesCmd.java deleted file mode 100644 index f9c096d7768..00000000000 --- a/api/src/com/cloud/agent/api/SecurityEgressRulesCmd.java +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package com.cloud.agent.api; - - -public class SecurityEgressRulesCmd extends Command { - public static class EgressIpPortAndProto { - String proto; - int startPort; - int endPort; - String [] allowedCidrs; - - public EgressIpPortAndProto() { } - - public EgressIpPortAndProto(String proto, int startPort, int endPort, - String[] allowedCidrs) { - super(); - this.proto = proto; - this.startPort = startPort; - this.endPort = endPort; - this.allowedCidrs = allowedCidrs; - } - - public String[] getAllowedCidrs() { - return allowedCidrs; - } - - public void setAllowedCidrs(String[] allowedCidrs) { - this.allowedCidrs = allowedCidrs; - } - - public String getProto() { - return proto; - } - - public int getStartPort() { - return startPort; - } - - public int getEndPort() { - return endPort; - } - - } - - - String guestIp; - String vmName; - String guestMac; - String signature; - Long seqNum; - Long vmId; - EgressIpPortAndProto [] ruleSet; - - public SecurityEgressRulesCmd() { - super(); - } - - - public SecurityEgressRulesCmd(String guestIp, String guestMac, String vmName, Long vmId, String signature, Long seqNum, EgressIpPortAndProto[] ruleSet) { - super(); - this.guestIp = guestIp; - this.vmName = vmName; - this.ruleSet = ruleSet; - this.guestMac = guestMac; - this.signature = signature; - this.seqNum = seqNum; - this.vmId = vmId; - } - - - @Override - public boolean executeInSequence() { - return true; - } - - - public EgressIpPortAndProto[] getRuleSet() { - return ruleSet; - } - - - public void setRuleSet(EgressIpPortAndProto[] ruleSet) { - this.ruleSet = ruleSet; - } - - - public String getGuestIp() { - return guestIp; - } - - - public String getVmName() { - return vmName; - } - - public String stringifyRules() { - StringBuilder ruleBuilder = new StringBuilder(); - for (SecurityEgressRulesCmd.EgressIpPortAndProto ipPandP: getRuleSet()) { - ruleBuilder.append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":"); - for (String cidr: ipPandP.getAllowedCidrs()) { - ruleBuilder.append(cidr).append(","); - } - ruleBuilder.append("NEXT"); - ruleBuilder.append(" "); - } - return ruleBuilder.toString(); - } - - public String getSignature() { - return signature; - } - - - public String getGuestMac() { - return guestMac; - } - - - public Long getSeqNum() { - return seqNum; - } - - - public Long getVmId() { - return vmId; - } - -} diff --git a/api/src/com/cloud/agent/api/SecurityIngressRuleAnswer.java b/api/src/com/cloud/agent/api/SecurityGroupRuleAnswer.java similarity index 73% rename from api/src/com/cloud/agent/api/SecurityIngressRuleAnswer.java rename to api/src/com/cloud/agent/api/SecurityGroupRuleAnswer.java index caaf00006ce..3e91d3f871b 100644 --- a/api/src/com/cloud/agent/api/SecurityIngressRuleAnswer.java +++ b/api/src/com/cloud/agent/api/SecurityGroupRuleAnswer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved * * This software is licensed under the GNU General Public License v3 or later. * @@ -17,7 +17,7 @@ */ package com.cloud.agent.api; -public class SecurityIngressRuleAnswer extends Answer { +public class SecurityGroupRuleAnswer extends Answer { public static enum FailureReason { NONE, UNKNOWN, @@ -29,36 +29,36 @@ public class SecurityIngressRuleAnswer extends Answer { FailureReason reason = FailureReason.NONE; - protected SecurityIngressRuleAnswer() { + protected SecurityGroupRuleAnswer() { } - public SecurityIngressRuleAnswer(SecurityIngressRulesCmd cmd) { + public SecurityGroupRuleAnswer(SecurityGroupRulesCmd cmd) { super(cmd); this.logSequenceNumber = cmd.getSeqNum(); this.vmId = cmd.getVmId(); } - public SecurityIngressRuleAnswer(SecurityIngressRulesCmd cmd, boolean result, String detail) { + public SecurityGroupRuleAnswer(SecurityGroupRulesCmd cmd, boolean result, String detail) { super(cmd, result, detail); this.logSequenceNumber = cmd.getSeqNum(); this.vmId = cmd.getVmId(); reason = FailureReason.PROGRAMMING_FAILED; } - public SecurityIngressRuleAnswer(SecurityIngressRulesCmd cmd, boolean result, String detail, FailureReason r) { + public SecurityGroupRuleAnswer(SecurityGroupRulesCmd cmd, boolean result, String detail, FailureReason r) { super(cmd, result, detail); this.logSequenceNumber = cmd.getSeqNum(); this.vmId = cmd.getVmId(); reason = r; } - public Long getLogSequenceNumber() { - return logSequenceNumber; - } + public Long getLogSequenceNumber() { + return logSequenceNumber; + } - public Long getVmId() { - return vmId; - } + public Long getVmId() { + return vmId; + } public FailureReason getReason() { return reason; diff --git a/api/src/com/cloud/agent/api/SecurityIngressRulesCmd.java b/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java similarity index 59% rename from api/src/com/cloud/agent/api/SecurityIngressRulesCmd.java rename to api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java index 439598e1299..b41288cb0e2 100644 --- a/api/src/com/cloud/agent/api/SecurityIngressRulesCmd.java +++ b/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved * * This software is licensed under the GNU General Public License v3 or later. * @@ -29,14 +29,14 @@ import com.cloud.agent.api.LogLevel.Log4jLevel; import com.cloud.utils.net.NetUtils; -public class SecurityIngressRulesCmd extends Command { - private static Logger s_logger = Logger.getLogger(SecurityIngressRulesCmd.class); +public class SecurityGroupRulesCmd extends Command { + private static Logger s_logger = Logger.getLogger(SecurityGroupRulesCmd.class); public static class IpPortAndProto { - String proto; - int startPort; - int endPort; + private String proto; + private int startPort; + private int endPort; @LogLevel(Log4jLevel.Trace) - String [] allowedCidrs; + private String [] allowedCidrs; public IpPortAndProto() { } @@ -79,18 +79,20 @@ public class SecurityIngressRulesCmd extends Command { Long seqNum; Long vmId; Long msId; - IpPortAndProto [] ruleSet; + IpPortAndProto [] ingressRuleSet; + IpPortAndProto [] egressRuleSet; - public SecurityIngressRulesCmd() { + public SecurityGroupRulesCmd() { super(); } - public SecurityIngressRulesCmd(String guestIp, String guestMac, String vmName, Long vmId, String signature, Long seqNum, IpPortAndProto[] ruleSet) { + public SecurityGroupRulesCmd(String guestIp, String guestMac, String vmName, Long vmId, String signature, Long seqNum, IpPortAndProto[] ingressRuleSet, IpPortAndProto[] egressRuleSet) { super(); this.guestIp = guestIp; this.vmName = vmName; - this.ruleSet = ruleSet; + this.ingressRuleSet = ingressRuleSet; + this.egressRuleSet = egressRuleSet; this.guestMac = guestMac; this.signature = signature; this.seqNum = seqNum; @@ -108,16 +110,24 @@ public class SecurityIngressRulesCmd extends Command { } - public IpPortAndProto[] getRuleSet() { - return ruleSet; + public IpPortAndProto[] getIngressRuleSet() { + return ingressRuleSet; } - public void setRuleSet(IpPortAndProto[] ruleSet) { - this.ruleSet = ruleSet; + public void setIngressRuleSet(IpPortAndProto[] ingressRuleSet) { + this.ingressRuleSet = ingressRuleSet; + } + + public IpPortAndProto[] getEgressRuleSet() { + return egressRuleSet; } + public void setEgressRuleSet(IpPortAndProto[] egressRuleSet) { + this.egressRuleSet = egressRuleSet; + } + public String getGuestIp() { return guestIp; } @@ -129,8 +139,16 @@ public class SecurityIngressRulesCmd extends Command { public String stringifyRules() { StringBuilder ruleBuilder = new StringBuilder(); - for (SecurityIngressRulesCmd.IpPortAndProto ipPandP: getRuleSet()) { - ruleBuilder.append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":"); + for (SecurityGroupRulesCmd.IpPortAndProto ipPandP: getIngressRuleSet()) { + ruleBuilder.append("I:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":"); + for (String cidr: ipPandP.getAllowedCidrs()) { + ruleBuilder.append(cidr).append(","); + } + ruleBuilder.append("NEXT"); + ruleBuilder.append(" "); + } + for (SecurityGroupRulesCmd.IpPortAndProto ipPandP: getEgressRuleSet()) { + ruleBuilder.append("E:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":"); for (String cidr: ipPandP.getAllowedCidrs()) { ruleBuilder.append(cidr).append(","); } @@ -150,8 +168,17 @@ public class SecurityIngressRulesCmd extends Command { public String stringifyCompressedRules() { StringBuilder ruleBuilder = new StringBuilder(); - for (SecurityIngressRulesCmd.IpPortAndProto ipPandP: getRuleSet()) { - ruleBuilder.append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":"); + for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getIngressRuleSet()) { + ruleBuilder.append("I:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":"); + for (String cidr: ipPandP.getAllowedCidrs()) { + //convert cidrs in the form "a.b.c.d/e" to "hexvalue of 32bit ip/e" + ruleBuilder.append(compressCidr(cidr)).append(","); + } + ruleBuilder.append("NEXT"); + ruleBuilder.append(" "); + } + for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getEgressRuleSet()) { + ruleBuilder.append("E:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":"); for (String cidr: ipPandP.getAllowedCidrs()) { //convert cidrs in the form "a.b.c.d/e" to "hexvalue of 32bit ip/e" ruleBuilder.append(compressCidr(cidr)).append(","); @@ -161,14 +188,23 @@ public class SecurityIngressRulesCmd extends Command { } return ruleBuilder.toString(); } + /* - * Compress the ingress rules using zlib compression to allow the call to the hypervisor + * Compress the security group rules using zlib compression to allow the call to the hypervisor * to scale beyond 8k cidrs. */ public String compressStringifiedRules() { StringBuilder ruleBuilder = new StringBuilder(); - for (SecurityIngressRulesCmd.IpPortAndProto ipPandP: getRuleSet()) { - ruleBuilder.append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":"); + for (SecurityGroupRulesCmd.IpPortAndProto ipPandP: getIngressRuleSet()) { + ruleBuilder.append("I:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":"); + for (String cidr: ipPandP.getAllowedCidrs()) { + ruleBuilder.append(cidr).append(","); + } + ruleBuilder.append("NEXT"); + ruleBuilder.append(" "); + } + for (SecurityGroupRulesCmd.IpPortAndProto ipPandP: getEgressRuleSet()) { + ruleBuilder.append("E:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":"); for (String cidr: ipPandP.getAllowedCidrs()) { ruleBuilder.append(cidr).append(","); } @@ -184,7 +220,7 @@ public class SecurityIngressRulesCmd extends Command { dzip.write(stringified.getBytes()); dzip.close(); } catch (IOException e) { - s_logger.warn("Exception while compressing ingress rules"); + s_logger.warn("Exception while compressing security group rules"); return null; } return Base64.encodeBase64String(out.toByteArray()); @@ -212,7 +248,10 @@ public class SecurityIngressRulesCmd extends Command { public int getTotalNumCidrs() { //useful for logging int count = 0; - for (IpPortAndProto i: ruleSet) { + for (IpPortAndProto i: ingressRuleSet) { + count += i.allowedCidrs.length; + } + for (IpPortAndProto i: egressRuleSet) { count += i.allowedCidrs.length; } return count; diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java index d81b6171108..96769ab960b 100755 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -103,8 +103,7 @@ import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LoadBalancer; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.security.EgressRule; -import com.cloud.network.security.IngressRule; +import com.cloud.network.security.SecurityRule; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupRules; import com.cloud.offering.DiskOffering; @@ -209,9 +208,7 @@ public interface ResponseGenerator { ListResponse createSecurityGroupResponses(List networkGroups); - SecurityGroupResponse createSecurityGroupResponseFromIngressRule(List ingressRules); - - SecurityGroupResponse createSecurityGroupResponseFromEgressRule(List egressRules); + SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List SecurityRules); SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group); diff --git a/api/src/com/cloud/api/commands/AuthorizeSecurityGroupEgressCmd.java b/api/src/com/cloud/api/commands/AuthorizeSecurityGroupEgressCmd.java new file mode 100644 index 00000000000..be522ccff34 --- /dev/null +++ b/api/src/com/cloud/api/commands/AuthorizeSecurityGroupEgressCmd.java @@ -0,0 +1,230 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.apache.log4j.Logger; +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SecurityGroupRuleResponse; +import com.cloud.api.response.SecurityGroupResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.security.SecurityRule; +import com.cloud.user.UserContext; +import com.cloud.utils.StringUtils; + +@Implementation(responseObject = SecurityGroupRuleResponse.class, description = "Authorizes a particular egress rule for this security group") +@SuppressWarnings("rawtypes") +public class AuthorizeSecurityGroupEgressCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(AuthorizeSecurityGroupIngressCmd.class.getName()); + + private static final String s_name = "authorizesecuritygroupegressresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, description = "TCP is default. UDP is the other supported protocol") + private String protocol; + + @Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "start port for this egress rule") + private Integer startPort; + + @Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "end port for this egress rule") + private Integer endPort; + + @Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the icmp message being sent") + private Integer icmpType; + + @Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this icmp message") + private Integer icmpCode; + + @Parameter(name=ApiConstants.CIDR_LIST, type=CommandType.LIST, collectionType=CommandType.STRING, description="the cidr list associated") + private List cidrList; + + @Parameter(name = ApiConstants.USER_SECURITY_GROUP_LIST, type = CommandType.MAP, description = "user to security group mapping") + private Map userSecurityGroupList; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId for the security group. If the account parameter is used, domainId must also be used.") + private Long domainId; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for the security group. Must be used with domainId.") + private String accountName; + + @IdentityMapper(entityTableName="projects") + @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="an optional project of the security group") + private Long projectId; + + @IdentityMapper(entityTableName="security_group") + @Parameter(name=ApiConstants.SECURITY_GROUP_ID, type=CommandType.LONG, description="The ID of the security group. Mutually exclusive with securityGroupName parameter") + private Long securityGroupId; + + @Parameter(name=ApiConstants.SECURITY_GROUP_NAME, type=CommandType.STRING, description="The name of the security group. Mutually exclusive with securityGroupName parameter") + private String securityGroupName; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getAccountName() { + return accountName; + } + + public List getCidrList() { + return cidrList; + } + + public Integer getEndPort() { + return endPort; + } + + public Integer getIcmpCode() { + return icmpCode; + } + + public Integer getIcmpType() { + return icmpType; + } + + public Long getSecurityGroupId() { + if (securityGroupId != null && securityGroupName != null) { + throw new InvalidParameterValueException("securityGroupId and securityGroupName parameters are mutually exclusive"); + } + + if (securityGroupName != null) { + securityGroupId = _responseGenerator.getSecurityGroupId(securityGroupName, getEntityOwnerId()); + if (securityGroupId == null) { + throw new InvalidParameterValueException("Unable to find security group " + securityGroupName + " for account id=" + getEntityOwnerId()); + } + securityGroupName = null; + } + + if (securityGroupId == null) { + throw new InvalidParameterValueException("Either securityGroupId or securityGroupName is required by authorizeSecurityGroupIngress command"); + } + + return securityGroupId; + } + + public String getProtocol() { + if (protocol == null) { + return "all"; + } + return protocol; + } + + public Integer getStartPort() { + return startPort; + } + + public Map getUserSecurityGroupList() { + return userSecurityGroupList; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public static String getResultObjectName() { + return "securitygroup"; + } + + @Override + public long getEntityOwnerId() { + Long accountId = getAccountId(accountName, domainId, projectId); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + + return accountId; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS; + } + + @Override + public String getEventDescription() { + StringBuilder sb = new StringBuilder(); + if (getUserSecurityGroupList() != null) { + sb.append("group list(group/account): "); + Collection userGroupCollection = getUserSecurityGroupList().values(); + Iterator iter = userGroupCollection.iterator(); + + HashMap userGroup = (HashMap) iter.next(); + String group = (String) userGroup.get("group"); + String authorizedAccountName = (String) userGroup.get("account"); + sb.append(group + "/" + authorizedAccountName); + + while (iter.hasNext()) { + userGroup = (HashMap) iter.next(); + group = (String) userGroup.get("group"); + authorizedAccountName = (String) userGroup.get("account"); + sb.append(", " + group + "/" + authorizedAccountName); + } + } else if (getCidrList() != null) { + sb.append("cidr list: "); + sb.append(StringUtils.join(getCidrList(), ", ")); + } else { + sb.append(""); + } + + return "authorizing egress to group: " + getSecurityGroupId() + " to " + sb.toString(); + } + + @Override + public void execute() { + List egressRules = _securityGroupService.authorizeSecurityGroupEgress(this); + if (egressRules != null && !egressRules.isEmpty()) { + SecurityGroupResponse response = _responseGenerator.createSecurityGroupResponseFromSecurityGroupRule(egressRules); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to authorize security group egress rule(s)"); + } + + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.SecurityGroup; + } + + @Override + public Long getInstanceId() { + return getSecurityGroupId(); + } +} diff --git a/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java b/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java index 5150f381c77..cd4b67693fc 100644 --- a/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java +++ b/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java @@ -34,17 +34,17 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.BaseCmd.CommandType; -import com.cloud.api.response.IngressRuleResponse; +import com.cloud.api.response.SecurityGroupRuleResponse; import com.cloud.api.response.SecurityGroupResponse; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.network.security.IngressRule; +import com.cloud.network.security.SecurityRule; import com.cloud.user.Account; import com.cloud.user.UserContext; import com.cloud.utils.StringUtils; -@Implementation(responseObject = IngressRuleResponse.class, description = "Authorizes a particular ingress rule for this security group") +@Implementation(responseObject = SecurityGroupRuleResponse.class, description = "Authorizes a particular ingress rule for this security group") @SuppressWarnings("rawtypes") public class AuthorizeSecurityGroupIngressCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(AuthorizeSecurityGroupIngressCmd.class.getName()); @@ -71,7 +71,7 @@ public class AuthorizeSecurityGroupIngressCmd extends BaseAsyncCmd { private Integer icmpCode; @Parameter(name=ApiConstants.CIDR_LIST, type=CommandType.LIST, collectionType=CommandType.STRING, description="the cidr list associated") - private List cidrList; + private List cidrList; @Parameter(name = ApiConstants.USER_SECURITY_GROUP_LIST, type = CommandType.MAP, description = "user to security group mapping") private Map userSecurityGroupList; @@ -102,7 +102,7 @@ public class AuthorizeSecurityGroupIngressCmd extends BaseAsyncCmd { return accountName; } - public List getCidrList() { + public List getCidrList() { return cidrList; } @@ -212,9 +212,9 @@ public class AuthorizeSecurityGroupIngressCmd extends BaseAsyncCmd { @Override public void execute() { - List ingressRules = _securityGroupService.authorizeSecurityGroupIngress(this); + List ingressRules = _securityGroupService.authorizeSecurityGroupIngress(this); if (ingressRules != null && !ingressRules.isEmpty()) { - SecurityGroupResponse response = _responseGenerator.createSecurityGroupResponseFromIngressRule(ingressRules); + SecurityGroupResponse response = _responseGenerator.createSecurityGroupResponseFromSecurityGroupRule(ingressRules); this.setResponseObject(response); } else { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to authorize security group ingress rule(s)"); diff --git a/api/src/com/cloud/api/commands/RevokeSecurityGroupEgressCmd.java b/api/src/com/cloud/api/commands/RevokeSecurityGroupEgressCmd.java new file mode 100644 index 00000000000..f9038314e9d --- /dev/null +++ b/api/src/com/cloud/api/commands/RevokeSecurityGroupEgressCmd.java @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.network.security.SecurityGroup; +import com.cloud.user.Account; + +@Implementation(responseObject = SuccessResponse.class, description = "Deletes a particular egress rule from this security group") +public class RevokeSecurityGroupEgressCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(RevokeSecurityGroupEgressCmd.class.getName()); + + private static final String s_name = "revokesecuritygroupegress"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="security_group_rule") + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = true, description = "The ID of the egress rule") + private Long id; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public static String getResultObjectName() { + return "revokesecuritygroupegress"; + } + + @Override + public long getEntityOwnerId() { + SecurityGroup group = _entityMgr.findById(SecurityGroup.class, getId()); + if (group != null) { + return group.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_SECURITY_GROUP_REVOKE_EGRESS; + } + + @Override + public String getEventDescription() { + return "revoking egress rule id: " + getId(); + } + + @Override + public void execute() { + boolean result = _securityGroupService.revokeSecurityGroupEgress(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to revoke security group egress rule"); + } + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.SecurityGroup; + } + + @Override + public Long getInstanceId() { + return getId(); + } +} diff --git a/api/src/com/cloud/api/commands/RevokeSecurityGroupIngressCmd.java b/api/src/com/cloud/api/commands/RevokeSecurityGroupIngressCmd.java index ed3da11015b..ef10852696a 100644 --- a/api/src/com/cloud/api/commands/RevokeSecurityGroupIngressCmd.java +++ b/api/src/com/cloud/api/commands/RevokeSecurityGroupIngressCmd.java @@ -43,7 +43,7 @@ public class RevokeSecurityGroupIngressCmd extends BaseAsyncCmd { // ////////////// API parameters ///////////////////// // /////////////////////////////////////////////////// - @IdentityMapper(entityTableName="security_ingress_rule") + @IdentityMapper(entityTableName="security_group_rule") @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = true, description = "The ID of the ingress rule") private Long id; diff --git a/api/src/com/cloud/api/response/IngressRuleResponse.java b/api/src/com/cloud/api/response/IngressRuleResponse.java deleted file mode 100644 index 2a29e5b18f7..00000000000 --- a/api/src/com/cloud/api/response/IngressRuleResponse.java +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package com.cloud.api.response; - -import com.cloud.api.ApiConstants; -import com.cloud.api.IdentityProxy; -import com.cloud.serializer.Param; -import com.google.gson.annotations.SerializedName; - -public class IngressRuleResponse extends BaseResponse { - @SerializedName("ruleid") @Param(description="the id of the ingress rule") - private IdentityProxy ruleId = new IdentityProxy("security_ingress_rule"); - - @SerializedName("protocol") @Param(description="the protocol of the ingress rule") - private String protocol; - - @SerializedName(ApiConstants.ICMP_TYPE) @Param(description="the type of the ICMP message response") - private Integer icmpType; - - @SerializedName(ApiConstants.ICMP_CODE) @Param(description="the code for the ICMP message response") - private Integer icmpCode; - - @SerializedName(ApiConstants.START_PORT) @Param(description="the starting IP of the ingress rule") - private Integer startPort; - - @SerializedName(ApiConstants.END_PORT) @Param(description="the ending IP of the ingress rule ") - private Integer endPort; - - @SerializedName(ApiConstants.SECURITY_GROUP_NAME) @Param(description="security group name") - private String securityGroupName; - - @SerializedName(ApiConstants.ACCOUNT) @Param(description="account owning the ingress rule") - private String accountName; - - @SerializedName(ApiConstants.CIDR) @Param(description="the CIDR notation for the base IP address of the ingress rule") - private String cidr; - - public Long getRuleId() { - return ruleId.getValue(); - } - - public void setRuleId(Long ruleId) { - this.ruleId.setValue(ruleId); - } - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public Integer getIcmpType() { - return icmpType; - } - - public void setIcmpType(Integer icmpType) { - this.icmpType = icmpType; - } - - public Integer getIcmpCode() { - return icmpCode; - } - - public void setIcmpCode(Integer icmpCode) { - this.icmpCode = icmpCode; - } - - public Integer getStartPort() { - return startPort; - } - - public void setStartPort(Integer startPort) { - this.startPort = startPort; - } - - public Integer getEndPort() { - return endPort; - } - - public void setEndPort(Integer endPort) { - this.endPort = endPort; - } - - public String getSecurityGroupName() { - return securityGroupName; - } - - public void setSecurityGroupName(String securityGroupName) { - this.securityGroupName = securityGroupName; - } - - public String getAccountName() { - return accountName; - } - - public void setAccountName(String accountName) { - this.accountName = accountName; - } - - public String getCidr() { - return cidr; - } - - public void setCidr(String cidr) { - this.cidr = cidr; - } -} diff --git a/api/src/com/cloud/api/response/SecurityGroupResponse.java b/api/src/com/cloud/api/response/SecurityGroupResponse.java index 99a7f44d042..b7e00617813 100644 --- a/api/src/com/cloud/api/response/SecurityGroupResponse.java +++ b/api/src/com/cloud/api/response/SecurityGroupResponse.java @@ -50,12 +50,12 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the security group") private String domainName; - @SerializedName("ingressrule") @Param(description="the list of ingress rules associated with the security group", responseObject = IngressRuleResponse.class) - private List ingressRules; - - @SerializedName("egressrule") @Param(description="the list of ingress rules associated with the security group", responseObject = EgressRuleResponse.class) - private List egressRules; + @SerializedName("ingressrule") @Param(description="the list of ingress rules associated with the security group", responseObject = SecurityGroupRuleResponse.class) + private List ingressRules; + @SerializedName("egressrule") @Param(description="the list of egress rules associated with the security group", responseObject = SecurityGroupRuleResponse.class) + private List egressRules; + public void setId(Long id) { this.id.setValue(id); } @@ -84,14 +84,14 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt this.domainName = domainName; } - public void setIngressRules(List ingressRules) { - this.ingressRules = ingressRules; - } - - public void setEgressRules(List egressRules) { - this.egressRules = egressRules; + public void setSecurityGroupIngressRules(List securityGroupRules) { + this.ingressRules = securityGroupRules; } + public void setSecurityGroupEgressRules(List securityGroupRules) { + this.egressRules = securityGroupRules; + } + @Override public Long getObjectId() { return getId(); diff --git a/api/src/com/cloud/api/response/EgressRuleResponse.java b/api/src/com/cloud/api/response/SecurityGroupRuleResponse.java similarity index 89% rename from api/src/com/cloud/api/response/EgressRuleResponse.java rename to api/src/com/cloud/api/response/SecurityGroupRuleResponse.java index 94ec20b7159..319a4b561c8 100644 --- a/api/src/com/cloud/api/response/EgressRuleResponse.java +++ b/api/src/com/cloud/api/response/SecurityGroupRuleResponse.java @@ -22,11 +22,11 @@ import com.cloud.api.IdentityProxy; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; -public class EgressRuleResponse extends BaseResponse { - @SerializedName("ruleid") @Param(description="the id of the ingress rule") - private IdentityProxy ruleId = new IdentityProxy("security_egress_rule"); +public class SecurityGroupRuleResponse extends BaseResponse { + @SerializedName("ruleid") @Param(description="the id of the security group rule") + private IdentityProxy ruleId = new IdentityProxy("security_group_rule"); - @SerializedName("protocol") @Param(description="the protocol of the ingress rule") + @SerializedName("protocol") @Param(description="the protocol of the security group rule") private String protocol; @SerializedName(ApiConstants.ICMP_TYPE) @Param(description="the type of the ICMP message response") @@ -35,19 +35,19 @@ public class EgressRuleResponse extends BaseResponse { @SerializedName(ApiConstants.ICMP_CODE) @Param(description="the code for the ICMP message response") private Integer icmpCode; - @SerializedName(ApiConstants.START_PORT) @Param(description="the starting IP of the ingress rule") + @SerializedName(ApiConstants.START_PORT) @Param(description="the starting IP of the security group rule") private Integer startPort; - @SerializedName(ApiConstants.END_PORT) @Param(description="the ending IP of the ingress rule ") + @SerializedName(ApiConstants.END_PORT) @Param(description="the ending IP of the security group rule ") private Integer endPort; @SerializedName(ApiConstants.SECURITY_GROUP_NAME) @Param(description="security group name") private String securityGroupName; - @SerializedName(ApiConstants.ACCOUNT) @Param(description="account owning the ingress rule") + @SerializedName(ApiConstants.ACCOUNT) @Param(description="account owning the security group rule") private String accountName; - @SerializedName(ApiConstants.CIDR) @Param(description="the CIDR notation for the base IP address of the ingress rule") + @SerializedName(ApiConstants.CIDR) @Param(description="the CIDR notation for the base IP address of the security group rule") private String cidr; public Long getRuleId() { diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index fc6004a84f8..f43b86c5470 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -176,6 +176,8 @@ public class EventTypes { // Security Groups public static final String EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS = "SG.AUTH.INGRESS"; public static final String EVENT_SECURITY_GROUP_REVOKE_INGRESS = "SG.REVOKE.INGRESS"; + public static final String EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS = "SG.AUTH.EGRESS"; + public static final String EVENT_SECURITY_GROUP_REVOKE_EGRESS = "SG.REVOKE.EGRESS"; public static final String EVENT_SECURITY_GROUP_CREATE = "SG.CREATE"; public static final String EVENT_SECURITY_GROUP_DELETE = "SG.DELETE"; diff --git a/api/src/com/cloud/network/security/EgressRule.java b/api/src/com/cloud/network/security/EgressRule.java deleted file mode 100644 index 005e91d61d5..00000000000 --- a/api/src/com/cloud/network/security/EgressRule.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package com.cloud.network.security; - -import com.cloud.async.AsyncInstanceCreateStatus; - -public interface EgressRule { - long getId(); - - long getSecurityGroupId(); - - int getStartPort(); - - int getEndPort(); - - String getProtocol(); - - AsyncInstanceCreateStatus getCreateStatus(); - - Long getAllowedNetworkId(); - - String getAllowedDestinationIpCidr(); - -} diff --git a/api/src/com/cloud/network/security/SecurityGroupRules.java b/api/src/com/cloud/network/security/SecurityGroupRules.java index 92ad02db00f..5bec8d58bb0 100644 --- a/api/src/com/cloud/network/security/SecurityGroupRules.java +++ b/api/src/com/cloud/network/security/SecurityGroupRules.java @@ -16,6 +16,7 @@ * */ package com.cloud.network.security; +import com.cloud.network.security.SecurityRule.SecurityRuleType; public interface SecurityGroupRules { long getId(); @@ -39,4 +40,6 @@ public interface SecurityGroupRules { Long getAllowedNetworkId(); String getAllowedSourceIpCidr(); + + SecurityRuleType getRuleType(); } diff --git a/api/src/com/cloud/network/security/SecurityGroupService.java b/api/src/com/cloud/network/security/SecurityGroupService.java index 8d90a205ee4..4b9c0ee54f2 100644 --- a/api/src/com/cloud/network/security/SecurityGroupService.java +++ b/api/src/com/cloud/network/security/SecurityGroupService.java @@ -20,10 +20,12 @@ package com.cloud.network.security; import java.util.List; import com.cloud.api.commands.AuthorizeSecurityGroupIngressCmd; +import com.cloud.api.commands.AuthorizeSecurityGroupEgressCmd; import com.cloud.api.commands.CreateSecurityGroupCmd; import com.cloud.api.commands.DeleteSecurityGroupCmd; import com.cloud.api.commands.ListSecurityGroupsCmd; import com.cloud.api.commands.RevokeSecurityGroupIngressCmd; +import com.cloud.api.commands.RevokeSecurityGroupEgressCmd; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceInUseException; @@ -36,6 +38,7 @@ public interface SecurityGroupService { */ public SecurityGroup createSecurityGroup(CreateSecurityGroupCmd command) throws PermissionDeniedException, InvalidParameterValueException; boolean revokeSecurityGroupIngress(RevokeSecurityGroupIngressCmd cmd); + boolean revokeSecurityGroupEgress(RevokeSecurityGroupEgressCmd cmd); boolean deleteSecurityGroup(DeleteSecurityGroupCmd cmd) throws ResourceInUseException; @@ -46,6 +49,8 @@ public interface SecurityGroupService { */ public List searchForSecurityGroupRules(ListSecurityGroupsCmd cmd) throws PermissionDeniedException, InvalidParameterValueException; - public List authorizeSecurityGroupIngress(AuthorizeSecurityGroupIngressCmd cmd); + public List authorizeSecurityGroupIngress(AuthorizeSecurityGroupIngressCmd cmd); + + public List authorizeSecurityGroupEgress(AuthorizeSecurityGroupEgressCmd cmd); } diff --git a/api/src/com/cloud/network/security/IngressRule.java b/api/src/com/cloud/network/security/SecurityRule.java similarity index 66% rename from api/src/com/cloud/network/security/IngressRule.java rename to api/src/com/cloud/network/security/SecurityRule.java index 6eaeabbcbb1..b8ee413443c 100644 --- a/api/src/com/cloud/network/security/IngressRule.java +++ b/api/src/com/cloud/network/security/SecurityRule.java @@ -23,7 +23,21 @@ import com.cloud.async.AsyncInstanceCreateStatus; * @author ahuang * */ -public interface IngressRule { +public interface SecurityRule { + + public static class SecurityRuleType { + public static final SecurityRuleType IngressRule = new SecurityRuleType("ingress"); + public static final SecurityRuleType EgressRule = new SecurityRuleType("egress"); + + public SecurityRuleType(String type) { + this._type = type; + } + + public String getType(){ + return _type; + } + private String _type; + } long getId(); long getSecurityGroupId(); @@ -31,7 +45,11 @@ public interface IngressRule { int getStartPort(); int getEndPort(); - + + String getType(); + + SecurityRuleType getRuleType(); + String getProtocol(); AsyncInstanceCreateStatus getCreateStatus(); @@ -39,5 +57,7 @@ public interface IngressRule { Long getAllowedNetworkId(); String getAllowedSourceIpCidr(); + + String getUuid(); } diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index fcd3ac64491..e4b6b56dd0d 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -226,6 +226,8 @@ createSecurityGroup=com.cloud.api.commands.CreateSecurityGroupCmd;15 deleteSecurityGroup=com.cloud.api.commands.DeleteSecurityGroupCmd;15 authorizeSecurityGroupIngress=com.cloud.api.commands.AuthorizeSecurityGroupIngressCmd;15 revokeSecurityGroupIngress=com.cloud.api.commands.RevokeSecurityGroupIngressCmd;15 +authorizeSecurityGroupEgress=com.cloud.api.commands.AuthorizeSecurityGroupEgressCmd;15 +revokeSecurityGroupEgress=com.cloud.api.commands.RevokeSecurityGroupEgressCmd;15 listSecurityGroups=com.cloud.api.commands.ListSecurityGroupsCmd;15 #### vm group commands diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 70c8516a8f9..3cd2b155728 100755 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -115,10 +115,8 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; -import com.cloud.agent.api.SecurityEgressRuleAnswer; -import com.cloud.agent.api.SecurityEgressRulesCmd; -import com.cloud.agent.api.SecurityIngressRuleAnswer; -import com.cloud.agent.api.SecurityIngressRulesCmd; +import com.cloud.agent.api.SecurityGroupRuleAnswer; +import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; import com.cloud.agent.api.StartAnswer; @@ -477,8 +475,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((VpnUsersCfgCommand)cmd); } else if (clazz == CheckSshCommand.class) { return execute((CheckSshCommand)cmd); - } else if (clazz == SecurityIngressRulesCmd.class) { - return execute((SecurityIngressRulesCmd) cmd); + } else if (clazz == SecurityGroupRulesCmd.class) { + return execute((SecurityGroupRulesCmd) cmd); } else if (clazz == OvsCreateGreTunnelCommand.class) { return execute((OvsCreateGreTunnelCommand)cmd); } else if (clazz == OvsSetTagAndFlowCommand.class) { @@ -4747,37 +4745,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new OvsCreateGreTunnelAnswer(cmd, false, "EXCEPTION", _host.ip, bridge); } - private Answer execute(SecurityEgressRulesCmd cmd) { - Connection conn = getConnection(); - if (s_logger.isTraceEnabled()) { - s_logger.trace("Sending network rules command to " + _host.ip); - } - - if (!_canBridgeFirewall) { - s_logger.info("Host " + _host.ip + " cannot do bridge firewalling"); - return new SecurityEgressRuleAnswer(cmd, false, "Host " + _host.ip + " cannot do bridge firewalling"); - } - - String result = callHostPlugin(conn, "vmops", "network_rules", - "vmName", cmd.getVmName(), - "vmIP", cmd.getGuestIp(), - "vmMAC", cmd.getGuestMac(), - "type", "egress", - "vmID", Long.toString(cmd.getVmId()), - "signature", cmd.getSignature(), - "seqno", Long.toString(cmd.getSeqNum()), - "rules", cmd.stringifyRules()); - - if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { - s_logger.warn("Failed to program network rules for vm " + cmd.getVmName()); - return new SecurityEgressRuleAnswer(cmd, false, "programming network rules failed"); - } else { - s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", numrules=" + cmd.getRuleSet().length); - return new SecurityEgressRuleAnswer(cmd); - } - } - - private Answer execute(SecurityIngressRulesCmd cmd) { + private Answer execute(SecurityGroupRulesCmd cmd) { Connection conn = getConnection(); if (s_logger.isTraceEnabled()) { s_logger.trace("Sending network rules command to " + _host.ip); @@ -4785,16 +4753,15 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!_canBridgeFirewall) { s_logger.warn("Host " + _host.ip + " cannot do bridge firewalling"); - return new SecurityIngressRuleAnswer(cmd, false, - "Host " + _host.ip + " cannot do bridge firewalling", - SecurityIngressRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); + return new SecurityGroupRuleAnswer(cmd, false, + "Host " + _host.ip + " cannot do bridge firewalling", + SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); } - + String result = callHostPlugin(conn, "vmops", "network_rules", "vmName", cmd.getVmName(), "vmIP", cmd.getGuestIp(), "vmMAC", cmd.getGuestMac(), - "type", "ingress", "vmID", Long.toString(cmd.getVmId()), "signature", cmd.getSignature(), "seqno", Long.toString(cmd.getSeqNum()), @@ -4803,13 +4770,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program network rules for vm " + cmd.getVmName()); - return new SecurityIngressRuleAnswer(cmd, false, "programming network rules failed"); + return new SecurityGroupRuleAnswer(cmd, false, "programming network rules failed"); } else { - s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", numrules=" + cmd.getRuleSet().length); - return new SecurityIngressRuleAnswer(cmd); + s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", ingress numrules=" + cmd.getIngressRuleSet().length + ", egress numrules=" + cmd.getEgressRuleSet().length); + return new SecurityGroupRuleAnswer(cmd); } } - + protected Answer execute(DeleteStoragePoolCommand cmd) { Connection conn = getConnection(); StorageFilerTO poolTO = cmd.getPool(); diff --git a/core/src/com/cloud/network/security/EgressRuleVO.java b/core/src/com/cloud/network/security/EgressRuleVO.java deleted file mode 100644 index ef329b2f96b..00000000000 --- a/core/src/com/cloud/network/security/EgressRuleVO.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package com.cloud.network.security; - -import java.util.UUID; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; - -import com.cloud.api.Identity; -import com.cloud.async.AsyncInstanceCreateStatus; -import com.google.gson.annotations.Expose; - -@Entity -@Table(name = ("security_egress_rule")) -public class EgressRuleVO implements EgressRule, Identity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private long id; - - @Column(name = "security_group_id") - private long securityGroupId; - - @Column(name = "start_port") - private int startPort; - - @Column(name = "end_port") - private int endPort; - - @Column(name = "protocol") - private String protocol; - - @Column(name = "allowed_network_id", nullable = true) - private Long allowedNetworkId = null; - - @Column(name = "allowed_ip_cidr", nullable = true) - private String allowedDestinationIpCidr = null; - - @Expose - @Column(name = "create_status", updatable = true, nullable = false) - @Enumerated(value = EnumType.STRING) - private AsyncInstanceCreateStatus createStatus; - - @Column(name = "uuid") - private String uuid = UUID.randomUUID().toString(); - - public EgressRuleVO() { - } - - public EgressRuleVO(long securityGroupId, int fromPort, int toPort, String protocol, long allowedNetworkId) { - this.securityGroupId = securityGroupId; - this.startPort = fromPort; - this.endPort = toPort; - this.protocol = protocol; - this.allowedNetworkId = allowedNetworkId; - } - - public EgressRuleVO(long securityGroupId, int fromPort, int toPort, String protocol, String allowedIpCidr) { - this.securityGroupId = securityGroupId; - this.startPort = fromPort; - this.endPort = toPort; - this.protocol = protocol; - this.allowedDestinationIpCidr = allowedIpCidr; - } - - @Override - public long getId() { - return id; - } - - @Override - public long getSecurityGroupId() { - return securityGroupId; - } - - @Override - public int getStartPort() { - return startPort; - } - - @Override - public int getEndPort() { - return endPort; - } - - @Override - public String getProtocol() { - return protocol; - } - - @Override - public AsyncInstanceCreateStatus getCreateStatus() { - return createStatus; - } - - public void setCreateStatus(AsyncInstanceCreateStatus createStatus) { - this.createStatus = createStatus; - } - - @Override - public Long getAllowedNetworkId() { - return allowedNetworkId; - } - - @Override - public String getAllowedDestinationIpCidr() { - return allowedDestinationIpCidr; - } - - @Override - public String getUuid() { - return this.uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } -} diff --git a/core/src/com/cloud/network/security/IngressRuleVO.java b/core/src/com/cloud/network/security/SecurityGroupRuleVO.java similarity index 75% rename from core/src/com/cloud/network/security/IngressRuleVO.java rename to core/src/com/cloud/network/security/SecurityGroupRuleVO.java index 4931a26f3a8..bbf17549878 100644 --- a/core/src/com/cloud/network/security/IngressRuleVO.java +++ b/core/src/com/cloud/network/security/SecurityGroupRuleVO.java @@ -34,8 +34,8 @@ import com.cloud.async.AsyncInstanceCreateStatus; import com.google.gson.annotations.Expose; @Entity -@Table(name = ("security_ingress_rule")) -public class IngressRuleVO implements IngressRule, Identity { +@Table(name = ("security_group_rule")) +public class SecurityGroupRuleVO implements SecurityRule { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") @@ -50,6 +50,9 @@ public class IngressRuleVO implements IngressRule, Identity { @Column(name = "end_port") private int endPort; + @Column(name = "type") + private String type; + @Column(name = "protocol") private String protocol; @@ -67,38 +70,60 @@ public class IngressRuleVO implements IngressRule, Identity { @Column(name = "uuid") private String uuid; - public IngressRuleVO() { + public SecurityGroupRuleVO() { this.uuid = UUID.randomUUID().toString(); } - public IngressRuleVO(long securityGroupId, int fromPort, int toPort, String protocol, long allowedNetworkId) { + public SecurityGroupRuleVO(SecurityRuleType type,long securityGroupId, int fromPort, int toPort, String protocol, long allowedNetworkId ) { this.securityGroupId = securityGroupId; this.startPort = fromPort; this.endPort = toPort; this.protocol = protocol; this.allowedNetworkId = allowedNetworkId; this.uuid = UUID.randomUUID().toString(); + if (type == SecurityRuleType.IngressRule) { + this.type = SecurityRuleType.IngressRule.getType(); + } else { + this.type = SecurityRuleType.EgressRule.getType(); + } } - public IngressRuleVO(long securityGroupId, int fromPort, int toPort, String protocol, String allowedIpCidr) { + public SecurityGroupRuleVO(SecurityRuleType type,long securityGroupId, int fromPort, int toPort, String protocol, String allowedIpCidr) { this.securityGroupId = securityGroupId; this.startPort = fromPort; this.endPort = toPort; this.protocol = protocol; this.allowedSourceIpCidr = allowedIpCidr; this.uuid = UUID.randomUUID().toString(); + if (type == SecurityRuleType.IngressRule) { + this.type = SecurityRuleType.IngressRule.getType(); + } else { + this.type = SecurityRuleType.EgressRule.getType(); + } } @Override public long getId() { return id; } + + @Override + public String getType() { + return type; + } @Override public long getSecurityGroupId() { return securityGroupId; } - + + public SecurityRuleType getRuleType() { + if ("ingress".equalsIgnoreCase(this.type)) + return SecurityRuleType.IngressRule; + else + return SecurityRuleType.EgressRule; + } + @Override public int getStartPort() { return startPort; diff --git a/core/src/com/cloud/network/security/SecurityGroupRulesVO.java b/core/src/com/cloud/network/security/SecurityGroupRulesVO.java index 7485711ff94..fc2b4d6f56c 100644 --- a/core/src/com/cloud/network/security/SecurityGroupRulesVO.java +++ b/core/src/com/cloud/network/security/SecurityGroupRulesVO.java @@ -26,10 +26,11 @@ import javax.persistence.Id; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.SecondaryTable; import javax.persistence.Table; +import com.cloud.network.security.SecurityRule.SecurityRuleType; @Entity @Table(name = ("security_group")) -@SecondaryTable(name = "security_ingress_rule", join = "left", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "id", referencedColumnName = "security_group_id") }) +@SecondaryTable(name = "security_group_rule", join = "left", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "id", referencedColumnName = "security_group_id") }) public class SecurityGroupRulesVO implements SecurityGroupRules { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -48,22 +49,25 @@ public class SecurityGroupRulesVO implements SecurityGroupRules { @Column(name = "account_id") private Long accountId; - @Column(name = "id", table = "security_ingress_rule", insertable = false, updatable = false) + @Column(name = "id", table = "security_group_rule", insertable = false, updatable = false) private Long ruleId; - @Column(name = "start_port", table = "security_ingress_rule", insertable = false, updatable = false) + @Column(name = "start_port", table = "security_group_rule", insertable = false, updatable = false) private int startPort; - @Column(name = "end_port", table = "security_ingress_rule", insertable = false, updatable = false) + @Column(name = "end_port", table = "security_group_rule", insertable = false, updatable = false) private int endPort; - @Column(name = "protocol", table = "security_ingress_rule", insertable = false, updatable = false) + @Column(name = "protocol", table = "security_group_rule", insertable = false, updatable = false) private String protocol; + + @Column(name = "type", table = "security_group_rule", insertable = false, updatable = false) + private String type; - @Column(name = "allowed_network_id", table = "security_ingress_rule", insertable = false, updatable = false, nullable = true) + @Column(name = "allowed_network_id", table = "security_group_rule", insertable = false, updatable = false, nullable = true) private Long allowedNetworkId = null; - @Column(name = "allowed_ip_cidr", table = "security_ingress_rule", insertable = false, updatable = false, nullable = true) + @Column(name = "allowed_ip_cidr", table = "security_group_rule", insertable = false, updatable = false, nullable = true) private String allowedSourceIpCidr = null; public SecurityGroupRulesVO() { @@ -128,6 +132,15 @@ public class SecurityGroupRulesVO implements SecurityGroupRules { public String getProtocol() { return protocol; } + + @Override + public SecurityRuleType getRuleType() { + if ("ingress".equalsIgnoreCase(this.type)) { + return SecurityRuleType.IngressRule; + } else { + return SecurityRuleType.EgressRule; + } + } @Override public Long getAllowedNetworkId() { diff --git a/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java b/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java index 304fad3a1e2..6ff983d942f 100755 --- a/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java +++ b/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java @@ -55,8 +55,8 @@ import com.cloud.agent.api.ReadyAnswer; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; -import com.cloud.agent.api.SecurityIngressRuleAnswer; -import com.cloud.agent.api.SecurityIngressRulesCmd; +import com.cloud.agent.api.SecurityGroupRuleAnswer; +import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; @@ -1045,7 +1045,7 @@ public class OvmResourceBase implements ServerResource, HypervisorResource { } } - private Answer execute(SecurityIngressRulesCmd cmd) { + private Answer execute(SecurityGroupRulesCmd cmd) { boolean result = false; try { OvmVif.Details vif = getVifFromVm(cmd.getVmName(), null); @@ -1059,10 +1059,10 @@ public class OvmResourceBase implements ServerResource, HypervisorResource { if (!result) { s_logger.warn("Failed to program network rules for vm " + cmd.getVmName()); - return new SecurityIngressRuleAnswer(cmd, false, "programming network rules failed"); + return new SecurityGroupRuleAnswer(cmd, false, "programming network rules failed"); } else { - s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", numrules=" + cmd.getRuleSet().length); - return new SecurityIngressRuleAnswer(cmd); + s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ":ingress num rules=" + cmd.getIngressRuleSet().length + ":egress num rules=" + cmd.getEgressRuleSet().length); + return new SecurityGroupRuleAnswer(cmd); } } @@ -1270,8 +1270,8 @@ public class OvmResourceBase implements ServerResource, HypervisorResource { return execute((FenceCommand)cmd); } else if (clazz == AttachIsoCommand.class) { return execute((AttachIsoCommand)cmd); - } else if (clazz == SecurityIngressRulesCmd.class) { - return execute((SecurityIngressRulesCmd) cmd); + } else if (clazz == SecurityGroupRulesCmd.class) { + return execute((SecurityGroupRulesCmd) cmd); } else if (clazz == CleanupNetworkRulesCmd.class) { return execute((CleanupNetworkRulesCmd) cmd); } else if (clazz == PrepareOCFS2NodesCommand.class) { diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 72733f617d7..6bbc5c3370c 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -372,7 +372,10 @@ def chain_name_def(vm_name): return '-'.join(vm_name.split('-')[:-2]) + "-def" return '-'.join(vm_name.split('-')[:-1]) + "-def" return vm_name - + +def egress_chain_name(vm_name): + return chain_name(vm_name) + "-eg" + @echo def can_bridge_firewall(session, args): host_uuid = args.get('host_uuid') @@ -476,6 +479,7 @@ def ipset(ipsetname, proto, start, end, ips): def destroy_network_rules_for_vm(session, args): vm_name = args.pop('vmName') vmchain = chain_name(vm_name) + vmchain_egress = egress_chain_name(vm_name) vmchain_default = chain_name_def(vm_name) delete_rules_for_vm_in_bridge_firewall_chain(vm_name) @@ -492,9 +496,14 @@ def destroy_network_rules_for_vm(session, args): util.pread2(['iptables', '-F', vmchain]) util.pread2(['iptables', '-X', vmchain]) except: - util.SMlog("Ignoring failure to delete chain " + vmchain) + util.SMlog("Ignoring failure to delete ingress chain " + vmchain) + try: + util.pread2(['iptables', '-F', vmchain_egress]) + util.pread2(['iptables', '-X', vmchain_egress]) + except: + util.SMlog("Ignoring failure to delete egress chain " + vmchain_egress) remove_rule_log_for_vm(vm_name) @@ -630,7 +639,7 @@ def default_network_rules_systemvm(session, args): return 'false' - util.pread2(['iptables', '-A', vmchain, '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', vmchain, '-j', 'RETURN']) if write_rule_log_for_vm(vm_name, '-1', '_ignore_', domid, '_initial_', '-1') == False: util.SMlog("Failed to log default network rules for systemvm, ignoring") @@ -671,6 +680,7 @@ def default_network_rules(session, args): vmchain = chain_name(vm_name) + vmchain_egress = egress_chain_name(vm_name) vmchain_default = chain_name_def(vm_name) destroy_ebtables_rules(vmchain) @@ -680,6 +690,11 @@ def default_network_rules(session, args): util.pread2(['iptables', '-N', vmchain]) except: util.pread2(['iptables', '-F', vmchain]) + + try: + util.pread2(['iptables', '-N', vmchain_egress]) + except: + util.pread2(['iptables', '-F', vmchain_egress]) try: util.pread2(['iptables', '-N', vmchain_default]) @@ -698,8 +713,11 @@ def default_network_rules(session, args): #don't let vm spoof its ip address for v in vifs: - util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip, '-j', 'RETURN']) - util.pread2(['iptables', '-A', vmchain_default, '-j', vmchain]) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip,'-p', 'udp', '--dport', '53', '-j', 'RETURN']) + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip, '-j', vmchain_egress]) + + for v in vifs: + util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain]) except: util.SMlog("Failed to program default rules for vm " + vm_name) return 'false' @@ -900,7 +918,7 @@ def cleanup_rules(session, args): instance = 'VM' try: - chainscmd = "iptables-save | grep '^:' | awk '{print $1}' | cut -d':' -f2 | sed 's/-def/-%s/'|sort|uniq" % instance + chainscmd = "iptables-save | grep '^:' | awk '{print $1}' | cut -d':' -f2 | sed 's/-def/-%s/' | sed 's/-eg//' |sort|uniq" % instance chains = util.pread2(['/bin/bash', '-c', chainscmd]).split('\n') cleaned = 0 cleanup = [] @@ -1055,7 +1073,7 @@ def network_rules(session, args): except: pass - vmchain = chain_name(vm_name) + reason = 'seqno_change_or_sig_change' [reprogramDefault, reprogramChain, rewriteLog] = \ check_rule_log_for_vm (vm_name, vm_id, vm_ip, domid, signature, seqno) @@ -1089,17 +1107,27 @@ def network_rules(session, args): " update iptables, reason=%s" % (vm_name, seqno, len(lines), signature, vm_ip, reason)) cmds = [] + egressrules = 0 for line in lines: tokens = line.split(':') - if len(tokens) != 4: + if len(tokens) != 5: continue - protocol = tokens[0] - start = tokens[1] - end = tokens[2] + type = tokens[0] + protocol = tokens[1] + start = tokens[2] + end = tokens[3] cidrs = tokens.pop(); ips = cidrs.split(",") ips.pop() allow_any = False + action = "RETURN" + if type == 'E': + vmchain = egress_chain_name(vm_name) + direction = "dst" + egressrules = egressrules + 1 + else: + vmchain = chain_name(vm_name) + direction = "src" if '0.0.0.0/0' in ips: i = ips.index('0.0.0.0/0') del ips[i] @@ -1114,31 +1142,41 @@ def network_rules(session, args): util.SMlog(" failed to create ipset for rule " + str(tokens)) if protocol == 'all': - iptables = ['iptables', '-I', vmchain, '-m', 'state', '--state', 'NEW', '-m', 'set', '--match-set', ipsetname, 'src', '-j', 'ACCEPT'] + iptables = ['iptables', '-I', vmchain, '-m', 'state', '--state', 'NEW', '-m', 'set', '--match-set', ipsetname, direction, '-j', action] elif protocol != 'icmp': - iptables = ['iptables', '-I', vmchain, '-p', protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-m', 'set', '--match-set', ipsetname, 'src', '-j', 'ACCEPT'] + iptables = ['iptables', '-I', vmchain, '-p', protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-m', 'set', '--match-set', ipsetname, direction, '-j', action] else: range = start + "/" + end if start == "-1": range = "any" - iptables = ['iptables', '-I', vmchain, '-p', 'icmp', '--icmp-type', range, '-m', 'set', '--match-set', ipsetname, 'src', '-j', 'ACCEPT'] + iptables = ['iptables', '-I', vmchain, '-p', 'icmp', '--icmp-type', range, '-m', 'set', '--match-set', ipsetname, direction, '-j', action] cmds.append(iptables) util.SMlog(iptables) if allow_any and protocol != 'all': if protocol != 'icmp': - iptables = ['iptables', '-I', vmchain, '-p', protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-j', 'ACCEPT'] + iptables = ['iptables', '-I', vmchain, '-p', protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-j', action] else: range = start + "/" + end if start == "-1": range = "any" - iptables = ['iptables', '-I', vmchain, '-p', 'icmp', '--icmp-type', range, '-j', 'ACCEPT'] + iptables = ['iptables', '-I', vmchain, '-p', 'icmp', '--icmp-type', range, '-j', action] cmds.append(iptables) util.SMlog(iptables) - + + vmchain = chain_name(vm_name) util.pread2(['iptables', '-F', vmchain]) + egress_vmchain = egress_chain_name(vm_name) + util.pread2(['iptables', '-F', egress_vmchain]) + for cmd in cmds: util.pread2(cmd) + + if egressrules == 0 : + util.pread2(['iptables', '-A', egress_vmchain, '-j', 'RETURN']) + else: + util.pread2(['iptables', '-A', egress_vmchain, '-j', 'DROP']) + util.pread2(['iptables', '-A', vmchain, '-j', 'DROP']) if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, signature, seqno) == False: @@ -1206,3 +1244,4 @@ if __name__ == "__main__": "setLinkLocalIP":setLinkLocalIP, "lt2p_vpn":lt2p_vpn, "cleanup_rules":cleanup_rules, "checkRouter":checkRouter, "bumpUpPriority":bumpUpPriority, "getDomRVersion":getDomRVersion }) + diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py index de59df698c6..ee01fb22028 100755 --- a/scripts/vm/network/security_group.py +++ b/scripts/vm/network/security_group.py @@ -82,6 +82,7 @@ def ipset(ipsetname, proto, start, end, ips): def destroy_network_rules_for_vm(vm_name, vif=None): vmchain = vm_name + vmchain_egress = egress_chain_name(vm_name) vmchain_default = None delete_rules_for_vm_in_bridge_firewall_chain(vm_name) @@ -111,7 +112,19 @@ def destroy_network_rules_for_vm(vm_name, vif=None): execute("iptables -X " + vmchain) except: logging.debug("Ignoring failure to delete chain " + vmchain) + + + try: + execute("iptables -F " + vmchain_egress) + except: + logging.debug("Ignoring failure to delete chain " + vmchain_egress) + try: + execute("iptables -X " + vmchain_egress) + except: + logging.debug("Ignoring failure to delete chain " + vmchain_egress) + + if vif is not None: try: dnats = execute("iptables -t nat -S | grep " + vif + " | sed 's/-A/-D/'").split("\n") @@ -230,7 +243,7 @@ def default_network_rules_systemvm(vm_name, brname): logging.debug("Failed to program default rules") return 'false' - execute("iptables -A " + vmchain + " -j ACCEPT") + execute("iptables -A " + vmchain + " -j RETURN") if write_rule_log_for_vm(vm_name, '-1', '_ignore_', domid, '_initial_', '-1') == False: logging.debug("Failed to log default network rules for systemvm, ignoring") @@ -246,6 +259,7 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname): domID = getvmId(vm_name) delete_rules_for_vm_in_bridge_firewall_chain(vmName) vmchain = vm_name + vmchain_egress = egress_chain_name(vm_name) vmchain_default = '-'.join(vmchain.split('-')[:-1]) + "-def" destroy_ebtables_rules(vmName, vif) @@ -254,7 +268,12 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname): execute("iptables -N " + vmchain) except: execute("iptables -F " + vmchain) - + + try: + execute("iptables -N " + vmchain_egress) + except: + execute("iptables -F " + vmchain_egress) + try: execute("iptables -N " + vmchain_default) except: @@ -270,8 +289,9 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname): #don't let vm spoof its ip address if vm_ip is not None: - execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -j ACCEPT") - execute("iptables -A " + vmchain_default + " -j " + vmchain) + execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -p udp --dport 53 -j RETURN ") + execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -j " + vmchain_egress) + execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain) execute("iptables -A " + vmchain + " -j DROP") except: logging.debug("Failed to program default rules for vm " + vm_name) @@ -468,7 +488,7 @@ def cleanup_rules_for_dead_vms(): def cleanup_rules(): try: - chainscmd = "iptables-save | grep '^:' | grep -v '.*-def' | awk '{print $1}' | cut -d':' -f2" + chainscmd = "iptables-save | grep '^:' | grep -v '.*-def' | grep -v '.*-eg' | awk '{print $1}' | cut -d':' -f2" chains = execute(chainscmd).split('\n') cleaned = 0 cleanup = [] @@ -552,12 +572,17 @@ def remove_rule_log_for_vm(vmName): return result +def egress_chain_name(vm_name): + return vm_name + "-eg" + def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif, brname): try: vmName = vm_name domId = getvmId(vmName) - vmchain = vm_name + + + changes = [] changes = check_rule_log_for_vm(vmName, vm_id, vm_ip, domId, signature, seqno) @@ -574,20 +599,32 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif lines = rules.split(';')[:-1] logging.debug(" programming network rules for IP: " + vm_ip + " vmname=" + vm_name) + vmchain = vm_name execute("iptables -F " + vmchain) - + egress_vmchain = egress_chain_name(vm_name) + execute("iptables -F " + egress_vmchain) + egressrule = 0 for line in lines: tokens = line.split(':') - if len(tokens) != 4: + if len(tokens) != 5: continue - protocol = tokens[0] - start = tokens[1] - end = tokens[2] + ruletype = tokens[0] + protocol = tokens[1] + start = tokens[2] + end = tokens[3] cidrs = tokens.pop(); ips = cidrs.split(",") ips.pop() allow_any = False + action = "RETURN" + if ruletype == 'E': + vmchain = egress_chain_name(vm_name) + direction = "-d" + egressrule = egressrule + 1 + else: + vmchain = vm_name + direction = "-s" if '0.0.0.0/0' in ips: i = ips.index('0.0.0.0/0') del ips[i] @@ -596,28 +633,38 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif if ips: if protocol == 'all': for ip in ips: - execute("iptables -I " + vmchain + " -m state --state NEW -s " + ip + " -j ACCEPT") + execute("iptables -I " + vmchain + " -m state --state NEW " + direction + " " + ip + " -j "+action) elif protocol != 'icmp': for ip in ips: - execute("iptables -I " + vmchain + " -p " + protocol + " -m " + protocol + " --dport " + range + " -m state --state NEW -s " + ip + " -j ACCEPT") + execute("iptables -I " + vmchain + " -p " + protocol + " -m " + protocol + " --dport " + range + " -m state --state NEW " + direction + " " + ip + " -j "+ action) else: range = start + "/" + end if start == "-1": range = "any" for ip in ips: - execute("iptables -I " + vmchain + " -p icmp --icmp-type " + range + " -s " + ip + " -j ACCEPT") + execute("iptables -I " + vmchain + " -p icmp --icmp-type " + range + " " + direction + " " + ip + " -j "+ action) if allow_any and protocol != 'all': if protocol != 'icmp': - execute("iptables -I " + vmchain + " -p " + protocol + " -m " + protocol + " --dport " + range + " -m state --state NEW -j ACCEPT") + execute("iptables -I " + vmchain + " -p " + protocol + " -m " + protocol + " --dport " + range + " -m state --state NEW -j "+ action) else: range = start + "/" + end if start == "-1": range = "any" - execute("iptables -I " + vmchain + " -p icmp --icmp-type " + range + " -j ACCEPT") + execute("iptables -I " + vmchain + " -p icmp --icmp-type " + range + " -j "+action) + + egress_vmchain = egress_chain_name(vm_name) + if egressrule == 0 : + iptables = "iptables -A " + egress_vmchain + " -j RETURN" + execute(iptables) + else: + iptables = "iptables -A " + egress_vmchain + " -j DROP" + execute(iptables) + vmchain = vm_name iptables = "iptables -A " + vmchain + " -j DROP" - execute(iptables) + execute(iptables) + if write_rule_log_for_vm(vmName, vm_id, vm_ip, domId, signature, seqno) == False: return 'false' @@ -682,10 +729,10 @@ def addFWFramework(brname): execute("iptables -I FORWARD -i " + brname + " -m physdev --physdev-is-bridged -j " + brfw) execute("iptables -I FORWARD -o " + brname + " -m physdev --physdev-is-bridged -j " + brfw) phydev = execute("brctl show |grep " + brname + " | awk '{print $4}'").strip() - execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-out " + phydev + " -j ACCEPT") execute("iptables -A " + brfw + " -m state --state RELATED,ESTABLISHED -j ACCEPT") execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-is-out -j " + brfwout) execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-is-in -j " + brfwin) + execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-out " + phydev + " -j ACCEPT") return True diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index e789bc7ff70..3f2dff6f417 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -49,7 +49,6 @@ import com.cloud.api.response.CreateCmdResponse; import com.cloud.api.response.DiskOfferingResponse; import com.cloud.api.response.DomainResponse; import com.cloud.api.response.DomainRouterResponse; -import com.cloud.api.response.EgressRuleResponse; import com.cloud.api.response.EventResponse; import com.cloud.api.response.ExtractResponse; import com.cloud.api.response.FirewallResponse; @@ -57,8 +56,8 @@ import com.cloud.api.response.FirewallRuleResponse; import com.cloud.api.response.HostResponse; import com.cloud.api.response.HypervisorCapabilitiesResponse; import com.cloud.api.response.IPAddressResponse; -import com.cloud.api.response.IngressRuleResponse; -import com.cloud.api.response.IngressRuleResultObject; +import com.cloud.api.response.SecurityGroupRuleResponse; +import com.cloud.api.response.SecurityGroupRuleResultObject; import com.cloud.api.response.InstanceGroupResponse; import com.cloud.api.response.IpForwardingRuleResponse; import com.cloud.api.response.ListResponse; @@ -139,8 +138,8 @@ import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LoadBalancer; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.security.EgressRule; -import com.cloud.network.security.IngressRule; +import com.cloud.network.security.SecurityRule; +import com.cloud.network.security.SecurityRule.SecurityRuleType; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupRules; import com.cloud.network.security.SecurityGroupVO; @@ -2065,8 +2064,10 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public ListResponse createSecurityGroupResponses(List networkGroups) { - List groupResultObjs = SecurityGroupResultObject.transposeNetworkGroups(networkGroups); + public ListResponse createSecurityGroupResponses( + List networkGroups) { + List groupResultObjs = SecurityGroupResultObject + .transposeNetworkGroups(networkGroups); ListResponse response = new ListResponse(); List netGrpResponses = new ArrayList(); @@ -2075,37 +2076,48 @@ public class ApiResponseHelper implements ResponseGenerator { netGrpResponse.setId(networkGroup.getId()); netGrpResponse.setName(networkGroup.getName()); netGrpResponse.setDescription(networkGroup.getDescription()); - + populateOwner(netGrpResponse, networkGroup); - List ingressRules = networkGroup.getIngressRules(); - if ((ingressRules != null) && !ingressRules.isEmpty()) { - List ingressRulesResponse = new ArrayList(); + List securityGroupRules = networkGroup + .getSecurityGroupRules(); + if ((securityGroupRules != null) && !securityGroupRules.isEmpty()) { + List ingressRulesResponse = new ArrayList(); + List egressRulesResponse = new ArrayList(); + for (SecurityGroupRuleResultObject securityGroupRule : securityGroupRules) { + SecurityGroupRuleResponse ruleData = new SecurityGroupRuleResponse(); + ruleData.setRuleId(securityGroupRule.getId()); + ruleData.setProtocol(securityGroupRule.getProtocol()); - for (IngressRuleResultObject ingressRule : ingressRules) { - IngressRuleResponse ingressData = new IngressRuleResponse(); - - ingressData.setRuleId(ingressRule.getId()); - ingressData.setProtocol(ingressRule.getProtocol()); - if ("icmp".equalsIgnoreCase(ingressRule.getProtocol())) { - ingressData.setIcmpType(ingressRule.getStartPort()); - ingressData.setIcmpCode(ingressRule.getEndPort()); + if ("icmp".equalsIgnoreCase(securityGroupRule.getProtocol())) { + ruleData.setIcmpType(securityGroupRule.getStartPort()); + ruleData.setIcmpCode(securityGroupRule.getEndPort()); } else { - ingressData.setStartPort(ingressRule.getStartPort()); - ingressData.setEndPort(ingressRule.getEndPort()); + ruleData.setStartPort(securityGroupRule.getStartPort()); + ruleData.setEndPort(securityGroupRule.getEndPort()); } - if (ingressRule.getAllowedSecurityGroup() != null) { - ingressData.setSecurityGroupName(ingressRule.getAllowedSecurityGroup()); - ingressData.setAccountName(ingressRule.getAllowedSecGroupAcct()); + if (securityGroupRule.getAllowedSecurityGroup() != null) { + ruleData.setSecurityGroupName(securityGroupRule + .getAllowedSecurityGroup()); + ruleData.setAccountName(securityGroupRule + .getAllowedSecGroupAcct()); } else { - ingressData.setCidr(ingressRule.getAllowedSourceIpCidr()); + ruleData.setCidr(securityGroupRule + .getAllowedSourceIpCidr()); } - ingressData.setObjectName("ingressrule"); - ingressRulesResponse.add(ingressData); + if (securityGroupRule.getRuleType() == SecurityRuleType.IngressRule) { + ruleData.setObjectName("ingressrule"); + ingressRulesResponse.add(ruleData); + } else { + ruleData.setObjectName("egressrule"); + egressRulesResponse.add(ruleData); + } } - netGrpResponse.setIngressRules(ingressRulesResponse); + netGrpResponse + .setSecurityGroupIngressRules(ingressRulesResponse); + netGrpResponse.setSecurityGroupEgressRules(egressRulesResponse); } netGrpResponse.setObjectName("securitygroup"); netGrpResponses.add(netGrpResponse); @@ -2114,7 +2126,6 @@ public class ApiResponseHelper implements ResponseGenerator { response.setResponses(netGrpResponses); return response; } - @Override public SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group) { SecurityGroupResponse response = new SecurityGroupResponse(); @@ -2474,14 +2485,14 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public SecurityGroupResponse createSecurityGroupResponseFromIngressRule(List ingressRules) { + public SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List securityRules) { SecurityGroupResponse response = new SecurityGroupResponse(); Map securiytGroupAccounts = new HashMap(); Map allowedSecurityGroups = new HashMap(); Map allowedSecuriytGroupAccounts = new HashMap(); - if ((ingressRules != null) && !ingressRules.isEmpty()) { - SecurityGroup securityGroup = ApiDBUtils.findSecurityGroupById(ingressRules.get(0).getSecurityGroupId()); + if ((securityRules != null) && !securityRules.isEmpty()) { + SecurityGroup securityGroup = ApiDBUtils.findSecurityGroupById(securityRules.get(0).getSecurityGroupId()); response.setId(securityGroup.getId()); response.setName(securityGroup.getName()); response.setDescription(securityGroup.getDescription()); @@ -2496,21 +2507,22 @@ public class ApiResponseHelper implements ResponseGenerator { populateAccount(response, account.getId()); populateDomain(response, account.getDomainId()); - List responses = new ArrayList(); - for (IngressRule ingressRule : ingressRules) { - IngressRuleResponse ingressData = new IngressRuleResponse(); + List egressResponses = new ArrayList(); + List ingressResponses = new ArrayList(); + for (SecurityRule securityRule : securityRules) { + SecurityGroupRuleResponse securityGroupData = new SecurityGroupRuleResponse(); - ingressData.setRuleId(ingressRule.getId()); - ingressData.setProtocol(ingressRule.getProtocol()); - if ("icmp".equalsIgnoreCase(ingressRule.getProtocol())) { - ingressData.setIcmpType(ingressRule.getStartPort()); - ingressData.setIcmpCode(ingressRule.getEndPort()); + securityGroupData.setRuleId(securityRule.getId()); + securityGroupData.setProtocol(securityRule.getProtocol()); + if ("icmp".equalsIgnoreCase(securityRule.getProtocol())) { + securityGroupData.setIcmpType(securityRule.getStartPort()); + securityGroupData.setIcmpCode(securityRule.getEndPort()); } else { - ingressData.setStartPort(ingressRule.getStartPort()); - ingressData.setEndPort(ingressRule.getEndPort()); + securityGroupData.setStartPort(securityRule.getStartPort()); + securityGroupData.setEndPort(securityRule.getEndPort()); } - Long allowedSecurityGroupId = ingressRule.getAllowedNetworkId(); + Long allowedSecurityGroupId = securityRule.getAllowedNetworkId(); if (allowedSecurityGroupId != null) { SecurityGroup allowedSecurityGroup = allowedSecurityGroups.get(allowedSecurityGroupId); if (allowedSecurityGroup == null) { @@ -2518,7 +2530,7 @@ public class ApiResponseHelper implements ResponseGenerator { allowedSecurityGroups.put(allowedSecurityGroupId, allowedSecurityGroup); } - ingressData.setSecurityGroupName(allowedSecurityGroup.getName()); + securityGroupData.setSecurityGroupName(allowedSecurityGroup.getName()); Account allowedAccount = allowedSecuriytGroupAccounts.get(allowedSecurityGroup.getAccountId()); if (allowedAccount == null) { @@ -2526,84 +2538,21 @@ public class ApiResponseHelper implements ResponseGenerator { allowedSecuriytGroupAccounts.put(allowedAccount.getId(), allowedAccount); } - ingressData.setAccountName(allowedAccount.getAccountName()); + securityGroupData.setAccountName(allowedAccount.getAccountName()); } else { - ingressData.setCidr(ingressRule.getAllowedSourceIpCidr()); + securityGroupData.setCidr(securityRule.getAllowedSourceIpCidr()); + } + if (securityRule.getRuleType() == SecurityRuleType.IngressRule) { + securityGroupData.setObjectName("ingressrule"); + ingressResponses.add(securityGroupData); + } else { + securityGroupData.setObjectName("egressrule"); + egressResponses.add(securityGroupData); } - ingressData.setObjectName("ingressrule"); - responses.add(ingressData); } - response.setIngressRules(responses); - response.setObjectName("securitygroup"); - - } - return response; - } - - @Override - public SecurityGroupResponse createSecurityGroupResponseFromEgressRule(List egressRules) { - SecurityGroupResponse response = new SecurityGroupResponse(); - Map securiytGroupAccounts = new HashMap(); - Map allowedSecurityGroups = new HashMap(); - Map allowedSecuriytGroupAccounts = new HashMap(); - - if ((egressRules != null) && !egressRules.isEmpty()) { - SecurityGroup securityGroup = ApiDBUtils.findSecurityGroupById(egressRules.get(0).getSecurityGroupId()); - response.setId(securityGroup.getId()); - response.setName(securityGroup.getName()); - response.setDescription(securityGroup.getDescription()); - - Account account = securiytGroupAccounts.get(securityGroup.getAccountId()); - - if (account == null) { - account = ApiDBUtils.findAccountById(securityGroup.getAccountId()); - securiytGroupAccounts.put(securityGroup.getAccountId(), account); - } - - populateAccount(response, account.getId()); - populateDomain(response, account.getDomainId()); - - - List responses = new ArrayList(); - for (EgressRule egressRule : egressRules) { - EgressRuleResponse egressData = new EgressRuleResponse(); - - egressData.setRuleId(egressRule.getId()); - egressData.setProtocol(egressRule.getProtocol()); - if ("icmp".equalsIgnoreCase(egressRule.getProtocol())) { - egressData.setIcmpType(egressRule.getStartPort()); - egressData.setIcmpCode(egressRule.getEndPort()); - } else { - egressData.setStartPort(egressRule.getStartPort()); - egressData.setEndPort(egressRule.getEndPort()); - } - - Long allowedSecurityGroupId = egressRule.getAllowedNetworkId(); - if (allowedSecurityGroupId != null) { - SecurityGroup allowedSecurityGroup = allowedSecurityGroups.get(allowedSecurityGroupId); - if (allowedSecurityGroup == null) { - allowedSecurityGroup = ApiDBUtils.findSecurityGroupById(allowedSecurityGroupId); - allowedSecurityGroups.put(allowedSecurityGroupId, allowedSecurityGroup); - } - - egressData.setSecurityGroupName(allowedSecurityGroup.getName()); - - Account allowedAccount = allowedSecuriytGroupAccounts.get(allowedSecurityGroup.getAccountId()); - if (allowedAccount == null) { - allowedAccount = ApiDBUtils.findAccountById(allowedSecurityGroup.getAccountId()); - allowedSecuriytGroupAccounts.put(allowedAccount.getId(), allowedAccount); - } - - egressData.setAccountName(allowedAccount.getAccountName()); - } else { - egressData.setCidr(egressRule.getAllowedDestinationIpCidr()); - } - - egressData.setObjectName("egressrule"); - responses.add(egressData); - } - response.setEgressRules(responses); + response.setSecurityGroupIngressRules(ingressResponses); + response.setSecurityGroupEgressRules(egressResponses); response.setObjectName("securitygroup"); } diff --git a/server/src/com/cloud/api/response/EgressRuleResultObject.java b/server/src/com/cloud/api/response/EgressRuleResultObject.java deleted file mode 100644 index 85313c7cad2..00000000000 --- a/server/src/com/cloud/api/response/EgressRuleResultObject.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package com.cloud.api.response; - -import com.cloud.serializer.Param; - -public class EgressRuleResultObject { - @Param(name="id") - private Long id; - - @Param(name="startport") - private int startPort; - - @Param(name="endport") - private int endPort; - - @Param(name="protocol") - private String protocol; - - @Param(name="securitygroup") - private String allowedSecurityGroup = null; - - @Param(name="account") - private String allowedSecGroupAcct = null; - - @Param(name="cidr") - private String allowedDestinationIpCidr = null; - - public EgressRuleResultObject() { } - - public EgressRuleResultObject(Long id, int startPort, int endPort, String protocol, String allowedSecurityGroup, String allowedSecGroupAcct, String allowedSourceIpCidr) { - this.id = id; - this.startPort = startPort; - this.endPort = endPort; - this.protocol = protocol; - this.allowedSecurityGroup = allowedSecurityGroup; - this.allowedSecGroupAcct = allowedSecGroupAcct; - this.allowedDestinationIpCidr = allowedSourceIpCidr; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public int getStartPort() { - return startPort; - } - - public void setStartPort(int startPort) { - this.startPort = startPort; - } - - public int getEndPort() { - return endPort; - } - - public void setEndPort(int endPort) { - this.endPort = endPort; - } - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getAllowedSecurityGroup() { - return allowedSecurityGroup; - } - - public void setAllowedSecurityGroup(String allowedSecurityGroup) { - this.allowedSecurityGroup = allowedSecurityGroup; - } - - public String getAllowedSecGroupAcct() { - return allowedSecGroupAcct; - } - - public void setAllowedSecGroupAcct(String allowedSecGroupAcct) { - this.allowedSecGroupAcct = allowedSecGroupAcct; - } - - public String getAllowedDestinationIpCidr() { - return allowedDestinationIpCidr; - } - - public void setAllowedDestinationIpCidr(String allowedDestinationIpCidr) { - this.allowedDestinationIpCidr = allowedDestinationIpCidr; - } -} diff --git a/server/src/com/cloud/api/response/SecurityGroupResultObject.java b/server/src/com/cloud/api/response/SecurityGroupResultObject.java index 454f8a2ffc2..d436dbc1bb7 100644 --- a/server/src/com/cloud/api/response/SecurityGroupResultObject.java +++ b/server/src/com/cloud/api/response/SecurityGroupResultObject.java @@ -49,20 +49,20 @@ public class SecurityGroupResultObject implements ControlledEntity{ @Param(name = "accountname") private String accountName = null; - @Param(name = "ingressrules") - private List ingressRules = null; + @Param(name = "securitygrouprules") + private List securityGroupRules = null; public SecurityGroupResultObject() { } - public SecurityGroupResultObject(Long id, String name, String description, long domainId, long accountId, String accountName, List ingressRules) { + public SecurityGroupResultObject(Long id, String name, String description, long domainId, long accountId, String accountName, List ingressRules) { this.id = id; this.name = name; this.description = description; this.domainId = domainId; this.accountId = accountId; this.accountName = accountName; - this.ingressRules = ingressRules; + this.securityGroupRules = ingressRules; } public Long getId() { @@ -113,12 +113,12 @@ public class SecurityGroupResultObject implements ControlledEntity{ this.accountName = accountName; } - public List getIngressRules() { - return ingressRules; + public List getSecurityGroupRules() { + return securityGroupRules; } - public void setIngressRules(List ingressRules) { - this.ingressRules = ingressRules; + public void setSecurityGroupRules(List securityGroupRules) { + this.securityGroupRules = securityGroupRules; } public static List transposeNetworkGroups(List groups) { @@ -127,7 +127,7 @@ public class SecurityGroupResultObject implements ControlledEntity{ Map accounts = new HashMap(); if ((groups != null) && !groups.isEmpty()) { - List ingressDataList = new ArrayList(); + List securityGroupRuleDataList = new ArrayList(); SecurityGroupResultObject currentGroup = null; List processedGroups = new ArrayList(); @@ -137,9 +137,9 @@ public class SecurityGroupResultObject implements ControlledEntity{ processedGroups.add(groupId); if (currentGroup != null) { - if (!ingressDataList.isEmpty()) { - currentGroup.setIngressRules(ingressDataList); - ingressDataList = new ArrayList(); + if (!securityGroupRuleDataList.isEmpty()) { + currentGroup.setSecurityGroupRules(securityGroupRuleDataList); + securityGroupRuleDataList = new ArrayList(); } resultObjects.add(currentGroup); } @@ -164,13 +164,13 @@ public class SecurityGroupResultObject implements ControlledEntity{ } if (netGroupRule.getRuleId() != null) { - // there's at least one ingress rule for this network group, add the ingress rule data - IngressRuleResultObject ingressData = new IngressRuleResultObject(); - ingressData.setEndPort(netGroupRule.getEndPort()); - ingressData.setStartPort(netGroupRule.getStartPort()); - ingressData.setId(netGroupRule.getRuleId()); - ingressData.setProtocol(netGroupRule.getProtocol()); - + // there's at least one securitygroup rule for this network group, add the securitygroup rule data + SecurityGroupRuleResultObject securityGroupRuleData = new SecurityGroupRuleResultObject(); + securityGroupRuleData.setEndPort(netGroupRule.getEndPort()); + securityGroupRuleData.setStartPort(netGroupRule.getStartPort()); + securityGroupRuleData.setId(netGroupRule.getRuleId()); + securityGroupRuleData.setProtocol(netGroupRule.getProtocol()); + securityGroupRuleData.setRuleType(netGroupRule.getRuleType()); Long allowedSecurityGroupId = netGroupRule.getAllowedNetworkId(); if (allowedSecurityGroupId != null) { SecurityGroup allowedSecurityGroup = allowedSecurityGroups.get(allowedSecurityGroupId); @@ -179,7 +179,7 @@ public class SecurityGroupResultObject implements ControlledEntity{ allowedSecurityGroups.put(allowedSecurityGroupId, allowedSecurityGroup); } - ingressData.setAllowedSecurityGroup(allowedSecurityGroup.getName()); + securityGroupRuleData.setAllowedSecurityGroup(allowedSecurityGroup.getName()); Account allowedAccount = accounts.get(allowedSecurityGroup.getAccountId()); if (allowedAccount == null) { @@ -187,18 +187,18 @@ public class SecurityGroupResultObject implements ControlledEntity{ accounts.put(allowedAccount.getId(), allowedAccount); } - ingressData.setAllowedSecGroupAcct(allowedAccount.getAccountName()); + securityGroupRuleData.setAllowedSecGroupAcct(allowedAccount.getAccountName()); } else if (netGroupRule.getAllowedSourceIpCidr() != null) { - ingressData.setAllowedSourceIpCidr(netGroupRule.getAllowedSourceIpCidr()); + securityGroupRuleData.setAllowedSourceIpCidr(netGroupRule.getAllowedSourceIpCidr()); } - ingressDataList.add(ingressData); + securityGroupRuleDataList.add(securityGroupRuleData); } } // all rules have been processed, add the final data into the list if (currentGroup != null) { - if (!ingressDataList.isEmpty()) { - currentGroup.setIngressRules(ingressDataList); + if (!securityGroupRuleDataList.isEmpty()) { + currentGroup.setSecurityGroupRules(securityGroupRuleDataList); } resultObjects.add(currentGroup); } diff --git a/server/src/com/cloud/api/response/IngressRuleResultObject.java b/server/src/com/cloud/api/response/SecurityGroupRuleResultObject.java similarity index 81% rename from server/src/com/cloud/api/response/IngressRuleResultObject.java rename to server/src/com/cloud/api/response/SecurityGroupRuleResultObject.java index 12d2c054b8d..022e02fe707 100644 --- a/server/src/com/cloud/api/response/IngressRuleResultObject.java +++ b/server/src/com/cloud/api/response/SecurityGroupRuleResultObject.java @@ -17,10 +17,11 @@ */ package com.cloud.api.response; - + +import com.cloud.network.security.SecurityRule.SecurityRuleType; import com.cloud.serializer.Param; -public class IngressRuleResultObject { +public class SecurityGroupRuleResultObject { @Param(name="id") private Long id; @@ -40,11 +41,13 @@ public class IngressRuleResultObject { private String allowedSecGroupAcct = null; @Param(name="cidr") - private String allowedSourceIpCidr = null; + private String allowedSourceIpCidr = null; + + private SecurityRuleType type; - public IngressRuleResultObject() { } + public SecurityGroupRuleResultObject() { } - public IngressRuleResultObject(Long id, int startPort, int endPort, String protocol, String allowedSecurityGroup, String allowedSecGroupAcct, String allowedSourceIpCidr) { + public SecurityGroupRuleResultObject(Long id, int startPort, int endPort, String protocol, String allowedSecurityGroup, String allowedSecGroupAcct, String allowedSourceIpCidr) { this.id = id; this.startPort = startPort; this.endPort = endPort; @@ -65,7 +68,16 @@ public class IngressRuleResultObject { public int getStartPort() { return startPort; } - + + public void setRuleType(SecurityRuleType type) { + this.type = type; + } + + + public SecurityRuleType getRuleType() { + return type; + } + public void setStartPort(int startPort) { this.startPort = startPort; } diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 76c3b1dcc3a..223153eed9b 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -118,7 +118,7 @@ import com.cloud.network.router.VirtualNetworkApplianceManagerImpl; import com.cloud.network.rules.RulesManagerImpl; import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl; import com.cloud.network.security.SecurityGroupManagerImpl2; -import com.cloud.network.security.dao.IngressRuleDaoImpl; +import com.cloud.network.security.dao.SecurityGroupRuleDaoImpl; import com.cloud.network.security.dao.SecurityGroupDaoImpl; import com.cloud.network.security.dao.SecurityGroupRulesDaoImpl; import com.cloud.network.security.dao.SecurityGroupVMMapDaoImpl; @@ -233,7 +233,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("LBStickinessPolicyDao", LBStickinessPolicyDaoImpl.class); addDao("DataCenterIpAddressDao", DataCenterIpAddressDaoImpl.class); addDao("SecurityGroupDao", SecurityGroupDaoImpl.class); - addDao("IngressRuleDao", IngressRuleDaoImpl.class); + addDao("SecurityGroupRuleDao", SecurityGroupRuleDaoImpl.class); addDao("SecurityGroupVMMapDao", SecurityGroupVMMapDaoImpl.class); addDao("SecurityGroupRulesDao", SecurityGroupRulesDaoImpl.class); addDao("SecurityGroupWorkDao", SecurityGroupWorkDaoImpl.class); diff --git a/server/src/com/cloud/network/security/SecurityGroupListener.java b/server/src/com/cloud/network/security/SecurityGroupListener.java index 9742bbe03b6..e29f5be84bf 100755 --- a/server/src/com/cloud/network/security/SecurityGroupListener.java +++ b/server/src/com/cloud/network/security/SecurityGroupListener.java @@ -33,10 +33,10 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.Command; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; -import com.cloud.agent.api.SecurityIngressRuleAnswer; +import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; -import com.cloud.agent.api.SecurityIngressRuleAnswer.FailureReason; +import com.cloud.agent.api.SecurityGroupRuleAnswer.FailureReason; import com.cloud.agent.manager.Commands; import com.cloud.exception.AgentUnavailableException; import com.cloud.host.HostVO; @@ -89,8 +89,8 @@ public class SecurityGroupListener implements Listener { List affectedVms = new ArrayList(); int commandNum = 0; for (Answer ans: answers) { - if (ans instanceof SecurityIngressRuleAnswer) { - SecurityIngressRuleAnswer ruleAnswer = (SecurityIngressRuleAnswer) ans; + if (ans instanceof SecurityGroupRuleAnswer) { + SecurityGroupRuleAnswer ruleAnswer = (SecurityGroupRuleAnswer) ans; if (ans.getResult()) { s_logger.debug("Successfully programmed rule " + ruleAnswer.toString() + " into host " + agentId); _workDao.updateStep(ruleAnswer.getVmId(), ruleAnswer.getLogSequenceNumber(), Step.Done); diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index 9c93e4cfb7f..744e31d9ca4 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -42,14 +42,16 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.NetworkRulesSystemVmCommand; -import com.cloud.agent.api.SecurityIngressRulesCmd; -import com.cloud.agent.api.SecurityIngressRulesCmd.IpPortAndProto; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto; import com.cloud.agent.manager.Commands; import com.cloud.api.commands.AuthorizeSecurityGroupIngressCmd; +import com.cloud.api.commands.AuthorizeSecurityGroupEgressCmd; import com.cloud.api.commands.CreateSecurityGroupCmd; import com.cloud.api.commands.DeleteSecurityGroupCmd; import com.cloud.api.commands.ListSecurityGroupsCmd; import com.cloud.api.commands.RevokeSecurityGroupIngressCmd; +import com.cloud.api.commands.RevokeSecurityGroupEgressCmd; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.domain.Domain; @@ -66,7 +68,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.network.security.SecurityGroupWork.Step; -import com.cloud.network.security.dao.IngressRuleDao; +import com.cloud.network.security.dao.SecurityGroupRuleDao; import com.cloud.network.security.dao.SecurityGroupDao; import com.cloud.network.security.dao.SecurityGroupRulesDao; import com.cloud.network.security.dao.SecurityGroupVMMapDao; @@ -108,6 +110,7 @@ import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.network.security.SecurityRule.SecurityRuleType; import edu.emory.mathcs.backport.java.util.Collections; @@ -118,7 +121,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG @Inject SecurityGroupDao _securityGroupDao; @Inject - IngressRuleDao _ingressRuleDao; + SecurityGroupRuleDao _securityGroupRuleDao; @Inject SecurityGroupVMMapDao _securityGroupVMMapDao; @Inject @@ -327,14 +330,14 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG } - protected Map> generateRulesForVM(Long userVmId) { + protected Map> generateRulesForVM(Long userVmId, SecurityRuleType type) { Map> allowed = new TreeMap>(); List groupsForVm = _securityGroupVMMapDao.listByInstanceId(userVmId); for (SecurityGroupVMMapVO mapVO : groupsForVm) { - List rules = _ingressRuleDao.listBySecurityGroupId(mapVO.getSecurityGroupId()); - for (IngressRuleVO rule : rules) { + List rules = _securityGroupRuleDao.listBySecurityGroupId(mapVO.getSecurityGroupId(), type); + for (SecurityGroupRuleVO rule : rules) { PortAndProto portAndProto = new PortAndProto(rule.getProtocol(), rule.getStartPort(), rule.getEndPort()); Set cidrs = allowed.get(portAndProto); if (cidrs == null) { @@ -362,8 +365,9 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG return allowed; } - protected String generateRulesetSignature(Map> allowed) { - String ruleset = allowed.toString(); + protected String generateRulesetSignature(Map> ingress, Map> egress) { + String ruleset = ingress.toString(); + ruleset.concat(egress.toString()); return DigestUtils.md5Hex(ruleset); } @@ -445,11 +449,11 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG List affectedVms = new ArrayList(); affectedVms.add(vm.getId()); List groupsForVm = _securityGroupVMMapDao.listByInstanceId(vm.getId()); - // For each group, find the ingress rules that allow the group + // For each group, find the security rules that allow the group for (SecurityGroupVMMapVO mapVO : groupsForVm) {// FIXME: use custom sql in the dao - List allowingRules = _ingressRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId()); - // For each ingress rule that allows a group that the vm belongs to, find the group it belongs to - affectedVms.addAll(getAffectedVmsForIngressRules(allowingRules)); + List allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId()); + // For each security rule that allows a group that the vm belongs to, find the group it belongs to + affectedVms.addAll(getAffectedVmsForSecurityRules(allowingRules)); } return affectedVms; } @@ -457,20 +461,20 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG protected List getAffectedVmsForVmStop(VMInstanceVO vm) { List affectedVms = new ArrayList(); List groupsForVm = _securityGroupVMMapDao.listByInstanceId(vm.getId()); - // For each group, find the ingress rules that allow the group + // For each group, find the security rules rules that allow the group for (SecurityGroupVMMapVO mapVO : groupsForVm) {// FIXME: use custom sql in the dao - List allowingRules = _ingressRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId()); - // For each ingress rule that allows a group that the vm belongs to, find the group it belongs to - affectedVms.addAll(getAffectedVmsForIngressRules(allowingRules)); + List allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId()); + // For each security rule that allows a group that the vm belongs to, find the group it belongs to + affectedVms.addAll(getAffectedVmsForSecurityRules(allowingRules)); } return affectedVms; } - protected List getAffectedVmsForIngressRules(List allowingRules) { + protected List getAffectedVmsForSecurityRules(List allowingRules) { Set distinctGroups = new HashSet(); List affectedVms = new ArrayList(); - for (IngressRuleVO allowingRule : allowingRules) { + for (SecurityGroupRuleVO allowingRule : allowingRules) { distinctGroups.add(allowingRule.getSecurityGroupId()); } for (Long groupId : distinctGroups) { @@ -480,16 +484,24 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG return affectedVms; } - protected SecurityIngressRulesCmd generateRulesetCmd(String vmName, String guestIp, String guestMac, Long vmId, String signature, long seqnum, Map> rules) { - List result = new ArrayList(); - for (PortAndProto pAp : rules.keySet()) { - Set cidrs = rules.get(pAp); + protected SecurityGroupRulesCmd generateRulesetCmd(String vmName, String guestIp, String guestMac, Long vmId, String signature, long seqnum, Map> ingressRules, Map> egressRules) { + List ingressResult = new ArrayList(); + List egressResult = new ArrayList(); + for (PortAndProto pAp : ingressRules.keySet()) { + Set cidrs = ingressRules.get(pAp); if (cidrs.size() > 0) { - IpPortAndProto ipPortAndProto = new SecurityIngressRulesCmd.IpPortAndProto(pAp.getProto(), pAp.getStartPort(), pAp.getEndPort(), cidrs.toArray(new String[cidrs.size()])); - result.add(ipPortAndProto); + IpPortAndProto ipPortAndProto = new SecurityGroupRulesCmd.IpPortAndProto(pAp.getProto(), pAp.getStartPort(), pAp.getEndPort(), cidrs.toArray(new String[cidrs.size()])); + ingressResult.add(ipPortAndProto); } } - return new SecurityIngressRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqnum, result.toArray(new IpPortAndProto[result.size()])); + for (PortAndProto pAp : egressRules.keySet()) { + Set cidrs = egressRules.get(pAp); + if (cidrs.size() > 0) { + IpPortAndProto ipPortAndProto = new SecurityGroupRulesCmd.IpPortAndProto(pAp.getProto(), pAp.getStartPort(), pAp.getEndPort(), cidrs.toArray(new String[cidrs.size()])); + egressResult.add(ipPortAndProto); + } + } + return new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqnum, ingressResult.toArray(new IpPortAndProto[ingressResult.size()]), egressResult.toArray(new IpPortAndProto[egressResult.size()])); } protected void handleVmStopped(VMInstanceVO vm) { @@ -520,11 +532,11 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG scheduleRulesetUpdateToHosts(affectedVms, true, null); } } - @Override @DB @SuppressWarnings("rawtypes") - public List authorizeSecurityGroupIngress(AuthorizeSecurityGroupIngressCmd cmd) { + @ActionEvent(eventType = EventTypes.EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS, eventDescription = "Adding Egress Rule ", async = true) + public List authorizeSecurityGroupEgress(AuthorizeSecurityGroupEgressCmd cmd) { Long securityGroupId = cmd.getSecurityGroupId(); String protocol = cmd.getProtocol(); Integer startPort = cmd.getStartPort(); @@ -533,9 +545,29 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG Integer icmpCode = cmd.getIcmpCode(); List cidrList = cmd.getCidrList(); Map groupList = cmd.getUserSecurityGroupList(); + return authorizeSecurityGroupRule(securityGroupId, protocol, startPort, endPort, icmpType, icmpCode, cidrList, groupList, SecurityRuleType.EgressRule); + } + + @Override + @DB + @SuppressWarnings("rawtypes") + @ActionEvent(eventType = EventTypes.EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS, eventDescription = "Adding Ingress Rule ", async = true) + public List authorizeSecurityGroupIngress(AuthorizeSecurityGroupIngressCmd cmd) { + Long securityGroupId = cmd.getSecurityGroupId(); + String protocol = cmd.getProtocol(); + Integer startPort = cmd.getStartPort(); + Integer endPort = cmd.getEndPort(); + Integer icmpType = cmd.getIcmpType(); + Integer icmpCode = cmd.getIcmpCode(); + List cidrList = cmd.getCidrList(); + Map groupList = cmd.getUserSecurityGroupList(); + return authorizeSecurityGroupRule(securityGroupId,protocol,startPort,endPort,icmpType,icmpCode,cidrList,groupList,SecurityRuleType.IngressRule); + } + + private List authorizeSecurityGroupRule(Long securityGroupId,String protocol,Integer startPort,Integer endPort,Integer icmpType,Integer icmpCode,List cidrList,Map groupList,SecurityRuleType ruleType) { Integer startPortOrType = null; Integer endPortOrCode = null; - + // Validate parameters SecurityGroup securityGroup = _securityGroupDao.findById(securityGroupId); if (securityGroup == null) { @@ -621,13 +653,13 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG Account authorizedAccount = _accountDao.findActiveAccount(authorizedAccountName, domainId); if (authorizedAccount == null) { - throw new InvalidParameterValueException("Nonexistent account: " + authorizedAccountName + " when trying to authorize ingress for " + securityGroupId + ":" + protocol + ":" + throw new InvalidParameterValueException("Nonexistent account: " + authorizedAccountName + " when trying to authorize security group rule for " + securityGroupId + ":" + protocol + ":" + startPortOrType + ":" + endPortOrCode); } SecurityGroupVO groupVO = _securityGroupDao.findByAccountAndName(authorizedAccount.getId(), group); if (groupVO == null) { - throw new InvalidParameterValueException("Nonexistent group " + group + " for account " + authorizedAccountName + "/" + domainId + " is given, unable to authorize ingress."); + throw new InvalidParameterValueException("Nonexistent group " + group + " for account " + authorizedAccountName + "/" + domainId + " is given, unable to authorize security group rule."); } // Check permissions @@ -645,13 +677,13 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG authorizedGroups2.addAll(authorizedGroups); // Ensure we don't re-lock the same row txn.start(); - // Prevents other threads/management servers from creating duplicate ingress rules + // Prevents other threads/management servers from creating duplicate security rules securityGroup = _securityGroupDao.acquireInLockTable(securityGroupId); if (securityGroup == null) { s_logger.warn("Could not acquire lock on network security group: id= " + securityGroupId); return null; } - List newRules = new ArrayList(); + List newRules = new ArrayList(); try { for (final SecurityGroupVO ngVO : authorizedGroups2) { final Long ngId = ngVO.getId(); @@ -664,23 +696,23 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG return null; } } - IngressRuleVO ingressRule = _ingressRuleDao.findByProtoPortsAndAllowedGroupId(securityGroup.getId(), protocol, startPortOrType, endPortOrCode, ngVO.getId()); - if (ingressRule != null) { + SecurityGroupRuleVO securityGroupRule = _securityGroupRuleDao.findByProtoPortsAndAllowedGroupId(securityGroup.getId(), protocol, startPortOrType, endPortOrCode, ngVO.getId()); + if ((securityGroupRule != null) && (securityGroupRule.getRuleType() == ruleType)) { continue; // rule already exists. } - ingressRule = new IngressRuleVO(securityGroup.getId(), startPortOrType, endPortOrCode, protocol, ngVO.getId()); - ingressRule = _ingressRuleDao.persist(ingressRule); - newRules.add(ingressRule); + securityGroupRule = new SecurityGroupRuleVO(ruleType, securityGroup.getId(), startPortOrType, endPortOrCode, protocol, ngVO.getId()); + securityGroupRule = _securityGroupRuleDao.persist(securityGroupRule); + newRules.add(securityGroupRule); } if (cidrList != null) { for (String cidr : cidrList) { - IngressRuleVO ingressRule = _ingressRuleDao.findByProtoPortsAndCidr(securityGroup.getId(), protocol, startPortOrType, endPortOrCode, cidr); - if (ingressRule != null) { + SecurityGroupRuleVO securityGroupRule = _securityGroupRuleDao.findByProtoPortsAndCidr(securityGroup.getId(), protocol, startPortOrType, endPortOrCode, cidr); + if ((securityGroupRule != null) && (securityGroupRule.getRuleType() == ruleType)) { continue; } - ingressRule = new IngressRuleVO(securityGroup.getId(), startPortOrType, endPortOrCode, protocol, cidr); - ingressRule = _ingressRuleDao.persist(ingressRule); - newRules.add(ingressRule); + securityGroupRule = new SecurityGroupRuleVO(ruleType, securityGroup.getId(), startPortOrType, endPortOrCode, protocol, cidr); + securityGroupRule = _securityGroupRuleDao.persist(securityGroupRule); + newRules.add(securityGroupRule); } } if (s_logger.isDebugEnabled()) { @@ -692,28 +724,48 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG scheduleRulesetUpdateToHosts(affectedVms, true, null); return newRules; } catch (Exception e) { - s_logger.warn("Exception caught when adding ingress rules ", e); - throw new CloudRuntimeException("Exception caught when adding ingress rules", e); + s_logger.warn("Exception caught when adding security group rules ", e); + throw new CloudRuntimeException("Exception caught when adding security group rules", e); } finally { if (securityGroup != null) { _securityGroupDao.releaseFromLockTable(securityGroup.getId()); } } } - + @Override @DB + @ActionEvent(eventType = EventTypes.EVENT_SECURITY_GROUP_REVOKE_EGRESS, eventDescription = "Revoking Egress Rule ", async = true) + public boolean revokeSecurityGroupEgress(RevokeSecurityGroupEgressCmd cmd) { + Long id = cmd.getId(); + return revokeSecurityGroupRule(id, SecurityRuleType.EgressRule); + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_SECURITY_GROUP_REVOKE_INGRESS, eventDescription = "Revoking Ingress Rule ", async = true) public boolean revokeSecurityGroupIngress(RevokeSecurityGroupIngressCmd cmd) { + + Long id = cmd.getId(); + return revokeSecurityGroupRule(id, SecurityRuleType.IngressRule); + } + + private boolean revokeSecurityGroupRule(Long id, SecurityRuleType type) { // input validation Account caller = UserContext.current().getCaller(); - Long id = cmd.getId(); - - IngressRuleVO rule = _ingressRuleDao.findById(id); + + SecurityGroupRuleVO rule = _securityGroupRuleDao.findById(id); if (rule == null) { - s_logger.debug("Unable to find ingress rule with id " + id); - throw new InvalidParameterValueException("Unable to find ingress rule with id " + id); + s_logger.debug("Unable to find security rule with id " + id); + throw new InvalidParameterValueException("Unable to find security rule with id " + id); } + // check type + if (type != rule.getRuleType()) { + s_logger.debug("Mismatch in rule type for security rule with id " + id ); + throw new InvalidParameterValueException("Mismatch in rule type for security rule with id " + id); + } + // Check permissions SecurityGroup securityGroup = _securityGroupDao.findById(rule.getSecurityGroupId()); _accountMgr.checkAccess(caller, null, securityGroup); @@ -730,8 +782,8 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG return false; } - _ingressRuleDao.remove(id); - s_logger.debug("revokeSecurityGroupIngress succeeded for ingress rule id: " + id); + _securityGroupRuleDao.remove(id); + s_logger.debug("revokeSecurityGroupRule succeeded for security rule id: " + id); final ArrayList affectedVms = new ArrayList(); affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(groupHandle.getId())); @@ -739,8 +791,8 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG return true; } catch (Exception e) { - s_logger.warn("Exception caught when deleting ingress rules ", e); - throw new CloudRuntimeException("Exception caught when deleting ingress rules", e); + s_logger.warn("Exception caught when deleting security rules ", e); + throw new CloudRuntimeException("Exception caught when deleting security rules", e); } finally { if (groupHandle != null) { _securityGroupDao.releaseFromLockTable(groupHandle.getId()); @@ -884,18 +936,20 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG seqnum = log.getLogsequence(); if (vm != null && vm.getState() == State.Running) { - Map> rules = generateRulesForVM(userVmId); + Map> ingressRules = generateRulesForVM(userVmId, SecurityRuleType.IngressRule); + Map> egressRules = generateRulesForVM(userVmId, SecurityRuleType.EgressRule); agentId = vm.getHostId(); if (agentId != null) { - SecurityIngressRulesCmd cmd = generateRulesetCmd(vm.getInstanceName(), vm.getPrivateIpAddress(), vm.getPrivateMacAddress(), vm.getId(), generateRulesetSignature(rules), seqnum, - rules); + SecurityGroupRulesCmd cmd = generateRulesetCmd( vm.getInstanceName(), vm.getPrivateIpAddress(), vm.getPrivateMacAddress(), vm.getId(), generateRulesetSignature(ingressRules, egressRules), seqnum, + ingressRules, egressRules); Commands cmds = new Commands(cmd); try { _agentMgr.send(agentId, cmds, _answerListener); } catch (AgentUnavailableException e) { - s_logger.debug("Unable to send updates for vm: " + userVmId + "(agentid=" + agentId + ")"); + s_logger.debug("Unable to send ingress rules updates for vm: " + userVmId + "(agentid=" + agentId + ")"); _workDao.updateStep(work.getInstanceId(), seqnum, Step.Done); } + } } } finally { @@ -1003,10 +1057,10 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG throw new InvalidParameterValueException("The network group default is reserved"); } - List allowingRules = _ingressRuleDao.listByAllowedSecurityGroupId(groupId); + List allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(groupId); List securityGroupVmMap = _securityGroupVMMapDao.listBySecurityGroup(groupId); if (!allowingRules.isEmpty()) { - throw new ResourceInUseException("Cannot delete group when there are ingress rules that allow this group"); + throw new ResourceInUseException("Cannot delete group when there are security rules that allow this group"); } else if (!securityGroupVmMap.isEmpty()) { throw new ResourceInUseException("Cannot delete group when it's in use by virtual machines"); } diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java index ed52e79a65f..a57a050d32f 100644 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java @@ -28,7 +28,7 @@ import java.util.concurrent.ConcurrentHashMap; import javax.ejb.Local; import javax.naming.ConfigurationException; -import com.cloud.agent.api.SecurityIngressRulesCmd; +import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.manager.Commands; import com.cloud.configuration.Config; import com.cloud.exception.AgentUnavailableException; @@ -39,7 +39,7 @@ import com.cloud.utils.Profiler; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.mgmt.JmxUtil; import com.cloud.vm.VirtualMachine.State; - +import com.cloud.network.security.SecurityRule.SecurityRuleType; /** * Same as the base class -- except it uses the abstracted security group work queue @@ -163,21 +163,17 @@ public class SecurityGroupManagerImpl2 extends SecurityGroupManagerImpl{ if (s_logger.isTraceEnabled()) { s_logger.trace("SecurityGroupManager v2: found vm, " + userVmId + " state=" + vm.getState()); } + Map> ingressRules = generateRulesForVM(userVmId, SecurityRuleType.IngressRule); + Map> egressRules = generateRulesForVM(userVmId, SecurityRuleType.EgressRule); Long agentId = vm.getHostId(); if (agentId != null) { - if ( !_workTracker.canSend(agentId)) { - s_logger.debug("SecurityGroupManager v2: not sending ruleset update for vm " + vm.getInstanceName() - + ": too many messages outstanding on host " + agentId); - return; - } - Map> rules = generateRulesForVM(userVmId); - SecurityIngressRulesCmd cmd = generateRulesetCmd(vm.getInstanceName(), vm.getPrivateIpAddress(), + SecurityGroupRulesCmd cmd = generateRulesetCmd(vm.getInstanceName(), vm.getPrivateIpAddress(), vm.getPrivateMacAddress(), vm.getId(), null, - work.getLogsequenceNumber(), rules); + work.getLogsequenceNumber(), ingressRules, egressRules); cmd.setMsId(_serverId); if (s_logger.isDebugEnabled()) { s_logger.debug("SecurityGroupManager v2: sending ruleset update for vm " + vm.getInstanceName() + - ": num rules=" + cmd.getRuleSet().length + " num cidrs=" + cmd.getTotalNumCidrs() + " sig=" + cmd.getSignature()); + ":ingress num rules=" + cmd.getIngressRuleSet().length + ":egress num rules=" + cmd.getEgressRuleSet().length + " num cidrs=" + cmd.getTotalNumCidrs() + " sig=" + cmd.getSignature()); } Commands cmds = new Commands(cmd); try { @@ -212,14 +208,14 @@ public class SecurityGroupManagerImpl2 extends SecurityGroupManagerImpl{ * then we get all ips, including the default nic ip. This is also probably the correct behavior. */ @Override - protected Map> generateRulesForVM(Long userVmId) { + protected Map> generateRulesForVM(Long userVmId, SecurityRuleType type) { Map> allowed = new TreeMap>(); List groupsForVm = _securityGroupVMMapDao.listByInstanceId(userVmId); for (SecurityGroupVMMapVO mapVO : groupsForVm) { - List rules = _ingressRuleDao.listBySecurityGroupId(mapVO.getSecurityGroupId()); - for (IngressRuleVO rule : rules) { + List rules = _securityGroupRuleDao.listBySecurityGroupId(mapVO.getSecurityGroupId(), type); + for (SecurityGroupRuleVO rule : rules) { PortAndProto portAndProto = new PortAndProto(rule.getProtocol(), rule.getStartPort(), rule.getEndPort()); Set cidrs = allowed.get(portAndProto); if (cidrs == null) { diff --git a/server/src/com/cloud/network/security/SecurityManagerMBeanImpl.java b/server/src/com/cloud/network/security/SecurityManagerMBeanImpl.java index dc8d15196b2..bf228f2de6e 100644 --- a/server/src/com/cloud/network/security/SecurityManagerMBeanImpl.java +++ b/server/src/com/cloud/network/security/SecurityManagerMBeanImpl.java @@ -14,6 +14,7 @@ import com.cloud.network.security.LocalSecurityGroupWorkQueue.LocalSecurityGroup import com.cloud.network.security.SecurityGroupWork.Step; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine.Type; +import com.cloud.network.security.SecurityRule.SecurityRuleType; public class SecurityManagerMBeanImpl extends StandardMBean implements SecurityGroupManagerMBean, RuleUpdateLog { SecurityGroupManagerImpl2 _sgMgr; diff --git a/server/src/com/cloud/network/security/dao/EgressRuleDao.java b/server/src/com/cloud/network/security/dao/EgressRuleDao.java deleted file mode 100644 index 9cc514d0a86..00000000000 --- a/server/src/com/cloud/network/security/dao/EgressRuleDao.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package com.cloud.network.security.dao; - -import java.util.List; - -import com.cloud.network.security.EgressRuleVO; -import com.cloud.utils.db.GenericDao; - -public interface EgressRuleDao extends GenericDao { - List listBySecurityGroupId(long networkGroupId); - List listByAllowedSecurityGroupId(long networkGroupId); - EgressRuleVO findByProtoPortsAndCidr(long networkGroupId, String proto, int startPort, int endPort, String cidr); - EgressRuleVO findByProtoPortsAndGroup(String proto, int startPort, int endPort, String networkGroup); - EgressRuleVO findByProtoPortsAndAllowedGroupId(long networkGroupId, String proto, int startPort, int endPort, Long allowedGroupId); - int deleteBySecurityGroup(long securityGroupId); - int deleteByPortProtoAndGroup(long securityGroupId, String protocol, int startPort,int endPort, Long id); - int deleteByPortProtoAndCidr(long securityGroupId, String protocol, int startPort,int endPort, String cidr); - -} diff --git a/server/src/com/cloud/network/security/dao/EgressRuleDaoImpl.java b/server/src/com/cloud/network/security/dao/EgressRuleDaoImpl.java deleted file mode 100644 index adb11b71e43..00000000000 --- a/server/src/com/cloud/network/security/dao/EgressRuleDaoImpl.java +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package com.cloud.network.security.dao; - -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import com.cloud.network.security.EgressRuleVO; -import com.cloud.network.security.SecurityGroupVO; -import com.cloud.utils.component.Inject; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; - -@Local(value={EgressRuleDao.class}) -public class EgressRuleDaoImpl extends GenericDaoBase implements EgressRuleDao { - - @Inject SecurityGroupDao _securityGroupDao; - - protected SearchBuilder securityGroupIdSearch; - protected SearchBuilder allowedSecurityGroupIdSearch; - protected SearchBuilder protoPortsAndCidrSearch; - protected SearchBuilder protoPortsAndSecurityGroupNameSearch; - protected SearchBuilder protoPortsAndSecurityGroupIdSearch; - - - - protected EgressRuleDaoImpl() { - securityGroupIdSearch = createSearchBuilder(); - securityGroupIdSearch.and("securityGroupId", securityGroupIdSearch.entity().getSecurityGroupId(), SearchCriteria.Op.EQ); - securityGroupIdSearch.done(); - - allowedSecurityGroupIdSearch = createSearchBuilder(); - allowedSecurityGroupIdSearch.and("allowedNetworkId", allowedSecurityGroupIdSearch.entity().getAllowedNetworkId(), SearchCriteria.Op.EQ); - allowedSecurityGroupIdSearch.done(); - - protoPortsAndCidrSearch = createSearchBuilder(); - protoPortsAndCidrSearch.and("securityGroupId", protoPortsAndCidrSearch.entity().getSecurityGroupId(), SearchCriteria.Op.EQ); - protoPortsAndCidrSearch.and("proto", protoPortsAndCidrSearch.entity().getProtocol(), SearchCriteria.Op.EQ); - protoPortsAndCidrSearch.and("startPort", protoPortsAndCidrSearch.entity().getStartPort(), SearchCriteria.Op.EQ); - protoPortsAndCidrSearch.and("endPort", protoPortsAndCidrSearch.entity().getEndPort(), SearchCriteria.Op.EQ); - protoPortsAndCidrSearch.and("cidr", protoPortsAndCidrSearch.entity().getAllowedDestinationIpCidr(), SearchCriteria.Op.EQ); - protoPortsAndCidrSearch.done(); - - protoPortsAndSecurityGroupIdSearch = createSearchBuilder(); - protoPortsAndSecurityGroupIdSearch.and("securityGroupId", protoPortsAndSecurityGroupIdSearch.entity().getSecurityGroupId(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupIdSearch.and("proto", protoPortsAndSecurityGroupIdSearch.entity().getProtocol(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupIdSearch.and("startPort", protoPortsAndSecurityGroupIdSearch.entity().getStartPort(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupIdSearch.and("endPort", protoPortsAndSecurityGroupIdSearch.entity().getEndPort(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupIdSearch.and("allowedNetworkId", protoPortsAndSecurityGroupIdSearch.entity().getAllowedNetworkId(), SearchCriteria.Op.EQ); - - } - - public List listBySecurityGroupId(long securityGroupId) { - SearchCriteria sc = securityGroupIdSearch.create(); - sc.setParameters("securityGroupId", securityGroupId); - return listBy(sc); - } - - public int deleteBySecurityGroup(long securityGroupId) { - SearchCriteria sc = securityGroupIdSearch.create(); - sc.setParameters("securityGroupId", securityGroupId); - return expunge(sc); - } - - @Override - public List listByAllowedSecurityGroupId(long securityGroupId) { - SearchCriteria sc = allowedSecurityGroupIdSearch.create(); - sc.setParameters("allowedNetworkId", securityGroupId); - return listBy(sc); - } - - @Override - public EgressRuleVO findByProtoPortsAndCidr(long securityGroupId, String proto, int startPort, - int endPort, String cidr) { - SearchCriteria sc = protoPortsAndCidrSearch.create(); - sc.setParameters("securityGroupId", securityGroupId); - sc.setParameters("proto", proto); - sc.setParameters("startPort", startPort); - sc.setParameters("endPort", endPort); - sc.setParameters("cidr", cidr); - return findOneIncludingRemovedBy(sc); - } - - @Override - public EgressRuleVO findByProtoPortsAndGroup(String proto, int startPort, - int endPort, String securityGroup) { - SearchCriteria sc = protoPortsAndSecurityGroupNameSearch.create(); - sc.setParameters("proto", proto); - sc.setParameters("startPort", startPort); - sc.setParameters("endPort", endPort); - sc.setJoinParameters("groupName", "groupName", securityGroup); - return findOneIncludingRemovedBy(sc); - } - - @Override - public boolean configure(String name, Map params) - throws ConfigurationException { - protoPortsAndSecurityGroupNameSearch = createSearchBuilder(); - protoPortsAndSecurityGroupNameSearch.and("proto", protoPortsAndSecurityGroupNameSearch.entity().getProtocol(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupNameSearch.and("startPort", protoPortsAndSecurityGroupNameSearch.entity().getStartPort(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupNameSearch.and("endPort", protoPortsAndSecurityGroupNameSearch.entity().getEndPort(), SearchCriteria.Op.EQ); - SearchBuilder ngSb = _securityGroupDao.createSearchBuilder(); - ngSb.and("groupName", ngSb.entity().getName(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupNameSearch.join("groupName", ngSb, protoPortsAndSecurityGroupNameSearch.entity().getAllowedNetworkId(), ngSb.entity().getId(), JoinBuilder.JoinType.INNER); - protoPortsAndSecurityGroupNameSearch.done(); - return super.configure(name, params); - } - - @Override - public int deleteByPortProtoAndGroup(long securityGroupId, String protocol, int startPort, int endPort, Long allowedGroupId) { - SearchCriteria sc = protoPortsAndSecurityGroupIdSearch.create(); - sc.setParameters("securityGroupId", securityGroupId); - sc.setParameters("proto", protocol); - sc.setParameters("startPort", startPort); - sc.setParameters("endPort", endPort); - sc.setParameters("allowedNetworkId", allowedGroupId); - - return expunge(sc); - - } - - @Override - public int deleteByPortProtoAndCidr(long securityGroupId, String protocol, int startPort, int endPort, String cidr) { - SearchCriteria sc = protoPortsAndCidrSearch.create(); - sc.setParameters("securityGroupId", securityGroupId); - sc.setParameters("proto", protocol); - sc.setParameters("startPort", startPort); - sc.setParameters("endPort", endPort); - sc.setParameters("cidr", cidr); - - return expunge(sc); - } - - @Override - public EgressRuleVO findByProtoPortsAndAllowedGroupId(long securityGroupId, String proto, - int startPort, int endPort, Long allowedGroupId) { - SearchCriteria sc = protoPortsAndSecurityGroupIdSearch.create(); - sc.addAnd("securityGroupId", SearchCriteria.Op.EQ, securityGroupId); - sc.setParameters("proto", proto); - sc.setParameters("startPort", startPort); - sc.setParameters("endPort", endPort); - sc.setParameters("allowedNetworkId", allowedGroupId); - - return findOneIncludingRemovedBy(sc); - } -} diff --git a/server/src/com/cloud/network/security/dao/IngressRuleDaoImpl.java b/server/src/com/cloud/network/security/dao/IngressRuleDaoImpl.java deleted file mode 100644 index dab386e1170..00000000000 --- a/server/src/com/cloud/network/security/dao/IngressRuleDaoImpl.java +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package com.cloud.network.security.dao; - -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import com.cloud.network.security.IngressRuleVO; -import com.cloud.network.security.SecurityGroupVO; -import com.cloud.utils.component.Inject; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; - -@Local(value={IngressRuleDao.class}) -public class IngressRuleDaoImpl extends GenericDaoBase implements IngressRuleDao { - - @Inject SecurityGroupDao _securityGroupDao; - - protected SearchBuilder securityGroupIdSearch; - protected SearchBuilder allowedSecurityGroupIdSearch; - protected SearchBuilder protoPortsAndCidrSearch; - protected SearchBuilder protoPortsAndSecurityGroupNameSearch; - protected SearchBuilder protoPortsAndSecurityGroupIdSearch; - - - - protected IngressRuleDaoImpl() { - securityGroupIdSearch = createSearchBuilder(); - securityGroupIdSearch.and("securityGroupId", securityGroupIdSearch.entity().getSecurityGroupId(), SearchCriteria.Op.EQ); - securityGroupIdSearch.done(); - - allowedSecurityGroupIdSearch = createSearchBuilder(); - allowedSecurityGroupIdSearch.and("allowedNetworkId", allowedSecurityGroupIdSearch.entity().getAllowedNetworkId(), SearchCriteria.Op.EQ); - allowedSecurityGroupIdSearch.done(); - - protoPortsAndCidrSearch = createSearchBuilder(); - protoPortsAndCidrSearch.and("securityGroupId", protoPortsAndCidrSearch.entity().getSecurityGroupId(), SearchCriteria.Op.EQ); - protoPortsAndCidrSearch.and("proto", protoPortsAndCidrSearch.entity().getProtocol(), SearchCriteria.Op.EQ); - protoPortsAndCidrSearch.and("startPort", protoPortsAndCidrSearch.entity().getStartPort(), SearchCriteria.Op.EQ); - protoPortsAndCidrSearch.and("endPort", protoPortsAndCidrSearch.entity().getEndPort(), SearchCriteria.Op.EQ); - protoPortsAndCidrSearch.and("cidr", protoPortsAndCidrSearch.entity().getAllowedSourceIpCidr(), SearchCriteria.Op.EQ); - protoPortsAndCidrSearch.done(); - - protoPortsAndSecurityGroupIdSearch = createSearchBuilder(); - protoPortsAndSecurityGroupIdSearch.and("securityGroupId", protoPortsAndSecurityGroupIdSearch.entity().getSecurityGroupId(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupIdSearch.and("proto", protoPortsAndSecurityGroupIdSearch.entity().getProtocol(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupIdSearch.and("startPort", protoPortsAndSecurityGroupIdSearch.entity().getStartPort(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupIdSearch.and("endPort", protoPortsAndSecurityGroupIdSearch.entity().getEndPort(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupIdSearch.and("allowedNetworkId", protoPortsAndSecurityGroupIdSearch.entity().getAllowedNetworkId(), SearchCriteria.Op.EQ); - - } - - public List listBySecurityGroupId(long securityGroupId) { - SearchCriteria sc = securityGroupIdSearch.create(); - sc.setParameters("securityGroupId", securityGroupId); - return listBy(sc); - } - - public int deleteBySecurityGroup(long securityGroupId) { - SearchCriteria sc = securityGroupIdSearch.create(); - sc.setParameters("securityGroupId", securityGroupId); - return expunge(sc); - } - - @Override - public List listByAllowedSecurityGroupId(long securityGroupId) { - SearchCriteria sc = allowedSecurityGroupIdSearch.create(); - sc.setParameters("allowedNetworkId", securityGroupId); - return listBy(sc); - } - - @Override - public IngressRuleVO findByProtoPortsAndCidr(long securityGroupId, String proto, int startPort, - int endPort, String cidr) { - SearchCriteria sc = protoPortsAndCidrSearch.create(); - sc.setParameters("securityGroupId", securityGroupId); - sc.setParameters("proto", proto); - sc.setParameters("startPort", startPort); - sc.setParameters("endPort", endPort); - sc.setParameters("cidr", cidr); - return findOneIncludingRemovedBy(sc); - } - - @Override - public IngressRuleVO findByProtoPortsAndGroup(String proto, int startPort, - int endPort, String securityGroup) { - SearchCriteria sc = protoPortsAndSecurityGroupNameSearch.create(); - sc.setParameters("proto", proto); - sc.setParameters("startPort", startPort); - sc.setParameters("endPort", endPort); - sc.setJoinParameters("groupName", "groupName", securityGroup); - return findOneIncludingRemovedBy(sc); - } - - @Override - public boolean configure(String name, Map params) - throws ConfigurationException { - protoPortsAndSecurityGroupNameSearch = createSearchBuilder(); - protoPortsAndSecurityGroupNameSearch.and("proto", protoPortsAndSecurityGroupNameSearch.entity().getProtocol(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupNameSearch.and("startPort", protoPortsAndSecurityGroupNameSearch.entity().getStartPort(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupNameSearch.and("endPort", protoPortsAndSecurityGroupNameSearch.entity().getEndPort(), SearchCriteria.Op.EQ); - SearchBuilder ngSb = _securityGroupDao.createSearchBuilder(); - ngSb.and("groupName", ngSb.entity().getName(), SearchCriteria.Op.EQ); - protoPortsAndSecurityGroupNameSearch.join("groupName", ngSb, protoPortsAndSecurityGroupNameSearch.entity().getAllowedNetworkId(), ngSb.entity().getId(), JoinBuilder.JoinType.INNER); - protoPortsAndSecurityGroupNameSearch.done(); - return super.configure(name, params); - } - - @Override - public int deleteByPortProtoAndGroup(long securityGroupId, String protocol, int startPort, int endPort, Long allowedGroupId) { - SearchCriteria sc = protoPortsAndSecurityGroupIdSearch.create(); - sc.setParameters("securityGroupId", securityGroupId); - sc.setParameters("proto", protocol); - sc.setParameters("startPort", startPort); - sc.setParameters("endPort", endPort); - sc.setParameters("allowedNetworkId", allowedGroupId); - - return expunge(sc); - - } - - @Override - public int deleteByPortProtoAndCidr(long securityGroupId, String protocol, int startPort, int endPort, String cidr) { - SearchCriteria sc = protoPortsAndCidrSearch.create(); - sc.setParameters("securityGroupId", securityGroupId); - sc.setParameters("proto", protocol); - sc.setParameters("startPort", startPort); - sc.setParameters("endPort", endPort); - sc.setParameters("cidr", cidr); - - return expunge(sc); - } - - @Override - public IngressRuleVO findByProtoPortsAndAllowedGroupId(long securityGroupId, String proto, - int startPort, int endPort, Long allowedGroupId) { - SearchCriteria sc = protoPortsAndSecurityGroupIdSearch.create(); - sc.addAnd("securityGroupId", SearchCriteria.Op.EQ, securityGroupId); - sc.setParameters("proto", proto); - sc.setParameters("startPort", startPort); - sc.setParameters("endPort", endPort); - sc.setParameters("allowedNetworkId", allowedGroupId); - - return findOneIncludingRemovedBy(sc); - } -} diff --git a/server/src/com/cloud/network/security/dao/IngressRuleDao.java b/server/src/com/cloud/network/security/dao/SecurityGroupRuleDao.java similarity index 59% rename from server/src/com/cloud/network/security/dao/IngressRuleDao.java rename to server/src/com/cloud/network/security/dao/SecurityGroupRuleDao.java index c95e4ee567b..dad4c23c472 100644 --- a/server/src/com/cloud/network/security/dao/IngressRuleDao.java +++ b/server/src/com/cloud/network/security/dao/SecurityGroupRuleDao.java @@ -20,15 +20,16 @@ package com.cloud.network.security.dao; import java.util.List; -import com.cloud.network.security.IngressRuleVO; +import com.cloud.network.security.SecurityGroupRuleVO; +import com.cloud.network.security.SecurityRule.SecurityRuleType; import com.cloud.utils.db.GenericDao; -public interface IngressRuleDao extends GenericDao { - List listBySecurityGroupId(long networkGroupId); - List listByAllowedSecurityGroupId(long networkGroupId); - IngressRuleVO findByProtoPortsAndCidr(long networkGroupId, String proto, int startPort, int endPort, String cidr); - IngressRuleVO findByProtoPortsAndGroup(String proto, int startPort, int endPort, String networkGroup); - IngressRuleVO findByProtoPortsAndAllowedGroupId(long networkGroupId, String proto, int startPort, int endPort, Long allowedGroupId); +public interface SecurityGroupRuleDao extends GenericDao { + List listBySecurityGroupId(long securityGroupId, SecurityRuleType type); + List listByAllowedSecurityGroupId(long networkGroupId); + SecurityGroupRuleVO findByProtoPortsAndCidr(long networkGroupId, String proto, int startPort, int endPort, String cidr); + SecurityGroupRuleVO findByProtoPortsAndGroup(String proto, int startPort, int endPort, String networkGroup); + SecurityGroupRuleVO findByProtoPortsAndAllowedGroupId(long networkGroupId, String proto, int startPort, int endPort, Long allowedGroupId); int deleteBySecurityGroup(long securityGroupId); int deleteByPortProtoAndGroup(long securityGroupId, String protocol, int startPort,int endPort, Long id); int deleteByPortProtoAndCidr(long securityGroupId, String protocol, int startPort,int endPort, String cidr); diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java b/server/src/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java new file mode 100644 index 00000000000..a5813b548b9 --- /dev/null +++ b/server/src/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java @@ -0,0 +1,175 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.network.security.dao; + +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import com.cloud.network.security.SecurityGroupRuleVO; +import com.cloud.network.security.SecurityGroupVO; +import com.cloud.network.security.SecurityRule.SecurityRuleType; +import com.cloud.utils.component.Inject; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Local(value={SecurityGroupRuleDao.class}) +public class SecurityGroupRuleDaoImpl extends GenericDaoBase implements SecurityGroupRuleDao { + + @Inject SecurityGroupDao _securityGroupDao; + + protected SearchBuilder securityGroupIdSearch; + protected SearchBuilder securityGroupIdAndTypeSearch; + protected SearchBuilder allowedSecurityGroupIdSearch; + protected SearchBuilder protoPortsAndCidrSearch; + protected SearchBuilder protoPortsAndSecurityGroupNameSearch; + protected SearchBuilder protoPortsAndSecurityGroupIdSearch; + + + + protected SecurityGroupRuleDaoImpl() { + securityGroupIdSearch = createSearchBuilder(); + securityGroupIdSearch.and("securityGroupId", securityGroupIdSearch.entity().getSecurityGroupId(), SearchCriteria.Op.EQ); + securityGroupIdSearch.done(); + + securityGroupIdAndTypeSearch = createSearchBuilder(); + securityGroupIdAndTypeSearch.and("securityGroupId", securityGroupIdAndTypeSearch.entity().getSecurityGroupId(), SearchCriteria.Op.EQ); + securityGroupIdAndTypeSearch.and("type", securityGroupIdAndTypeSearch.entity().getType(), SearchCriteria.Op.EQ); + securityGroupIdAndTypeSearch.done(); + + allowedSecurityGroupIdSearch = createSearchBuilder(); + allowedSecurityGroupIdSearch.and("allowedNetworkId", allowedSecurityGroupIdSearch.entity().getAllowedNetworkId(), SearchCriteria.Op.EQ); + allowedSecurityGroupIdSearch.done(); + + protoPortsAndCidrSearch = createSearchBuilder(); + protoPortsAndCidrSearch.and("securityGroupId", protoPortsAndCidrSearch.entity().getSecurityGroupId(), SearchCriteria.Op.EQ); + protoPortsAndCidrSearch.and("proto", protoPortsAndCidrSearch.entity().getProtocol(), SearchCriteria.Op.EQ); + protoPortsAndCidrSearch.and("startPort", protoPortsAndCidrSearch.entity().getStartPort(), SearchCriteria.Op.EQ); + protoPortsAndCidrSearch.and("endPort", protoPortsAndCidrSearch.entity().getEndPort(), SearchCriteria.Op.EQ); + protoPortsAndCidrSearch.and("cidr", protoPortsAndCidrSearch.entity().getAllowedSourceIpCidr(), SearchCriteria.Op.EQ); + protoPortsAndCidrSearch.done(); + + protoPortsAndSecurityGroupIdSearch = createSearchBuilder(); + protoPortsAndSecurityGroupIdSearch.and("securityGroupId", protoPortsAndSecurityGroupIdSearch.entity().getSecurityGroupId(), SearchCriteria.Op.EQ); + protoPortsAndSecurityGroupIdSearch.and("proto", protoPortsAndSecurityGroupIdSearch.entity().getProtocol(), SearchCriteria.Op.EQ); + protoPortsAndSecurityGroupIdSearch.and("startPort", protoPortsAndSecurityGroupIdSearch.entity().getStartPort(), SearchCriteria.Op.EQ); + protoPortsAndSecurityGroupIdSearch.and("endPort", protoPortsAndSecurityGroupIdSearch.entity().getEndPort(), SearchCriteria.Op.EQ); + protoPortsAndSecurityGroupIdSearch.and("allowedNetworkId", protoPortsAndSecurityGroupIdSearch.entity().getAllowedNetworkId(), SearchCriteria.Op.EQ); + + } + + public List listBySecurityGroupId(long securityGroupId, SecurityRuleType type) { + SearchCriteria sc = securityGroupIdAndTypeSearch.create(); + sc.setParameters("securityGroupId", securityGroupId); + String dbType; + if (type == SecurityRuleType.EgressRule) { + dbType = SecurityRuleType.EgressRule.getType(); + }else { + dbType = SecurityRuleType.IngressRule.getType(); + } + + sc.setParameters("type", dbType); + return listBy(sc); + } + + public int deleteBySecurityGroup(long securityGroupId) { + SearchCriteria sc = securityGroupIdSearch.create(); + sc.setParameters("securityGroupId", securityGroupId); + return expunge(sc); + } + + @Override + public List listByAllowedSecurityGroupId(long securityGroupId) { + SearchCriteria sc = allowedSecurityGroupIdSearch.create(); + sc.setParameters("allowedNetworkId", securityGroupId); + return listBy(sc); + } + + @Override + public SecurityGroupRuleVO findByProtoPortsAndCidr(long securityGroupId, + String proto, int startPort, int endPort, String cidr) { + SearchCriteria sc = protoPortsAndCidrSearch.create(); + sc.setParameters("securityGroupId", securityGroupId); + sc.setParameters("proto", proto); + sc.setParameters("startPort", startPort); + sc.setParameters("endPort", endPort); + sc.setParameters("cidr", cidr); + return findOneIncludingRemovedBy(sc); + } + + @Override + public SecurityGroupRuleVO findByProtoPortsAndGroup(String proto, int startPort, int endPort, String securityGroup) { + SearchCriteria sc = protoPortsAndSecurityGroupNameSearch.create(); + sc.setParameters("proto", proto); + sc.setParameters("startPort", startPort); + sc.setParameters("endPort", endPort); + sc.setJoinParameters("groupName", "groupName", securityGroup); + return findOneIncludingRemovedBy(sc); + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + protoPortsAndSecurityGroupNameSearch = createSearchBuilder(); + protoPortsAndSecurityGroupNameSearch.and("proto", protoPortsAndSecurityGroupNameSearch.entity().getProtocol(), SearchCriteria.Op.EQ); + protoPortsAndSecurityGroupNameSearch.and("startPort", protoPortsAndSecurityGroupNameSearch.entity().getStartPort(), SearchCriteria.Op.EQ); + protoPortsAndSecurityGroupNameSearch.and("endPort", protoPortsAndSecurityGroupNameSearch.entity().getEndPort(), SearchCriteria.Op.EQ); + SearchBuilder ngSb = _securityGroupDao.createSearchBuilder(); + ngSb.and("groupName", ngSb.entity().getName(), SearchCriteria.Op.EQ); + protoPortsAndSecurityGroupNameSearch.join("groupName", ngSb, protoPortsAndSecurityGroupNameSearch.entity().getAllowedNetworkId(), ngSb.entity().getId(), JoinBuilder.JoinType.INNER); + protoPortsAndSecurityGroupNameSearch.done(); + return super.configure(name, params); + } + + @Override + public int deleteByPortProtoAndGroup(long securityGroupId, String protocol, int startPort, int endPort, Long allowedGroupId) { + SearchCriteria sc = protoPortsAndSecurityGroupIdSearch.create(); + sc.setParameters("securityGroupId", securityGroupId); + sc.setParameters("proto", protocol); + sc.setParameters("startPort", startPort); + sc.setParameters("endPort", endPort); + sc.setParameters("allowedNetworkId", allowedGroupId); + return expunge(sc); + } + + @Override + public int deleteByPortProtoAndCidr(long securityGroupId, String protocol, int startPort, int endPort, String cidr) { + SearchCriteria sc = protoPortsAndCidrSearch.create(); + sc.setParameters("securityGroupId", securityGroupId); + sc.setParameters("proto", protocol); + sc.setParameters("startPort", startPort); + sc.setParameters("endPort", endPort); + sc.setParameters("cidr", cidr); + return expunge(sc); + } + + @Override + public SecurityGroupRuleVO findByProtoPortsAndAllowedGroupId(long securityGroupId, String proto, int startPort, int endPort, Long allowedGroupId) { + SearchCriteria sc = protoPortsAndSecurityGroupIdSearch.create(); + sc.addAnd("securityGroupId", SearchCriteria.Op.EQ, securityGroupId); + sc.setParameters("proto", proto); + sc.setParameters("startPort", startPort); + sc.setParameters("endPort", endPort); + sc.setParameters("allowedNetworkId", allowedGroupId); + return findOneIncludingRemovedBy(sc); + } +} diff --git a/server/src/com/cloud/vm/dao/UserVmData.java b/server/src/com/cloud/vm/dao/UserVmData.java index 56b3a778f97..4cb014bd67f 100644 --- a/server/src/com/cloud/vm/dao/UserVmData.java +++ b/server/src/com/cloud/vm/dao/UserVmData.java @@ -22,7 +22,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import com.cloud.api.response.IngressRuleResponse; +import com.cloud.api.response.SecurityGroupRuleResponse; public class UserVmData { private Long id; @@ -580,7 +580,7 @@ public class UserVmData { private String domainName; private Long jobId; private Integer jobStatus; - private List ingressRules; + private List securityGroupRules; public String getObjectName() { return objectName; @@ -637,16 +637,15 @@ public class UserVmData { public void setDomainName(String domainName) { this.domainName = domainName; } - - public List getIngressRules() { - return ingressRules; +/* FIXME : the below functions are not used, so commenting out later need to include egress list + public List getIngressRules() { + return securityGroupRules; } - public void setIngressRules(List ingressRules) { - this.ingressRules = ingressRules; - } + public void setIngressRules(List securityGroupRules) { + this.securityGroupRules = securityGroupRules; + } */ - @Override public int hashCode() { final int prime = 31; diff --git a/setup/db/create-index-fk.sql b/setup/db/create-index-fk.sql index 2b8c543f19d..79537178748 100755 --- a/setup/db/create-index-fk.sql +++ b/setup/db/create-index-fk.sql @@ -60,10 +60,10 @@ ALTER TABLE `cloud`.`security_group` ADD CONSTRAINT `fk_security_group___account ALTER TABLE `cloud`.`security_group` ADD CONSTRAINT `fk_security_group__domain_id` FOREIGN KEY `fk_security_group__domain_id` (`domain_id`) REFERENCES `domain` (`id`); ALTER TABLE `cloud`.`security_group` ADD INDEX `i_security_group_name`(`name`); -ALTER TABLE `cloud`.`security_ingress_rule` ADD CONSTRAINT `fk_security_ingress_rule___security_group_id` FOREIGN KEY `fk_security_ingress_rule__security_group_id` (`security_group_id`) REFERENCES `security_group` (`id`) ON DELETE CASCADE; -ALTER TABLE `cloud`.`security_ingress_rule` ADD CONSTRAINT `fk_security_ingress_rule___allowed_network_id` FOREIGN KEY `fk_security_ingress_rule__allowed_network_id` (`allowed_network_id`) REFERENCES `security_group` (`id`) ON DELETE CASCADE; -ALTER TABLE `cloud`.`security_ingress_rule` ADD INDEX `i_security_ingress_rule_network_id`(`security_group_id`); -ALTER TABLE `cloud`.`security_ingress_rule` ADD INDEX `i_security_ingress_rule_allowed_network`(`allowed_network_id`); +ALTER TABLE `cloud`.`security_group_rule` ADD CONSTRAINT `fk_security_group_rule___security_group_id` FOREIGN KEY `fk_security_group_rule__security_group_id` (`security_group_id`) REFERENCES `security_group` (`id`) ON DELETE CASCADE; +ALTER TABLE `cloud`.`security_group_rule` ADD CONSTRAINT `fk_security_group_rule___allowed_network_id` FOREIGN KEY `fk_security_group_rule__allowed_network_id` (`allowed_network_id`) REFERENCES `security_group` (`id`) ON DELETE CASCADE; +ALTER TABLE `cloud`.`security_group_rule` ADD INDEX `i_security_group_rule_network_id`(`security_group_id`); +ALTER TABLE `cloud`.`security_group_rule` ADD INDEX `i_security_group_rule_allowed_network`(`allowed_network_id`); ALTER TABLE `cloud`.`security_group_vm_map` ADD CONSTRAINT `fk_security_group_vm_map___security_group_id` FOREIGN KEY `fk_security_group_vm_map___security_group_id` (`security_group_id`) REFERENCES `security_group` (`id`) ON DELETE CASCADE; ALTER TABLE `cloud`.`security_group_vm_map` ADD CONSTRAINT `fk_security_group_vm_map___instance_id` FOREIGN KEY `fk_security_group_vm_map___instance_id` (`instance_id`) REFERENCES `user_vm` (`id`) ON DELETE CASCADE; diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 6b061663166..464183010a3 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -109,7 +109,7 @@ DROP TABLE IF EXISTS `cloud`.`ovs_work`; DROP TABLE IF EXISTS `cloud`.`remote_access_vpn`; DROP TABLE IF EXISTS `cloud`.`resource_count`; DROP TABLE IF EXISTS `cloud`.`security_ingress_rule`; -DROP TABLE IF EXISTS `cloud`.`security_egress_rule`; +DROP TABLE IF EXISTS `cloud`.`security_group_rule`; DROP TABLE IF EXISTS `cloud`.`stack_maid`; DROP TABLE IF EXISTS `cloud`.`storage_pool_work`; DROP TABLE IF EXISTS `cloud`.`user_vm_details`; @@ -1542,10 +1542,11 @@ CREATE TABLE `cloud`.`security_group` ( CONSTRAINT `uc_security_group__uuid` UNIQUE (`uuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`security_ingress_rule` ( +CREATE TABLE `cloud`.`security_group_rule` ( `id` bigint unsigned NOT NULL auto_increment, `uuid` varchar(40), `security_group_id` bigint unsigned NOT NULL, + `type` varchar(10) default 'ingress', `start_port` varchar(10) default NULL, `end_port` varchar(10) default NULL, `protocol` varchar(16) NOT NULL default 'TCP', @@ -1553,21 +1554,7 @@ CREATE TABLE `cloud`.`security_ingress_rule` ( `allowed_ip_cidr` varchar(44), `create_status` varchar(32) COMMENT 'rule creation status', PRIMARY KEY (`id`), - CONSTRAINT `uc_security_ingress_rule__uuid` UNIQUE (`uuid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`security_egress_rule` ( - `id` bigint unsigned NOT NULL auto_increment, - `uuid` varchar(40), - `security_group_id` bigint unsigned NOT NULL, - `start_port` varchar(10) default NULL, - `end_port` varchar(10) default NULL, - `protocol` varchar(16) NOT NULL default 'TCP', - `allowed_network_id` bigint unsigned, - `allowed_ip_cidr` varchar(44), - `create_status` varchar(32) COMMENT 'rule creation status', - PRIMARY KEY (`id`), - CONSTRAINT `uc_security_egress_rule__uuid` UNIQUE (`uuid`) + CONSTRAINT `uc_security_group_rule__uuid` UNIQUE (`uuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`security_group_vm_map` ( diff --git a/setup/db/db/schema-2214to30.sql b/setup/db/db/schema-2214to30.sql index 9127577ed07..9b375cfe058 100755 --- a/setup/db/db/schema-2214to30.sql +++ b/setup/db/db/schema-2214to30.sql @@ -201,12 +201,6 @@ ALTER TABLE `cloud`.`firewall_rules` ADD CONSTRAINT `uc_firewall_rules__uuid` UN ALTER TABLE `cloud`.`cluster` ADD COLUMN `uuid` varchar(40); ALTER TABLE `cloud`.`cluster` ADD CONSTRAINT `uc_cluster__uuid` UNIQUE (`uuid`); -ALTER TABLE `cloud`.`security_ingress_rule` ADD COLUMN `uuid` varchar(40); -ALTER TABLE `cloud`.`security_ingress_rule` ADD CONSTRAINT `uc_security_ingress_rule__uuid` UNIQUE (`uuid`); - -ALTER TABLE `cloud`.`security_egress_rule` ADD COLUMN `uuid` varchar(40); -ALTER TABLE `cloud`.`security_egress_rule` ADD CONSTRAINT `uc_security_egress_rule__uuid` UNIQUE (`uuid`); - ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `uuid` varchar(40); ALTER TABLE `cloud`.`network_offerings` ADD CONSTRAINT `uc_network_offerings__uuid` UNIQUE (`uuid`); @@ -285,3 +279,20 @@ ALTER TABLE `cloud_usage`.`usage_vpn_user` ADD INDEX `i_usage_vpn_user__created` ALTER TABLE `cloud_usage`.`usage_vpn_user` ADD INDEX `i_usage_vpn_user__deleted`(`deleted`); ALTER TABLE `cloud`.`vm_instance` DROP COLUMN `private_netmask`; + +ALTER TABLE `cloud`.`security_ingress_rule` drop foreign key `fk_security_ingress_rule___security_group_id`; +ALTER TABLE `cloud`.`security_ingress_rule` drop foreign key `fk_security_ingress_rule___allowed_network_id`; +ALTER TABLE `cloud`.`security_ingress_rule` drop index `i_security_ingress_rule_network_id`; +ALTER TABLE `cloud`.`security_ingress_rule` drop index `i_security_ingress_rule_allowed_network`; + +ALTER TABLE `cloud`.`security_ingress_rule` RENAME TO `security_group_rule`; + +ALTER TABLE `cloud`.`security_group_rule` ADD COLUMN `type` varchar(10) default 'ingress' AFTER security_group_id; +ALTER TABLE `cloud`.`security_group_rule` ADD COLUMN `uuid` varchar(40) AFTER id; +ALTER TABLE `cloud`.`security_group_rule` ADD CONSTRAINT `uc_security_group_rule__uuid` UNIQUE (`uuid`); + +ALTER TABLE `cloud`.`security_group_rule` ADD CONSTRAINT `fk_security_group_rule___security_group_id` FOREIGN KEY `fk_security_group_rule__security_group_id` (`security_group_id`) REFERENCES `security_group` (`id`) ON DELETE CASCADE; +ALTER TABLE `cloud`.`security_group_rule` ADD CONSTRAINT `fk_security_group_rule___allowed_network_id` FOREIGN KEY `fk_security_group_rule__allowed_network_id` (`allowed_network_id`) REFERENCES `security_group` (`id`) ON DELETE CASCADE; +ALTER TABLE `cloud`.`security_group_rule` ADD INDEX `i_security_group_rule_network_id`(`security_group_id`); +ALTER TABLE `cloud`.`security_group_rule` ADD INDEX `i_security_group_rule_allowed_network`(`allowed_network_id`); +