diff --git a/core/src/com/cloud/network/resource/NetscalerMPXResource.java b/core/src/com/cloud/network/resource/NetscalerMPXResource.java index 3c25a83feb1..2a0f49b5fb3 100644 --- a/core/src/com/cloud/network/resource/NetscalerMPXResource.java +++ b/core/src/com/cloud/network/resource/NetscalerMPXResource.java @@ -211,6 +211,8 @@ 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); } @@ -221,7 +223,7 @@ public class NetscalerMPXResource implements ServerResource { } protected Answer execute(MaintainCommand cmd) { - return new MaintainAnswer(cmd); + return new MaintainAnswer(cmd, "Put host in maintaince"); } private synchronized Answer execute(IpAssocCommand cmd, int numRetries) { @@ -259,33 +261,14 @@ public class NetscalerMPXResource implements ServerResource { } private synchronized Answer execute(LoadBalancerConfigCommand cmd, int numRetries) { - try { - String lbProtocol; - String lbMethod; + try { LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers(); for (LoadBalancerTO loadBalancer : loadBalancers) { - - if (loadBalancer.getProtocol() == null) { - lbProtocol = "TCP"; - } else if (loadBalancer.getProtocol().equals(NetUtils.TCP_PROTO)){ - lbProtocol = "TCP"; - } else if (loadBalancer.getProtocol().equals(NetUtils.UDP_PROTO)) { - lbProtocol = "UDP"; - } else { - throw new ExecutionException("Got invalid protocol: " + loadBalancer.getProtocol()); - } - - if (loadBalancer.getAlgorithm().equals("roundrobin")) { - lbMethod = "ROUNDROBIN"; - } else if (loadBalancer.getAlgorithm().equals("leastconn")) { - lbMethod = "LEASTCONNECTION"; - } else { - throw new ExecutionException("Got invalid load balancing algorithm: " + loadBalancer.getAlgorithm()); - } - String srcIp = loadBalancer.getSrcIp(); - int srcPort = loadBalancer.getSrcPort(); + int srcPort = loadBalancer.getSrcPort(); + String lbProtocol = loadBalancer.getProtocol(); + String lbAlgorithm = loadBalancer.getAlgorithm(); String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort, lbProtocol); boolean destinationsToAdd = false; @@ -299,10 +282,7 @@ public class NetscalerMPXResource implements ServerResource { if (!loadBalancer.isRevoked() && destinationsToAdd) { // create a load balancing virtual server - addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbMethod, lbProtocol); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Created load balancing virtual server " + nsVirtualServerName + " on the Netscaler device"); - } + addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol); for (DestinationTO destination : loadBalancer.getDestinations()) { @@ -360,13 +340,13 @@ public class NetscalerMPXResource implements ServerResource { // delete the binding apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(nsService, binding); if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to delete the binding between the virtual server: " + nsVirtualServerName + " and service:" + nsServiceName); + throw new ExecutionException("Failed to delete the binding between the virtual server: " + nsVirtualServerName + " and service:" + nsServiceName + " due to" + apiCallResult.message); } // delete the service apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(nsService, nsServiceName); if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to delete service: " + nsServiceName); + throw new ExecutionException("Failed to delete service: " + nsServiceName + " due to " + apiCallResult.message); } // delete the server if there is no associated services @@ -374,7 +354,7 @@ public class NetscalerMPXResource implements ServerResource { if ((services == null) || (services.length == 0)) { apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(nsService, nsServerName); if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to remove server:" + nsServerName); + throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message); } } } @@ -383,8 +363,8 @@ public class NetscalerMPXResource implements ServerResource { } } } else { - // delete the deployed load balancing rule and its destinations - lbvserver lbserver = lbvserver.get(nsService, nsVirtualServerName); + // delete the implemented load balancing rule and its destinations + lbvserver lbserver = getVirtualServerIfExisits(nsVirtualServerName); if (lbserver == null) { throw new ExecutionException("Failed to find virtual server with name:" + nsVirtualServerName); } @@ -396,7 +376,7 @@ public class NetscalerMPXResource implements ServerResource { String serviceName = binding.get_servicename(); apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(nsService, binding); if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to unbind servic from the lb virtual server: " + nsVirtualServerName); + throw new ExecutionException("Failed to unbind service from the lb virtual server: " + nsVirtualServerName + " due to " + apiCallResult.message); } com.citrix.netscaler.nitro.resource.config.basic.service svc = com.citrix.netscaler.nitro.resource.config.basic.service.get(nsService, serviceName); @@ -410,7 +390,7 @@ public class NetscalerMPXResource implements ServerResource { if ((services == null) || (services.length == 0)) { apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(nsService, nsServerName); if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to remove server:" + nsServerName); + throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message); } } } @@ -546,9 +526,10 @@ public class NetscalerMPXResource implements ServerResource { } } } catch (nitro_exception e) { - throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage()); + throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device"); } catch (Exception e) { - throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage()); + s_logger.error(e); + throw new ExecutionException(e.getMessage()); } } @@ -581,6 +562,20 @@ public class NetscalerMPXResource implements ServerResource { } } + private lbvserver getVirtualServerIfExisits(String lbVServerName ) throws ExecutionException { + try { + return lbvserver.get(nsService, lbVServerName); + } catch (nitro_exception e) { + if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { + return null; + } else { + throw new ExecutionException(e.getMessage()); + } + } catch (Exception e) { + throw new ExecutionException(e.getMessage()); + } + } + private boolean nsServiceExists(String serviceName) throws ExecutionException { try { if (com.citrix.netscaler.nitro.resource.config.basic.service.get(nsService, serviceName) != null) { @@ -644,7 +639,7 @@ public class NetscalerMPXResource implements ServerResource { // remove the server apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(nsService, server.get_name()); if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to remove server:" + server.get_name()); + throw new ExecutionException("Failed to remove server:" + server.get_name()+ " due to " + apiCallResult.message); } } } @@ -655,15 +650,45 @@ public class NetscalerMPXResource implements ServerResource { private void addLBVirtualServer(String virtualServerName, String srcIp, int srcPort, String lbMethod, String lbProtocol) throws ExecutionException { try { - lbvserver vserver = new lbvserver(); + + if (lbProtocol == null) { + lbProtocol = "TCP"; + } else if (lbProtocol.equals(NetUtils.TCP_PROTO)){ + lbProtocol = "TCP"; + } else if (lbProtocol.equals(NetUtils.UDP_PROTO)) { + lbProtocol = "UDP"; + } else { + throw new ExecutionException("Got invalid protocol: " + lbProtocol); + } + + if (lbMethod.equals("roundrobin")) { + lbMethod = "ROUNDROBIN"; + } else if (lbMethod.equals("leastconn")) { + lbMethod = "LEASTCONNECTION"; + } else { + throw new ExecutionException("Got invalid load balancing algorithm: " + lbMethod); + } + + boolean vserverExisis = false; + lbvserver vserver = getVirtualServerIfExisits(virtualServerName); + if (vserver == null) { + vserver = new lbvserver(); + } else { + vserverExisis = true; + } vserver.set_name(virtualServerName); vserver.set_ipv46(srcIp); vserver.set_port(srcPort); vserver.set_servicetype(lbProtocol); vserver.set_lbmethod(lbMethod); - apiCallResult = lbvserver.add(nsService,vserver); + + if (vserverExisis) { + apiCallResult = lbvserver.update(nsService,vserver); + } else { + apiCallResult = lbvserver.add(nsService,vserver); + } if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to create new virtual server:" + virtualServerName); + throw new ExecutionException("Failed to create new virtual server:" + virtualServerName+ " due to " + apiCallResult.message); } } catch (nitro_exception e) { if (e.getErrorCode() != NitroError.NS_RESOURCE_EXISTS) { @@ -682,10 +707,14 @@ public class NetscalerMPXResource implements ServerResource { } apiCallResult = lbvserver.delete(nsService, vserver); if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Failed to remove virtual server:" + virtualServerName); + throw new ExecutionException("Failed to remove virtual server:" + virtualServerName + " due to " + apiCallResult.message); } } catch (nitro_exception e) { - throw new ExecutionException("Failed to remove virtual server:" + virtualServerName +" due to " + e.getMessage()); + if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) { + return; + } else { + throw new ExecutionException("Failed remove virtual server:" + virtualServerName +" due to " + e.getMessage()); + } } catch (Exception e) { throw new ExecutionException("Failed to remove virtual server:" + virtualServerName +" due to " + e.getMessage()); } @@ -695,7 +724,7 @@ public class NetscalerMPXResource implements ServerResource { try { apiCallResult = nsconfig.save(nsService); if (apiCallResult.errorcode != 0) { - throw new ExecutionException("Error occured while saving configuration changes to Netscaler device due to error:" + apiCallResult.errorcode); + throw new ExecutionException("Error occured while saving configuration changes to Netscaler device due to " + apiCallResult.message); } } catch (nitro_exception e) { throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage());