Refactoring listNetworkGroups to new API framework. The search is done entirely within NetworkGroupManager, and this is one instances of a response with nested data (the ingress rules are nested within the groups). Some work will need to be done to serialize this response properly.

This commit is contained in:
Kris McQueen 2010-09-01 14:05:39 -07:00
parent ec9ad29c9a
commit fbcb02cd9e
7 changed files with 229 additions and 178 deletions

View File

@ -2,39 +2,25 @@ package com.cloud.api.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.api.BaseCmd;
import com.cloud.api.BaseCmd.Manager;
import com.cloud.api.BaseListCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.IngressRuleResponse;
import com.cloud.api.response.NetworkGroupResponse;
import com.cloud.async.executor.IngressRuleResultObject;
import com.cloud.async.executor.NetworkGroupResultObject;
import com.cloud.network.security.NetworkGroupRulesVO;
import com.cloud.server.Criteria;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.vm.UserVmVO;
import com.cloud.serializer.SerializerHelper;
public class ListNetworkGroupsCmd extends BaseCmd {
@Implementation(method="searchForNetworkGroupRules", manager=Manager.NetworkGroupManager)
public class ListNetworkGroupsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListNetworkGroupsCmd.class.getName());
private static final String s_name = "listnetworkgroupsresponse";
private static final List<Pair<Enum, Boolean>> s_properties = new ArrayList<Pair<Enum, Boolean>>();
static {
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ACCOUNT, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.DOMAIN_ID, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.NETWORK_GROUP_NAME, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.VIRTUAL_MACHINE_ID, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.KEYWORD, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PAGE, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PAGESIZE, Boolean.FALSE));
}
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@ -77,149 +63,57 @@ public class ListNetworkGroupsCmd extends BaseCmd {
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getName() {
return s_name;
}
public List<Pair<Enum, Boolean>> getProperties() {
return s_properties;
}
@Override @SuppressWarnings("unchecked")
public String getResponse() {
List<NetworkGroupRulesVO> networkGroups = (List<NetworkGroupRulesVO>)getResponseObject();
List<NetworkGroupResultObject> groupResultObjs = NetworkGroupResultObject.transposeNetworkGroups(networkGroups);
@Override
public List<Pair<String, Object>> execute(Map<String, Object> 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());
String networkGroup = (String)params.get(BaseCmd.Properties.NETWORK_GROUP_NAME.getName());
Long vmId = (Long)params.get(BaseCmd.Properties.VIRTUAL_MACHINE_ID.getName());
String keyword = (String)params.get(BaseCmd.Properties.KEYWORD.getName());
Integer page = (Integer)params.get(BaseCmd.Properties.PAGE.getName());
Integer pageSize = (Integer)params.get(BaseCmd.Properties.PAGESIZE.getName());
List<NetworkGroupResponse> response = new ArrayList<NetworkGroupResponse>();
for (NetworkGroupResultObject networkGroup : groupResultObjs) {
NetworkGroupResponse netGrpResponse = new NetworkGroupResponse();
netGrpResponse.setId(networkGroup.getId());
netGrpResponse.setName(networkGroup.getName());
netGrpResponse.setDescription(networkGroup.getDescription());
netGrpResponse.setAccountName(networkGroup.getAccountName());
netGrpResponse.setDomainId(networkGroup.getDomainId());
netGrpResponse.setDomainName(getManagementServer().findDomainIdById(networkGroup.getDomainId()).getName());
Long accountId = null;
boolean recursive = false;
List<IngressRuleResultObject> ingressRules = networkGroup.getIngressRules();
if ((ingressRules != null) && !ingressRules.isEmpty()) {
List<IngressRuleResponse> ingressRulesResponse = new ArrayList<IngressRuleResponse>();
// permissions check
if ((account == null) || isAdmin(account.getType())) {
if (domainId != null) {
if ((account != null) && !getManagementServer().isChildDomain(account.getDomainId(), domainId)) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to list network groups for account " + accountName + " in domain " + domainId + "; permission denied.");
}
if (accountName != null) {
Account acct = getManagementServer().findActiveAccount(accountName, domainId);
if (acct != null) {
accountId = acct.getId();
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());
} else {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find account " + accountName + " in domain " + domainId);
ingressData.setStartPort(ingressRule.getStartPort());
ingressData.setEndPort(ingressRule.getEndPort());
}
}
} else if (vmId != null) {
UserVmVO userVM = getManagementServer().findUserVMInstanceById(vmId);
if (userVM == null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to list network groups for virtual machine instance " + vmId + "; instance not found.");
}
if ((account != null) && !getManagementServer().isChildDomain(account.getDomainId(), userVM.getDomainId())) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to list network groups for virtual machine instance " + vmId + "; permission denied.");
}
} else if (account != null) {
// either an admin is searching for their own group, or admin is listing all groups and the search needs to be restricted to domain admin's domain
if (networkGroup != null) {
accountId = account.getId();
} else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
domainId = account.getDomainId();
recursive = true;
}
}
} else {
if (vmId != null) {
UserVmVO userVM = getManagementServer().findUserVMInstanceById(vmId);
if (userVM == null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to list network groups for virtual machine instance " + vmId + "; instance not found.");
}
if (account != null) {
// check that the user is the owner of the VM (admin case was already verified
if (account.getId().longValue() != userVM.getAccountId()) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to list network groups for virtual machine instance " + vmId + "; permission denied.");
if (ingressRule.getAllowedNetworkGroup() != null) {
ingressData.setNetworkGroupName(ingressRule.getAllowedNetworkGroup());
ingressData.setAccountName(ingressRule.getAllowedNetGroupAcct());
} else {
ingressData.setCidr(ingressRule.getAllowedSourceIpCidr());
}
}
} else {
accountId = ((account != null) ? account.getId() : null);
}
}
Long startIndex = Long.valueOf(0);
int pageSizeNum = 50;
if (pageSize != null) {
pageSizeNum = pageSize.intValue();
}
if (page != null) {
int pageNum = page.intValue();
if (pageNum > 0) {
startIndex = Long.valueOf(pageSizeNum * (pageNum-1));
ingressRulesResponse.add(ingressData);
}
netGrpResponse.setIngressRules(ingressRulesResponse);
}
response.add(netGrpResponse);
}
Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum));
c.addCriteria(Criteria.ACCOUNTID, accountId);
c.addCriteria(Criteria.DOMAINID, domainId);
c.addCriteria(Criteria.NETWORKGROUP, networkGroup);
c.addCriteria(Criteria.INSTANCEID, vmId);
c.addCriteria(Criteria.ISRECURSIVE, recursive);
c.addCriteria(Criteria.KEYWORD, keyword);
List<NetworkGroupRulesVO> groups = getManagementServer().searchForNetworkGroupRules(c);
List<NetworkGroupResultObject> groupResultObjs = NetworkGroupResultObject.transposeNetworkGroups(groups);
Object[] groupDataArray = null;
if (groupResultObjs != null) {
groupDataArray = new Object[groupResultObjs.size()];
int i = 0;
for (NetworkGroupResultObject groupResultObj : groupResultObjs) {
List<Pair<String, Object>> groupData = new ArrayList<Pair<String, Object>>();
groupData.add(new Pair<String, Object>(BaseCmd.Properties.ID.getName(), groupResultObj.getId().toString()));
groupData.add(new Pair<String, Object>(BaseCmd.Properties.NAME.getName(), groupResultObj.getName()));
groupData.add(new Pair<String, Object>(BaseCmd.Properties.DESCRIPTION.getName(), groupResultObj.getDescription()));
groupData.add(new Pair<String, Object>(BaseCmd.Properties.ACCOUNT.getName(), groupResultObj.getAccountName()));
groupData.add(new Pair<String, Object>(BaseCmd.Properties.DOMAIN_ID.getName(), groupResultObj.getDomainId().toString()));
groupData.add(new Pair<String, Object>(BaseCmd.Properties.DOMAIN.getName(), getManagementServer().findDomainIdById(groupResultObj.getDomainId()).getName()));
List<IngressRuleResultObject> ingressRules = groupResultObj.getIngressRules();
if ((ingressRules != null) && !ingressRules.isEmpty()) {
Object[] ingressDataArray = new Object[ingressRules.size()];
int j = 0;
for (IngressRuleResultObject ingressRule : ingressRules) {
List<Pair<String, Object>> ingressData = new ArrayList<Pair<String, Object>>();
ingressData.add(new Pair<String, Object>(BaseCmd.Properties.RULE_ID.getName(), ingressRule.getId().toString()));
ingressData.add(new Pair<String, Object>(BaseCmd.Properties.PROTOCOL.getName(), ingressRule.getProtocol()));
if ("icmp".equalsIgnoreCase(ingressRule.getProtocol())) {
ingressData.add(new Pair<String, Object>(BaseCmd.Properties.ICMP_TYPE.getName(), Integer.valueOf(ingressRule.getStartPort()).toString()));
ingressData.add(new Pair<String, Object>(BaseCmd.Properties.ICMP_CODE.getName(), Integer.valueOf(ingressRule.getEndPort()).toString()));
} else {
ingressData.add(new Pair<String, Object>(BaseCmd.Properties.START_PORT.getName(), Integer.valueOf(ingressRule.getStartPort()).toString()));
ingressData.add(new Pair<String, Object>(BaseCmd.Properties.END_PORT.getName(), Integer.valueOf(ingressRule.getEndPort()).toString()));
}
if (ingressRule.getAllowedNetworkGroup() != null) {
ingressData.add(new Pair<String, Object>(BaseCmd.Properties.NETWORK_GROUP_NAME.getName(), ingressRule.getAllowedNetworkGroup()));
ingressData.add(new Pair<String, Object>(BaseCmd.Properties.ACCOUNT.getName(), ingressRule.getAllowedNetGroupAcct()));
} else if (ingressRule.getAllowedSourceIpCidr() != null) {
ingressData.add(new Pair<String, Object>(BaseCmd.Properties.CIDR.getName(), ingressRule.getAllowedSourceIpCidr()));
}
ingressDataArray[j++] = ingressData;
}
groupData.add(new Pair<String, Object>("ingressrule", ingressDataArray));
}
groupDataArray[i++] = groupData;
}
}
List<Pair<String, Object>> groupsTags = new ArrayList<Pair<String, Object>>();
if (groupDataArray != null) {
Pair<String, Object> groupRulesTags = new Pair<String, Object>("networkgroup", groupDataArray);
groupsTags.add(groupRulesTags);
}
return groupsTags;
}
return SerializerHelper.toSerializedString(response);
}
}

View File

@ -0,0 +1,105 @@
package com.cloud.api.response;
import com.cloud.api.ResponseObject;
import com.cloud.serializer.Param;
public class IngressRuleResponse implements ResponseObject {
@Param(name="ruleid")
private Long ruleId;
@Param(name="protocol")
private String protocol;
@Param(name="icmptype")
private Integer icmpType;
@Param(name="icmpcode")
private Integer icmpCode;
@Param(name="startport")
private Integer startPort;
@Param(name="endport")
private Integer endPort;
@Param(name="networkgroupname")
private String networkGroupName;
@Param(name="account")
private String accountName;
@Param(name="cidr")
private String cidr;
public Long getRuleId() {
return ruleId;
}
public void setRuleId(Long ruleId) {
this.ruleId = 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 getNetworkGroupName() {
return networkGroupName;
}
public void setNetworkGroupName(String networkGroupName) {
this.networkGroupName = networkGroupName;
}
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;
}
}

View File

@ -1,5 +1,7 @@
package com.cloud.api.response;
import java.util.List;
import com.cloud.api.ResponseObject;
import com.cloud.serializer.Param;
@ -22,6 +24,9 @@ public class NetworkGroupResponse implements ResponseObject {
@Param(name="domain")
private String domainName;
@Param(name="ingressrule")
private List<IngressRuleResponse> ingressRules;
public Long getId() {
return id;
}
@ -69,4 +74,12 @@ public class NetworkGroupResponse implements ResponseObject {
public void setDomainName(String domainName) {
this.domainName = domainName;
}
public List<IngressRuleResponse> getIngressRules() {
return ingressRules;
}
public void setIngressRules(List<IngressRuleResponse> ingressRules) {
this.ingressRules = ingressRules;
}
}

View File

@ -21,11 +21,11 @@ import java.util.HashMap;
import java.util.List;
import com.cloud.api.commands.CreateNetworkGroupCmd;
import com.cloud.api.commands.ListNetworkGroupsCmd;
import com.cloud.api.commands.RevokeNetworkGroupIngressCmd;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.server.Criteria;
import com.cloud.user.AccountVO;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
@ -71,7 +71,7 @@ public interface NetworkGroupManager extends Manager {
* The search terms are specified in the search criteria.
* @return the list of network groups and associated ingress rules
*/
public List<NetworkGroupRulesVO> searchForNetworkGroupRules(Criteria c);
public List<NetworkGroupRulesVO> searchForNetworkGroupRules(ListNetworkGroupsCmd cmd) throws PermissionDeniedException, InvalidParameterValueException;
public void fullSync(long agentId, HashMap<String, Pair<Long, Long>> newGroupStates);

View File

@ -46,6 +46,7 @@ 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.ListNetworkGroupsCmd;
import com.cloud.api.commands.RevokeNetworkGroupIngressCmd;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.domain.DomainVO;
@ -61,7 +62,6 @@ import com.cloud.network.security.dao.NetworkGroupRulesDao;
import com.cloud.network.security.dao.NetworkGroupVMMapDao;
import com.cloud.network.security.dao.NetworkGroupWorkDao;
import com.cloud.network.security.dao.VmRulesetLogDao;
import com.cloud.server.Criteria;
import com.cloud.server.ManagementServer;
import com.cloud.user.Account;
import com.cloud.user.AccountVO;
@ -80,6 +80,7 @@ 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.UserVmVO;
import com.cloud.vm.dao.UserVmDao;
@Local(value={NetworkGroupManager.class})
@ -496,7 +497,7 @@ public class NetworkGroupManagerImpl implements NetworkGroupManager {
}
@Override
@DB
@DB @SuppressWarnings("rawtypes")
public boolean revokeNetworkGroupIngress(RevokeNetworkGroupIngressCmd cmd) {
//input validation
@ -1002,14 +1003,66 @@ public class NetworkGroupManagerImpl implements NetworkGroupManager {
}
@Override
public List<NetworkGroupRulesVO> searchForNetworkGroupRules(Criteria c) {
Filter searchFilter = new Filter(NetworkGroupRulesVO.class, "id", true, c.getOffset(), c.getLimit());
Object accountId = c.getCriteria(Criteria.ACCOUNTID);
Object domainId = c.getCriteria(Criteria.DOMAINID);
Object networkGroup = c.getCriteria(Criteria.NETWORKGROUP);
Object instanceId = c.getCriteria(Criteria.INSTANCEID);
Object recursive = c.getCriteria(Criteria.ISRECURSIVE);
Object keyword = c.getCriteria(Criteria.KEYWORD);
public List<NetworkGroupRulesVO> searchForNetworkGroupRules(ListNetworkGroupsCmd cmd) throws PermissionDeniedException, InvalidParameterValueException {
Account account = (Account)UserContext.current().getAccountObject();
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
Long instanceId = cmd.getVirtualMachineId();
String networkGroup = cmd.getNetworkGroupName();
Boolean recursive = Boolean.FALSE;
// permissions check
if ((account == null) || isAdmin(account.getType())) {
if (domainId != null) {
if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) {
throw new PermissionDeniedException("Unable to list network groups for account " + accountName + " in domain " + domainId + "; permission denied.");
}
if (accountName != null) {
Account acct = _accountDao.findActiveAccount(accountName, domainId);
if (acct != null) {
accountId = acct.getId();
} else {
throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
}
}
} else if (instanceId != null) {
UserVmVO userVM = _userVMDao.findById(instanceId);
if (userVM == null) {
throw new InvalidParameterValueException("Unable to list network groups for virtual machine instance " + instanceId + "; instance not found.");
}
if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), userVM.getDomainId())) {
throw new PermissionDeniedException("Unable to list network groups for virtual machine instance " + instanceId + "; permission denied.");
}
} else if (account != null) {
// either an admin is searching for their own group, or admin is listing all groups and the search needs to be restricted to domain admin's domain
if (networkGroup != null) {
accountId = account.getId();
} else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
domainId = account.getDomainId();
recursive = Boolean.TRUE;
}
}
} else {
if (instanceId != null) {
UserVmVO userVM = _userVMDao.findById(instanceId);
if (userVM == null) {
throw new InvalidParameterValueException("Unable to list network groups for virtual machine instance " + instanceId + "; instance not found.");
}
if (account != null) {
// check that the user is the owner of the VM (admin case was already verified
if (account.getId().longValue() != userVM.getAccountId()) {
throw new PermissionDeniedException("Unable to list network groups for virtual machine instance " + instanceId + "; permission denied.");
}
}
} else {
accountId = ((account != null) ? account.getId() : null);
}
}
Filter searchFilter = new Filter(NetworkGroupRulesVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
Object keyword = cmd.getKeyword();
SearchBuilder<NetworkGroupRulesVO> sb = _networkGroupRulesDao.createSearchBuilder();
sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);

View File

@ -90,7 +90,6 @@ import com.cloud.network.LoadBalancerVO;
import com.cloud.network.NetworkRuleConfigVO;
import com.cloud.network.SecurityGroupVO;
import com.cloud.network.security.IngressRuleVO;
import com.cloud.network.security.NetworkGroupRulesVO;
import com.cloud.network.security.NetworkGroupVO;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.storage.DiskOfferingVO;
@ -1914,13 +1913,6 @@ public interface ManagementServer {
*/
void deleteNetworkGroup(Long groupId, Long accountId) throws ResourceInUseException, PermissionDeniedException;
/**
* Search for network groups and associated ingress rules for the given account, domain, group name, and/or keyword.
* The search terms are specified in the search criteria.
* @return the list of network groups and associated ingress rules
*/
public List<NetworkGroupRulesVO> searchForNetworkGroupRules(Criteria c);
HostStats getHostStatistics(long hostId);
/**

View File

@ -189,7 +189,6 @@ import com.cloud.network.dao.SecurityGroupDao;
import com.cloud.network.dao.SecurityGroupVMMapDao;
import com.cloud.network.security.IngressRuleVO;
import com.cloud.network.security.NetworkGroupManager;
import com.cloud.network.security.NetworkGroupRulesVO;
import com.cloud.network.security.NetworkGroupVO;
import com.cloud.network.security.dao.NetworkGroupDao;
import com.cloud.offering.ServiceOffering;
@ -8229,11 +8228,6 @@ public class ManagementServerImpl implements ManagementServer {
_networkGroupMgr.deleteNetworkGroup(groupId, accountId);
}
@Override
public List<NetworkGroupRulesVO> searchForNetworkGroupRules(Criteria c) {
return _networkGroupMgr.searchForNetworkGroupRules(c);
}
@Override
public HostStats getHostStatistics(long hostId) {
return _statsCollector.getHostStats(hostId);