diff --git a/server/src/com/cloud/api/commands/CreateIPForwardingRuleCmd.java b/server/src/com/cloud/api/commands/CreateIPForwardingRuleCmd.java index 458b31b8674..2114b2979fc 100644 --- a/server/src/com/cloud/api/commands/CreateIPForwardingRuleCmd.java +++ b/server/src/com/cloud/api/commands/CreateIPForwardingRuleCmd.java @@ -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> 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.IP_ADDRESS, Boolean.TRUE)); - s_properties.add(new Pair(BaseCmd.Properties.PRIVATE_PORT, Boolean.TRUE)); - s_properties.add(new Pair(BaseCmd.Properties.PROTOCOL, Boolean.TRUE)); - s_properties.add(new Pair(BaseCmd.Properties.PUBLIC_PORT, Boolean.TRUE)); - s_properties.add(new Pair(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(); + + 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()); + + return SerializerHelper.toSerializedString(fwResponse); } - - @Override - public List> execute(Map 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()); - - 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> groupsTags = new ArrayList>(); - Object[] forwardingTag = new Object[1]; - - List> ruleData = new ArrayList>(); - - ruleData.add(new Pair(BaseCmd.Properties.ID.getName(), firewallRule.getId().toString())); - ruleData.add(new Pair(BaseCmd.Properties.PUBLIC_PORT.getName(), firewallRule.getPublicPort())); - ruleData.add(new Pair(BaseCmd.Properties.PRIVATE_PORT.getName(), firewallRule.getPrivatePort())); - ruleData.add(new Pair(BaseCmd.Properties.PROTOCOL.getName(), firewallRule.getProtocol())); - ruleData.add(new Pair(BaseCmd.Properties.VIRTUAL_MACHINE_NAME.getName(), userVM.getName())); - ruleData.add(new Pair(BaseCmd.Properties.VIRTUAL_MACHINE_ID.getName(), Long.toString(userVM.getId()))); - - forwardingTag[0] = ruleData; - - Pair eventTag = new Pair("portforwardingrule", forwardingTag); - groupsTags.add(eventTag); - return groupsTags; - } } diff --git a/server/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java b/server/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java index 9ad2f2cb902..06f481b6033 100644 --- a/server/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java +++ b/server/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java @@ -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> 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.ALGORITHM, Boolean.TRUE)); - s_properties.add(new Pair(BaseCmd.Properties.DESCRIPTION, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.NAME, Boolean.TRUE)); - s_properties.add(new Pair(BaseCmd.Properties.PRIVATE_PORT, Boolean.TRUE)); - s_properties.add(new Pair(BaseCmd.Properties.PUBLIC_IP, Boolean.TRUE)); - s_properties.add(new Pair(BaseCmd.Properties.PUBLIC_PORT, Boolean.TRUE)); - } ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -115,99 +92,25 @@ public class CreateLoadBalancerRuleCmd extends BaseCmd { public String getName() { return s_name; - } - public List> getProperties() { - return s_properties; - } - + } + @Override - public List> execute(Map 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); - - if (userId == null) { - userId = Long.valueOf(1); - } + 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()); - 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 = _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> embeddedObject = new ArrayList>(); - List> returnValues = new ArrayList>(); - returnValues.add(new Pair(BaseCmd.Properties.ID.getName(), loadBalancer.getId().toString())); - returnValues.add(new Pair(BaseCmd.Properties.NAME.getName(), loadBalancer.getName())); - returnValues.add(new Pair(BaseCmd.Properties.DESCRIPTION.getName(), loadBalancer.getDescription())); - returnValues.add(new Pair(BaseCmd.Properties.PUBLIC_IP.getName(), loadBalancer.getIpAddress())); - returnValues.add(new Pair(BaseCmd.Properties.PUBLIC_PORT.getName(), loadBalancer.getPublicPort())); - returnValues.add(new Pair(BaseCmd.Properties.PRIVATE_PORT.getName(), loadBalancer.getPrivatePort())); - returnValues.add(new Pair(BaseCmd.Properties.ALGORITHM.getName(), loadBalancer.getAlgorithm())); - - Account accountTemp = getManagementServer().findAccountById(loadBalancer.getAccountId()); - if (accountTemp != null) { - returnValues.add(new Pair(BaseCmd.Properties.ACCOUNT.getName(), accountTemp.getAccountName())); - returnValues.add(new Pair(BaseCmd.Properties.DOMAIN_ID.getName(), accountTemp.getDomainId())); - returnValues.add(new Pair(BaseCmd.Properties.DOMAIN.getName(), getManagementServer().findDomainIdById(accountTemp.getDomainId()).getName())); - } - embeddedObject.add(new Pair("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); } } diff --git a/server/src/com/cloud/api/response/FirewallRuleResponse.java b/server/src/com/cloud/api/response/FirewallRuleResponse.java new file mode 100644 index 00000000000..e906318e108 --- /dev/null +++ b/server/src/com/cloud/api/response/FirewallRuleResponse.java @@ -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; + } +} diff --git a/server/src/com/cloud/api/response/LoadBalancerResponse.java b/server/src/com/cloud/api/response/LoadBalancerResponse.java new file mode 100644 index 00000000000..f66eb39b897 --- /dev/null +++ b/server/src/com/cloud/api/response/LoadBalancerResponse.java @@ -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; + } +} diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index b9fb4dbdfb9..864ef68083a 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -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 updateFirewallRules(String publicIpAddress, List 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. diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index cef66bf7840..330515f34a5 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -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; @@ -1362,9 +1364,11 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager if (answers.length != ipAddrList.size()) { 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 existingRulesOnPubIp = _rulesDao.listIPForwarding(ipAddress.getAddress()); + Map> mappedPublicPorts = new HashMap>(); + + if (existingRulesOnPubIp != null) { + for (FirewallRuleVO fwRule : existingRulesOnPubIp) { + mappedPublicPorts.put(fwRule.getPublicPort(), new Pair(fwRule.getPrivateIpAddress(), fwRule.getPrivatePort())); + } + } + + Pair 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 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; diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index 5a2c3f85777..c31caf051b3 100644 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -1265,18 +1265,6 @@ public interface ManagementServer { */ List 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 listLoadBalancerInstances(long loadBalancerId, boolean applied); List 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 authorizedGroups); boolean revokeNetworkGroupIngress(AccountVO account, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List 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 diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index c2f236eb553..77fc4b3c6df 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -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 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 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 instanceIds, Map 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 authorizeNetworkGroupIngress(AccountVO account, String groupName, String protocol, int startPort, int endPort, String [] cidrList, List 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);