Services: Add support for K8S service's port edit use case

Kubernetes supports edit operation for API resources.
This patch extends service handler to support edit operation
of  K8S service's port field.

Change-Id: I286dd8a1383de8eda78637d455e6f8035f178c02
Closes-Bug: 1684096
This commit is contained in:
Yossi Boaron 2018-03-11 15:27:45 +02:00
parent e7b76bf2a5
commit 677c38b2a6
2 changed files with 56 additions and 2 deletions

View File

@ -429,11 +429,23 @@ class LoadBalancerHandler(k8s_base.ResourceEventHandler):
return changed
def _is_pool_in_spec(self, pool, lbaas_state, lbaas_spec):
# NOTE(yboaron): in order to check if a specific pool is in lbaas_spec
# we should:
# 1. get the listener that pool is attached to
# 2. check if listener's attributes appear in lbaas_spec.
for l in lbaas_state.listeners:
if l.id != pool.listener_id:
continue
for port in lbaas_spec.ports:
if l.port == port.port and l.protocol == port.protocol:
return True
return False
def _remove_unused_pools(self, endpoints, lbaas_state, lbaas_spec):
current_pools = {m.pool_id for m in lbaas_state.members}
removed_ids = set()
for pool in lbaas_state.pools:
if pool.id in current_pools:
if self._is_pool_in_spec(pool, lbaas_state, lbaas_spec):
continue
self._drv_lbaas.release_pool(endpoints,
lbaas_state.loadbalancer,

View File

@ -712,6 +712,48 @@ class TestLoadBalancerHandler(test_base.TestCase):
self.assertEqual([], observed_targets)
self.assertEqual(expected_ip, str(state.loadbalancer.ip))
@mock.patch('kuryr_kubernetes.controller.drivers.base'
'.PodSubnetsDriver.get_instance')
@mock.patch('kuryr_kubernetes.controller.drivers.base'
'.PodProjectDriver.get_instance')
@mock.patch('kuryr_kubernetes.controller.drivers.base'
'.LBaaSDriver.get_instance')
def test_sync_lbaas_members_svc_listener_port_edit(
self, m_get_drv_lbaas, m_get_drv_project, m_get_drv_subnets):
# REVISIT(ivc): test methods separately and verify ensure/release
project_id = uuidutils.generate_uuid()
subnet_id = uuidutils.generate_uuid()
current_ip = '1.1.1.1'
current_targets = {
'1.1.1.101': (1001, 10001)}
expected_ip = '1.1.1.1'
expected_targets = {
'1.1.1.101': (1201, 10001)}
endpoints = self._generate_endpoints(expected_targets)
state = self._generate_lbaas_state(
current_ip, current_targets, project_id, subnet_id)
spec = self._generate_lbaas_spec(expected_ip, expected_targets,
project_id, subnet_id)
m_drv_lbaas = mock.Mock(wraps=FakeLBaaSDriver())
m_drv_project = mock.Mock()
m_drv_project.get_project.return_value = project_id
m_drv_subnets = mock.Mock()
m_drv_subnets.get_subnets.return_value = {
subnet_id: mock.sentinel.subnet}
m_get_drv_lbaas.return_value = m_drv_lbaas
m_get_drv_project.return_value = m_drv_project
m_get_drv_subnets.return_value = m_drv_subnets
handler = h_lbaas.LoadBalancerHandler()
with mock.patch.object(handler, '_get_pod_subnet') as m_get_pod_subnet:
m_get_pod_subnet.return_value = subnet_id
handler._sync_lbaas_members(endpoints, state, spec)
self.assertEqual(expected_ip, str(state.loadbalancer.ip))
m_drv_lbaas.release_pool.assert_called_once()
def test_get_lbaas_spec(self):
self.skipTest("skipping until generalised annotation handling is "
"implemented")