lib/vagrant-softlayer/util/load_balancer.rb
module VagrantPlugins
module SoftLayer
module Util
# This mixin contains utility methods for load balancer management.
module LoadBalancer
# Whether load balancer management is enabled or not.
def enabled?
if @env[:machine].provider_config.load_balancers.empty?
@logger.debug("No load balancer has been defined. Going ahead.")
return false
end
# Currently we don't do load balancing for private machines.
if @env[:machine].provider_config.private_only
@logger.info("Load balancing doesn't work for private machines. Going ahead.")
return false
end
true
end
# Get existing stuff.
def read_load_balancers
mask = [
"id",
"ipAddress.ipAddress",
"virtualServers.serviceGroups.services.groupReferences",
"virtualServers.serviceGroups.services.healthChecks"
].join(",")
@logger.debug("Looking for existing load balancers.")
@load_balancers = sl_warden { @services["Account"].object_mask("mask[#{mask}]").getAdcLoadBalancers }
@logger.debug("Got load balancer configuration:")
@logger.debug("-- #{@load_balancers}")
end
# For each load balancer, check if total connections
# are less than 100% and, if so, rebalance the allocations.
def rebalance!
read_load_balancers
@load_balancers.each do |load_balancer|
next if load_balancer["virtualServers"].empty?
next if 100 == load_balancer["virtualServers"].inject(0) { |sum, vs| sum += vs["allocation"] }
# Create allocation slots.
count = load_balancer["virtualServers"].count
allocation = [100 / count] * count
(100 % count).times { |i| allocation[i] += 1 }
# Rebalance allocations.
load_balancer["virtualServers"].each do |vs|
vs["allocation"] = allocation.pop
end
# Update the VIP object.
@logger.debug("Rebalancing VIP #{load_balancer['id']}")
@logger.debug("-- #{load_balancer}")
@services["VirtualIpAddress"].object_with_id(load_balancer["id"]).editObject("virtualServers" => load_balancer["virtualServers"])
end
end
# Initial setup.
def setup
# A plethora of service objects is required for managing
# load balancers. We instanciate'em all here.
@services = { "Account" => @env[:sl_client]["SoftLayer_Account"] }
[
"Health_Check_Type",
"Routing_Method",
"Routing_Type",
"Service",
"Service_Group",
"VirtualIpAddress",
"VirtualServer"
].each { |service| @services[service] = @env[:sl_client]["SoftLayer_Network_Application_Delivery_Controller_LoadBalancer_#{service}"] }
# We create enumerations for the various configurables.
@enums = {}
[
"Health_Check_Type",
"Routing_Method",
"Routing_Type"
].each do |service|
{}.tap do |enum|
sl_warden { @services[service].getAllObjects }.each do |record|
enum[record["name"].upcase] = record["id"]
end
@enums[service] = enum
end
end
read_load_balancers
end
end
end
end
end