Refactoring CreateIPForwardingRule and CreateLoadBalancerRule to new API framework

This commit is contained in:
Kris McQueen 2010-08-17 14:13:20 -07:00
parent a6c34d422c
commit 82d6edcdf3
8 changed files with 449 additions and 343 deletions

View File

@ -18,41 +18,21 @@
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.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.BaseCmd.Manager;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.api.response.FirewallRuleResponse;
import com.cloud.network.FirewallRuleVO;
import com.cloud.network.IPAddressVO;
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.utils.Pair;
import com.cloud.vm.UserVmVO;
import com.cloud.serializer.SerializerHelper;
@Implementation(method="createPortForwardingRule", manager=Manager.NetworkManager)
public class CreateIPForwardingRuleCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreateIPForwardingRuleCmd.class.getName());
private static final String s_name = "createportforwardingruleresponse";
private static final List<Pair<Enum, Boolean>> s_properties = new ArrayList<Pair<Enum, Boolean>>();
static {
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.USER_ID, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.IP_ADDRESS, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PRIVATE_PORT, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PROTOCOL, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PUBLIC_PORT, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.VIRTUAL_MACHINE_ID, Boolean.TRUE));
}
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@ -110,82 +90,17 @@ public class CreateIPForwardingRuleCmd extends BaseCmd {
@Override
public String getResponse() {
}
FirewallRuleVO fwRule = (FirewallRuleVO)getResponseObject();
@Override
public List<Pair<String, Object>> execute(Map<String, Object> params) {
Long userId = (Long)params.get(BaseCmd.Properties.USER_ID.getName());
Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
String ipAddress = (String)params.get(BaseCmd.Properties.IP_ADDRESS.getName());
String publicPort = (String)params.get(BaseCmd.Properties.PUBLIC_PORT.getName());
String privatePort = (String)params.get(BaseCmd.Properties.PRIVATE_PORT.getName());
String protocol = (String)params.get(BaseCmd.Properties.PROTOCOL.getName());
Long vmId = (Long)params.get(BaseCmd.Properties.VIRTUAL_MACHINE_ID.getName());
FirewallRuleResponse fwResponse = new FirewallRuleResponse();
fwResponse.setId(fwRule.getId());
fwResponse.setPrivatePort(fwRule.getPrivatePort());
fwResponse.setProtocol(fwRule.getProtocol());
fwResponse.setPublicPort(fwRule.getPublicPort());
// TODO: implement
// fwResponse.setVirtualMachineId(fwRule.getVirtualMachineId());
// fwResponse.setVirtualMachineName(fwRule.getVirtualMachineName());
if (userId == null) {
userId = Long.valueOf(User.UID_SYSTEM);
}
IPAddressVO ipAddressVO = getManagementServer().findIPAddressById(ipAddress);
if (ipAddressVO == null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find IP address " + ipAddress);
}
UserVmVO userVM = getManagementServer().findUserVMInstanceById(vmId);
if (userVM == null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find virtual machine with id " + vmId);
}
if ((ipAddressVO.getAccountId() == null) || (ipAddressVO.getAccountId().longValue() != userVM.getAccountId())) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to create port forwarding rule, IP address " + ipAddress + " owner is not the same as owner of virtual machine " + userVM.toString());
}
if (ipAddressVO.getDataCenterId() != userVM.getDataCenterId()) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to create port forwarding rule, IP address " + ipAddress + " owner is not in the same availability zone as virtual machine " + userVM.toString());
}
// if an admin account was passed in, or no account was passed in, make sure we honor the accountName/domainId parameters
if (account != null) {
if (isAdmin(account.getType())) {
Account vmOwner = getManagementServer().findAccountById(userVM.getAccountId());
if (!getManagementServer().isChildDomain(account.getDomainId(), vmOwner.getDomainId())) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to create port forwarding rule, IP address " + ipAddress + " to virtual machine " + vmId + ", permission denied.");
}
} else if (account.getId().longValue() != userVM.getAccountId()) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to create port forwarding rule, IP address " + ipAddress + " to virtual machine " + vmId + ", permission denied.");
}
}
FirewallRuleVO firewallRule = null;
try {
firewallRule = getManagementServer().createPortForwardingRule(userId.longValue(), ipAddressVO, userVM, publicPort, privatePort, protocol);
} catch (NetworkRuleConflictException ex) {
throw new ServerApiException(BaseCmd.NET_CONFLICT_IPFW_RULE_ERROR, "Network rule conflict creating a forwarding rule on address:port " + ipAddress + ":" + publicPort + " to virtual machine " + userVM.toString());
} catch (IllegalArgumentException argEx) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, argEx.getMessage());
}
if (firewallRule == null) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "The port forwarding rule from public port " + publicPort + " to private port " + privatePort + " for address " + ipAddress + " and virtual machine " + userVM.toString() + " already exists.");
}
List<Pair<String, Object>> groupsTags = new ArrayList<Pair<String, Object>>();
Object[] forwardingTag = new Object[1];
List<Pair<String, Object>> ruleData = new ArrayList<Pair<String, Object>>();
ruleData.add(new Pair<String, Object>(BaseCmd.Properties.ID.getName(), firewallRule.getId().toString()));
ruleData.add(new Pair<String, Object>(BaseCmd.Properties.PUBLIC_PORT.getName(), firewallRule.getPublicPort()));
ruleData.add(new Pair<String, Object>(BaseCmd.Properties.PRIVATE_PORT.getName(), firewallRule.getPrivatePort()));
ruleData.add(new Pair<String, Object>(BaseCmd.Properties.PROTOCOL.getName(), firewallRule.getProtocol()));
ruleData.add(new Pair<String, Object>(BaseCmd.Properties.VIRTUAL_MACHINE_NAME.getName(), userVM.getName()));
ruleData.add(new Pair<String, Object>(BaseCmd.Properties.VIRTUAL_MACHINE_ID.getName(), Long.toString(userVM.getId())));
forwardingTag[0] = ruleData;
Pair<String, Object> eventTag = new Pair<String, Object>("portforwardingrule", forwardingTag);
groupsTags.add(eventTag);
return groupsTags;
return SerializerHelper.toSerializedString(fwResponse);
}
}

View File

@ -18,44 +18,21 @@
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.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.network.IPAddressVO;
import com.cloud.api.response.LoadBalancerResponse;
import com.cloud.network.LoadBalancerVO;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.serializer.SerializerHelper;
@Implementation(method="createLoadBalancerRule", manager=Manager.NetworkManager)
public class CreateLoadBalancerRuleCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreateLoadBalancerRuleCmd.class.getName());
private static final String s_name = "createloadbalancerruleresponse";
private static final List<Pair<Enum, Boolean>> s_properties = new ArrayList<Pair<Enum, Boolean>>();
static {
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.USER_ID, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ALGORITHM, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.DESCRIPTION, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.NAME, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PRIVATE_PORT, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PUBLIC_IP, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PUBLIC_PORT, Boolean.TRUE));
}
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@ -116,98 +93,24 @@ public class CreateLoadBalancerRuleCmd extends BaseCmd {
public String getName() {
return s_name;
}
public List<Pair<Enum, Boolean>> getProperties() {
return s_properties;
}
@Override
public List<Pair<String, Object>> execute(Map<String, Object> params) {
Long userId = (Long)params.get(BaseCmd.Properties.USER_ID.getName());
Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
String name = (String)params.get(BaseCmd.Properties.NAME.getName());
String description = (String)params.get(BaseCmd.Properties.DESCRIPTION.getName());
String publicIP = (String)params.get(BaseCmd.Properties.PUBLIC_IP.getName());
String publicPort = (String)params.get(BaseCmd.Properties.PUBLIC_PORT.getName());
String privatePort = (String)params.get(BaseCmd.Properties.PRIVATE_PORT.getName());
String algorithm = (String)params.get(BaseCmd.Properties.ALGORITHM.getName());
public String getResponse() {
LoadBalancerVO responseObj = (LoadBalancerVO)getResponseObject();
UserVmDao _userVmDao;
ComponentLocator locator = ComponentLocator.getLocator("management-server");
_userVmDao = locator.getDao(UserVmDao.class);
LoadBalancerResponse response = new LoadBalancerResponse();
response.setAlgorithm(responseObj.getAlgorithm());
response.setDescription(responseObj.getDescription());
response.setId(responseObj.getId());
response.setName(responseObj.getName());
response.setPrivatePort(responseObj.getPrivatePort());
response.setPublicIp(responseObj.getIpAddress());
response.setPublicPort(responseObj.getPublicPort());
response.setAccountName(responseObj.getAccountName());
response.setDomainId(responseObj.getDomainId());
// TODO: implement
// response.setDomainName(responseObj.getDomainName());
if (userId == null) {
userId = Long.valueOf(1);
}
IPAddressVO ipAddr = getManagementServer().findIPAddressById(publicIP);
if (ipAddr == null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to create load balancer rule, invalid IP address " + publicIP);
}
VlanVO vlan = getManagementServer().findVlanById(ipAddr.getVlanDbId());
if (vlan != null) {
if (!VlanType.VirtualNetwork.equals(vlan.getVlanType())) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to create load balancer rule for IP address " + publicIP + ", only VirtualNetwork type IP addresses can be used for load balancers.");
}
} // else ERROR?
// Verify input parameters
Account accountByIp = getManagementServer().findAccountByIpAddress(publicIP);
if(accountByIp == null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to create load balancer rule, cannot find account owner for ip " + publicIP);
}
Long accountId = accountByIp.getId();
if (account != null) {
if (!isAdmin(account.getType())) {
if (account.getId().longValue() != accountId.longValue()) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to create load balancer rule, account " + account.getAccountName() + " doesn't own ip address " + publicIP);
}
} else if (!getManagementServer().isChildDomain(account.getDomainId(), accountByIp.getDomainId())) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to create load balancer rule on IP address " + publicIP + ", permission denied.");
}
}
List<UserVmVO> userVmVO = _userVmDao.listByAccountId(accountId);
if(userVmVO.size()==0)
{
//this means there are no associated vm's to the user account, and hence, the load balancer cannot be created
throw new ServerApiException(BaseCmd.UNSUPPORTED_ACTION_ERROR, "Unable to create load balancer rule, no vm for the user exists.");
}
LoadBalancerVO existingLB = getManagementServer().findLoadBalancer(accountId, name);
if (existingLB != null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to create load balancer rule, an existing load balancer rule with name " + name + " already exisits.");
}
try {
LoadBalancerVO loadBalancer = getManagementServer().createLoadBalancer(userId, accountId, name, description, publicIP, publicPort, privatePort, algorithm);
List<Pair<String, Object>> embeddedObject = new ArrayList<Pair<String, Object>>();
List<Pair<String, Object>> returnValues = new ArrayList<Pair<String, Object>>();
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.ID.getName(), loadBalancer.getId().toString()));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.NAME.getName(), loadBalancer.getName()));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.DESCRIPTION.getName(), loadBalancer.getDescription()));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.PUBLIC_IP.getName(), loadBalancer.getIpAddress()));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.PUBLIC_PORT.getName(), loadBalancer.getPublicPort()));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.PRIVATE_PORT.getName(), loadBalancer.getPrivatePort()));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.ALGORITHM.getName(), loadBalancer.getAlgorithm()));
Account accountTemp = getManagementServer().findAccountById(loadBalancer.getAccountId());
if (accountTemp != null) {
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.ACCOUNT.getName(), accountTemp.getAccountName()));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.DOMAIN_ID.getName(), accountTemp.getDomainId()));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.DOMAIN.getName(), getManagementServer().findDomainIdById(accountTemp.getDomainId()).getName()));
}
embeddedObject.add(new Pair<String, Object>("loadbalancerrule", new Object[] { returnValues } ));
return embeddedObject;
} catch (InvalidParameterValueException paramError) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, paramError.getMessage());
} catch (PermissionDeniedException permissionError) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, permissionError.getMessage());
} catch (Exception ex) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
}
return SerializerHelper.toSerializedString(response);
}
}

View File

@ -0,0 +1,72 @@
package com.cloud.api.response;
import com.cloud.api.ResponseObject;
import com.cloud.serializer.Param;
public class FirewallRuleResponse implements ResponseObject {
@Param(name="id")
private Long id;
@Param(name="privateport")
private String privatePort;
@Param(name="protocol")
private String protocol;
@Param(name="publicport")
private String publicPort;
@Param(name="virtualmachineid")
private Long virtualMachineId;
@Param(name="virtualmachinename")
private String virtualMachineName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPrivatePort() {
return privatePort;
}
public void setPrivatePort(String privatePort) {
this.privatePort = privatePort;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getPublicPort() {
return publicPort;
}
public void setPublicPort(String publicPort) {
this.publicPort = publicPort;
}
public Long getVirtualMachineId() {
return virtualMachineId;
}
public void setVirtualMachineId(Long virtualMachineId) {
this.virtualMachineId = virtualMachineId;
}
public String getVirtualMachineName() {
return virtualMachineName;
}
public void setVirtualMachineName(String virtualMachineName) {
this.virtualMachineName = virtualMachineName;
}
}

View File

@ -0,0 +1,116 @@
package com.cloud.api.response;
import com.cloud.api.ResponseObject;
import com.cloud.serializer.Param;
public class LoadBalancerResponse implements ResponseObject {
@Param(name="id")
private Long id;
@Param(name="name")
private String name;
@Param(name="description")
private String description;
@Param(name="publicip")
private String publicIp;
@Param(name="publicport")
private String publicPort;
@Param(name="privateport")
private String privatePort;
@Param(name="algorithm")
private String algorithm;
@Param(name="account")
private String accountName;
@Param(name="domainid")
private Long domainId;
@Param(name="domain")
private String domainName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPublicIp() {
return publicIp;
}
public void setPublicIp(String publicIp) {
this.publicIp = publicIp;
}
public String getPublicPort() {
return publicPort;
}
public void setPublicPort(String publicPort) {
this.publicPort = publicPort;
}
public String getPrivatePort() {
return privatePort;
}
public void setPrivatePort(String privatePort) {
this.privatePort = privatePort;
}
public String getAlgorithm() {
return algorithm;
}
public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public Long getDomainId() {
return domainId;
}
public void setDomainId(Long domainId) {
this.domainId = domainId;
}
public String getDomainName() {
return domainName;
}
public void setDomainName(String domainName) {
this.domainName = domainName;
}
}

View File

@ -22,6 +22,7 @@ import java.util.Map;
import com.cloud.api.commands.AssignToLoadBalancerRuleCmd;
import com.cloud.api.commands.CreateIPForwardingRuleCmd;
import com.cloud.api.commands.CreateLoadBalancerRuleCmd;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.VlanVO;
@ -165,11 +166,18 @@ public interface NetworkManager extends Manager {
public List<FirewallRuleVO> updateFirewallRules(String publicIpAddress, List<FirewallRuleVO> fwRules, DomainRouterVO router);
/**
* Create a port forwarding rule from the giving ipAddress/port to the given virtual machine/port.
* Create a port forwarding rule from the given ipAddress/port to the given virtual machine/port.
* @param cmd the command specifying the ip address, public port, protocol, private port, and virtual machine id.
* @return the newly created FirewallRuleVO if successful, null otherwise.
*/
public FirewallRuleVO createPortForwardingRule(CreateIPForwardingRuleCmd cmd) throws InvalidParameterValueException;
public FirewallRuleVO createPortForwardingRule(CreateIPForwardingRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, NetworkRuleConflictException;
/**
* Create a load balancer rule from the given ipAddress/port to the given private port
* @param cmd the command specifying the ip address, public port, protocol, private port, and algorithm
* @return the newly created LoadBalancerVO if successful, null otherwise
*/
public LoadBalancerVO createLoadBalancerRule(CreateLoadBalancerRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException;
/**
* Associates or disassociates a list of public IP address for a router.

View File

@ -18,6 +18,7 @@
package com.cloud.network;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -55,10 +56,9 @@ import com.cloud.agent.api.routing.SavePasswordCommand;
import com.cloud.agent.api.routing.SetFirewallRuleCommand;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.alert.AlertManager;
import com.cloud.api.BaseCmd;
import com.cloud.api.ServerApiException;
import com.cloud.api.commands.AssignToLoadBalancerRuleCmd;
import com.cloud.api.commands.CreateIPForwardingRuleCmd;
import com.cloud.api.commands.CreateLoadBalancerRuleCmd;
import com.cloud.async.AsyncJobExecutor;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
@ -103,6 +103,7 @@ import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.LoadBalancerVMMapDao;
import com.cloud.network.dao.SecurityGroupDao;
import com.cloud.network.dao.SecurityGroupVMMapDao;
import com.cloud.offering.ServiceOffering.GuestIpType;
import com.cloud.service.ServiceOfferingVO;
@ -189,6 +190,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager
@Inject ConfigurationManager _configMgr;
@Inject AsyncJobManager _asyncMgr;
@Inject StoragePoolDao _storagePoolDao = null;
@Inject SecurityGroupDao _securityGroupDao = null;
@Inject ServiceOfferingDao _serviceOfferingDao = null;
@Inject UserStatisticsDao _statsDao;
@ -1363,8 +1365,10 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager
return false;
}
for (int i1=0; i1 < answers.length; i1++) {
Answer ans = answers[i1];
// FIXME: this used to be a loop for all answers, but then we always returned the
// first one in the array, so what should really be done here?
if (answers.length > 0) {
Answer ans = answers[0];
return ans.getResult();
}
@ -1538,7 +1542,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager
}
@Override
public FirewallRuleVO createPortForwardingRule(CreateIPForwardingRuleCmd cmd) throws InvalidParameterValueException {
public FirewallRuleVO createPortForwardingRule(CreateIPForwardingRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, NetworkRuleConflictException {
// validate IP Address exists
IPAddressVO ipAddress = _ipAddressDao.findById(cmd.getIpAddress());
if (ipAddress == null) {
@ -1561,7 +1565,95 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager
throw new InvalidParameterValueException("Unable to create port forwarding rule, IP address " + ipAddress + " is not in the same availability zone as virtual machine " + userVM.toString());
}
// if an admin account was passed in, or no account was passed in, make sure we honor the accountName/domainId parameters
Account account = (Account)UserContext.current().getAccountObject();
if (account != null) {
if ((account.getType() == Account.ACCOUNT_TYPE_ADMIN) || (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) {
if (!_domainDao.isChildDomain(account.getDomainId(), userVM.getDomainId())) {
throw new PermissionDeniedException("Unable to create port forwarding rule, IP address " + ipAddress + " to virtual machine " + cmd.getVirtualMachineId() + ", permission denied.");
}
} else if (account.getId().longValue() != userVM.getAccountId()) {
throw new PermissionDeniedException("Unable to create port forwarding rule, IP address " + ipAddress + " to virtual machine " + cmd.getVirtualMachineId() + ", permission denied.");
}
}
// set up some local variables
String protocol = cmd.getProtocol();
String publicPort = cmd.getPublicPort();
String privatePort = cmd.getPrivatePort();
// sanity check that the vm can be applied to the load balancer
ServiceOfferingVO offering = _serviceOfferingDao.findById(userVM.getServiceOfferingId());
if ((offering == null) || !GuestIpType.Virtualized.equals(offering.getGuestIpType())) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to create port forwarding rule (" + protocol + ":" + publicPort + "->" + privatePort + ") for virtual machine " + userVM.toString() + ", bad network type (" + ((offering == null) ? "null" : offering.getGuestIpType()) + ")");
}
throw new IllegalArgumentException("Unable to create port forwarding rule (" + protocol + ":" + publicPort + "->" + privatePort + ") for virtual machine " + userVM.toString() + ", bad network type (" + ((offering == null) ? "null" : offering.getGuestIpType()) + ")");
}
// check for ip address/port conflicts by checking existing forwarding and load balancing rules
List<FirewallRuleVO> existingRulesOnPubIp = _rulesDao.listIPForwarding(ipAddress.getAddress());
Map<String, Pair<String, String>> mappedPublicPorts = new HashMap<String, Pair<String, String>>();
if (existingRulesOnPubIp != null) {
for (FirewallRuleVO fwRule : existingRulesOnPubIp) {
mappedPublicPorts.put(fwRule.getPublicPort(), new Pair<String, String>(fwRule.getPrivateIpAddress(), fwRule.getPrivatePort()));
}
}
Pair<String, String> privateIpPort = mappedPublicPorts.get(publicPort);
if (privateIpPort != null) {
if (privateIpPort.first().equals(userVM.getGuestIpAddress()) && privateIpPort.second().equals(privatePort)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("skipping the creating of firewall rule " + ipAddress + ":" + publicPort + " to " + userVM.getGuestIpAddress() + ":" + privatePort + "; rule already exists.");
}
return null; // already mapped
} else {
// FIXME: Will we need to refactor this for both assign port forwarding service and create port forwarding rule?
// throw new NetworkRuleConflictException("An existing port forwarding service rule for " + ipAddress + ":" + publicPort
// + " already exists, found while trying to create mapping to " + userVM.getGuestIpAddress() + ":" + privatePort + ((securityGroupId == null) ? "." : " from port forwarding service "
// + securityGroupId.toString() + "."));
throw new NetworkRuleConflictException("An existing port forwarding service rule for " + ipAddress + ":" + publicPort
+ " already exists, found while trying to create mapping to " + userVM.getGuestIpAddress() + ":" + privatePort + ".");
}
}
FirewallRuleVO newFwRule = new FirewallRuleVO();
newFwRule.setEnabled(true);
newFwRule.setForwarding(true);
newFwRule.setPrivatePort(privatePort);
newFwRule.setProtocol(protocol);
newFwRule.setPublicPort(publicPort);
newFwRule.setPublicIpAddress(ipAddress.getAddress());
newFwRule.setPrivateIpAddress(userVM.getGuestIpAddress());
// newFwRule.setGroupId(securityGroupId);
newFwRule.setGroupId(null);
// In 1.0 the rules were always persisted when a user created a rule. When the rules get sent down
// the stopOnError parameter is set to false, so the agent will apply all rules that it can. That
// behavior is preserved here by persisting the rule before sending it to the agent.
_rulesDao.persist(newFwRule);
boolean success = updateFirewallRule(newFwRule, null, null);
// Save and create the event
String description;
String ruleName = "ip forwarding";
String level = EventVO.LEVEL_INFO;
if (success == true) {
description = "created new " + ruleName + " rule [" + newFwRule.getPublicIpAddress() + ":" + newFwRule.getPublicPort() + "]->["
+ newFwRule.getPrivateIpAddress() + ":" + newFwRule.getPrivatePort() + "]" + " " + newFwRule.getProtocol();
} else {
level = EventVO.LEVEL_ERROR;
description = "failed to create new " + ruleName + " rule [" + newFwRule.getPublicIpAddress() + ":" + newFwRule.getPublicPort() + "]->["
+ newFwRule.getPrivateIpAddress() + ":" + newFwRule.getPrivatePort() + "]" + " " + newFwRule.getProtocol();
}
EventUtils.saveEvent(UserContext.current().getUserId(), userVM.getAccountId(), level, EventTypes.EVENT_NET_RULE_ADD, description);
return newFwRule;
}
@Override
@ -1794,6 +1886,121 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager
}
}
@Override
public LoadBalancerVO createLoadBalancerRule(CreateLoadBalancerRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException {
String publicIp = cmd.getPublicIp();
// make sure ip address exists
IPAddressVO ipAddr = _ipAddressDao.findById(cmd.getPublicIp());
if (ipAddr == null) {
throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address " + publicIp);
}
VlanVO vlan = _vlanDao.findById(ipAddr.getVlanDbId());
if (vlan != null) {
if (!VlanType.VirtualNetwork.equals(vlan.getVlanType())) {
throw new InvalidParameterValueException("Unable to create load balancer rule for IP address " + publicIp + ", only VirtualNetwork type IP addresses can be used for load balancers.");
}
} // else ERROR?
// Verify input parameters
if ((ipAddr.getAccountId() == null) || (ipAddr.getAllocated() == null)) {
throw new InvalidParameterValueException("Unable to create load balancer rule, cannot find account owner for ip " + publicIp);
}
Account account = (Account)UserContext.current().getAccountObject();
if (account != null) {
if ((account.getType() == Account.ACCOUNT_TYPE_ADMIN) || (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) {
if (!_domainDao.isChildDomain(account.getDomainId(), ipAddr.getDomainId())) {
throw new PermissionDeniedException("Unable to create load balancer rule on IP address " + publicIp + ", permission denied.");
}
} else if (account.getId().longValue() != ipAddr.getAccountId().longValue()) {
throw new PermissionDeniedException("Unable to create load balancer rule, account " + account.getAccountName() + " doesn't own ip address " + publicIp);
}
}
String loadBalancerName = cmd.getLoadBalancerRuleName();
LoadBalancerVO existingLB = _loadBalancerDao.findByAccountAndName(ipAddr.getAccountId(), loadBalancerName);
if (existingLB != null) {
throw new InvalidParameterValueException("Unable to create load balancer rule, an existing load balancer rule with name " + loadBalancerName + " already exists.");
}
// validate params
String publicPort = cmd.getPublicPort();
String privatePort = cmd.getPrivatePort();
String algorithm = cmd.getAlgorithm();
if (!NetUtils.isValidPort(publicPort)) {
throw new InvalidParameterValueException("publicPort is an invalid value");
}
if (!NetUtils.isValidPort(privatePort)) {
throw new InvalidParameterValueException("privatePort is an invalid value");
}
if ((algorithm == null) || !NetUtils.isValidAlgorithm(algorithm)) {
throw new InvalidParameterValueException("Invalid algorithm");
}
boolean locked = false;
try {
LoadBalancerVO exitingLB = _loadBalancerDao.findByIpAddressAndPublicPort(publicIp, publicPort);
if (exitingLB != null) {
throw new InvalidParameterValueException("IP Address/public port already load balanced by an existing load balancer rule");
}
List<FirewallRuleVO> existingFwRules = _rulesDao.listIPForwarding(publicIp, publicPort, true);
if ((existingFwRules != null) && !existingFwRules.isEmpty()) {
FirewallRuleVO existingFwRule = existingFwRules.get(0);
String securityGroupName = null;
if (existingFwRule.getGroupId() != null) {
long groupId = existingFwRule.getGroupId();
SecurityGroupVO securityGroup = _securityGroupDao.findById(groupId);
securityGroupName = securityGroup.getName();
}
throw new InvalidParameterValueException("IP Address (" + publicIp + ") and port (" + publicPort + ") already in use" +
((securityGroupName == null) ? "" : " by port forwarding service " + securityGroupName));
}
ipAddr = _ipAddressDao.acquire(publicIp);
if (ipAddr == null) {
throw new PermissionDeniedException("User does not own ip address " + publicIp);
}
locked = true;
LoadBalancerVO loadBalancer = new LoadBalancerVO(loadBalancerName, cmd.getDescription(), ipAddr.getAccountId(), publicIp, publicPort, privatePort, algorithm);
loadBalancer = _loadBalancerDao.persist(loadBalancer);
Long id = loadBalancer.getId();
// Save off information for the event that the security group was applied
Long userId = UserContext.current().getUserId();
if (userId == null) {
userId = Long.valueOf(User.UID_SYSTEM);
}
EventVO event = new EventVO();
event.setUserId(userId);
event.setAccountId(ipAddr.getAccountId());
event.setType(EventTypes.EVENT_LOAD_BALANCER_CREATE);
if (id == null) {
event.setDescription("Failed to create load balancer " + loadBalancer.getName() + " on ip address " + publicIp + "[" + publicPort + "->" + privatePort + "]");
event.setLevel(EventVO.LEVEL_ERROR);
} else {
event.setDescription("Successfully created load balancer " + loadBalancer.getName() + " on ip address " + publicIp + "[" + publicPort + "->" + privatePort + "]");
String params = "id="+loadBalancer.getId()+"\ndcId="+ipAddr.getDataCenterId();
event.setParameters(params);
event.setLevel(EventVO.LEVEL_INFO);
}
_eventDao.persist(event);
return _loadBalancerDao.findById(id);
} finally {
if (locked) {
_ipAddressDao.release(publicIp);
}
}
}
@Override @DB
public boolean releasePublicIpAddress(long userId, final String ipAddress) {
IPAddressVO ip = null;

View File

@ -1265,18 +1265,6 @@ public interface ManagementServer {
*/
List<FirewallRuleVO> listIPForwarding(String publicIPAddress, boolean forwarding);
/**
* Create a single port forwarding rule from the given ip address and port to the vm's guest IP address and private port with the given protocol.
* @param userId the id of the user performing the action (could be an admin's ID if performing on behalf of a user)
* @param ipAddressVO
* @param userVM
* @param publicPort
* @param privatePort
* @param protocol
* @return
*/
FirewallRuleVO createPortForwardingRule(long userId, IPAddressVO ipAddressVO, UserVmVO userVM, String publicPort, String privatePort, String protocol) throws NetworkRuleConflictException;
/**
* Update an existing port forwarding rule on the given public IP / public port for the given protocol
* @param userId id of the user performing the action
@ -1931,7 +1919,6 @@ public interface ManagementServer {
LoadBalancerVO findLoadBalancerById(long loadBalancerId);
List<UserVmVO> listLoadBalancerInstances(long loadBalancerId, boolean applied);
List<LoadBalancerVO> searchForLoadBalancers(Criteria c);
LoadBalancerVO createLoadBalancer(Long userId, Long accountId, String name, String description, String ipAddress, String publicPort, String privatePort, String algorithm) throws InvalidParameterValueException, PermissionDeniedException;
boolean deleteLoadBalancer(long userId, long loadBalancerId);
long deleteLoadBalancerAsync(long userId, long loadBalancerId);
@ -2093,8 +2080,6 @@ public interface ManagementServer {
long revokeNetworkGroupIngressAsync(Long accountId, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List<NetworkGroupVO> authorizedGroups);
boolean revokeNetworkGroupIngress(AccountVO account, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List<NetworkGroupVO> authorizedGroups);
NetworkGroupVO createNetworkGroup(String name, String description, Long domainId, Long accountId, String accountName);
/**
* Delete an empty network group. If the group is not empty an error is returned.
* @param groupId

View File

@ -112,7 +112,6 @@ import com.cloud.async.executor.NetworkGroupIngressParam;
import com.cloud.async.executor.ResetVMPasswordParam;
import com.cloud.async.executor.SecurityGroupParam;
import com.cloud.async.executor.UpdateLoadBalancerParam;
import com.cloud.async.executor.UpgradeVMParam;
import com.cloud.async.executor.VMOperationParam;
import com.cloud.async.executor.VMOperationParam.VmOp;
import com.cloud.async.executor.VolumeOperationParam;
@ -5165,11 +5164,6 @@ public class ManagementServerImpl implements ManagementServer {
return _firewallRulesDao.listIPForwarding(publicIPAddress, forwarding);
}
@Override
public FirewallRuleVO createPortForwardingRule(long userId, IPAddressVO ipAddressVO, UserVmVO userVM, String publicPort, String privatePort, String protocol) throws NetworkRuleConflictException {
return createFirewallRule(userId, ipAddressVO.getAddress(), userVM, publicPort, privatePort, protocol, null);
}
@Override
public FirewallRuleVO updatePortForwardingRule(long userId, String publicIp, String privateIp, String publicPort, String privatePort, String protocol) {
List<FirewallRuleVO> fwRules = _firewallRulesDao.listIPForwardingForUpdate(publicIp, publicPort, protocol);
@ -7234,86 +7228,6 @@ public class ManagementServerImpl implements ManagementServer {
return _loadBalancerDao.findById(Long.valueOf(loadBalancerId));
}
@Override
@DB
public LoadBalancerVO createLoadBalancer(Long userId, Long accountId, String name, String description, String ipAddress, String publicPort, String privatePort, String algorithm)
throws InvalidParameterValueException, PermissionDeniedException {
if (accountId == null) {
throw new InvalidParameterValueException("accountId not specified");
}
if (!NetUtils.isValidIp(ipAddress)) {
throw new InvalidParameterValueException("invalid ip address");
}
if (!NetUtils.isValidPort(publicPort)) {
throw new InvalidParameterValueException("publicPort is an invalid value");
}
if (!NetUtils.isValidPort(privatePort)) {
throw new InvalidParameterValueException("privatePort is an invalid value");
}
if ((algorithm == null) || !NetUtils.isValidAlgorithm(algorithm)) {
throw new InvalidParameterValueException("Invalid algorithm");
}
boolean locked = false;
try {
LoadBalancerVO exitingLB = _loadBalancerDao.findByIpAddressAndPublicPort(ipAddress, publicPort);
if (exitingLB != null) {
throw new InvalidParameterValueException("IP Address/public port already load balanced by an existing load balancer rule");
}
List<FirewallRuleVO> existingFwRules = _firewallRulesDao.listIPForwarding(ipAddress, publicPort, true);
if ((existingFwRules != null) && !existingFwRules.isEmpty()) {
FirewallRuleVO existingFwRule = existingFwRules.get(0);
String securityGroupName = null;
if (existingFwRule.getGroupId() != null) {
long groupId = existingFwRule.getGroupId();
SecurityGroupVO securityGroup = _securityGroupDao.findById(groupId);
securityGroupName = securityGroup.getName();
}
throw new InvalidParameterValueException("IP Address (" + ipAddress + ") and port (" + publicPort + ") already in use" +
((securityGroupName == null) ? "" : " by port forwarding service " + securityGroupName));
}
IPAddressVO addr = _publicIpAddressDao.acquire(ipAddress);
if (addr == null) {
throw new PermissionDeniedException("User does not own ip address " + ipAddress);
}
locked = true;
if ((addr.getAllocated() == null) || !accountId.equals(addr.getAccountId())) {
throw new PermissionDeniedException("User does not own ip address " + ipAddress);
}
LoadBalancerVO loadBalancer = new LoadBalancerVO(name, description, accountId.longValue(), ipAddress, publicPort, privatePort, algorithm);
loadBalancer = _loadBalancerDao.persist(loadBalancer);
Long id = loadBalancer.getId();
// Save off information for the event that the security group was applied
EventVO event = new EventVO();
event.setUserId(userId);
event.setAccountId(accountId);
event.setType(EventTypes.EVENT_LOAD_BALANCER_CREATE);
if (id == null) {
event.setDescription("Failed to create load balancer " + loadBalancer.getName() + " on ip address " + ipAddress + "[" + publicPort + "->" + privatePort + "]");
event.setLevel(EventVO.LEVEL_ERROR);
} else {
event.setDescription("Successfully created load balancer " + loadBalancer.getName() + " on ip address " + ipAddress + "[" + publicPort + "->" + privatePort + "]");
String params = "id="+loadBalancer.getId()+"\ndcId="+addr.getDataCenterId();
event.setParameters(params);
event.setLevel(EventVO.LEVEL_INFO);
}
_eventDao.persist(event);
return _loadBalancerDao.findById(id);
} finally {
if (locked) {
_publicIpAddressDao.release(ipAddress);
}
}
}
/*
@Override @DB
public long assignToLoadBalancerAsync(long userId, long loadBalancerId, List<Long> instanceIds, Map<String, String> params) {
@ -8296,15 +8210,6 @@ public class ManagementServerImpl implements ManagementServer {
return groupVO;
}
@Override
public boolean isNetworkSecurityGroupNameInUse(Long domainId, Long accountId, String name) {
if (domainId == null) {
domainId = DomainVO.ROOT_DOMAIN;
}
_networkGroupMgr.createDefaultNetworkGroup(accountId);
return _networkSecurityGroupDao.isNameInUse(accountId, domainId, name);
}
@Override
public List<IngressRuleVO> authorizeNetworkGroupIngress(AccountVO account, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List<NetworkGroupVO> authorizedGroups) {
return _networkGroupMgr.authorizeNetworkGroupIngress(account, groupName, protocol, startPort, endPort, cidrList, authorizedGroups);
@ -8352,11 +8257,6 @@ public class ManagementServerImpl implements ManagementServer {
return _asyncMgr.submitAsyncJob(job);
}
@Override
public NetworkGroupVO createNetworkGroup(String name, String description, Long domainId, Long accountId, String accountName) {
return _networkGroupMgr.createNetworkGroup(name, description, domainId, accountId, accountName);
}
@Override
public void deleteNetworkGroup(Long groupId, Long accountId) throws ResourceInUseException, PermissionDeniedException {
_networkGroupMgr.deleteNetworkGroup(groupId, accountId);