lbaasv2: Fix for deployments missing the proxy

When Octavia stopped needing neutron-lbaasv2 devstack plugin we tried it
out with success but we still kept usage the plugin so that our devstack
plugin could target older than pike.

Unfortunately during this time the proxy became unnecessary and not well
maintained and due to our gates still using it, when we tried queens
with the supported proxy less Octavia we realized that it fails.

This patch addresses it by making the existing neutronclient usage point
to the load-balancer endpoint when the proxy is not in place.

Change-Id: Iafd74f23bdf336a4d78ba4759f702cf989c8bc30
Closes-Bug: #1763045
Signed-off-by: Antoni Segura Puimedon <antonisp@celebdor.com>
(cherry picked from commit 285456a672)
This commit is contained in:
Antoni Segura Puimedon 2018-04-11 16:02:39 +02:00 committed by Michał Dulko
parent 044d7db0af
commit c0455e9b62
11 changed files with 342 additions and 160 deletions

View File

@ -696,3 +696,172 @@ function run_openshift_node {
run_process openshift-node "sudo $command"
fi
}
# lb_state
# Description: Returns the state of the load balancer
# Params:
# id - Id or name of the loadbalancer the state of which needs to be
# retrieved.
function lb_state {
local lb_id
lb_id="$1"
# Checks Neutron lbaas for the Load balancer state
if is_service_enabled octavia; then
openstack loadbalancer show "$lb_id" | \
awk '/provisioning_status/ {print $4}'
else
neutron lbaas-loadbalancer-show "$lb_id" | \
awk '/provisioning_status/ {print $4}'
fi
}
# create_load_balancer
# Description: Creates an OpenStack Load Balancer with either neutron LBaaS
# or Octavia
# Params:
# lb_name: Name to give to the load balancer.
# lb_vip: Virtual IP to give to the load balancer.
# lb_vip_subnet: Id or name of the subnet where lb_vip should be
# allocated.
function create_load_balancer {
local lb_name
local lb_vip
local lb_vip_subnet
lb_name="$1"
lb_vip="$2"
lb_vip_subnet="$3"
if is_service_enabled octavia; then
openstack loadbalancer create --name "$lb_name" \
--vip-address "$lb_vip" \
--vip-subnet-id "$lb_vip_subnet"
else
neutron lbaas-loadbalancer-create --name "$lb_name" \
--vip-address "$lb_vip" \
"$lb_vip_subnet"
fi
}
# create_load_balancer_listener
# Description: Creates an OpenStack Load Balancer Listener for the specified
# Load Balancer with either neutron LBaaS or Octavia
# Params:
# name: Name to give to the load balancer listener.
# protocol: Whether it is HTTP, HTTPS, TCP, etc.
# port: The TCP port number to listen to.
# lb: Id or name of the Load Balancer we want to add the Listener to.
function create_load_balancer_listener {
local name
local protocol
local port
local lb
name="$1"
protocol="$2"
port="$3"
lb="$4"
# Octavia needs the LB to be active for the listener
while [[ "$(lb_state $lb)" != "ACTIVE" ]]; do
sleep 1
done
if is_service_enabled octavia; then
openstack loadbalancer listener create --name "$name" \
--protocol "$protocol" \
--protocol-port "$port" \
"$lb"
else
neutron lbaas-listener-create --name "$name" \
--protocol "$protocol" \
--protocol-port "$port" \
--loadbalancer "$lb"
fi
}
# create_load_balancer_pool
# Description: Creates an OpenStack Load Balancer Pool for the specified
# Load Balancer listener with either neutron LBaaS or Octavia
# Params:
# name: Name to give to the load balancer listener.
# protocol: Whether it is HTTP, HTTPS, TCP, etc.
# algorithm: Load Balancing algorithm to use.
# listener: Id or name of the Load Balancer Listener we want to add the
# pool to.
# lb: Id or name of the Load Balancer we want to add the pool to
# (optional).
function create_load_balancer_pool {
local name
local protocol
local algorithm
local listener
local lb
name="$1"
protocol="$2"
algorithm="$3"
listener="$4"
lb="$5"
# We must wait for the LB to be active before we can put a Pool for it
while [[ "$(lb_state $lb)" != "ACTIVE" ]]; do
sleep 1
done
if is_service_enabled octavia; then
openstack loadbalancer pool create --name "$name" \
--listener "$listener" \
--protocol "$protocol" \
--lb-algorithm "$algorithm"
else
neutron lbaas-pool-create --name "$name" \
--loadbalancer "$lb_name" \
--listener "$listener" \
--protocol "$protocol" \
--lb-algorithm "$algorithm"
fi
}
# create_load_balancer_member
# Description: Creates an OpenStack load balancer pool member
# Params:
# name: Name to give to the load balancer pool member.
# address: Whether it is HTTP, HTTPS, TCP, etc.
# port: Port number the pool member is listening on.
# pool: Id or name of the Load Balancer pool this member belongs to.
# subnet: Id or name of the subnet the member address belongs to.
# lb: Id or name of the load balancer the member belongs to.
function create_load_balancer_member {
local name
local address
local port
local pool
local subnet
local lb
name="$1"
address="$2"
port="$3"
pool="$4"
subnet="$5"
lb="$6"
# We must wait for the pool creation update before we can add members
while [[ "$(lb_state $lb)" != "ACTIVE" ]]; do
sleep 1
done
if is_service_enabled octavia; then
openstack loadbalancer member create --name "$name" \
--address "$address" \
--protocol-port "$port" \
"$pool"
else
neutron lbaas-member-create --name "$name" \
--subnet "$subnet" \
--address "$address" \
--protocol-port "$port" \
"$pool"
fi
}

View File

@ -81,11 +81,6 @@ if [[ "$KURYR_K8S_LBAAS_USE_OCTAVIA" == "True" ]]; then
### Glance
enable_service g-api
enable_service g-reg
### Neutron-lbaas
#### In case Octavia is older than Pike, neutron-lbaas is needed
enable_plugin neutron-lbaas \
git://git.openstack.org/openstack/neutron-lbaas
enable_service q-lbaasv2
else
# LBaaSv2 service and Haproxy agent
enable_plugin neutron-lbaas \

View File

@ -62,11 +62,6 @@ if [[ "$KURYR_K8S_LBAAS_USE_OCTAVIA" == "True" ]]; then
### Glance
enable_service g-api
enable_service g-reg
### Neutron-lbaas
#### In case Octavia is older than Pike, neutron-lbaas is needed
enable_plugin neutron-lbaas \
git://git.openstack.org/openstack/neutron-lbaas
enable_service q-lbaasv2
else
# LBaaSv2 service and Haproxy agent
enable_plugin neutron-lbaas \

View File

@ -62,11 +62,6 @@ if [[ "$KURYR_K8S_LBAAS_USE_OCTAVIA" == "True" ]]; then
### Glance
enable_service g-api
enable_service g-reg
### Neutron-lbaas
#### In case Octavia is older than Pike, neutron-lbaas is needed
enable_plugin neutron-lbaas \
git://git.openstack.org/openstack/neutron-lbaas
enable_service q-lbaasv2
else
# LBaaSv2 service and Haproxy agent
enable_plugin neutron-lbaas \

View File

@ -188,11 +188,6 @@ function copy_tempest_kubeconfig {
fi
}
function _lb_state {
# Checks Neutron lbaas for the Load balancer state
neutron lbaas-loadbalancer-show "$1" | awk '/provisioning_status/ {print $4}'
}
function create_k8s_api_service {
# This allows pods that need access to kubernetes API (like the
# containerized kuryr controller or kube-dns) to talk to the K8s API
@ -211,34 +206,11 @@ function create_k8s_api_service {
k8s_api_clusterip=$(_cidr_range "$service_cidr" | cut -f1)
neutron lbaas-loadbalancer-create --name "$lb_name" \
--vip-address "$k8s_api_clusterip" \
create_load_balancer "$lb_name" "$k8s_api_clusterip" \
"$KURYR_NEUTRON_DEFAULT_SERVICE_SUBNET"
# Octavia needs the LB to be active for the listener
while [[ "$(_lb_state $lb_name)" != "ACTIVE" ]]; do
sleep 1
done
neutron lbaas-listener-create --loadbalancer "$lb_name" \
--name default/kubernetes:443 \
--protocol HTTPS \
--protocol-port 443
# We must wait for the LB to be active before we can put a Pool for it
while [[ "$(_lb_state $lb_name)" != "ACTIVE" ]]; do
sleep 1
done
neutron lbaas-pool-create --loadbalancer "$lb_name" \
--name default/kubernetes:443 \
--listener default/kubernetes:443 \
--protocol HTTPS \
--lb-algorithm ROUND_ROBIN
# We must wait for the pending pool creation update
while [[ "$(_lb_state $lb_name)" != "ACTIVE" ]]; do
sleep 1
done
create_load_balancer_listener default/kubernetes:443 HTTPS 443 "$lb_name"
create_load_balancer_pool default/kubernetes:443 HTTPS ROUND_ROBIN \
default/kubernetes:443 "$lb_name"
local api_port
if is_service_enabled openshift-master; then
@ -246,10 +218,9 @@ function create_k8s_api_service {
else
api_port=6443
fi
neutron lbaas-member-create --subnet public-subnet \
--address ${kubelet_iface_ip} \
--protocol-port ${api_port} \
default/kubernetes:443
create_load_balancer_member "$(hostname)" "$kubelet_iface_ip" "$api_port" \
default/kubernetes:443 public-subnet "$lb_name"
}
function configure_neutron_defaults {

View File

@ -17,9 +17,11 @@ from kuryr.lib import utils
from kuryr_kubernetes import config
from kuryr_kubernetes import k8s_client
from neutronclient import client as n_client
_clients = {}
_NEUTRON_CLIENT = 'neutron-client'
_LB_CLIENT = 'load-balancer-client'
_KUBERNETES_CLIENT = 'kubernetes-client'
@ -27,12 +29,17 @@ def get_neutron_client():
return _clients[_NEUTRON_CLIENT]
def get_loadbalancer_client():
return _clients[_LB_CLIENT]
def get_kubernetes_client():
return _clients[_KUBERNETES_CLIENT]
def setup_clients():
setup_neutron_client()
setup_loadbalancer_client()
setup_kubernetes_client()
@ -40,6 +47,24 @@ def setup_neutron_client():
_clients[_NEUTRON_CLIENT] = utils.get_neutron_client()
def setup_loadbalancer_client():
neutron_client = get_neutron_client()
if any(ext['alias'] == 'lbaasv2' for
ext in neutron_client.list_extensions()['extensions']):
_clients[_LB_CLIENT] = neutron_client
else:
# Since Octavia is lbaasv2 API compatible (A superset of it) we'll just
# wire an extra neutron client instance to point to it
lbaas_client = utils.get_neutron_client()
conf_group = utils.kuryr_config.neutron_group.name
auth_plugin = utils.get_auth_plugin(conf_group)
octo_httpclient = n_client.construct_http_client(
session=utils.get_keystone_session(conf_group, auth_plugin),
service_type='load-balancer')
lbaas_client.httpclient = octo_httpclient
_clients[_LB_CLIENT] = lbaas_client
def setup_kubernetes_client():
_clients[_KUBERNETES_CLIENT] = k8s_client.K8sClient(
config.CONF.kubernetes.api_root)

View File

@ -63,8 +63,9 @@ class LBaaSv2Driver(base.LBaaSDriver):
def release_loadbalancer(self, endpoints, loadbalancer):
neutron = clients.get_neutron_client()
lbaas = clients.get_loadbalancer_client()
self._release(loadbalancer, loadbalancer,
neutron.delete_loadbalancer, loadbalancer.id)
lbaas.delete_loadbalancer, loadbalancer.id)
sg_id = self._find_listeners_sg(loadbalancer)
if sg_id:
@ -150,8 +151,9 @@ class LBaaSv2Driver(base.LBaaSDriver):
def release_listener(self, endpoints, loadbalancer, listener):
neutron = clients.get_neutron_client()
lbaas = clients.get_loadbalancer_client()
self._release(loadbalancer, listener,
neutron.delete_listener,
lbaas.delete_listener,
listener.id)
sg_id = self._find_listeners_sg(loadbalancer)
@ -176,9 +178,9 @@ class LBaaSv2Driver(base.LBaaSDriver):
self._find_pool)
def release_pool(self, endpoints, loadbalancer, pool):
neutron = clients.get_neutron_client()
lbaas = clients.get_loadbalancer_client()
self._release(loadbalancer, pool,
neutron.delete_lbaas_pool,
lbaas.delete_lbaas_pool,
pool.id)
def ensure_member(self, endpoints, loadbalancer, pool,
@ -196,9 +198,9 @@ class LBaaSv2Driver(base.LBaaSDriver):
self._find_member)
def release_member(self, endpoints, loadbalancer, member):
neutron = clients.get_neutron_client()
lbaas = clients.get_loadbalancer_client()
self._release(loadbalancer, member,
neutron.delete_lbaas_member,
lbaas.delete_lbaas_member,
member.id, member.pool_id)
def _get_vip_port_id(self, loadbalancer):
@ -217,11 +219,10 @@ class LBaaSv2Driver(base.LBaaSDriver):
return None
def _create_loadbalancer(self, loadbalancer):
neutron = clients.get_neutron_client()
response = neutron.create_loadbalancer({'loadbalancer': {
lbaas = clients.get_loadbalancer_client()
response = lbaas.create_loadbalancer({'loadbalancer': {
'name': loadbalancer.name,
'project_id': loadbalancer.project_id,
'tenant_id': loadbalancer.project_id,
'vip_address': str(loadbalancer.ip),
'vip_subnet_id': loadbalancer.subnet_id}})
loadbalancer.id = response['loadbalancer']['id']
@ -230,11 +231,10 @@ class LBaaSv2Driver(base.LBaaSDriver):
return loadbalancer
def _find_loadbalancer(self, loadbalancer):
neutron = clients.get_neutron_client()
response = neutron.list_loadbalancers(
lbaas = clients.get_loadbalancer_client()
response = lbaas.list_loadbalancers(
name=loadbalancer.name,
project_id=loadbalancer.project_id,
tenant_id=loadbalancer.project_id,
vip_address=str(loadbalancer.ip),
vip_subnet_id=loadbalancer.subnet_id)
@ -248,11 +248,10 @@ class LBaaSv2Driver(base.LBaaSDriver):
return loadbalancer
def _create_listener(self, listener):
neutron = clients.get_neutron_client()
response = neutron.create_listener({'listener': {
lbaas = clients.get_loadbalancer_client()
response = lbaas.create_listener({'listener': {
'name': listener.name,
'project_id': listener.project_id,
'tenant_id': listener.project_id,
'loadbalancer_id': listener.loadbalancer_id,
'protocol': listener.protocol,
'protocol_port': listener.port}})
@ -260,11 +259,10 @@ class LBaaSv2Driver(base.LBaaSDriver):
return listener
def _find_listener(self, listener):
neutron = clients.get_neutron_client()
response = neutron.list_listeners(
lbaas = clients.get_loadbalancer_client()
response = lbaas.list_listeners(
name=listener.name,
project_id=listener.project_id,
tenant_id=listener.project_id,
loadbalancer_id=listener.loadbalancer_id,
protocol=listener.protocol,
protocol_port=listener.port)
@ -279,12 +277,11 @@ class LBaaSv2Driver(base.LBaaSDriver):
def _create_pool(self, pool):
# TODO(ivc): make lb_algorithm configurable
lb_algorithm = 'ROUND_ROBIN'
neutron = clients.get_neutron_client()
lbaas = clients.get_loadbalancer_client()
try:
response = neutron.create_lbaas_pool({'pool': {
response = lbaas.create_lbaas_pool({'pool': {
'name': pool.name,
'project_id': pool.project_id,
'tenant_id': pool.project_id,
'listener_id': pool.listener_id,
'loadbalancer_id': pool.loadbalancer_id,
'protocol': pool.protocol,
@ -293,14 +290,14 @@ class LBaaSv2Driver(base.LBaaSDriver):
return pool
except n_exc.StateInvalidClient:
with excutils.save_and_reraise_exception():
self._cleanup_bogus_pool(neutron, pool, lb_algorithm)
self._cleanup_bogus_pool(lbaas, pool, lb_algorithm)
def _cleanup_bogus_pool(self, neutron, pool, lb_algorithm):
def _cleanup_bogus_pool(self, lbaas, pool, lb_algorithm):
# REVISIT(ivc): LBaaSv2 creates pool object despite raising an
# exception. The created pool is not bound to listener, but
# it is bound to loadbalancer and will cause an error on
# 'release_loadbalancer'.
pools = neutron.list_lbaas_pools(
pools = lbaas.list_lbaas_pools(
name=pool.name, project_id=pool.project_id,
loadbalancer_id=pool.loadbalancer_id,
protocol=pool.protocol, lb_algorithm=lb_algorithm)
@ -310,16 +307,15 @@ class LBaaSv2Driver(base.LBaaSDriver):
try:
LOG.debug("Removing bogus pool %(id)s %(pool)s", {
'id': pool_id, 'pool': pool})
neutron.delete_lbaas_pool(pool_id)
lbaas.delete_lbaas_pool(pool_id)
except (n_exc.NotFound, n_exc.StateInvalidClient):
pass
def _find_pool(self, pool):
neutron = clients.get_neutron_client()
response = neutron.list_lbaas_pools(
lbaas = clients.get_loadbalancer_client()
response = lbaas.list_lbaas_pools(
name=pool.name,
project_id=pool.project_id,
tenant_id=pool.project_id,
loadbalancer_id=pool.loadbalancer_id,
protocol=pool.protocol)
@ -333,11 +329,10 @@ class LBaaSv2Driver(base.LBaaSDriver):
return pool
def _create_member(self, member):
neutron = clients.get_neutron_client()
response = neutron.create_lbaas_member(member.pool_id, {'member': {
lbaas = clients.get_loadbalancer_client()
response = lbaas.create_lbaas_member(member.pool_id, {'member': {
'name': member.name,
'project_id': member.project_id,
'tenant_id': member.project_id,
'subnet_id': member.subnet_id,
'address': str(member.ip),
'protocol_port': member.port}})
@ -345,12 +340,11 @@ class LBaaSv2Driver(base.LBaaSDriver):
return member
def _find_member(self, member):
neutron = clients.get_neutron_client()
response = neutron.list_lbaas_members(
lbaas = clients.get_loadbalancer_client()
response = lbaas.list_lbaas_members(
member.pool_id,
name=member.name,
project_id=member.project_id,
tenant_id=member.project_id,
subnet_id=member.subnet_id,
address=member.ip,
protocol_port=member.port)
@ -398,10 +392,10 @@ class LBaaSv2Driver(base.LBaaSDriver):
raise k_exc.ResourceNotReady(obj)
def _wait_for_provisioning(self, loadbalancer, timeout):
neutron = clients.get_neutron_client()
lbaas = clients.get_loadbalancer_client()
for remaining in self._provisioning_timer(timeout):
response = neutron.show_loadbalancer(loadbalancer.id)
response = lbaas.show_loadbalancer(loadbalancer.id)
status = response['loadbalancer']['provisioning_status']
if status == 'ACTIVE':
LOG.debug("Provisioning complete for %(lb)s", {

View File

@ -73,7 +73,8 @@ class TestLBaaSv2Driver(test_base.TestCase):
sg_ids, 'ClusterIP')
def test_release_loadbalancer(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
endpoints = mock.sentinel.endpoints
@ -82,7 +83,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
cls.release_loadbalancer(m_driver, endpoints, loadbalancer)
m_driver._release.assert_called_once_with(loadbalancer, loadbalancer,
neutron.delete_loadbalancer,
lbaas.delete_loadbalancer,
loadbalancer.id)
def test_ensure_listener(self):
@ -121,6 +122,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
def test_release_listener(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
neutron.list_security_group_rules.return_value = {
'security_group_rules': []}
cls = d_lbaasv2.LBaaSv2Driver
@ -132,7 +134,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
cls.release_listener(m_driver, endpoints, loadbalancer, listener)
m_driver._release.assert_called_once_with(loadbalancer, listener,
neutron.delete_listener,
lbaas.delete_listener,
listener.id)
def test_ensure_pool(self):
@ -162,7 +164,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
self.assertEqual(expected_resp, resp)
def test_release_pool(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
endpoints = mock.sentinel.endpoints
@ -172,7 +174,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
cls.release_pool(m_driver, endpoints, loadbalancer, pool)
m_driver._release.assert_called_once_with(loadbalancer, pool,
neutron.delete_lbaas_pool,
lbaas.delete_lbaas_pool,
pool.id)
def test_ensure_member(self):
@ -207,7 +209,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
self.assertEqual(expected_resp, resp)
def test_release_member(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
endpoints = mock.sentinel.endpoints
@ -217,11 +219,11 @@ class TestLBaaSv2Driver(test_base.TestCase):
cls.release_member(m_driver, endpoints, loadbalancer, member)
m_driver._release.assert_called_once_with(loadbalancer, member,
neutron.delete_lbaas_member,
lbaas.delete_lbaas_member,
member.id, member.pool_id)
def test_create_loadbalancer(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
loadbalancer = obj_lbaas.LBaaSLoadBalancer(
@ -232,22 +234,21 @@ class TestLBaaSv2Driver(test_base.TestCase):
req = {'loadbalancer': {
'name': loadbalancer.name,
'project_id': loadbalancer.project_id,
'tenant_id': loadbalancer.project_id,
'vip_address': str(loadbalancer.ip),
'vip_subnet_id': loadbalancer.subnet_id,
}}
resp = {'loadbalancer': {'id': loadbalancer_id, 'provider': 'haproxy'}}
neutron.create_loadbalancer.return_value = resp
lbaas.create_loadbalancer.return_value = resp
ret = cls._create_loadbalancer(m_driver, loadbalancer)
neutron.create_loadbalancer.assert_called_once_with(req)
lbaas.create_loadbalancer.assert_called_once_with(req)
for attr in loadbalancer.obj_fields:
self.assertEqual(getattr(loadbalancer, attr),
getattr(ret, attr))
self.assertEqual(loadbalancer_id, ret.id)
def test_find_loadbalancer(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
loadbalancer = obj_lbaas.LBaaSLoadBalancer(
@ -257,13 +258,12 @@ class TestLBaaSv2Driver(test_base.TestCase):
loadbalancer_id = '00EE9E11-91C2-41CF-8FD4-7970579E5C4C'
resp = {'loadbalancers': [{'id': loadbalancer_id,
'provider': 'haproxy'}]}
neutron.list_loadbalancers.return_value = resp
lbaas.list_loadbalancers.return_value = resp
ret = cls._find_loadbalancer(m_driver, loadbalancer)
neutron.list_loadbalancers.assert_called_once_with(
lbaas.list_loadbalancers.assert_called_once_with(
name=loadbalancer.name,
project_id=loadbalancer.project_id,
tenant_id=loadbalancer.project_id,
vip_address=str(loadbalancer.ip),
vip_subnet_id=loadbalancer.subnet_id)
for attr in loadbalancer.obj_fields:
@ -272,26 +272,25 @@ class TestLBaaSv2Driver(test_base.TestCase):
self.assertEqual(loadbalancer_id, ret.id)
def test_find_loadbalancer_not_found(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
loadbalancer = obj_lbaas.LBaaSLoadBalancer(
name='TEST_NAME', project_id='TEST_PROJECT', ip='1.2.3.4',
subnet_id='D3FA400A-F543-4B91-9CD3-047AF0CE42D1')
resp = {'loadbalancers': []}
neutron.list_loadbalancers.return_value = resp
lbaas.list_loadbalancers.return_value = resp
ret = cls._find_loadbalancer(m_driver, loadbalancer)
neutron.list_loadbalancers.assert_called_once_with(
lbaas.list_loadbalancers.assert_called_once_with(
name=loadbalancer.name,
project_id=loadbalancer.project_id,
tenant_id=loadbalancer.project_id,
vip_address=str(loadbalancer.ip),
vip_subnet_id=loadbalancer.subnet_id)
self.assertIsNone(ret)
def test_create_listener(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
listener = obj_lbaas.LBaaSListener(
@ -301,22 +300,21 @@ class TestLBaaSv2Driver(test_base.TestCase):
req = {'listener': {
'name': listener.name,
'project_id': listener.project_id,
'tenant_id': listener.project_id,
'loadbalancer_id': listener.loadbalancer_id,
'protocol': listener.protocol,
'protocol_port': listener.port}}
resp = {'listener': {'id': listener_id}}
neutron.create_listener.return_value = resp
lbaas.create_listener.return_value = resp
ret = cls._create_listener(m_driver, listener)
neutron.create_listener.assert_called_once_with(req)
lbaas.create_listener.assert_called_once_with(req)
for attr in listener.obj_fields:
self.assertEqual(getattr(listener, attr),
getattr(ret, attr))
self.assertEqual(listener_id, ret.id)
def test_find_listener(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
listener = obj_lbaas.LBaaSListener(
@ -324,13 +322,12 @@ class TestLBaaSv2Driver(test_base.TestCase):
port=1234, loadbalancer_id='00EE9E11-91C2-41CF-8FD4-7970579E5C4C')
listener_id = 'A57B7771-6050-4CA8-A63C-443493EC98AB'
resp = {'listeners': [{'id': listener_id}]}
neutron.list_listeners.return_value = resp
lbaas.list_listeners.return_value = resp
ret = cls._find_listener(m_driver, listener)
neutron.list_listeners.assert_called_once_with(
lbaas.list_listeners.assert_called_once_with(
name=listener.name,
project_id=listener.project_id,
tenant_id=listener.project_id,
loadbalancer_id=listener.loadbalancer_id,
protocol=listener.protocol,
protocol_port=listener.port)
@ -340,27 +337,26 @@ class TestLBaaSv2Driver(test_base.TestCase):
self.assertEqual(listener_id, ret.id)
def test_find_listener_not_found(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
listener = obj_lbaas.LBaaSListener(
name='TEST_NAME', project_id='TEST_PROJECT', protocol='TCP',
port=1234, loadbalancer_id='00EE9E11-91C2-41CF-8FD4-7970579E5C4C')
resp = {'listeners': []}
neutron.list_listeners.return_value = resp
lbaas.list_listeners.return_value = resp
ret = cls._find_listener(m_driver, listener)
neutron.list_listeners.assert_called_once_with(
lbaas.list_listeners.assert_called_once_with(
name=listener.name,
project_id=listener.project_id,
tenant_id=listener.project_id,
loadbalancer_id=listener.loadbalancer_id,
protocol=listener.protocol,
protocol_port=listener.port)
self.assertIsNone(ret)
def test_create_pool(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
lb_algorithm = 'ROUND_ROBIN'
@ -372,23 +368,22 @@ class TestLBaaSv2Driver(test_base.TestCase):
req = {'pool': {
'name': pool.name,
'project_id': pool.project_id,
'tenant_id': pool.project_id,
'listener_id': pool.listener_id,
'loadbalancer_id': pool.loadbalancer_id,
'protocol': pool.protocol,
'lb_algorithm': lb_algorithm}}
resp = {'pool': {'id': pool_id}}
neutron.create_lbaas_pool.return_value = resp
lbaas.create_lbaas_pool.return_value = resp
ret = cls._create_pool(m_driver, pool)
neutron.create_lbaas_pool.assert_called_once_with(req)
lbaas.create_lbaas_pool.assert_called_once_with(req)
for attr in pool.obj_fields:
self.assertEqual(getattr(pool, attr),
getattr(ret, attr))
self.assertEqual(pool_id, ret.id)
def test_create_pool_conflict(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
lb_algorithm = 'ROUND_ROBIN'
@ -399,17 +394,16 @@ class TestLBaaSv2Driver(test_base.TestCase):
req = {'pool': {
'name': pool.name,
'project_id': pool.project_id,
'tenant_id': pool.project_id,
'listener_id': pool.listener_id,
'loadbalancer_id': pool.loadbalancer_id,
'protocol': pool.protocol,
'lb_algorithm': lb_algorithm}}
neutron.create_lbaas_pool.side_effect = n_exc.StateInvalidClient
lbaas.create_lbaas_pool.side_effect = n_exc.StateInvalidClient
self.assertRaises(n_exc.StateInvalidClient, cls._create_pool, m_driver,
pool)
neutron.create_lbaas_pool.assert_called_once_with(req)
m_driver._cleanup_bogus_pool.assert_called_once_with(neutron, pool,
lbaas.create_lbaas_pool.assert_called_once_with(req)
m_driver._cleanup_bogus_pool.assert_called_once_with(lbaas, pool,
lb_algorithm)
def test_cleanup_bogus_pool(self):
@ -417,7 +411,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
self.skipTest("not implemented")
def test_find_pool(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
pool = obj_lbaas.LBaaSPool(
@ -427,13 +421,12 @@ class TestLBaaSv2Driver(test_base.TestCase):
pool_id = 'D4F35594-27EB-4F4C-930C-31DD40F53B77'
resp = {'pools': [{'id': pool_id,
'listeners': [{'id': pool.listener_id}]}]}
neutron.list_lbaas_pools.return_value = resp
lbaas.list_lbaas_pools.return_value = resp
ret = cls._find_pool(m_driver, pool)
neutron.list_lbaas_pools.assert_called_once_with(
lbaas.list_lbaas_pools.assert_called_once_with(
name=pool.name,
project_id=pool.project_id,
tenant_id=pool.project_id,
loadbalancer_id=pool.loadbalancer_id,
protocol=pool.protocol)
for attr in pool.obj_fields:
@ -442,7 +435,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
self.assertEqual(pool_id, ret.id)
def test_find_pool_not_found(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
pool = obj_lbaas.LBaaSPool(
@ -450,19 +443,18 @@ class TestLBaaSv2Driver(test_base.TestCase):
listener_id='A57B7771-6050-4CA8-A63C-443493EC98AB',
loadbalancer_id='00EE9E11-91C2-41CF-8FD4-7970579E5C4C')
resp = {'pools': []}
neutron.list_lbaas_pools.return_value = resp
lbaas.list_lbaas_pools.return_value = resp
ret = cls._find_pool(m_driver, pool)
neutron.list_lbaas_pools.assert_called_once_with(
lbaas.list_lbaas_pools.assert_called_once_with(
name=pool.name,
project_id=pool.project_id,
tenant_id=pool.project_id,
loadbalancer_id=pool.loadbalancer_id,
protocol=pool.protocol)
self.assertIsNone(ret)
def test_create_member(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
member = obj_lbaas.LBaaSMember(
@ -473,15 +465,14 @@ class TestLBaaSv2Driver(test_base.TestCase):
req = {'member': {
'name': member.name,
'project_id': member.project_id,
'tenant_id': member.project_id,
'subnet_id': member.subnet_id,
'address': str(member.ip),
'protocol_port': member.port}}
resp = {'member': {'id': member_id}}
neutron.create_lbaas_member.return_value = resp
lbaas.create_lbaas_member.return_value = resp
ret = cls._create_member(m_driver, member)
neutron.create_lbaas_member.assert_called_once_with(
lbaas.create_lbaas_member.assert_called_once_with(
member.pool_id, req)
for attr in member.obj_fields:
self.assertEqual(getattr(member, attr),
@ -489,7 +480,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
self.assertEqual(member_id, ret.id)
def test_find_member(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
member = obj_lbaas.LBaaSMember(
@ -498,14 +489,13 @@ class TestLBaaSv2Driver(test_base.TestCase):
pool_id='D4F35594-27EB-4F4C-930C-31DD40F53B77')
member_id = '3A70CEC0-392D-4BC1-A27C-06E63A0FD54F'
resp = {'members': [{'id': member_id}]}
neutron.list_lbaas_members.return_value = resp
lbaas.list_lbaas_members.return_value = resp
ret = cls._find_member(m_driver, member)
neutron.list_lbaas_members.assert_called_once_with(
lbaas.list_lbaas_members.assert_called_once_with(
member.pool_id,
name=member.name,
project_id=member.project_id,
tenant_id=member.project_id,
subnet_id=member.subnet_id,
address=member.ip,
protocol_port=member.port)
@ -515,7 +505,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
self.assertEqual(member_id, ret.id)
def test_find_member_not_found(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
member = obj_lbaas.LBaaSMember(
@ -523,14 +513,13 @@ class TestLBaaSv2Driver(test_base.TestCase):
port=1234, subnet_id='D3FA400A-F543-4B91-9CD3-047AF0CE42D1',
pool_id='D4F35594-27EB-4F4C-930C-31DD40F53B77')
resp = {'members': []}
neutron.list_lbaas_members.return_value = resp
lbaas.list_lbaas_members.return_value = resp
ret = cls._find_member(m_driver, member)
neutron.list_lbaas_members.assert_called_once_with(
lbaas.list_lbaas_members.assert_called_once_with(
member.pool_id,
name=member.name,
project_id=member.project_id,
tenant_id=member.project_id,
subnet_id=member.subnet_id,
address=member.ip,
protocol_port=member.port)
@ -670,7 +659,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
self.assertEqual(call_count, m_delete.call_count)
def test_wait_for_provisioning(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
loadbalancer = mock.Mock()
@ -678,14 +667,14 @@ class TestLBaaSv2Driver(test_base.TestCase):
timer = [mock.sentinel.t0, mock.sentinel.t1]
m_driver._provisioning_timer.return_value = timer
resp = {'loadbalancer': {'provisioning_status': 'ACTIVE'}}
neutron.show_loadbalancer.return_value = resp
lbaas.show_loadbalancer.return_value = resp
cls._wait_for_provisioning(m_driver, loadbalancer, timeout)
neutron.show_loadbalancer.assert_called_once_with(loadbalancer.id)
lbaas.show_loadbalancer.assert_called_once_with(loadbalancer.id)
def test_wait_for_provisioning_not_ready(self):
neutron = self.useFixture(k_fix.MockNeutronClient()).client
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
loadbalancer = mock.Mock()
@ -693,12 +682,12 @@ class TestLBaaSv2Driver(test_base.TestCase):
timer = [mock.sentinel.t0, mock.sentinel.t1]
m_driver._provisioning_timer.return_value = timer
resp = {'loadbalancer': {'provisioning_status': 'NOT_ACTIVE'}}
neutron.show_loadbalancer.return_value = resp
lbaas.show_loadbalancer.return_value = resp
self.assertRaises(k_exc.ResourceNotReady, cls._wait_for_provisioning,
m_driver, loadbalancer, timeout)
self.assertEqual(len(timer), neutron.show_loadbalancer.call_count)
self.assertEqual(len(timer), lbaas.show_loadbalancer.call_count)
def test_provisioning_timer(self):
# REVISIT(ivc): add test if _provisioning_timer is to stay

View File

@ -33,3 +33,11 @@ class MockNeutronClient(fixtures.Fixture):
self.useFixture(fixtures.MockPatch(
'kuryr_kubernetes.clients.get_neutron_client',
lambda: self.client))
class MockLBaaSClient(fixtures.Fixture):
def _setUp(self):
self.client = mock.Mock()
self.useFixture(fixtures.MockPatch(
'kuryr_kubernetes.clients.get_loadbalancer_client',
lambda: self.client))

View File

@ -24,18 +24,57 @@ class TestK8sClient(test_base.TestCase):
@mock.patch('kuryr_kubernetes.config.CONF')
@mock.patch('kuryr_kubernetes.k8s_client.K8sClient')
@mock.patch('kuryr.lib.utils.get_neutron_client')
def test_setup_clients(self, m_neutron, m_k8s, m_cfg):
def test_setup_clients_lbaasv2(self, m_neutron, m_k8s, m_cfg):
k8s_api_root = 'http://127.0.0.1:1234'
neutron_dummy = object()
neutron_mock = mock.Mock()
k8s_dummy = object()
neutron_mock.list_extensions.return_value = {
'extensions': [
{'alias': 'lbaasv2',
'description': 'Provides Load Balancing',
'links': [],
'name': 'Load Balancing v2',
'updated': '2017-11-28T09:00:00-00:00'}]}
m_cfg.kubernetes.api_root = k8s_api_root
m_neutron.return_value = neutron_dummy
m_neutron.return_value = neutron_mock
m_k8s.return_value = k8s_dummy
clients.setup_clients()
m_k8s.assert_called_with(k8s_api_root)
self.assertIs(k8s_dummy, clients.get_kubernetes_client())
self.assertIs(neutron_dummy, clients.get_neutron_client())
self.assertIs(neutron_mock, clients.get_neutron_client())
self.assertIs(neutron_mock, clients.get_loadbalancer_client())
@mock.patch('neutronclient.client.construct_http_client')
@mock.patch('kuryr.lib.utils.get_auth_plugin')
@mock.patch('kuryr_kubernetes.config.CONF')
@mock.patch('kuryr_kubernetes.k8s_client.K8sClient')
@mock.patch('kuryr.lib.utils.get_neutron_client')
def test_setup_clients_octavia(self, m_neutron, m_k8s, m_cfg,
m_auth_plugin, m_construct_http_client):
k8s_api_root = 'http://127.0.0.1:1234'
neutron_mock = mock.Mock()
k8s_dummy = object()
neutron_mock.list_extensions.return_value = {
'extensions': []}
octavia_httpclient = mock.sentinel.octavia_httpclient
m_construct_http_client.return_value = octavia_httpclient
m_auth_plugin.return_value = mock.sentinel.auth_plugin
m_cfg.kubernetes.api_root = k8s_api_root
m_neutron.return_value = neutron_mock
m_k8s.return_value = k8s_dummy
clients.setup_clients()
m_k8s.assert_called_with(k8s_api_root)
self.assertIs(k8s_dummy, clients.get_kubernetes_client())
self.assertIs(neutron_mock, clients.get_neutron_client())
self.assertIs(octavia_httpclient,
clients.get_loadbalancer_client().httpclient)

View File

@ -75,11 +75,12 @@
fi
# Kuryr watcher
enable_service kuryr-kubernetes
# LBaaS service
ENABLED_SERVICES+=,q-lbaasv2
enable_plugin neutron-lbaas git://git.openstack.org/openstack/neutron-lbaas
if [ "{{ loadbalancer }}" == "lbaasv2" ]; then
# LBaaS service
ENABLED_SERVICES+=,q-lbaasv2
enable_plugin neutron-lbaas git://git.openstack.org/openstack/neutron-lbaas
# Haproxy agent
NEUTRON_LBAAS_SERVICE_PROVIDERV2=LOADBALANCERV2:Haproxy:neutron_lbaas.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default
elif [ "{{ loadbalancer }}" == "octavia" ]; then
@ -87,6 +88,7 @@
enable_plugin octavia https://git.openstack.org/openstack/octavia
enable_plugin barbican https://git.openstack.org/openstack/barbican
ENABLED_SERVICES+=,octavia,o-api,o-cw,o-hk,o-hm
LIBS_FROM_GIT+=,python-octaviaclient
fi
if [ "{{ kuryr_daemon }}" == "True" ]; then