diff --git a/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java b/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java index 22cdf646b7d..a371a48c822 100644 --- a/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java @@ -26,6 +26,7 @@ import com.cloud.api.ApiConstants; import com.cloud.api.BaseListCmd; import com.cloud.api.Implementation; import com.cloud.api.Parameter; +import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.FirewallRuleResponse; import com.cloud.api.response.IpForwardingRuleResponse; import com.cloud.api.response.ListResponse; @@ -44,6 +45,12 @@ public class ListIpForwardingRulesCmd extends BaseListCmd { @Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, description="list the rule belonging to this public ip address") private String publicIpAddress; + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account associated with the ip forwarding rule. Must be used with the domainId parameter.") + private String accountName; + + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="Lists all rules for this id. If used with the account parameter, returns all rules for an account in the specified domain ID.") + private Long domainId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -65,6 +72,14 @@ public class ListIpForwardingRulesCmd extends BaseListCmd { this.publicIpAddress = publicIpAddress; } + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + @Override public void execute(){ List result = _mgr.searchForIpForwardingRules(this); diff --git a/api/src/com/cloud/api/response/IpForwardingRuleResponse.java b/api/src/com/cloud/api/response/IpForwardingRuleResponse.java index 45aaa6e0e4d..feae3d89a99 100644 --- a/api/src/com/cloud/api/response/IpForwardingRuleResponse.java +++ b/api/src/com/cloud/api/response/IpForwardingRuleResponse.java @@ -25,15 +25,9 @@ public class IpForwardingRuleResponse extends BaseResponse { @SerializedName(ApiConstants.ID) @Param(description="the ID of the port forwarding rule") private Long id; - @SerializedName(ApiConstants.PRIVATE_PORT) @Param(description="the private port for the port forwarding rule") - private String privatePort; - @SerializedName(ApiConstants.PROTOCOL) @Param(description="the protocol of the port forwarding rule") private String protocol; - @SerializedName(ApiConstants.PUBLIC_PORT) @Param(description="the public port for the port forwarding rule") - private String publicPort; - @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) @Param(description="the VM ID for the port forwarding rule") private Long virtualMachineId; @@ -54,14 +48,6 @@ public class IpForwardingRuleResponse extends BaseResponse { this.id = id; } - public String getPrivatePort() { - return privatePort; - } - - public void setPrivatePort(String privatePort) { - this.privatePort = privatePort; - } - public String getProtocol() { return protocol; } @@ -70,14 +56,6 @@ public class IpForwardingRuleResponse extends BaseResponse { this.protocol = protocol; } - public String getPublicPort() { - return publicPort; - } - - public void setPublicPort(String publicPort) { - this.publicPort = publicPort; - } - public Long getVirtualMachineId() { return virtualMachineId; } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index edeb70b087d..f26f014dcf3 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1068,9 +1068,7 @@ public class ApiResponseHelper implements ResponseGenerator { public IpForwardingRuleResponse createIpForwardingRuleResponse(FirewallRule fwRule) { IpForwardingRuleResponse response = new IpForwardingRuleResponse(); response.setId(fwRule.getId()); - response.setPrivatePort(fwRule.getPrivatePort()); response.setProtocol(fwRule.getProtocol()); - response.setPublicPort(fwRule.getPublicPort()); response.setPublicIpAddress(fwRule.getPublicIpAddress()); if (fwRule.getPublicIpAddress() != null && fwRule.getPrivateIpAddress() != null) { UserVm vm = ApiDBUtils.findUserVmByPublicIpAndGuestIp(fwRule.getPublicIpAddress(), fwRule.getPrivateIpAddress()); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 8b450c5ae02..d0918928afe 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -2553,42 +2553,136 @@ public class ManagementServerImpl implements ManagementServer { @Override public List searchForIpForwardingRules(ListIpForwardingRulesCmd cmd){ + //Note + //The following was decided after discussing with Will + //ListIpForwardingRules with no params lists the rules for that user ; with a listAll() for admin + //ListIpForwardingRules with accountName and domainId lists the rule for that account (provided the executing user has the right perms) + //ListIpForwardingRules with ipAddress lists the rule for that ip address (provided the executing user has the right perms) + String ipAddress = cmd.getPublicIpAddress(); - Account account = UserContext.current().getAccount(); - - IPAddressVO ipAddressVO = _publicIpAddressDao.findById(ipAddress); - if (ipAddressVO == null) { - throw new InvalidParameterValueException("Unable to find IP address " + ipAddress); - } - - Account addrOwner = _accountDao.findById(ipAddressVO.getAccountId()); - - // if an admin account was passed in, or no account was passed in, make sure we honor the accountName/domainId parameters - if ((account != null) && isAdmin(account.getType())) { - if (ipAddressVO.getAccountId() != null) { - if ((addrOwner != null) && !_domainDao.isChildDomain(account.getDomainId(), addrOwner.getDomainId())) { - throw new PermissionDeniedException("Unable to list ip forwarding rules for address " + ipAddress + ", permission denied for account " + account.getId()); - } - } - } else { - if (account != null) { - if ((ipAddressVO.getAccountId() == null) || (account.getId() != ipAddressVO.getAccountId().longValue())) { - throw new PermissionDeniedException("Unable to list ip forwarding rules for address " + ipAddress + ", permission denied for account " + account.getId()); - } - } + String accountName = cmd.getAccountName(); + Long domainId = cmd.getDomainId(); + Account account = null; + + if((accountName != null && domainId == null) || (accountName == null && domainId != null)){ + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Account name and domain id both have to be passed as a tuple"); } + if(accountName != null && domainId != null && ipAddress != null){ + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Either Account name and domain id both have to be passed as a tuple; or the ip address has to be passed whilst searching"); + } + + //account and domainId both provided case + if(accountName != null && domainId != null){ + account = _accountDao.findAccount(accountName, domainId); + if(account == null) + throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Specified account for domainId:"+domainId+" account name:"+accountName+" doesn't exist"); + else{ + //get the ctxaccount to see if he has permissions + Account ctxAccount = UserContext.current().getAccount(); + + if(!isChildDomain(ctxAccount.getDomainId(), account.getDomainId())){ + throw new PermissionDeniedException("Unable to list ip forwarding rules for address " + ipAddress + ", permission denied for the executing account: " + ctxAccount.getId()+" to view rules for account: "+account.getId()); + } + + Filter searchFilter = new Filter(FirewallRuleVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder sb = _firewallRulesDao.createSearchBuilder(); + + SearchBuilder sb1 = _publicIpAddressDao.createSearchBuilder(); + sb1.and("accountId", sb1.entity().getAccountId(), SearchCriteria.Op.EQ); + sb1.and("oneToOneNat", sb1.entity().isOneToOneNat(), SearchCriteria.Op.EQ); + sb.join("sb1", sb1, sb.entity().getPublicIpAddress(),sb1.entity().getAddress(), JoinBuilder.JoinType.INNER); + + SearchCriteria sc = sb.create(); + sc.setJoinParameters("sb1","oneToOneNat", new Long(1)); + sc.setJoinParameters("sb1", "accountId", account.getId()); + + return _firewallRulesDao.search(sc, searchFilter); + } + } + + if(account == null){ + account = UserContext.current().getAccount();//use user context + } + + if(account == null || account.getType() == Account.ACCOUNT_TYPE_ADMIN){ + return searchIpForwardingRulesInternal(ipAddress, cmd, null, Account.ACCOUNT_TYPE_ADMIN); + } + + if((account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)){ + if(ipAddress != null){ + IPAddressVO ipAddressVO = _publicIpAddressDao.findById(ipAddress); + if (ipAddressVO == null) { + throw new InvalidParameterValueException("Unable to find IP address " + ipAddress); + }else{ + //check permissions + Account addrOwner = _accountDao.findById(ipAddressVO.getAccountId()); + if ((addrOwner != null) && !_domainDao.isChildDomain(account.getDomainId(), addrOwner.getDomainId())) { + throw new PermissionDeniedException("Unable to list ip forwarding rule for address " + ipAddress + ", permission denied for account " + account.getId()); + }else{ + return searchIpForwardingRulesInternal(ipAddress, cmd, null, Account.ACCOUNT_TYPE_DOMAIN_ADMIN); + } + } + }else{ + //need to list all rules visible to the domain admin + //join with the ip_address table where account_id = user's account id + return searchIpForwardingRulesInternal(ipAddress, cmd, account.getId(), Account.ACCOUNT_TYPE_DOMAIN_ADMIN); + } + } + + if(account.getType() == Account.ACCOUNT_TYPE_NORMAL){ + if(ipAddress != null){ + IPAddressVO ipAddressVO = _publicIpAddressDao.findById(ipAddress); + if (ipAddressVO == null) { + throw new InvalidParameterValueException("Unable to find IP address " + ipAddress); + }else{ + //check permissions + if ((ipAddressVO.getAccountId() == null) || (account.getId() != ipAddressVO.getAccountId().longValue())) { + throw new PermissionDeniedException("Unable to list ip forwarding rule for address " + ipAddress + ", permission denied for account " + account.getId()); + }else{ + return searchIpForwardingRulesInternal(ipAddress, cmd, null, Account.ACCOUNT_TYPE_NORMAL); + } + } + }else{ + //need to list all rules visible to the user + //join with the ip_address table where account_id = user's account id + return searchIpForwardingRulesInternal(ipAddress, cmd, account.getId(), Account.ACCOUNT_TYPE_NORMAL); + } + } + + return new ArrayList(); + } + + private List searchIpForwardingRulesInternal(String ipAddress, ListIpForwardingRulesCmd cmd, Long accountId, short accountType){ Filter searchFilter = new Filter(FirewallRuleVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); - SearchCriteria sc = _firewallRulesDao.createSearchCriteria(); - - if (ipAddress != null) { - sc.addAnd("publicIpAddress", SearchCriteria.Op.EQ, ipAddress); + if(accountId == null){ + SearchCriteria sc = _firewallRulesDao.createSearchCriteria(); + if (ipAddress != null) { + sc.addAnd("publicIpAddress", SearchCriteria.Op.EQ, ipAddress); + } + //search for rules with protocol = nat + sc.addAnd("protocol", SearchCriteria.Op.EQ, NetUtils.NAT_PROTO); + return _firewallRulesDao.search(sc, searchFilter); + + }else{ + //accountId and accountType both given + if((accountType == Account.ACCOUNT_TYPE_NORMAL) || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)){ + SearchBuilder sb = _firewallRulesDao.createSearchBuilder(); + + SearchBuilder sb1 = _publicIpAddressDao.createSearchBuilder(); + sb1.and("accountId", sb1.entity().getAccountId(), SearchCriteria.Op.EQ); + sb1.and("oneToOneNat", sb1.entity().isOneToOneNat(), SearchCriteria.Op.EQ); + sb.join("sb1", sb1, sb.entity().getPublicIpAddress(),sb1.entity().getAddress(), JoinBuilder.JoinType.INNER); + + SearchCriteria sc = sb.create(); + sc.setJoinParameters("sb1","oneToOneNat", new Long(1)); + sc.setJoinParameters("sb1", "accountId", accountId); + + return _firewallRulesDao.search(sc, searchFilter); + } } - //search for rules with protocol = nat - sc.addAnd("protocol", SearchCriteria.Op.EQ, NetUtils.NAT_PROTO); - - return _firewallRulesDao.search(sc, searchFilter); + return new ArrayList(); } @Override