diff --git a/server/src/com/cloud/api/BaseAsyncCmd.java b/server/src/com/cloud/api/BaseAsyncCmd.java index d8ce6a8db1a..b00e81c3cf0 100644 --- a/server/src/com/cloud/api/BaseAsyncCmd.java +++ b/server/src/com/cloud/api/BaseAsyncCmd.java @@ -1,6 +1,7 @@ package com.cloud.api; import com.cloud.serializer.SerializerHelper; +import com.cloud.user.Account; /** * A base command for supporting asynchronous API calls. When an API command is received, the command will be diff --git a/server/src/com/cloud/api/commands/RevokeNetworkGroupIngressCmd.java b/server/src/com/cloud/api/commands/RevokeNetworkGroupIngressCmd.java index 75598ca3855..c0fb69cc4cb 100644 --- a/server/src/com/cloud/api/commands/RevokeNetworkGroupIngressCmd.java +++ b/server/src/com/cloud/api/commands/RevokeNetworkGroupIngressCmd.java @@ -1,44 +1,19 @@ package com.cloud.api.commands; -import java.util.ArrayList; -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.BaseCmd; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.Implementation; import com.cloud.api.Parameter; -import com.cloud.api.ServerApiException; -import com.cloud.network.security.NetworkGroupVO; -import com.cloud.user.Account; -import com.cloud.utils.Pair; -import com.cloud.utils.net.NetUtils; +import com.cloud.api.BaseCmd.Manager; -public class RevokeNetworkGroupIngressCmd extends BaseCmd { +@Implementation(method="revokeNetworkGroupIngress", manager=Manager.NetworkGroupManager) +public class RevokeNetworkGroupIngressCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RevokeNetworkGroupIngressCmd.class.getName()); private static final String s_name = "revokenetworkgroupingress"; - private static final List> s_properties = new ArrayList>(); - - static { - s_properties.add(new Pair(BaseCmd.Properties.USER_ID, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE)); - - s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.CIDR_LIST, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.DOMAIN_ID, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.END_PORT, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.ICMP_CODE, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.ICMP_TYPE, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.NETWORK_GROUP_NAME, Boolean.TRUE)); - s_properties.add(new Pair(BaseCmd.Properties.PROTOCOL, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.START_PORT, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.USER_NETWORK_GROUP_LIST, Boolean.FALSE)); - - } ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -130,180 +105,182 @@ public class RevokeNetworkGroupIngressCmd extends BaseCmd { return "revokenetworkgroupingress"; } - public List> getProperties() { - return s_properties; - } +// @Override +// public List> execute(Map params) { +// Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName()); +// String accountName = (String)params.get(BaseCmd.Properties.ACCOUNT.getName()); +// Long domainId = (Long)params.get(BaseCmd.Properties.DOMAIN_ID.getName()); +// Long userId = (Long)params.get(BaseCmd.Properties.USER_ID.getName()); +// Integer startPort = (Integer)params.get(BaseCmd.Properties.START_PORT.getName()); +// Integer endPort = (Integer)params.get(BaseCmd.Properties.END_PORT.getName()); +// Integer icmpType = (Integer)params.get(BaseCmd.Properties.ICMP_TYPE.getName()); +// Integer icmpCode = (Integer)params.get(BaseCmd.Properties.ICMP_CODE.getName()); +// String protocol = (String)params.get(BaseCmd.Properties.PROTOCOL.getName()); +// String networkGroup = (String)params.get(BaseCmd.Properties.NETWORK_GROUP_NAME.getName()); +// String cidrList = (String)params.get(BaseCmd.Properties.CIDR_LIST.getName()); +// Map groupList = (Map)params.get(BaseCmd.Properties.USER_NETWORK_GROUP_LIST.getName()); +// +// Long accountId = null; +// Integer startPortOrType = null; +// Integer endPortOrCode = null; +// if (protocol == null) { +// protocol = "all"; +// } +// //FIXME: for exceptions below, add new enums to BaseCmd.PARAM_ to reflect the error condition more precisely +// if (!NetUtils.isValidNetworkGroupProto(protocol)) { +// s_logger.debug("Invalid protocol specified " + protocol); +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid protocol " + protocol); +// } +// if ("icmp".equalsIgnoreCase(protocol) ) { +// if ((icmpType == null) || (icmpCode == null)) { +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid ICMP type/code specified, icmpType = " + icmpType + ", icmpCode = " + icmpCode); +// } +// if (icmpType == -1 && icmpCode != -1) { +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid icmp type range" ); +// } +// if (icmpCode > 255) { +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid icmp code " ); +// } +// startPortOrType = icmpType; +// endPortOrCode= icmpCode; +// } else if (protocol.equals("all")) { +// if ((startPort != null) || (endPort != null)) { +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Cannot specify startPort or endPort without specifying protocol"); +// } +// startPortOrType = 0; +// endPortOrCode = 0; +// } else { +// if ((startPort == null) || (endPort == null)) { +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port range specified, startPort = " + startPort + ", endPort = " + endPort); +// } +// if (startPort == 0 && endPort == 0) { +// endPort = 65535; +// } +// if (startPort > endPort) { +// s_logger.debug("Invalid port range specified: " + startPort + ":" + endPort); +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port range " ); +// } +// if (startPort > 65535 || endPort > 65535 || startPort < -1 || endPort < -1) { +// s_logger.debug("Invalid port numbers specified: " + startPort + ":" + endPort); +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port numbers " ); +// } +// +// if (startPort < 0 || endPort < 0) { +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port range " ); +// } +// startPortOrType = startPort; +// endPortOrCode= endPort; +// } +// +// if ((account == null) || isAdmin(account.getType())) { +// if ((accountName != null) && (domainId != null)) { +// // if it's an admin account, do a quick permission check +// if ((account != null) && !getManagementServer().isChildDomain(account.getDomainId(), domainId)) { +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Unable to find rules for network security group id = " + networkGroup + ", permission denied."); +// } +// throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to find rules for network security group id = " + networkGroup + ", permission denied."); +// } +// Account groupOwner = getManagementServer().findActiveAccount(accountName, domainId); +// if (groupOwner == null) { +// throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find account " + accountName + " in domain " + domainId); +// } +// accountId = groupOwner.getId(); +// } else { +// if (account != null) { +// accountId = account.getId(); +// domainId = account.getDomainId(); +// } +// } +// } else { +// if (account != null) { +// accountId = account.getId(); +// domainId = account.getDomainId(); +// } +// } +// +// if (accountId == null) { +// throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find account for network security group " + networkGroup + "; failed to revoke ingress."); +// } +// +// NetworkGroupVO sg = getManagementServer().findNetworkGroupByName(accountId, networkGroup); +// if (sg == null) { +// s_logger.debug("Unable to find network security group with id " + networkGroup); +// throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find network security group with id " + networkGroup); +// } +// +// if (cidrList == null && groupList == null) { +// s_logger.debug("At least one cidr or at least one security group needs to be specified"); +// throw new ServerApiException(BaseCmd.PARAM_ERROR, "At least one cidr or at least one security group needs to be specified"); +// } +// List authorizedCidrs = new ArrayList(); +// if (cidrList != null) { +// if (protocol.equals("all")) { +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Cannot specify cidrs without specifying protocol and ports."); +// } +// String [] cidrs = cidrList.split(","); +// for (String cidr: cidrs) { +// if (!NetUtils.isValidCIDR(cidr)) { +// s_logger.debug( "Invalid cidr (" + cidr + ") given, unable to revoke ingress."); +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid cidr (" + cidr + ") given, unable to revoke ingress."); +// } +// authorizedCidrs.add(cidr); +// } +// } +// +// List authorizedGroups = new ArrayList (); +// if (groupList != null) { +// Collection userGroupCollection = groupList.values(); +// Iterator iter = userGroupCollection.iterator(); +// while (iter.hasNext()) { +// HashMap userGroup = (HashMap)iter.next(); +// String group = (String)userGroup.get("group"); +// String authorizedAccountName = (String)userGroup.get("account"); +// if ((group == null) || (authorizedAccountName == null)) { +// throw new ServerApiException(BaseCmd.PARAM_ERROR, "Invalid user group specified, fields 'group' and 'account' cannot be null, please specify groups in the form: userGroupList[0].group=XXX&userGroupList[0].account=YYY"); +// } +// +// Account authorizedAccount = getManagementServer().findActiveAccount(authorizedAccountName, domainId); +// if (authorizedAccount == null) { +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Nonexistent account: " + authorizedAccountName + ", domainid: " + domainId + " when trying to revoke ingress for " + networkGroup + ":" + protocol + ":" + startPortOrType + ":" + endPortOrCode); +// } +// throw new ServerApiException(BaseCmd.PARAM_ERROR, "Nonexistent account: " + authorizedAccountName + " when trying to revoke ingress for " + networkGroup + ":" + protocol + ":" + startPortOrType + ":" + endPortOrCode); +// } +// +// NetworkGroupVO groupVO = getManagementServer().findNetworkGroupByName(authorizedAccount.getId(), group); +// if (groupVO == null) { +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Nonexistent group and/or accountId: " + accountId + ", groupName=" + group); +// } +// throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid account/group pair (" + userGroup + ") given, unable to revoke ingress."); +// } +// authorizedGroups.add(groupVO); +// } +// } +// +// // If command is executed via 8096 port, set userId to the id of System account (1) +// if (userId == null) { +// userId = Long.valueOf(1); +// } +// +// long jobId = getManagementServer().revokeNetworkGroupIngressAsync(accountId, networkGroup, protocol, startPortOrType, endPortOrCode, authorizedCidrs.toArray(new String[authorizedCidrs.size()]), authorizedGroups); +// +// if (jobId == 0) { +// s_logger.warn("Unable to schedule async-job for RevokeNetworkGroupIngressCmd command"); +// } else { +// if (s_logger.isDebugEnabled()) +// s_logger.debug("RevokeNetworkGroupIngressCmd command has been accepted, job id: " + jobId); +// } +// +// List> returnValues = new ArrayList>(); +// returnValues.add(new Pair(BaseCmd.Properties.JOB_ID.getName(), Long.valueOf(jobId))); +// return returnValues; +// } - @Override - public List> execute(Map params) { - Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName()); - String accountName = (String)params.get(BaseCmd.Properties.ACCOUNT.getName()); - Long domainId = (Long)params.get(BaseCmd.Properties.DOMAIN_ID.getName()); - Long userId = (Long)params.get(BaseCmd.Properties.USER_ID.getName()); - Integer startPort = (Integer)params.get(BaseCmd.Properties.START_PORT.getName()); - Integer endPort = (Integer)params.get(BaseCmd.Properties.END_PORT.getName()); - Integer icmpType = (Integer)params.get(BaseCmd.Properties.ICMP_TYPE.getName()); - Integer icmpCode = (Integer)params.get(BaseCmd.Properties.ICMP_CODE.getName()); - String protocol = (String)params.get(BaseCmd.Properties.PROTOCOL.getName()); - String networkGroup = (String)params.get(BaseCmd.Properties.NETWORK_GROUP_NAME.getName()); - String cidrList = (String)params.get(BaseCmd.Properties.CIDR_LIST.getName()); - Map groupList = (Map)params.get(BaseCmd.Properties.USER_NETWORK_GROUP_LIST.getName()); - - Long accountId = null; - Integer startPortOrType = null; - Integer endPortOrCode = null; - if (protocol == null) { - protocol = "all"; - } - //FIXME: for exceptions below, add new enums to BaseCmd.PARAM_ to reflect the error condition more precisely - if (!NetUtils.isValidNetworkGroupProto(protocol)) { - s_logger.debug("Invalid protocol specified " + protocol); - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid protocol " + protocol); - } - if ("icmp".equalsIgnoreCase(protocol) ) { - if ((icmpType == null) || (icmpCode == null)) { - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid ICMP type/code specified, icmpType = " + icmpType + ", icmpCode = " + icmpCode); - } - if (icmpType == -1 && icmpCode != -1) { - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid icmp type range" ); - } - if (icmpCode > 255) { - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid icmp code " ); - } - startPortOrType = icmpType; - endPortOrCode= icmpCode; - } else if (protocol.equals("all")) { - if ((startPort != null) || (endPort != null)) { - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Cannot specify startPort or endPort without specifying protocol"); - } - startPortOrType = 0; - endPortOrCode = 0; - } else { - if ((startPort == null) || (endPort == null)) { - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port range specified, startPort = " + startPort + ", endPort = " + endPort); - } - if (startPort == 0 && endPort == 0) { - endPort = 65535; - } - if (startPort > endPort) { - s_logger.debug("Invalid port range specified: " + startPort + ":" + endPort); - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port range " ); - } - if (startPort > 65535 || endPort > 65535 || startPort < -1 || endPort < -1) { - s_logger.debug("Invalid port numbers specified: " + startPort + ":" + endPort); - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port numbers " ); - } - - if (startPort < 0 || endPort < 0) { - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port range " ); - } - startPortOrType = startPort; - endPortOrCode= endPort; - } - - if ((account == null) || isAdmin(account.getType())) { - if ((accountName != null) && (domainId != null)) { - // if it's an admin account, do a quick permission check - if ((account != null) && !getManagementServer().isChildDomain(account.getDomainId(), domainId)) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find rules for network security group id = " + networkGroup + ", permission denied."); - } - throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to find rules for network security group id = " + networkGroup + ", permission denied."); - } - Account groupOwner = getManagementServer().findActiveAccount(accountName, domainId); - if (groupOwner == null) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find account " + accountName + " in domain " + domainId); - } - accountId = groupOwner.getId(); - } else { - if (account != null) { - accountId = account.getId(); - domainId = account.getDomainId(); - } - } - } else { - if (account != null) { - accountId = account.getId(); - domainId = account.getDomainId(); - } - } - - if (accountId == null) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find account for network security group " + networkGroup + "; failed to revoke ingress."); - } - - NetworkGroupVO sg = getManagementServer().findNetworkGroupByName(accountId, networkGroup); - if (sg == null) { - s_logger.debug("Unable to find network security group with id " + networkGroup); - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find network security group with id " + networkGroup); - } - - if (cidrList == null && groupList == null) { - s_logger.debug("At least one cidr or at least one security group needs to be specified"); - throw new ServerApiException(BaseCmd.PARAM_ERROR, "At least one cidr or at least one security group needs to be specified"); - } - List authorizedCidrs = new ArrayList(); - if (cidrList != null) { - if (protocol.equals("all")) { - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Cannot specify cidrs without specifying protocol and ports."); - } - String [] cidrs = cidrList.split(","); - for (String cidr: cidrs) { - if (!NetUtils.isValidCIDR(cidr)) { - s_logger.debug( "Invalid cidr (" + cidr + ") given, unable to revoke ingress."); - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid cidr (" + cidr + ") given, unable to revoke ingress."); - } - authorizedCidrs.add(cidr); - } - } - - List authorizedGroups = new ArrayList (); - if (groupList != null) { - Collection userGroupCollection = groupList.values(); - Iterator iter = userGroupCollection.iterator(); - while (iter.hasNext()) { - HashMap userGroup = (HashMap)iter.next(); - String group = (String)userGroup.get("group"); - String authorizedAccountName = (String)userGroup.get("account"); - if ((group == null) || (authorizedAccountName == null)) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Invalid user group specified, fields 'group' and 'account' cannot be null, please specify groups in the form: userGroupList[0].group=XXX&userGroupList[0].account=YYY"); - } - - Account authorizedAccount = getManagementServer().findActiveAccount(authorizedAccountName, domainId); - if (authorizedAccount == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Nonexistent account: " + authorizedAccountName + ", domainid: " + domainId + " when trying to revoke ingress for " + networkGroup + ":" + protocol + ":" + startPortOrType + ":" + endPortOrCode); - } - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Nonexistent account: " + authorizedAccountName + " when trying to revoke ingress for " + networkGroup + ":" + protocol + ":" + startPortOrType + ":" + endPortOrCode); - } - - NetworkGroupVO groupVO = getManagementServer().findNetworkGroupByName(authorizedAccount.getId(), group); - if (groupVO == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Nonexistent group and/or accountId: " + accountId + ", groupName=" + group); - } - throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid account/group pair (" + userGroup + ") given, unable to revoke ingress."); - } - authorizedGroups.add(groupVO); - } - } - - // If command is executed via 8096 port, set userId to the id of System account (1) - if (userId == null) { - userId = Long.valueOf(1); - } - - long jobId = getManagementServer().revokeNetworkGroupIngressAsync(accountId, networkGroup, protocol, startPortOrType, endPortOrCode, authorizedCidrs.toArray(new String[authorizedCidrs.size()]), authorizedGroups); - - if (jobId == 0) { - s_logger.warn("Unable to schedule async-job for RevokeNetworkGroupIngressCmd command"); - } else { - if (s_logger.isDebugEnabled()) - s_logger.debug("RevokeNetworkGroupIngressCmd command has been accepted, job id: " + jobId); - } - - List> returnValues = new ArrayList>(); - returnValues.add(new Pair(BaseCmd.Properties.JOB_ID.getName(), Long.valueOf(jobId))); - return returnValues; + @Override + public String getResponse() { + // TODO Fix response + return null; } } diff --git a/server/src/com/cloud/network/security/NetworkGroupManager.java b/server/src/com/cloud/network/security/NetworkGroupManager.java index 9eaf5506153..069fc767e8e 100644 --- a/server/src/com/cloud/network/security/NetworkGroupManager.java +++ b/server/src/com/cloud/network/security/NetworkGroupManager.java @@ -21,6 +21,7 @@ import java.util.HashMap; import java.util.List; import com.cloud.api.commands.CreateNetworkGroupCmd; +import com.cloud.api.commands.RevokeNetworkGroupIngressCmd; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceInUseException; @@ -61,9 +62,7 @@ public interface NetworkGroupManager extends Manager { public void removeInstanceFromGroups(Long userVmId); - boolean revokeNetworkGroupIngress(AccountVO account, String groupName, - String proto, int startPort, int endPort, String[] cidrList, - List authorizedGroups); + boolean revokeNetworkGroupIngress(RevokeNetworkGroupIngressCmd cmd); public void deleteNetworkGroup(Long groupId, Long accountId) throws ResourceInUseException, PermissionDeniedException; diff --git a/server/src/com/cloud/network/security/NetworkGroupManagerImpl.java b/server/src/com/cloud/network/security/NetworkGroupManagerImpl.java index cb2c60dae97..8e0d11d5e0f 100644 --- a/server/src/com/cloud/network/security/NetworkGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/NetworkGroupManagerImpl.java @@ -18,10 +18,12 @@ package com.cloud.network.security; import java.util.ArrayList; +import java.util.Collection; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -41,7 +43,10 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.NetworkIngressRulesCmd; import com.cloud.agent.api.NetworkIngressRulesCmd.IpPortAndProto; import com.cloud.agent.manager.AgentManager; +import com.cloud.api.BaseCmd; +import com.cloud.api.ServerApiException; import com.cloud.api.commands.CreateNetworkGroupCmd; +import com.cloud.api.commands.RevokeNetworkGroupIngressCmd; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; @@ -73,6 +78,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; import com.cloud.vm.State; import com.cloud.vm.dao.UserVmDao; @@ -90,7 +96,6 @@ public class NetworkGroupManagerImpl implements NetworkGroupManager { @Inject NetworkGroupWorkDao _workDao; @Inject VmRulesetLogDao _rulesetLogDao; @Inject DomainDao _domainDao; - @Inject AgentManager _agentMgr; ScheduledExecutorService _executorPool; ScheduledExecutorService _cleanupExecutor; @@ -492,40 +497,195 @@ public class NetworkGroupManagerImpl implements NetworkGroupManager { @Override @DB - public boolean revokeNetworkGroupIngress(AccountVO account, - String groupName, String protocol, int startPort, - int endPort, String[] cidrList, List authorizedGroups) { + public boolean revokeNetworkGroupIngress(RevokeNetworkGroupIngressCmd cmd) { + + //input validation + Account account = (Account)UserContext.current().getAccountObject(); + Long userId = UserContext.current().getUserId(); + Long domainId = cmd.getDomainId(); + Integer startPort = cmd.getStartPort(); + Integer endPort = cmd.getEndPort(); + Integer icmpType = cmd.getIcmpType(); + Integer icmpCode = cmd.getIcmpCode(); + String protocol = cmd.getProtocol(); + String networkGroup = cmd.getNetworkGroupName(); + String cidrList = cmd.getCidrList(); + Map groupList = cmd.getUserNetworkGroupList(); + String [] cidrs = null; + Long accountId = null; + Integer startPortOrType = null; + Integer endPortOrCode = null; + if (protocol == null) { + protocol = "all"; + } + //FIXME: for exceptions below, add new enums to BaseCmd.PARAM_ to reflect the error condition more precisely + if (!NetUtils.isValidNetworkGroupProto(protocol)) { + s_logger.debug("Invalid protocol specified " + protocol); + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid protocol " + protocol); + } + if ("icmp".equalsIgnoreCase(protocol) ) { + if ((icmpType == null) || (icmpCode == null)) { + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid ICMP type/code specified, icmpType = " + icmpType + ", icmpCode = " + icmpCode); + } + if (icmpType == -1 && icmpCode != -1) { + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid icmp type range" ); + } + if (icmpCode > 255) { + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid icmp code " ); + } + startPortOrType = icmpType; + endPortOrCode= icmpCode; + } else if (protocol.equals("all")) { + if ((startPort != null) || (endPort != null)) { + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Cannot specify startPort or endPort without specifying protocol"); + } + startPortOrType = 0; + endPortOrCode = 0; + } else { + if ((startPort == null) || (endPort == null)) { + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port range specified, startPort = " + startPort + ", endPort = " + endPort); + } + if (startPort == 0 && endPort == 0) { + endPort = 65535; + } + if (startPort > endPort) { + s_logger.debug("Invalid port range specified: " + startPort + ":" + endPort); + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port range " ); + } + if (startPort > 65535 || endPort > 65535 || startPort < -1 || endPort < -1) { + s_logger.debug("Invalid port numbers specified: " + startPort + ":" + endPort); + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port numbers " ); + } + + if (startPort < 0 || endPort < 0) { + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid port range " ); + } + startPortOrType = startPort; + endPortOrCode= endPort; + } + + if ((account == null) || isAdmin(account.getType())) { + if ((account.getAccountName() != null) && (domainId != null)) { + // if it's an admin account, do a quick permission check + if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to find rules for network security group id = " + networkGroup + ", permission denied."); + } + throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to find rules for network security group id = " + networkGroup + ", permission denied."); + } + Account groupOwner = _accountDao.findActiveAccount(account.getAccountName(), domainId); + if (groupOwner == null) { + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find account " + account.getAccountName() + " in domain " + domainId); + } + accountId = groupOwner.getId(); + } else { + if (account != null) { + accountId = account.getId(); + domainId = account.getDomainId(); + } + } + } else { + if (account != null) { + accountId = account.getId(); + domainId = account.getDomainId(); + } + } + + if (accountId == null) { + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find account for network security group " + networkGroup + "; failed to revoke ingress."); + } + + NetworkGroupVO sg = _networkGroupDao.findByAccountAndName(accountId, networkGroup); + if (sg == null) { + s_logger.debug("Unable to find network security group with id " + networkGroup); + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find network security group with id " + networkGroup); + } + + if (cidrList == null && groupList == null) { + s_logger.debug("At least one cidr or at least one security group needs to be specified"); + throw new ServerApiException(BaseCmd.PARAM_ERROR, "At least one cidr or at least one security group needs to be specified"); + } + List authorizedCidrs = new ArrayList(); + if (cidrList != null) { + if (protocol.equals("all")) { + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Cannot specify cidrs without specifying protocol and ports."); + } + cidrs = cidrList.split(","); + for (String cidr: cidrs) { + if (!NetUtils.isValidCIDR(cidr)) { + s_logger.debug( "Invalid cidr (" + cidr + ") given, unable to revoke ingress."); + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid cidr (" + cidr + ") given, unable to revoke ingress."); + } + authorizedCidrs.add(cidr); + } + } + + List authorizedGroups = new ArrayList (); + if (groupList != null) { + Collection userGroupCollection = groupList.values(); + Iterator iter = userGroupCollection.iterator(); + while (iter.hasNext()) { + HashMap userGroup = (HashMap)iter.next(); + String group = (String)userGroup.get("group"); + String authorizedAccountName = (String)userGroup.get("account"); + if ((group == null) || (authorizedAccountName == null)) { + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Invalid user group specified, fields 'group' and 'account' cannot be null, please specify groups in the form: userGroupList[0].group=XXX&userGroupList[0].account=YYY"); + } + + Account authorizedAccount = _accountDao.findActiveAccount(authorizedAccountName, domainId); + if (authorizedAccount == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Nonexistent account: " + authorizedAccountName + ", domainid: " + domainId + " when trying to revoke ingress for " + networkGroup + ":" + protocol + ":" + startPortOrType + ":" + endPortOrCode); + } + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Nonexistent account: " + authorizedAccountName + " when trying to revoke ingress for " + networkGroup + ":" + protocol + ":" + startPortOrType + ":" + endPortOrCode); + } + + NetworkGroupVO groupVO = _networkGroupDao.findByAccountAndName(authorizedAccount.getId(), group); + if (groupVO == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Nonexistent group and/or accountId: " + accountId + ", groupName=" + group); + } + throw new ServerApiException(BaseCmd.NET_INVALID_PARAM_ERROR, "Invalid account/group pair (" + userGroup + ") given, unable to revoke ingress."); + } + authorizedGroups.add(groupVO); + } + } + + // If command is executed via 8096 port, set userId to the id of System account (1) + if (userId == null) { + userId = Long.valueOf(1); + } if (!_enabled) { return false; } int numDeleted = 0; - final int numToDelete = cidrList.length + authorizedGroups.size(); + final int numToDelete = cidrList.length() + authorizedGroups.size(); final Transaction txn = Transaction.currentTxn(); - final Long accountId = account.getId(); - NetworkGroupVO networkGroup = _networkGroupDao.findByAccountAndName(accountId, groupName); - if (networkGroup == null) { - s_logger.warn("Network security group not found: name= " + groupName); + + NetworkGroupVO networkGroupHandle = _networkGroupDao.findByAccountAndName(accountId, networkGroup); + if (networkGroupHandle == null) { + s_logger.warn("Network security group not found: name= " + networkGroup); return false; } try { txn.start(); - networkGroup = _networkGroupDao.acquire(networkGroup.getId()); - if (networkGroup == null) { - s_logger.warn("Could not acquire lock on network security group: name= " + groupName); + networkGroupHandle = _networkGroupDao.acquire(networkGroupHandle.getId()); + if (networkGroupHandle == null) { + s_logger.warn("Could not acquire lock on network security group: name= " + networkGroup); return false; } for (final NetworkGroupVO ngVO: authorizedGroups) { - numDeleted += _ingressRuleDao.deleteByPortProtoAndGroup(networkGroup.getId(), protocol, startPort, endPort, ngVO.getId()); + numDeleted += _ingressRuleDao.deleteByPortProtoAndGroup(networkGroupHandle.getId(), protocol, startPort, endPort, ngVO.getId()); } - for (final String cidr: cidrList) { - numDeleted += _ingressRuleDao.deleteByPortProtoAndCidr(networkGroup.getId(), protocol, startPort, endPort, cidr); + for (final String cidr: cidrs) { + numDeleted += _ingressRuleDao.deleteByPortProtoAndCidr(networkGroupHandle.getId(), protocol, startPort, endPort, cidr); } - s_logger.debug("revokeNetworkGroupIngress for group: " + groupName + ", numToDelete=" + numToDelete + ", numDeleted=" + numDeleted); + s_logger.debug("revokeNetworkGroupIngress for group: " + networkGroup + ", numToDelete=" + numToDelete + ", numDeleted=" + numDeleted); final Set affectedVms = new HashSet(); - affectedVms.addAll(_networkGroupVMMapDao.listVmIdsByNetworkGroup(networkGroup.getId())); + affectedVms.addAll(_networkGroupVMMapDao.listVmIdsByNetworkGroup(networkGroupHandle.getId())); scheduleRulesetUpdateToHosts(affectedVms, true, null); return true; @@ -534,12 +694,18 @@ public class NetworkGroupManagerImpl implements NetworkGroupManager { throw new CloudRuntimeException("Exception caught when deleting ingress rules", e); } finally { if (networkGroup != null) { - _networkGroupDao.release(networkGroup.getId()); + _networkGroupDao.release(networkGroupHandle.getId()); } txn.commit(); } } + + private static boolean isAdmin(short accountType) { + return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || + (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || + (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); + } @Override public NetworkGroupVO createNetworkGroup(CreateNetworkGroupCmd cmd) throws PermissionDeniedException, InvalidParameterValueException { diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index 948a3cb186a..bdf5ac62196 100644 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -2046,7 +2046,7 @@ public interface ManagementServer { * @return the job id if scheduled, 0 if the job was not scheduled */ long revokeNetworkGroupIngressAsync(Long accountId, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List authorizedGroups); - boolean revokeNetworkGroupIngress(AccountVO account, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List authorizedGroups); +// boolean revokeNetworkGroupIngress(AccountVO account, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List authorizedGroups); /** * Delete an empty network group. If the group is not empty an error is returned. diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 219c92e39a6..6eead0a7389 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -8111,10 +8111,10 @@ public class ManagementServerImpl implements ManagementServer { return _asyncMgr.submitAsyncJob(job); } - @Override - public boolean revokeNetworkGroupIngress(AccountVO account, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List authorizedGroups) { - return _networkGroupMgr.revokeNetworkGroupIngress(account, groupName, protocol, startPort, endPort, cidrList, authorizedGroups); - } +// @Override +// public boolean revokeNetworkGroupIngress(AccountVO account, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List authorizedGroups) { +// return _networkGroupMgr.revokeNetworkGroupIngress(account, groupName, protocol, startPort, endPort, cidrList, authorizedGroups); +// } @Override public long revokeNetworkGroupIngressAsync(Long accountId, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List authorizedGroups) {