From a623b2824ba230af3c8168963c1e12b10869726e Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Thu, 29 Sep 2011 18:59:46 +0530 Subject: [PATCH] bug 6876: netscaler integration added external lb network usage and inline support --- .../resource/NetscalerMPXResource.java | 86 ++-- .../network/ExternalFirewallManager.java | 35 -- .../network/ExternalLoadBalancerManager.java | 32 -- .../com/cloud/network/F5BigIpManagerImpl.java | 307 ------------- .../cloud/network/JuniperSrxManagerImpl.java | 425 ------------------ 5 files changed, 48 insertions(+), 837 deletions(-) delete mode 100644 server/src/com/cloud/network/ExternalFirewallManager.java delete mode 100644 server/src/com/cloud/network/ExternalLoadBalancerManager.java delete mode 100644 server/src/com/cloud/network/F5BigIpManagerImpl.java delete mode 100644 server/src/com/cloud/network/JuniperSrxManagerImpl.java diff --git a/core/src/com/cloud/network/resource/NetscalerMPXResource.java b/core/src/com/cloud/network/resource/NetscalerMPXResource.java index 2893ae270a8..3c25a83feb1 100644 --- a/core/src/com/cloud/network/resource/NetscalerMPXResource.java +++ b/core/src/com/cloud/network/resource/NetscalerMPXResource.java @@ -63,6 +63,8 @@ import com.citrix.netscaler.nitro.resource.config.basic.service; import com.citrix.netscaler.nitro.resource.config.network.*; import com.citrix.netscaler.nitro.resource.config.ns.*; import com.citrix.netscaler.nitro.resource.config.basic.server_service_binding; +import com.citrix.netscaler.nitro.resource.stat.lb.lbvserver_stats; + import org.apache.axis.types.*; import org.apache.log4j.Logger; @@ -145,50 +147,39 @@ public class NetscalerMPXResource implements ServerResource { _inline = Boolean.parseBoolean((String) params.get("inline")); - if (!login()) { - throw new ExecutionException("Failed to login to the Netscaler device."); - } - - if (!enableNetScalerLoadBalancing()) { - throw new ExecutionException("Failed to enable load balancing feature on the Netscaler device."); - } - + login(); + enableNetScalerLoadBalancing(); + return true; } catch (Exception e) { throw new ConfigurationException(e.getMessage()); } } - private boolean login() { + private void login() throws ExecutionException { try { nsService = new nitro_service(_ip, "https"); apiCallResult = nsService.login(_username, _password, timeout); - if (apiCallResult.errorcode == 0) { - return true; - } else { - s_logger.debug("Failed to log in to Netscaler device at " + _ip + " due to " + apiCallResult.message); - return false; + if (apiCallResult.errorcode != 0) { + throw new ExecutionException ("Failed to log in to Netscaler device at " + _ip + " due to " + apiCallResult.message); } } catch (nitro_exception e) { - s_logger.debug("Failed to log in to Netscaler device at " + _ip + " due to " + e.response[0].message); + throw new ExecutionException("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage()); } catch (Exception e) { - s_logger.debug("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage()); + throw new ExecutionException("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage()); } - return false; } - private boolean enableNetScalerLoadBalancing() { + private void enableNetScalerLoadBalancing() throws ExecutionException { try { String[] feature = new String[1]; feature[0] = "LB"; nsService.enable_features(feature); - return true; } catch (nitro_exception e) { - System.out.println("Enabling netscaler load balancing feature failed errorcode="+e.getErrorCode()+",message="+ e.getMessage()); + throw new ExecutionException("Enabling netscaler load balancing feature failed due to " + e.getMessage()); } catch (Exception e) { - System.out.println("Enabling netscaler load balancing feature failed due to "+e.getMessage()); + throw new ExecutionException("Enabling netscaler load balancing feature failed due to " + e.getMessage()); } - return false; } @Override @@ -220,8 +211,6 @@ public class NetscalerMPXResource implements ServerResource { return execute((LoadBalancerConfigCommand) cmd, numRetries); } else if (cmd instanceof ExternalNetworkResourceUsageCommand) { return execute((ExternalNetworkResourceUsageCommand) cmd); - } else if (cmd instanceof MaintainCommand) { - return execute((MaintainCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } @@ -232,10 +221,7 @@ public class NetscalerMPXResource implements ServerResource { } protected Answer execute(MaintainCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource MaintainCommand"); - } - return new MaintainAnswer(cmd, "Put host in maintaince"); + return new MaintainAnswer(cmd); } private synchronized Answer execute(IpAssocCommand cmd, int numRetries) { @@ -318,7 +304,6 @@ public class NetscalerMPXResource implements ServerResource { s_logger.debug("Created load balancing virtual server " + nsVirtualServerName + " on the Netscaler device"); } - List activePoolMembers = new ArrayList(); for (DestinationTO destination : loadBalancer.getDestinations()) { String nsServerName = generateNSServerName(destination.getDestIp()); @@ -398,7 +383,7 @@ public class NetscalerMPXResource implements ServerResource { } } } else { - // delete the implemented load balancing rule and its destinations + // delete the deployed load balancing rule and its destinations lbvserver lbserver = lbvserver.get(nsService, nsVirtualServerName); if (lbserver == null) { throw new ExecutionException("Failed to find virtual server with name:" + nsVirtualServerName); @@ -561,14 +546,13 @@ public class NetscalerMPXResource implements ServerResource { } } } catch (nitro_exception e) { - throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device"); + throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage()); } catch (Exception e) { - s_logger.error(e); - throw new ExecutionException(e.getMessage()); + throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage()); } } - private boolean nsVlanExists(long vlanTag) {// throws ExecutionException { + private boolean nsVlanExists(long vlanTag) { try { if (vlan.get(nsService, new Long(vlanTag)) != null) { return true; @@ -701,9 +685,9 @@ public class NetscalerMPXResource implements ServerResource { throw new ExecutionException("Failed to remove virtual server:" + virtualServerName); } } catch (nitro_exception e) { - throw new ExecutionException("Failed remove virtual server:" + virtualServerName +" due to " + e.getMessage()); + throw new ExecutionException("Failed to remove virtual server:" + virtualServerName +" due to " + e.getMessage()); } catch (Exception e) { - throw new ExecutionException("Failed remove virtual server:" + virtualServerName +" due to " + e.getMessage()); + throw new ExecutionException("Failed to remove virtual server:" + virtualServerName +" due to " + e.getMessage()); } } @@ -724,7 +708,25 @@ public class NetscalerMPXResource implements ServerResource { ExternalNetworkResourceUsageAnswer answer = new ExternalNetworkResourceUsageAnswer(cmd); try { - //TODO: add the stats collection + + lbvserver_stats[] stats = lbvserver_stats.get(nsService); + + for (lbvserver_stats stat_entry : stats) { + String lbvserverName = stat_entry.get_name(); + lbvserver vserver = lbvserver.get(nsService, lbvserverName); + String lbVirtualServerIp = vserver.get_ipv46(); + + long[] bytesSentAndReceived = answer.ipBytes.get(lbVirtualServerIp); + if (bytesSentAndReceived == null) { + bytesSentAndReceived = new long[]{0, 0}; + } + bytesSentAndReceived[0] += stat_entry.get_totalrequestbytes(); + bytesSentAndReceived[1] += stat_entry.get_totalresponsebytes(); + + if (bytesSentAndReceived[0] >= 0 && bytesSentAndReceived[1] >= 0) { + answer.ipBytes.put(lbVirtualServerIp, bytesSentAndReceived); + } + } } catch (Exception e) { s_logger.error(e); throw new ExecutionException(e.getMessage()); @@ -740,7 +742,15 @@ public class NetscalerMPXResource implements ServerResource { } private boolean shouldRetry(int numRetries) { - return (numRetries > 0 && login()); + try { + if (numRetries > 0) { + login(); + return true; + } + } catch (Exception e) { + s_logger.error("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage()); + } + return false; } private String generateVlanName(long vlanTag) { diff --git a/server/src/com/cloud/network/ExternalFirewallManager.java b/server/src/com/cloud/network/ExternalFirewallManager.java deleted file mode 100644 index 54dbedabd68..00000000000 --- a/server/src/com/cloud/network/ExternalFirewallManager.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (C) 2011 Cloud.com, Inc. All rights reserved. - */ - -package com.cloud.network; - -import java.util.List; - -import com.cloud.api.commands.AddExternalFirewallCmd; -import com.cloud.api.commands.DeleteExternalFirewallCmd; -import com.cloud.api.commands.ListExternalFirewallsCmd; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.network.rules.FirewallRule; -import com.cloud.offering.NetworkOffering; -import com.cloud.server.api.response.ExternalFirewallResponse; - -public interface ExternalFirewallManager extends ExternalNetworkManager { - - public Host addExternalFirewall(AddExternalFirewallCmd cmd); - - public boolean deleteExternalFirewall(DeleteExternalFirewallCmd cmd); - - public List listExternalFirewalls(ListExternalFirewallsCmd cmd); - - public ExternalFirewallResponse getApiResponse(Host externalFirewall); - - public boolean manageGuestNetwork(boolean add, Network network, NetworkOffering offering) throws ResourceUnavailableException; - - public boolean applyFirewallRules(Network network, List rules) throws ResourceUnavailableException; - - public boolean applyIps(Network network, List ipAddresses) throws ResourceUnavailableException; - -} diff --git a/server/src/com/cloud/network/ExternalLoadBalancerManager.java b/server/src/com/cloud/network/ExternalLoadBalancerManager.java deleted file mode 100644 index fdbd7426869..00000000000 --- a/server/src/com/cloud/network/ExternalLoadBalancerManager.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (C) 2011 Cloud.com, Inc. All rights reserved. - */ - -package com.cloud.network; - -import java.util.List; - -import com.cloud.api.commands.AddExternalLoadBalancerCmd; -import com.cloud.api.commands.DeleteExternalLoadBalancerCmd; -import com.cloud.api.commands.ListExternalLoadBalancersCmd; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.network.rules.FirewallRule; -import com.cloud.server.api.response.ExternalFirewallResponse; -import com.cloud.server.api.response.ExternalLoadBalancerResponse; -public interface ExternalLoadBalancerManager extends ExternalNetworkManager { - - public Host addExternalLoadBalancer(AddExternalLoadBalancerCmd cmd); - - public boolean deleteExternalLoadBalancer(DeleteExternalLoadBalancerCmd cmd); - - public List listExternalLoadBalancers(ListExternalLoadBalancersCmd cmd); - - public ExternalLoadBalancerResponse getApiResponse(Host externalLoadBalancer); - - public boolean manageGuestNetwork(boolean add, Network guestConfig) throws ResourceUnavailableException; - - public boolean applyLoadBalancerRules(Network network, List rules) throws ResourceUnavailableException; - -} diff --git a/server/src/com/cloud/network/F5BigIpManagerImpl.java b/server/src/com/cloud/network/F5BigIpManagerImpl.java deleted file mode 100644 index 28781e618e0..00000000000 --- a/server/src/com/cloud/network/F5BigIpManagerImpl.java +++ /dev/null @@ -1,307 +0,0 @@ -/** - * Copyright (C) 2011 Cloud.com, Inc. All rights reserved. - */ - -package com.cloud.network; - -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.routing.IpAssocCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; -import com.cloud.agent.api.to.IpAddressTO; -import com.cloud.agent.api.to.LoadBalancerTO; -import com.cloud.api.commands.AddExternalLoadBalancerCmd; -import com.cloud.api.commands.DeleteExternalLoadBalancerCmd; -import com.cloud.api.commands.ListExternalLoadBalancersCmd; -import com.cloud.configuration.ConfigurationManager; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.network.Networks.TrafficType; -import com.cloud.network.lb.LoadBalancingRule; -import com.cloud.network.lb.LoadBalancingRule.LbDestination; -import com.cloud.network.resource.F5BigIpResource; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRule.Purpose; -import com.cloud.server.api.response.ExternalLoadBalancerResponse; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.User; -import com.cloud.user.UserContext; -import com.cloud.user.dao.AccountDao; -import com.cloud.utils.component.Inject; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.net.NetUtils; -import com.cloud.utils.net.UrlUtil; -import com.cloud.vm.Nic; -import com.cloud.vm.Nic.ReservationStrategy; -import com.cloud.vm.NicVO; -import com.cloud.vm.dao.NicDao; -import com.cloud.vm.dao.UserVmDao; - -@Local(value = { ExternalLoadBalancerManager.class }) -public class F5BigIpManagerImpl extends ExternalNetworkManagerImpl implements ExternalLoadBalancerManager { - - @Inject - NetworkManager _networkMgr; - @Inject - NicDao _nicDao; - @Inject - AccountDao _accountDao; - @Inject - DataCenterDao _dcDao; - @Inject - UserVmDao _vmDao; - @Inject - ConfigurationManager _configMgr; - @Inject - AccountManager _accountMgr; - - private static final org.apache.log4j.Logger s_logger = Logger.getLogger(F5BigIpManagerImpl.class); - - @Override - public Host addExternalLoadBalancer(AddExternalLoadBalancerCmd cmd) { - long zoneId = cmd.getZoneId(); - - DataCenterVO zone = _dcDao.findById(zoneId); - String zoneName; - if (zone == null) { - throw new InvalidParameterValueException("Could not find zone with ID: " + zoneId); - } else { - zoneName = zone.getName(); - } - - List externalLoadBalancersInZone = _hostDao.listByTypeDataCenter(Host.Type.ExternalLoadBalancer, zoneId); - if (externalLoadBalancersInZone.size() != 0) { - throw new InvalidParameterValueException("Already found an external load balancer in zone: " + zoneName); - } - - URI uri; - try { - uri = new URI(cmd.getUrl()); - } catch (Exception e) { - s_logger.debug(e); - throw new InvalidParameterValueException(e.getMessage()); - } - - String ipAddress = uri.getHost(); - String username = cmd.getUsername(); - String password = cmd.getPassword(); - Map params = new HashMap(); - UrlUtil.parseQueryParameters(uri.getQuery(), true, params); - String publicInterface = params.get("publicinterface"); - String privateInterface = params.get("privateinterface"); - String numRetries = params.get("numretries"); - - if (publicInterface == null) { - throw new InvalidParameterValueException("Please specify a public interface."); - } - - if (privateInterface == null) { - throw new InvalidParameterValueException("Please specify a private interface."); - } - - if (numRetries == null) { - numRetries = "1"; - } - - F5BigIpResource resource = new F5BigIpResource(); - String guid = getExternalNetworkResourceGuid(zoneId, ExternalNetworkResourceName.F5BigIp, ipAddress); - - Map hostDetails = new HashMap(); - hostDetails.put("zoneId", String.valueOf(zoneId)); - hostDetails.put("ip", ipAddress); - hostDetails.put("username", username); - hostDetails.put("password", password); - hostDetails.put("publicInterface", publicInterface); - hostDetails.put("privateInterface", privateInterface); - hostDetails.put("numRetries", numRetries); - hostDetails.put("guid", guid); - hostDetails.put("name", guid); - - try { - resource.configure(guid, hostDetails); - } catch (ConfigurationException e) { - throw new CloudRuntimeException(e.getMessage()); - } - - Host host = _agentMgr.addHost(zoneId, resource, Host.Type.ExternalLoadBalancer, hostDetails); - if (host != null) { - zone.setLoadBalancerProvider(Network.Provider.F5BigIp.getName()); - _dcDao.update(zone.getId(), zone); - return host; - } else { - return null; - } - } - - @Override - public boolean deleteExternalLoadBalancer(DeleteExternalLoadBalancerCmd cmd) { - long hostId = cmd.getId(); - User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); - HostVO externalLoadBalancer = _hostDao.findById(hostId); - if (externalLoadBalancer == null) { - throw new InvalidParameterValueException("Could not find an external load balancer with ID: " + hostId); - } - - try { - if (_agentMgr.maintain(hostId) && _agentMgr.deleteHost(hostId, false, false, caller)) { - DataCenterVO zone = _dcDao.findById(externalLoadBalancer.getDataCenterId()); - - if (zone.getNetworkType().equals(NetworkType.Advanced)) { - zone.setLoadBalancerProvider(Network.Provider.VirtualRouter.getName()); - } else if (zone.getNetworkType().equals(NetworkType.Basic)) { - zone.setLoadBalancerProvider(null); - } - - return _dcDao.update(zone.getId(), zone); - } else { - return false; - } - } catch (AgentUnavailableException e) { - s_logger.debug(e); - return false; - } - } - - @Override - public List listExternalLoadBalancers(ListExternalLoadBalancersCmd cmd) { - long zoneId = cmd.getZoneId(); - return _hostDao.listByTypeDataCenter(Host.Type.ExternalLoadBalancer, zoneId); - } - - @Override - public ExternalLoadBalancerResponse getApiResponse(Host externalLoadBalancer) { - Map lbDetails = _detailsDao.findDetails(externalLoadBalancer.getId()); - ExternalLoadBalancerResponse response = new ExternalLoadBalancerResponse(); - response.setId(externalLoadBalancer.getId()); - response.setIpAddress(externalLoadBalancer.getPrivateIpAddress()); - response.setUsername(lbDetails.get("username")); - response.setPublicInterface(lbDetails.get("publicInterface")); - response.setPrivateInterface(lbDetails.get("privateInterface")); - response.setNumRetries(lbDetails.get("numRetries")); - return response; - } - - @Override - public boolean manageGuestNetwork(boolean add, Network guestConfig) throws ResourceUnavailableException { - if (guestConfig.getTrafficType() != TrafficType.Guest) { - s_logger.trace("F5BigIpManager can only add/remove guest networks."); - return false; - } - - // Find the external load balancer in this zone - long zoneId = guestConfig.getDataCenterId(); - DataCenterVO zone = _dcDao.findById(zoneId); - HostVO externalLoadBalancer = getExternalNetworkAppliance(zoneId, Host.Type.ExternalLoadBalancer); - - if (externalLoadBalancer == null) { - return false; - } - - // Send a command to the external load balancer to implement or shutdown the guest network - long guestVlanTag = Long.parseLong(guestConfig.getBroadcastUri().getHost()); - String selfIp = NetUtils.long2Ip(NetUtils.ip2Long(guestConfig.getGateway()) + 1); - String guestVlanNetmask = NetUtils.cidr2Netmask(guestConfig.getCidr()); - Integer networkRate = _networkMgr.getNetworkRate(guestConfig.getId(), null); - - IpAddressTO ip = new IpAddressTO(guestConfig.getAccountId(), null, add, false, true, String.valueOf(guestVlanTag), selfIp, guestVlanNetmask, null, null, networkRate, false); - IpAddressTO[] ips = new IpAddressTO[1]; - ips[0] = ip; - IpAssocCommand cmd = new IpAssocCommand(ips); - Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); - - if (answer == null || !answer.getResult()) { - String action = add ? "implement" : "shutdown"; - String answerDetails = (answer != null) ? answer.getDetails() : "answer was null"; - String msg = "F5BigIpManager was unable to " + action + " the guest network on the external load balancer in zone " + zone.getName() + " due to " + answerDetails; - s_logger.error(msg); - throw new ResourceUnavailableException(msg, DataCenter.class, zoneId); - } - - List reservedIpAddressesForGuestNetwork = _nicDao.listIpAddressInNetwork(guestConfig.getId()); - if (add && (!reservedIpAddressesForGuestNetwork.contains(selfIp))) { - // Insert a new NIC for this guest network to reserve the self IP - NicVO nic = new NicVO(null, null, guestConfig.getId(), null); - nic.setIp4Address(selfIp); - nic.setReservationStrategy(ReservationStrategy.PlaceHolder); - nic.setState(Nic.State.Reserved); - _nicDao.persist(nic); - } - - Account account = _accountDao.findByIdIncludingRemoved(guestConfig.getAccountId()); - String action = add ? "implemented" : "shut down"; - s_logger.debug("F5BigIpManager has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() + ") with VLAN tag " + guestVlanTag); - - return true; - } - - @Override - public boolean applyLoadBalancerRules(Network network, List rules) throws ResourceUnavailableException { - // Find the external load balancer in this zone - long zoneId = network.getDataCenterId(); - DataCenterVO zone = _dcDao.findById(zoneId); - HostVO externalLoadBalancer = getExternalNetworkAppliance(zoneId, Host.Type.ExternalLoadBalancer); - - if (externalLoadBalancer == null) { - return false; - } - - if (network.getState() == Network.State.Allocated) { - s_logger.debug("F5BigIpManager was asked to apply LB rules for network with ID " + network.getId() + "; this network is not implemented. Skipping backend commands."); - return true; - } - - List loadBalancingRules = new ArrayList(); - - for (FirewallRule rule : rules) { - if (rule.getPurpose().equals(Purpose.LoadBalancing)) { - loadBalancingRules.add((LoadBalancingRule) rule); - } - } - - LoadBalancerTO[] loadBalancers = new LoadBalancerTO[loadBalancingRules.size()]; - for (int i = 0; i < loadBalancingRules.size(); i++) { - LoadBalancingRule rule = loadBalancingRules.get(i); - - boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); - String protocol = rule.getProtocol(); - String algorithm = rule.getAlgorithm(); - String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr(); - int srcPort = rule.getSourcePortStart(); - List destinations = rule.getDestinations(); - - LoadBalancerTO loadBalancer = new LoadBalancerTO(srcIp, srcPort, protocol, algorithm, revoked, false, destinations); - loadBalancers[i] = loadBalancer; - } - - if (loadBalancers.length > 0) { - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancers); - Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); - if (answer == null || !answer.getResult()) { - String details = (answer != null) ? answer.getDetails() : "details unavailable"; - String msg = "Unable to apply load balancer rules to the F5 BigIp appliance in zone " + zone.getName() + " due to: " + details + "."; - s_logger.error(msg); - throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId()); - } - } - - return true; - } -} diff --git a/server/src/com/cloud/network/JuniperSrxManagerImpl.java b/server/src/com/cloud/network/JuniperSrxManagerImpl.java deleted file mode 100644 index a461826b2a1..00000000000 --- a/server/src/com/cloud/network/JuniperSrxManagerImpl.java +++ /dev/null @@ -1,425 +0,0 @@ -/** - * Copyright (C) 2011 Cloud.com, Inc. All rights reserved. - */ - -package com.cloud.network; - -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.routing.IpAssocCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.to.IpAddressTO; -import com.cloud.agent.api.to.PortForwardingRuleTO; -import com.cloud.agent.api.to.StaticNatRuleTO; -import com.cloud.api.commands.AddExternalFirewallCmd; -import com.cloud.api.commands.DeleteExternalFirewallCmd; -import com.cloud.api.commands.ListExternalFirewallsCmd; -import com.cloud.configuration.ConfigurationManager; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.network.Networks.TrafficType; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.resource.JuniperSrxResource; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRule.Purpose; -import com.cloud.network.rules.PortForwardingRule; -import com.cloud.network.rules.StaticNatRule; -import com.cloud.offering.NetworkOffering; -import com.cloud.server.api.response.ExternalFirewallResponse; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.User; -import com.cloud.user.UserContext; -import com.cloud.user.dao.AccountDao; -import com.cloud.user.dao.UserStatisticsDao; -import com.cloud.utils.component.Inject; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.net.NetUtils; -import com.cloud.utils.net.UrlUtil; -import com.cloud.vm.Nic.ReservationStrategy; -import com.cloud.vm.Nic.State; -import com.cloud.vm.NicVO; -import com.cloud.vm.dao.NicDao; - -@Local(value = { ExternalFirewallManager.class }) -public class JuniperSrxManagerImpl extends ExternalNetworkManagerImpl implements ExternalFirewallManager { - - @Inject - NetworkManager _networkMgr; - @Inject - NicDao _nicDao; - @Inject - AccountDao _accountDao; - @Inject - DataCenterDao _dcDao; - @Inject - FirewallRulesDao _firewallRulesDao; - @Inject - UserStatisticsDao _userStatsDao; - @Inject - ConfigurationManager _configMgr; - @Inject - AccountManager _accountMgr; - - private static final org.apache.log4j.Logger s_logger = Logger.getLogger(JuniperSrxManagerImpl.class); - - @Override - public Host addExternalFirewall(AddExternalFirewallCmd cmd) { - long zoneId = cmd.getZoneId(); - - DataCenterVO zone = _dcDao.findById(zoneId); - String zoneName; - if (zone == null) { - throw new InvalidParameterValueException("Could not find zone with ID: " + zoneId); - } else { - zoneName = zone.getName(); - } - - List externalFirewallsInZone = _hostDao.listByTypeDataCenter(Host.Type.ExternalFirewall, zoneId); - if (externalFirewallsInZone.size() != 0) { - throw new InvalidParameterValueException("Already added an external firewall in zone: " + zoneName); - } - - URI uri; - try { - uri = new URI(cmd.getUrl()); - } catch (Exception e) { - s_logger.debug(e); - throw new InvalidParameterValueException(e.getMessage()); - } - - String ipAddress = uri.getHost(); - String username = cmd.getUsername(); - String password = cmd.getPassword(); - Map params = new HashMap(); - UrlUtil.parseQueryParameters(uri.getQuery(), true, params); - String publicInterface = params.get("publicinterface"); - String usageInterface = params.get("usageinterface"); - String privateInterface = params.get("privateinterface"); - String publicZone = params.get("publiczone"); - String privateZone = params.get("privatezone"); - String numRetries = params.get("numretries"); - String timeout = params.get("timeout"); - - if (publicInterface != null) { - if (!publicInterface.contains(".")) { - publicInterface += ".0"; - } - } else { - throw new InvalidParameterValueException("Please specify a public interface."); - } - - if (usageInterface != null) { - if (!usageInterface.contains(".")) { - usageInterface += ".0"; - } - } - - if (privateInterface != null) { - if (privateInterface.contains(".")) { - throw new InvalidParameterValueException("The private interface name must not have a unit identifier."); - } - } else { - throw new InvalidParameterValueException("Please specify a private interface."); - } - - if (publicZone == null) { - publicZone = "untrust"; - } - - if (privateZone == null) { - privateZone = "trust"; - } - - if (numRetries == null) { - numRetries = "1"; - } - - if (timeout == null) { - timeout = "300"; - } - - JuniperSrxResource resource = new JuniperSrxResource(); - String guid = getExternalNetworkResourceGuid(zoneId, ExternalNetworkResourceName.JuniperSrx, ipAddress); - - Map hostDetails = new HashMap(); - hostDetails.put("zoneId", String.valueOf(zoneId)); - hostDetails.put("ip", ipAddress); - hostDetails.put("username", username); - hostDetails.put("password", password); - hostDetails.put("publicInterface", publicInterface); - hostDetails.put("privateInterface", privateInterface); - hostDetails.put("publicZone", publicZone); - hostDetails.put("privateZone", privateZone); - hostDetails.put("numRetries", numRetries); - hostDetails.put("timeout", timeout); - hostDetails.put("guid", guid); - hostDetails.put("name", guid); - - if (usageInterface != null) { - hostDetails.put("usageInterface", usageInterface); - } - - try { - resource.configure(guid, hostDetails); - } catch (ConfigurationException e) { - throw new CloudRuntimeException(e.getMessage()); - } - - Host externalFirewall = _agentMgr.addHost(zoneId, resource, Host.Type.ExternalFirewall, hostDetails); - if (externalFirewall != null) { - zone.setFirewallProvider(Network.Provider.JuniperSRX.getName()); - zone.setUserDataProvider(Network.Provider.DhcpServer.getName()); - zone.setVpnProvider(null); - - if (zone.getGatewayProvider() == null || !zone.getGatewayProvider().equals(Network.Provider.ExternalGateWay)) { - zone.setGatewayProvider(Network.Provider.JuniperSRX.getName()); - } - - if (zone.getDnsProvider() == null || !zone.getDnsProvider().equals(Network.Provider.ExternalDhcpServer)) { - zone.setDnsProvider(Network.Provider.DhcpServer.getName()); - } - - if (zone.getDhcpProvider() == null || !zone.getDhcpProvider().equals(Network.Provider.ExternalDhcpServer)) { - zone.setDhcpProvider(Network.Provider.DhcpServer.getName()); - } - - if (zone.getLoadBalancerProvider() == null || !zone.getLoadBalancerProvider().equals(Network.Provider.F5BigIp.getName())) { - zone.setLoadBalancerProvider(Network.Provider.None.getName()); - } - - _dcDao.update(zone.getId(), zone); - return externalFirewall; - } else { - return null; - } - } - - @Override - public boolean deleteExternalFirewall(DeleteExternalFirewallCmd cmd) { - long hostId = cmd.getId(); - User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); - HostVO externalFirewall = _hostDao.findById(hostId); - if (externalFirewall == null) { - throw new InvalidParameterValueException("Could not find an external firewall with ID: " + hostId); - } - - try { - if (_agentMgr.maintain(hostId) && _agentMgr.deleteHost(hostId, false, false, caller)) { - DataCenterVO zone = _dcDao.findById(externalFirewall.getDataCenterId()); - zone.setFirewallProvider(Network.Provider.VirtualRouter.getName()); - zone.setUserDataProvider(Network.Provider.VirtualRouter.getName()); - zone.setVpnProvider(Network.Provider.VirtualRouter.getName()); - - if (zone.getGatewayProvider() != null && !zone.getGatewayProvider().equals(Network.Provider.ExternalGateWay)) { - zone.setGatewayProvider(Network.Provider.VirtualRouter.getName()); - } - - if (zone.getDnsProvider() != null && !zone.getDnsProvider().equals(Network.Provider.ExternalDhcpServer)) { - zone.setDnsProvider(Network.Provider.VirtualRouter.getName()); - } - - if (zone.getDhcpProvider() != null && !zone.getDhcpProvider().equals(Network.Provider.ExternalDhcpServer)) { - zone.setDhcpProvider(Network.Provider.VirtualRouter.getName()); - } - - if (zone.getLoadBalancerProvider() != null && zone.getLoadBalancerProvider().equals(Network.Provider.None)) { - if (zone.getNetworkType().equals(NetworkType.Advanced)) { - zone.setLoadBalancerProvider(Network.Provider.VirtualRouter.getName()); - } else if (zone.getNetworkType().equals(NetworkType.Basic)) { - zone.setLoadBalancerProvider(null); - } - } - - return _dcDao.update(zone.getId(), zone); - } else { - return false; - } - } catch (AgentUnavailableException e) { - s_logger.debug(e); - return false; - } - } - - @Override - public List listExternalFirewalls(ListExternalFirewallsCmd cmd) { - long zoneId = cmd.getZoneId(); - return _hostDao.listByTypeDataCenter(Host.Type.ExternalFirewall, zoneId); - } - - @Override - public ExternalFirewallResponse getApiResponse(Host externalFirewall) { - Map fwDetails = _detailsDao.findDetails(externalFirewall.getId()); - ExternalFirewallResponse response = new ExternalFirewallResponse(); - response.setId(externalFirewall.getId()); - response.setIpAddress(externalFirewall.getPrivateIpAddress()); - response.setUsername(fwDetails.get("username")); - response.setPublicInterface(fwDetails.get("publicInterface")); - response.setUsageInterface(fwDetails.get("usageInterface")); - response.setPrivateInterface(fwDetails.get("privateInterface")); - response.setPublicZone(fwDetails.get("publicZone")); - response.setPrivateZone(fwDetails.get("privateZone")); - response.setNumRetries(fwDetails.get("numRetries")); - response.setTimeout(fwDetails.get("timeout")); - return response; - } - - @Override - public boolean manageGuestNetwork(boolean add, Network network, NetworkOffering offering) throws ResourceUnavailableException { - if (network.getTrafficType() != TrafficType.Guest) { - s_logger.trace("JuniperSrxManager can only add/remove guest networks."); - return false; - } - - // Find the external firewall in this zone - long zoneId = network.getDataCenterId(); - DataCenterVO zone = _dcDao.findById(zoneId); - HostVO externalFirewall = getExternalNetworkAppliance(zoneId, Host.Type.ExternalFirewall); - - if (externalFirewall == null) { - return false; - } - - Account account = _accountDao.findByIdIncludingRemoved(network.getAccountId()); - boolean sharedSourceNat = offering.isSharedSourceNatService(); - String sourceNatIp = null; - if (!sharedSourceNat) { - // Get the source NAT IP address for this network - List sourceNatIps = _networkMgr.listPublicIpAddressesInVirtualNetwork(network.getAccountId(), zoneId, true, null); - - if (sourceNatIps.size() != 1) { - String errorMsg = "JuniperSrxManager was unable to find the source NAT IP address for account " + account.getAccountName(); - return true; - } else { - sourceNatIp = sourceNatIps.get(0).getAddress().addr(); - } - } - - // Send a command to the external firewall to implement or shutdown the guest network - long guestVlanTag = Long.parseLong(network.getBroadcastUri().getHost()); - String guestVlanGateway = network.getGateway(); - String guestVlanNetmask = NetUtils.cidr2Netmask(network.getCidr()); - - // Get network rate - Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null); - - IpAddressTO ip = new IpAddressTO(network.getAccountId(), sourceNatIp, add, false, !sharedSourceNat, String.valueOf(guestVlanTag), guestVlanGateway, guestVlanNetmask, null, null, networkRate, false); - IpAddressTO[] ips = new IpAddressTO[1]; - ips[0] = ip; - IpAssocCommand cmd = new IpAssocCommand(ips); - Answer answer = _agentMgr.easySend(externalFirewall.getId(), cmd); - - if (answer == null || !answer.getResult()) { - String action = add ? "implement" : "shutdown"; - String answerDetails = (answer != null) ? answer.getDetails() : "answer was null"; - String msg = "JuniperSrxManager was unable to " + action + " the guest network on the external firewall in zone " + zone.getName() + " due to " + answerDetails; - s_logger.error(msg); - throw new ResourceUnavailableException(msg, DataCenter.class, zoneId); - } - - List reservedIpAddressesForGuestNetwork = _nicDao.listIpAddressInNetwork(network.getId()); - if (add && (!reservedIpAddressesForGuestNetwork.contains(network.getGateway()))) { - // Insert a new NIC for this guest network to reserve the gateway address - NicVO nic = new NicVO(null, null, network.getId(), null); - nic.setIp4Address(network.getGateway()); - nic.setReservationStrategy(ReservationStrategy.PlaceHolder); - nic.setState(State.Reserved); - _nicDao.persist(nic); - } - - String action = add ? "implemented" : "shut down"; - s_logger.debug("JuniperSrxManager has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() + ") with VLAN tag " + guestVlanTag); - - return true; - } - - @Override - public boolean applyFirewallRules(Network network, List rules) throws ResourceUnavailableException { - // Find the external firewall in this zone - long zoneId = network.getDataCenterId(); - DataCenterVO zone = _dcDao.findById(zoneId); - HostVO externalFirewall = getExternalNetworkAppliance(zoneId, Host.Type.ExternalFirewall); - - if (externalFirewall == null) { - return false; - } - - if (network.getState() == Network.State.Allocated) { - s_logger.debug("JuniperSrxManager was asked to apply firewall rules for network with ID " + network.getId() + "; this network is not implemented. Skipping backend commands."); - return true; - } - - List staticNatRules = new ArrayList(); - List portForwardingRules = new ArrayList(); - - for (FirewallRule rule : rules) { - IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - if (rule.getPurpose() == Purpose.StaticNat) { - StaticNatRule staticNatRule = (StaticNatRule) rule; - StaticNatRuleTO ruleTO = new StaticNatRuleTO(staticNatRule, sourceIp.getAddress().addr(), staticNatRule.getDestIpAddress()); - staticNatRules.add(ruleTO); - } else if (rule.getPurpose() == Purpose.PortForwarding) { - PortForwardingRuleTO ruleTO = new PortForwardingRuleTO((PortForwardingRule) rule, null, sourceIp.getAddress().addr()); - portForwardingRules.add(ruleTO); - } - } - - // Apply static nat rules - applyStaticNatRules(staticNatRules, zone, externalFirewall.getId()); - - // apply port forwarding rules - applyPortForwardingRules(portForwardingRules, zone, externalFirewall.getId()); - - return true; - } - - protected void applyStaticNatRules(List staticNatRules, DataCenter zone, long externalFirewallId) throws ResourceUnavailableException { - if (!staticNatRules.isEmpty()) { - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(staticNatRules); - Answer answer = _agentMgr.easySend(externalFirewallId, cmd); - if (answer == null || !answer.getResult()) { - String details = (answer != null) ? answer.getDetails() : "details unavailable"; - String msg = "JuniperSrxManager was unable to apply static nat rules to the SRX appliance in zone " + zone.getName() + " due to: " + details + "."; - s_logger.error(msg); - throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId()); - } - } - } - - protected void applyPortForwardingRules(List portForwardingRules, DataCenter zone, long externalFirewallId) throws ResourceUnavailableException { - if (!portForwardingRules.isEmpty()) { - SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(portForwardingRules); - Answer answer = _agentMgr.easySend(externalFirewallId, cmd); - if (answer == null || !answer.getResult()) { - String details = (answer != null) ? answer.getDetails() : "details unavailable"; - String msg = "JuniperSrxManager was unable to apply port forwarding rules to the SRX appliance in zone " + zone.getName() + " due to: " + details + "."; - s_logger.error(msg); - throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId()); - } - } - } - - @Override - public boolean applyIps(Network network, List ipAddresses) throws ResourceUnavailableException { - return true; - } - -}