package org.openstack.atlas.adapter.stm;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openstack.atlas.adapter.LoadBalancerEndpointConfiguration;
import org.openstack.atlas.adapter.exceptions.InsufficientRequestException;
import org.openstack.atlas.adapter.exceptions.RollBackException;
import org.openstack.atlas.adapter.exceptions.StmRollBackException;
import org.openstack.atlas.adapter.helpers.CustomMappings;
import org.openstack.atlas.adapter.helpers.IpHelper;
import org.openstack.atlas.adapter.helpers.ResourceTranslator;
import org.openstack.atlas.adapter.helpers.ZxtmNameBuilder;
import org.openstack.atlas.adapter.service.ReverseProxyLoadBalancerStmAdapter;
import org.openstack.atlas.service.domain.entities.*;
import org.openstack.atlas.service.domain.pojos.Stats;
import org.openstack.atlas.service.domain.pojos.ZeusSslTermination;
import org.openstack.atlas.service.domain.util.Constants;
import org.openstack.atlas.service.domain.util.StringUtilities;
import org.rackspace.stingray.client.StingrayRestClient;
import org.rackspace.stingray.client.counters.VirtualServerStats;
import org.rackspace.stingray.client.exception.StingrayRestClientException;
import org.rackspace.stingray.client.exception.StingrayRestClientObjectNotFoundException;
import org.rackspace.stingray.client.pool.Pool;
import org.rackspace.stingray.client.ssl.keypair.Keypair;
import org.rackspace.stingray.client.traffic.ip.TrafficIp;
import org.rackspace.stingray.client.util.EnumFactory;
import org.rackspace.stingray.client.virtualserver.VirtualServer;
import org.rackspace.stingray.client.virtualserver.VirtualServerHttp;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import org.openstack.atlas.util.debug.Debug;
@Component
public class StmAdapterImpl implements ReverseProxyLoadBalancerStmAdapter {
public static Log LOG = LogFactory.getLog(StmAdapterImpl.class.getName());
private StmAdapterResources resources;
/*
Load Balancer Resources
*/
public StmAdapterResources getResources() {
if (resources == null)
resources = new StmAdapterResources();
return resources;
}
@Override
public void createLoadBalancer(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer)
throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
String vsName = ZxtmNameBuilder.genVSName(loadBalancer);
String vsRedirectName = ZxtmNameBuilder.genRedirectVSName(loadBalancer);
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
translator.translateLoadBalancerResource(config, vsName, loadBalancer, loadBalancer);
try {
getResources().createPersistentClasses(config);
if (loadBalancer.getHealthMonitor() != null && !loadBalancer.hasSsl()) {
getResources().updateHealthMonitor(client, vsName, translator.getcMonitor());
}
if ((loadBalancer.getAccessLists() != null && !loadBalancer.getAccessLists().isEmpty())
|| loadBalancer.getConnectionLimit() != null) {
getResources().updateProtection(client, vsName, translator.getcProtection());
}
getResources().updateVirtualIps(client, vsName, translator.getcTrafficIpGroups());
getResources().updatePool(client, vsName, translator.getcPool());
getResources().updateVirtualServer(client, vsName, translator.getcVServer());
if (loadBalancer.isHttpsRedirect() != null && loadBalancer.isHttpsRedirect()) {
getResources().updateVirtualServer(client, vsRedirectName, translator.getcRedirectVServer());
}
client.destroy();
} catch (Exception e) {
LOG.error(String.format("Failed to create load balancer %s, rolling back...", loadBalancer.getId()));
deleteLoadBalancer(config, loadBalancer);
throw new StmRollBackException(String.format("Failed to create load balancer %s", loadBalancer.getId()), e);
}
}
@Override
public void updateLoadBalancer(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, LoadBalancer queLb, UserPages up)
throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
String vsName = ZxtmNameBuilder.genVSName(loadBalancer);
String vsRedirectName = ZxtmNameBuilder.genRedirectVSName(loadBalancer);
try {
translator.translateLoadBalancerResource(config, vsName, loadBalancer, queLb);
if (queLb.getHealthMonitor() != null && !loadBalancer.hasSsl()) {
getResources().updateHealthMonitor(client, vsName, translator.getcMonitor());
}
if ((queLb.getAccessLists() != null && !queLb.getAccessLists().isEmpty())
|| queLb.getConnectionLimit() != null) {
getResources().updateProtection(client, vsName, translator.getcProtection());
}
if ((queLb.getLoadBalancerJoinVip6Set() != null && !queLb.getLoadBalancerJoinVip6Set().isEmpty())
|| (queLb.getLoadBalancerJoinVipSet() != null && !queLb.getLoadBalancerJoinVipSet().isEmpty())) {
getResources().updateVirtualIps(client, vsName, translator.getcTrafficIpGroups());
}
UserPages userPages = queLb.getUserPages();
if (userPages != null) {
if (userPages.getErrorpage() != null) {
setErrorFile(config, loadBalancer, loadBalancer.getUserPages().getErrorpage());
}
}
if (loadBalancer.isUsingSsl()) {
//Handle SSLTerm https-redirect
if (queLb.isHttpsRedirect() != null && queLb.isHttpsRedirect()) {
getResources().updateVirtualServer(client, vsName, translator.getcRedirectVServer());
} else {
getResources().updatePool(client, vsName, translator.getcPool());
getResources().updateVirtualServer(client, vsName, translator.getcVServer());
}
//Handle SSLTerm LB
String secureVsName = ZxtmNameBuilder.genSslVSName(loadBalancer);
translator.translateLoadBalancerResource(config, secureVsName, loadBalancer, queLb);
getResources().updateVirtualServer(client, secureVsName, translator.getcVServer());
} else {
//Handle non-SSLTerm (normal) LB
getResources().updatePool(client, vsName, translator.getcPool());
getResources().updateVirtualServer(client, vsName, translator.getcVServer());
//Handle non-SSLTerm https-redirect
if (queLb.isHttpsRedirect() != null && queLb.isHttpsRedirect()) {
getResources().updateVirtualServer(client, vsRedirectName, translator.getcRedirectVServer());
} else {
getResources().deleteVirtualServer(client, vsRedirectName);
getResources().deletePool(client, vsRedirectName);
}
}
} catch (Exception ex) {
client.destroy();
LOG.error("Exception updating load balancer: " + ex);
throw new StmRollBackException("Failed to update loadbalancer", ex);
}
client.destroy();
}
@Override
public void deleteLoadBalancer(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
String vsName = ZxtmNameBuilder.genVSName(loadBalancer);
String vsRedirectName = ZxtmNameBuilder.genRedirectVSName(loadBalancer);
String errorPageName = ZxtmNameBuilder.generateErrorPageName(vsName);
LOG.debug(String.format("Removing loadbalancer: %s ...", vsName));
getResources().deleteRateLimit(config, loadBalancer, vsName);
getResources().deleteHealthMonitor(client, vsName);
getResources().deleteProtection(client, vsName);
deleteVirtualIps(config, loadBalancer);
getResources().deletePool(client, vsName);
getResources().deleteVirtualServer(client, vsName);
if (loadBalancer.hasSsl()) {
getResources().deleteVirtualServer(client, ZxtmNameBuilder.genSslVSName(loadBalancer));
}
if (loadBalancer.isHttpsRedirect() != null && loadBalancer.isHttpsRedirect()) {
getResources().deleteVirtualServer(client, vsRedirectName);
}
try {
client.deleteExtraFile(errorPageName);
} catch (Exception ignoredException) {}
client.destroy();
LOG.debug(String.format("Successfully removed loadbalancer: %s from the STM service...", vsName));
}
/*
Pool Resources
*/
@Override
public void setNodes(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer)
throws InsufficientRequestException, StmRollBackException {
String poolName = ZxtmNameBuilder.genVSName(loadBalancer);
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
StingrayRestClient client = getResources().loadSTMRestClient(config);
translator.translatePoolResource(poolName, loadBalancer, loadBalancer);
LOG.info(String.format("Setting nodes to pool '%s'", poolName));
getResources().updatePool(client, poolName, translator.getcPool());
LOG.info(String.format("Successfully added nodes to pool '%s'", poolName));
client.destroy();
}
@Override
public void removeNodes(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, List<Node> doomedNodes) throws InsufficientRequestException, StmRollBackException {
String poolName = ZxtmNameBuilder.genVSName(loadBalancer);
StingrayRestClient client = getResources().loadSTMRestClient(config);
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
Set<Node> currentNodes = loadBalancer.getNodes();
Map<Integer, Node> nodesMap = new HashMap<Integer, Node>();
for (Node currentNode : currentNodes) {
nodesMap.put(currentNode.getId(), currentNode);
}
for (Node doomedNode : doomedNodes) {
Integer id = doomedNode.getId();
if (nodesMap.containsKey(id)) {
currentNodes.remove(nodesMap.get(id));
}
}
Pool cpool = getResources().getPool(client, poolName);
cpool.getProperties().getBasic().getNodes().remove(doomedNodes.get(0).getIpAddress() + ":" + doomedNodes.get(0).getPort());
// cpool.getProperties().getLoad_balancing().getNode_weighting().get(0)
loadBalancer.setNodes(currentNodes);
translator.translatePoolResource(poolName, loadBalancer, loadBalancer);
LOG.info(String.format("Removing nodes from pool '%s'", poolName));
getResources().updatePool(client, poolName, translator.getcPool());
LOG.info(String.format("Successfully removed nodes from pool '%s'", poolName));
client.destroy();
}
@Override
public void removeNode(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, Node nodeToDelete) throws InsufficientRequestException, StmRollBackException {
List<Node> doomedNodes = new ArrayList<Node>();
doomedNodes.add(nodeToDelete);
removeNodes(config, loadBalancer, doomedNodes);
}
/*
VirtualIP Resources
*/
@Override
public void updateVirtualIps(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
String vsName = ZxtmNameBuilder.genVSName(loadBalancer);
translator.translateLoadBalancerResource(config, vsName, loadBalancer, loadBalancer);
LOG.debug(String.format("Updating virtual ips for virtual server %s", vsName));
getResources().updateVirtualIps(client, vsName, translator.getcTrafficIpGroups());
LOG.debug(String.format("Updating virtual server %s for virtual ip configuration update", vsName));
getResources().updateVirtualServer(client, vsName, translator.getcVServer());
LOG.info(String.format("Successfully updated virtual ips for virtual server %s", vsName));
client.destroy();
}
@Override
public void deleteVirtualIps(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, List<Integer> vipIds, UserPages up) throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
String vsName;
vsName = ZxtmNameBuilder.genVSName(loadBalancer);
//Lazy loading...
loadBalancer.setUserPages(up);
translator.translateLoadBalancerResource(config, vsName, loadBalancer, loadBalancer, false);
Map<String, TrafficIp> curTigMap = translator.getcTrafficIpGroups();
Set<LoadBalancerJoinVip> jvipsToRemove = new HashSet<LoadBalancerJoinVip>();
Set<LoadBalancerJoinVip6> jvips6ToRemove = new HashSet<LoadBalancerJoinVip6>();
//Remove vips to remove from lb and translate...
for (int id : vipIds) {
for (LoadBalancerJoinVip jvip : loadBalancer.getLoadBalancerJoinVipSet()) {
if (jvip.getVirtualIp().getId() == id) {
jvipsToRemove.add(jvip);
}
}
for (LoadBalancerJoinVip6 jvip : loadBalancer.getLoadBalancerJoinVip6Set()) {
if (jvip.getVirtualIp().getId() == id) {
jvips6ToRemove.add(jvip);
}
}
}
if (!jvipsToRemove.isEmpty()) loadBalancer.getLoadBalancerJoinVipSet().removeAll(jvipsToRemove);
if (!jvips6ToRemove.isEmpty()) loadBalancer.getLoadBalancerJoinVip6Set().removeAll(jvips6ToRemove);
translator.translateLoadBalancerResource(config, vsName, loadBalancer, loadBalancer, false);
// After translating, we need to add the vips back into the LB object so that the Listener can properly remove them from the DB
if (!jvipsToRemove.isEmpty()) loadBalancer.getLoadBalancerJoinVipSet().addAll(jvipsToRemove);
if (!jvips6ToRemove.isEmpty()) loadBalancer.getLoadBalancerJoinVip6Set().addAll(jvips6ToRemove);
String vipsToRemove = StringUtilities.DelimitString(vipIds, ",");
Map<String, TrafficIp> removeTigMap = translator.getcTrafficIpGroups();
Set<String> tigsToRemove = new HashSet<String>(curTigMap.keySet());
tigsToRemove.removeAll(removeTigMap.keySet());
if (tigsToRemove.isEmpty()) {
LOG.debug(String.format("Could not remove vip(s) %s for loadbalancer %s assuming vip is already deleted...", vipsToRemove, loadBalancer.getId()));
return;
}
String tname = null;
try {
LOG.debug(String.format("Attempting to update traffic ip configuration and remove vips %s for virtual server %s", vipsToRemove, vsName));
tname = null;
for (String tigname : tigsToRemove) {
tname = tigname;
LOG.debug(String.format("Removing virtual ip %s...", tigname));
client.deleteTrafficIp(tigname);
LOG.info(String.format("Successfully removed virtual ip %s...", tigname));
}
LOG.debug(String.format("Updating virtual server %s for updated virtual ip configuration..", vsName));
getResources().updateVirtualServer(client, vsName, translator.getcVServer());
LOG.info(String.format("Successfully updated traffic ip configuration and removed vips %s for virtual server %s", vipsToRemove, vsName));
} catch (StingrayRestClientObjectNotFoundException e) {
LOG.error(String.format("Object not found when removing virtual ip: %s for virtual server %s, continue...", tname, vsName));
} catch (Exception ex) {
String em = String.format("Error removing virtual ips for vs: %s ... \n Exception: %s",
vsName, ex);
LOG.error(em);
if (!curTigMap.isEmpty()) {
LOG.debug(String.format("Attempting to roll back to previous virtual ips: %s for virtual server %s", vipsToRemove, vsName));
getResources().updateVirtualIps(client, vsName, curTigMap);
LOG.info(String.format("Successfully rolled back to previous virtual ips: %s for virtual server %s", vipsToRemove, vsName));
}
throw new StmRollBackException(em, ex);
}
client.destroy();
}
protected void deleteVirtualIps(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StmRollBackException {
List<Integer> vipIds = new ArrayList<Integer>();
Set<LoadBalancerJoinVip> jvipset = loadBalancer.getLoadBalancerJoinVipSet();
Set<LoadBalancerJoinVip6> jvip6set = loadBalancer.getLoadBalancerJoinVip6Set();
for (LoadBalancerJoinVip jv : jvipset) {
vipIds.add(jv.getVirtualIp().getId());
}
for (LoadBalancerJoinVip6 jv : jvip6set) {
vipIds.add(jv.getVirtualIp().getId());
}
deleteVirtualIps(config, loadBalancer, vipIds, null);
}
/*
Monitor Resources
*/
@Override
public void updateHealthMonitor(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer)
throws InsufficientRequestException, StmRollBackException {
String vsName = ZxtmNameBuilder.genVSName(loadBalancer);
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
StingrayRestClient client = getResources().loadSTMRestClient(config);
translator.translateLoadBalancerResource(config, vsName, loadBalancer, loadBalancer);
getResources().updateHealthMonitor(client, vsName, translator.getcMonitor());
getResources().updatePool(client, vsName, translator.getcPool());
client.destroy();
}
@Override
public void deleteHealthMonitor(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StmRollBackException {
final String monitorName = ZxtmNameBuilder.genVSName(loadBalancer);
StingrayRestClient client = getResources().loadSTMRestClient(config);
getResources().deleteHealthMonitor(client, monitorName);
client.destroy();
}
/*
Protection Resources
*/
@Override
public void updateProtection(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws StmRollBackException, InsufficientRequestException {
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
StingrayRestClient client = getResources().loadSTMRestClient(config);
String protectionName = ZxtmNameBuilder.genVSName(loadBalancer);
LOG.info(String.format("Updating protection on %s...", protectionName));
getResources().updateProtection(client, protectionName, translator.translateProtectionResource(loadBalancer));
LOG.info(String.format("Successfully created protection %s", protectionName));
client.destroy();
}
@Override
public void deleteProtection(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
String protectionName = ZxtmNameBuilder.genVSName(loadBalancer);
LOG.info(String.format("Deleting protection on %s...", protectionName));
getResources().deleteProtection(client, protectionName);
LOG.info(String.format("Successfully deleted protection %s!", protectionName));
client.destroy();
}
@Override
public void updateAccessList(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StmRollBackException {
if (loadBalancer.getAccessLists() != null && !loadBalancer.getAccessLists().isEmpty()) {
String name = ZxtmNameBuilder.genVSName(loadBalancer);
LOG.info(String.format("Updating Access List on '%s'...", name));
updateProtection(config, loadBalancer);
LOG.info(String.format("Successfully updated Access List on '%s'...", name));
}
}
@Override
public void deleteAccessList(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, List<Integer> accessListToDelete)
throws InsufficientRequestException, StmRollBackException {
Set<AccessList> saveItems = new HashSet<AccessList>();
for (AccessList item : loadBalancer.getAccessLists()) {
if (!accessListToDelete.contains(item.getId())) {
saveItems.add(item);
}
}
loadBalancer.setAccessLists(saveItems);
String name = ZxtmNameBuilder.genVSName(loadBalancer);
LOG.info(String.format("Deleting Access List on '%s'...", name));
if (loadBalancer.getConnectionLimit() != null || !loadBalancer.getAccessLists().isEmpty()) {
updateProtection(config, loadBalancer);
} else {
deleteProtection(config, loadBalancer);
}
LOG.info(String.format("Successfully deleted Access List on '%s'.", name));
}
@Override
public void updateConnectionThrottle(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StmRollBackException {
if (loadBalancer.getConnectionLimit() != null) {
String name = ZxtmNameBuilder.genVSName(loadBalancer);
LOG.info(String.format("Updating Connection Throttling on '%s'...", name));
updateProtection(config, loadBalancer);
LOG.info(String.format("Successfully updated Connection Throttling on '%s'.", name));
}
}
@Override
public void deleteConnectionThrottle(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StmRollBackException {
String name = ZxtmNameBuilder.genVSName(loadBalancer);
LOG.info(String.format("Deleting Connection Throttling on '%s'...", name));
if (loadBalancer.getAccessLists() != null && !loadBalancer.getAccessLists().isEmpty()) {
ConnectionLimit nullConnectionLimit = new ConnectionLimit();
nullConnectionLimit.setRateInterval(1);
nullConnectionLimit.setMaxConnections(0);
nullConnectionLimit.setMinConnections(0);
nullConnectionLimit.setMaxConnectionRate(0);
loadBalancer.setConnectionLimit(nullConnectionLimit);
updateProtection(config, loadBalancer);
} else {
deleteProtection(config, loadBalancer);
}
LOG.info(String.format("Successfully deleted Connection Throttling on '%s'.", name));
}
/*
SSL Termination Resources
*/
@Override
public void updateSslTermination(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, ZeusSslTermination sslTermination, UserPages up) throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
String vsName = ZxtmNameBuilder.genVSName(loadBalancer);
String sslVsName = ZxtmNameBuilder.genSslVSName(loadBalancer);
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
loadBalancer.setUserPages(up);
translator.translateVirtualServerResource(config, sslVsName, loadBalancer);
translator.translateKeypairResource(loadBalancer, true);
VirtualServer createdServer = translator.getcVServer();
VirtualServerHttp http = new VirtualServerHttp();
http.setLocation_rewrite(EnumFactory.Accept_from.NEVER.toString());
createdServer.getProperties().setHttp(http);
if (loadBalancer.isSecureOnly()) {
VirtualServer virtualServer;
try {
virtualServer = client.getVirtualServer(vsName);
} catch (Exception e) {
LOG.error(String.format("Error retrieving non-secure virtual server.\n%s", Debug.getExtendedStackTrace(e)));
throw new StmRollBackException("Error retrieving non-secure virtual server.", e);
}
if (virtualServer != null) {
virtualServer.getProperties().getBasic().setEnabled(false);
getResources().updateVirtualServer(client, vsName, virtualServer);
}
}
Keypair keypair = translator.getcKeypair();
LOG.info(String.format("Updating certificate for load balancer: %s", loadBalancer.getId()));
getResources().updateKeypair(client, sslVsName, keypair);
try {
translator.translateLoadBalancerResource(config, vsName, loadBalancer, loadBalancer);
translator.translateLoadBalancerResource(config, sslVsName, loadBalancer, loadBalancer);
if ((loadBalancer.getAccessLists() != null && !loadBalancer.getAccessLists().isEmpty())
|| loadBalancer.getConnectionLimit() != null) {
getResources().updateProtection(client, vsName, translator.getcProtection());
}
getResources().updateVirtualIps(client, sslVsName, translator.getcTrafficIpGroups());
getResources().updateVirtualServer(client, sslVsName, createdServer);
} catch (Exception ex) {
LOG.error(ex);
throw new StmRollBackException("Failed to update loadbalancer, rolling back...", ex);
}
client.destroy();
}
@Override
public void removeSslTermination(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
String vsName = ZxtmNameBuilder.genSslVSName(loadBalancer);
LOG.debug(String.format("Removing ssl from loadbalancer: %s ...", vsName));
getResources().deleteKeypair(client, vsName);
getResources().deleteVirtualServer(client, vsName);
LOG.debug(String.format("Successfully removed ssl from loadbalancer: %s from the STM service...", vsName));
client.destroy();
}
@Override
public void addSuspension(LoadBalancerEndpointConfiguration config, LoadBalancer lb) throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
String vsName = ZxtmNameBuilder.genVSName(lb);
try {
LOG.info(String.format("Attempting to disable virtual server %s", vsName));
VirtualServer virtualServer = client.getVirtualServer(vsName);
virtualServer.getProperties().getBasic().setEnabled(false);
getResources().updateVirtualServer(client, vsName, virtualServer);
LOG.info(String.format("Successfully disabled virtual server %s", vsName));
if (lb.hasSsl()) {
LOG.info(String.format("Attempting to disable virtual server %s", vsName));
vsName = ZxtmNameBuilder.genSslVSName(lb);
VirtualServer secureServer = client.getVirtualServer(vsName);
secureServer.getProperties().getBasic().setEnabled(false);
getResources().updateVirtualServer(client, vsName, secureServer);
LOG.info(String.format("Successfully disabled virtual server %s", vsName));
}
LOG.info(String.format("Attempting to disable Traffic Ip Groups"));
translator.translateTrafficIpGroupsResource(config, lb, false);
getResources().updateVirtualIps(client, vsName, translator.getcTrafficIpGroups());
LOG.info(String.format("Traffic Ip Groups disabled"));
LOG.info("Successfully added load balancer suspension");
} catch (Exception e) {
LOG.error(String.format("Failed to suspend load balancer operation for load balancer: %s Exception: %s", lb.getId(), e));
throw new StmRollBackException("Failed to suspend loadbalancer", e);
}
client.destroy();
}
@Override
public void removeSuspension(LoadBalancerEndpointConfiguration config, LoadBalancer lb) throws InsufficientRequestException, RollBackException {
StingrayRestClient client;
client = getResources().loadSTMRestClient(config);
ResourceTranslator translator = ResourceTranslator.getNewResourceTranslator();
String vsName = ZxtmNameBuilder.genVSName(lb);
try {
LOG.info(String.format("Attempting to enable virtual server %s", vsName));
VirtualServer virtualServer = client.getVirtualServer(vsName);
virtualServer.getProperties().getBasic().setEnabled(true);
getResources().updateVirtualServer(client, vsName, virtualServer);
LOG.info(String.format("Successfully enabled virtual server %s", vsName));
if (lb.hasSsl()) {
LOG.info(String.format("Attempting to enable virtual server %s", vsName));
vsName = ZxtmNameBuilder.genSslVSName(lb);
VirtualServer secureServer = client.getVirtualServer(vsName);
secureServer.getProperties().getBasic().setEnabled(true);
getResources().updateVirtualServer(client, vsName, secureServer);
LOG.info(String.format("Successfully enabled virtual server %s", vsName));
}
LOG.info(String.format("Attempting to enable Traffic Ip Groups"));
translator.translateTrafficIpGroupsResource(config, lb, true);
getResources().updateVirtualIps(client, vsName, translator.getcTrafficIpGroups());
LOG.info(String.format("Successfully enabled Traffic Ip Groups"));
LOG.info("Successfully removed load balancer suspension");
} catch (Exception e) {
LOG.error(String.format("Failed to remove load balancer suspension for load balancer: %s. Exception: %s", lb.getId(), e));
throw new StmRollBackException("Failed to remove loadbalancer suspension ", e);
}
client.destroy();
}
@Override
public boolean isEndPointWorking(LoadBalancerEndpointConfiguration config) throws StmRollBackException {
try {
StingrayRestClient client = getResources().loadSTMRestClient(config);
client.getPools();
client.destroy();
return true;
} catch (Exception e) {
if (IpHelper.isNetworkConnectionException(e)) {
return false;
}
throw new StmRollBackException("Failed verifying endpoint", e);
}
}
@Override
public void changeHostForLoadBalancer(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, Host newHost) throws InsufficientRequestException, RollBackException {
}
/*
Rate Limit (Bandwidth) Resources
*/
@Override
public void setRateLimit(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, RateLimit rateLimit) throws InsufficientRequestException, StmRollBackException {
if (rateLimit != null) {
loadBalancer.setRateLimit(rateLimit);
getResources().setRateLimit(config, loadBalancer, ZxtmNameBuilder.genVSName(loadBalancer));
} else {
throw new StmRollBackException("Empty or null Rate Limit. Roll back...");
}
}
@Override
public void updateRateLimit(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, RateLimit rateLimit) throws InsufficientRequestException, StmRollBackException {
if (rateLimit != null) {
loadBalancer.setRateLimit(rateLimit);
getResources().updateRateLimit(config, loadBalancer, ZxtmNameBuilder.genVSName(loadBalancer));
} else {
throw new StmRollBackException("Empty or null Rate Limit. Roll back...");
}
}
@Override
public void deleteRateLimit(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StmRollBackException {
getResources().deleteRateLimit(config, loadBalancer, ZxtmNameBuilder.genVSName(loadBalancer));
}
/*
Error File Resources
*/
@Override
public void uploadDefaultErrorFile(LoadBalancerEndpointConfiguration config, String content)
throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
File errorFile = null;
try {
LOG.debug("Attempting to upload the default error file...");
errorFile = getResources().getFileWithContent(content);
client.createExtraFile(Constants.DEFAULT_ERRORFILE, errorFile);
LOG.info("Successfully uploaded the default error file...");
} catch (IOException e) {
LOG.error(String.format("Failed to upload default ErrorFile for %s -- IO exception", config.getEndpointUrl()));
} catch (StingrayRestClientException ce) {
LOG.error(String.format("Failed to upload default ErrorFile for %s -- REST Client exception", config.getEndpointUrl()));
} catch (StingrayRestClientObjectNotFoundException onf) {
LOG.error(String.format("Failed to upload default ErrorFile for %s -- Object not found", config.getEndpointUrl()));
}
if (errorFile != null) //noinspection ResultOfMethodCallIgnored
errorFile.delete();
client.destroy();
}
@Override
public void deleteErrorFile(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, UserPages up)
throws InsufficientRequestException, StmRollBackException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
getResources().deleteErrorFile(config, client, loadBalancer, up);
client.destroy();
}
@Override
public void setErrorFile(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer, String content) throws InsufficientRequestException, StmRollBackException {
if (content != null && !(content.equals(""))) {
StingrayRestClient client = getResources().loadSTMRestClient(config);
getResources().setErrorFile(config, client, loadBalancer, content);
client.destroy();
} else {
throw new StmRollBackException("No content provided for error page. Roll back...");
}
}
@Override
public Stats getVirtualServerStats(LoadBalancerEndpointConfiguration config, LoadBalancer loadBalancer) throws InsufficientRequestException, StingrayRestClientObjectNotFoundException, StingrayRestClientException {
StingrayRestClient client = getResources().loadSTMRestClient(config);
List<VirtualServerStats> sslVirtualServerList = new ArrayList<VirtualServerStats>();
List<VirtualServerStats> virtualServerList = new ArrayList<VirtualServerStats>();
for (URI endpoint : config.getRestStatsEndpoints()) {
if (loadBalancer.isUsingSsl()) {
sslVirtualServerList.add(client.getVirtualServerStats(ZxtmNameBuilder.genSslVSName(loadBalancer), endpoint));
}
virtualServerList.add(client.getVirtualServerStats(ZxtmNameBuilder.genVSName(loadBalancer), endpoint));
}
Stats stats = CustomMappings.mapVirtualServerStatsLists(virtualServerList, sslVirtualServerList);
return stats;
}
/**
* Deprecating these(SubnetMapping calls) as per ops. Unused call that is difficult to test, may support in future if needed... *
*/
// @Override
// public void setSubnetMappings(LoadBalancerEndpointConfiguration config, Hostssubnet hostssubnet) throws StmRollBackException {
// StingrayRestClient client;
// try {
// client = loadSTMRestClient(config);
// List<Hostsubnet> subnetList = hostssubnet.getHostsubnets();
//
// //Loop over Hosts ("dev1.lbaas.mysite.com", "dev2.lbaas.mysite.com", etc)
// for (Hostsubnet hostsubnet : subnetList) {
// String hsName = hostsubnet.getName();
// TrafficManager trafficManager = client.getTrafficManager(hsName);
// List<TrafficManagerTrafficIp> trafficManagerTrafficIpList = new ArrayList<TrafficManagerTrafficIp>();
// List<NetInterface> interfaceList = hostsubnet.getNetInterfaces();
//
// //Loop over interfaces (eth0, eth1, etc)
// for (NetInterface netInterface : interfaceList) {
// List<Cidr> cidrList = netInterface.getCidrs();
// TrafficManagerTrafficIp trafficManagerTrafficIp = new TrafficManagerTrafficIp();
// Set<String> networkList = new HashSet<String>();
//
// // Loop over Cidr list which contains one subnet per Cidr
// for (Cidr cidr : cidrList) {
// networkList.add(cidr.getBlock());
// }
//
// trafficManagerTrafficIp.setName(netInterface.getName());
// trafficManagerTrafficIp.setNetworks(networkList);
// trafficManagerTrafficIpList.add(trafficManagerTrafficIp);
// }
// trafficManager.getProperties().getBasic().setTrafficip(trafficManagerTrafficIpList);
// client.updateTrafficManager(hsName, trafficManager);
// }
// } catch (StingrayRestClientObjectNotFoundException e) {
// throw new StmRollBackException("Failed updating subnet mappings", e);
// } catch (StingrayRestClientException e) {
// throw new StmRollBackException("Failed updating subnet mappings", e);
// }
// }
//
// @Override
// public void deleteSubnetMappings(LoadBalancerEndpointConfiguration config, Hostssubnet hostssubnet) throws StmRollBackException {
// StingrayRestClient client;
// try {
// client = loadSTMRestClient(config);
// List<Hostsubnet> subnetList = hostssubnet.getHostsubnets();
//
// //Loop over Hosts ("dev1.lbaas.mysite.com", "dev2.lbaas.mysite.com", etc)
// for (Hostsubnet hostsubnet : subnetList) {
// String hsName = hostsubnet.getName(); // This name is of the form "dev1.lbaas.mysite.com"
// TrafficManager trafficManager = client.getTrafficManager(hsName);
// List<NetInterface> netInterfaceList = hostsubnet.getNetInterfaces();
// //trafficManagerTrafficIpList is the current list of TrafficIPs for the host
// List<TrafficManagerTrafficIp> trafficManagerTrafficIpList = trafficManager.getProperties().getBasic().getTrafficip();
// Map<String, TrafficManagerTrafficIp> tipsMap = new HashMap<String, TrafficManagerTrafficIp>();
//
// //Loop over tips to compile an indexed list by name
// for (TrafficManagerTrafficIp trafficManagerTrafficIp : trafficManagerTrafficIpList) {
// tipsMap.put(trafficManagerTrafficIp.getName(), trafficManagerTrafficIp);
// }
//
// //Loop over interfaces (eth0, eth1, etc)
// for (NetInterface netInterface : netInterfaceList) {
// String netInterfaceName = netInterface.getName(); //This name is of the form "eth0"
//
// if (tipsMap.containsKey(netInterfaceName)) {
// TrafficManagerTrafficIp tip = tipsMap.get(netInterfaceName);
// Set<String> networkSet = tip.getNetworks();
// List<Cidr> cidrList = netInterface.getCidrs(); //This is the list of objects containing subnet strings
//
// // Loop over Cidr list which contains one subnet per Cidr
// for (Cidr cidr : cidrList) {
// networkSet.remove(cidr.getBlock()); //Remove the subnet if it exists
// }
// }
// }
// client.updateTrafficManager(hsName, trafficManager);
// }
// } catch (StingrayRestClientObjectNotFoundException e) {
// throw new StmRollBackException("Failed removing subnet mappings", e);
// } catch (StingrayRestClientException e) {
// throw new StmRollBackException("Failed removing subnet mappings", e);
// }
// }
//
// @Override
// public Hostssubnet getSubnetMappings(LoadBalancerEndpointConfiguration config, String host) throws StmRollBackException {
// StingrayRestClient client;
// Hostssubnet ret = new Hostssubnet();
// try {
// client = loadSTMRestClient(config);
// TrafficManager trafficManager = client.getTrafficManager(host);
// //trafficManagerTrafficIpList is the current list of TrafficIPs for the host
// List<TrafficManagerTrafficIp> trafficManagerTrafficIpList = trafficManager.getProperties().getBasic().getTrafficip();
// List<Hostsubnet> subnetList = new ArrayList<Hostsubnet>();
// Hostsubnet hostsubnet = new Hostsubnet();
// hostsubnet.setName(host);
//
// //Loop over trafficIPs (== interfaces) (eth0, eth1, etc)
// for (TrafficManagerTrafficIp trafficManagerTrafficIp : trafficManagerTrafficIpList) {
// Set<String> networkSet = trafficManagerTrafficIp.getNetworks();
// NetInterface netInterface = new NetInterface();
// List<Cidr> cidrs = new ArrayList<Cidr>();
//
// //Loop over networks (== cidr blocks)
// for (String block : networkSet) {
// Cidr cidr = new Cidr();
// cidr.setBlock(block);
// cidrs.add(cidr);
// }
//
// netInterface.setName(trafficManagerTrafficIp.getName());
// netInterface.setCidrs(cidrs);
// hostsubnet.getNetInterfaces().add(netInterface);
// }
// subnetList.add(hostsubnet);
// ret.setHostsubnets(subnetList);
// } catch (StingrayRestClientObjectNotFoundException e) {
// throw new StmRollBackException("Failed retrieving subnet mappings", e);
// } catch (StingrayRestClientException e) {
// throw new StmRollBackException("Failed retrieving subnet mappings", e);
// }
// return ret;
// }
}