blob: 53faac081a266155a055147b3d39de4eb055f9af [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from libcloud.utils.py3 import httplib
from libcloud.utils.misc import reverse_dict
from libcloud.common.brightbox import BrightboxConnection
from libcloud.loadbalancer.base import Driver, Member, Algorithm, LoadBalancer
from libcloud.loadbalancer.types import State
API_VERSION = "1.0"
class BrightboxLBDriver(Driver):
connectionCls = BrightboxConnection
name = "Brightbox"
website = "http://www.brightbox.co.uk/"
LB_STATE_MAP = {
"creating": State.PENDING,
"active": State.RUNNING,
"deleting": State.UNKNOWN,
"deleted": State.UNKNOWN,
"failing": State.UNKNOWN,
"failed": State.UNKNOWN,
}
_VALUE_TO_ALGORITHM_MAP = {
"round-robin": Algorithm.ROUND_ROBIN,
"least-connections": Algorithm.LEAST_CONNECTIONS,
}
_ALGORITHM_TO_VALUE_MAP = reverse_dict(_VALUE_TO_ALGORITHM_MAP)
def list_protocols(self):
return ["tcp", "http"]
def list_balancers(self):
data = self.connection.request("/%s/load_balancers" % API_VERSION).object
return list(map(self._to_balancer, data))
def create_balancer(self, name, port, protocol, algorithm, members):
response = self._post(
"/%s/load_balancers" % API_VERSION,
{
"name": name,
"nodes": list(map(self._member_to_node, members)),
"policy": self._algorithm_to_value(algorithm),
"listeners": [{"in": port, "out": port, "protocol": protocol}],
"healthcheck": {"type": protocol, "port": port},
},
)
return self._to_balancer(response.object)
def destroy_balancer(self, balancer):
response = self.connection.request(
"/{}/load_balancers/{}".format(API_VERSION, balancer.id), method="DELETE"
)
return response.status == httplib.ACCEPTED
def get_balancer(self, balancer_id):
data = self.connection.request(
"/{}/load_balancers/{}".format(API_VERSION, balancer_id)
).object
return self._to_balancer(data)
def balancer_attach_compute_node(self, balancer, node):
return self.balancer_attach_member(balancer, node)
def balancer_attach_member(self, balancer, member):
path = "/{}/load_balancers/{}/add_nodes".format(API_VERSION, balancer.id)
self._post(path, {"nodes": [self._member_to_node(member)]})
return member
def balancer_detach_member(self, balancer, member):
path = "/{}/load_balancers/{}/remove_nodes".format(API_VERSION, balancer.id)
response = self._post(path, {"nodes": [self._member_to_node(member)]})
return response.status == httplib.ACCEPTED
def balancer_list_members(self, balancer):
path = "/{}/load_balancers/{}".format(API_VERSION, balancer.id)
data = self.connection.request(path).object
def func(data):
return self._node_to_member(data, balancer)
return list(map(func, data["nodes"]))
def _post(self, path, data={}):
headers = {"Content-Type": "application/json"}
return self.connection.request(path, data=data, headers=headers, method="POST")
def _to_balancer(self, data):
return LoadBalancer(
id=data["id"],
name=data["name"],
state=self.LB_STATE_MAP.get(data["status"], State.UNKNOWN),
ip=self._public_ip(data),
port=data["listeners"][0]["in"],
driver=self.connection.driver,
)
def _member_to_node(self, member):
return {"node": member.id}
def _node_to_member(self, data, balancer):
return Member(id=data["id"], ip=None, port=None, balancer=balancer)
def _public_ip(self, data):
if len(data["cloud_ips"]) > 0:
ip = data["cloud_ips"][0]["public_ip"]
else:
ip = None
return ip