search functionality for ip forwarding rules, with covering of cerner cases

This commit is contained in:
abhishek 2010-12-01 18:33:22 -08:00
parent d28d6894e1
commit d0fc07496f
4 changed files with 139 additions and 54 deletions

View File

@ -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<? extends FirewallRule> result = _mgr.searchForIpForwardingRules(this);

View File

@ -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;
}

View File

@ -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());

View File

@ -2553,42 +2553,136 @@ public class ManagementServerImpl implements ManagementServer {
@Override
public List<FirewallRuleVO> 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<FirewallRuleVO> sb = _firewallRulesDao.createSearchBuilder();
SearchBuilder<IPAddressVO> 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<FirewallRuleVO> 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<FirewallRuleVO>();
}
private List<FirewallRuleVO> searchIpForwardingRulesInternal(String ipAddress, ListIpForwardingRulesCmd cmd, Long accountId, short accountType){
Filter searchFilter = new Filter(FirewallRuleVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
SearchCriteria<FirewallRuleVO> sc = _firewallRulesDao.createSearchCriteria();
if (ipAddress != null) {
sc.addAnd("publicIpAddress", SearchCriteria.Op.EQ, ipAddress);
if(accountId == null){
SearchCriteria<FirewallRuleVO> 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<FirewallRuleVO> sb = _firewallRulesDao.createSearchBuilder();
SearchBuilder<IPAddressVO> 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<FirewallRuleVO> 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<FirewallRuleVO>();
}
@Override