diff --git a/src/layer.yaml b/src/layer.yaml index 1915a32c..eac684ca 100644 --- a/src/layer.yaml +++ b/src/layer.yaml @@ -4,6 +4,7 @@ includes: - interface:mysql-shared - interface:rabbitmq - interface:keystone + - interface:neutron-load-balancer options: basic: use_venv: True diff --git a/src/metadata.yaml b/src/metadata.yaml index 414b34ce..6eac20ee 100644 --- a/src/metadata.yaml +++ b/src/metadata.yaml @@ -19,3 +19,6 @@ tags: series: - bionic subordinate: false +requires: + neutron-load-balancer: + interface: neutron-load-balancer diff --git a/src/reactive/octavia_handlers.py b/src/reactive/octavia_handlers.py index 42b98a1c..13fb3807 100644 --- a/src/reactive/octavia_handlers.py +++ b/src/reactive/octavia_handlers.py @@ -18,6 +18,7 @@ import charms.reactive as reactive import charms.leadership as leadership import charms_openstack.charm as charm +import charms_openstack.ip as os_ip import charm.openstack.octavia as octavia # noqa @@ -38,6 +39,16 @@ def generate_heartbeat_key(): leadership.leader_set({'heartbeat-key': str(uuid.uuid4())}) +@reactive.when('neutron-load-balancer.available') +def setup_neutron_lbaas_proxy(): + neutron = reactive.endpoint_from_flag('neutron-load-balancer.available') + with charm.provide_charm_instance() as octavia_charm: + octavia_url = '{}:{}'.format( + os_ip.canonical_url(endpoint_type=os_ip.INTERNAL), + octavia_charm.api_port('octavia-api')) + neutron.publish_load_balancer_info('octavia', octavia_url) + + @reactive.when('shared-db.available') @reactive.when('identity-service.available') @reactive.when('amqp.available') diff --git a/unit_tests/test_octavia_handlers.py b/unit_tests/test_octavia_handlers.py index a24b77f9..a67d298c 100644 --- a/unit_tests/test_octavia_handlers.py +++ b/unit_tests/test_octavia_handlers.py @@ -42,6 +42,8 @@ class TestRegisteredHooks(test_utils.TestRegisteredHooks): 'init_db': ('config.rendered',), 'cluster_connected': ('ha.connected',), 'generate_heartbeat_key': ('leadership.is_leader',), + 'setup_neutron_lbaas_proxy': ( + 'neutron-load-balancer.available',), }, 'when_not': { 'init_db': ('db.synced',), @@ -74,6 +76,24 @@ class TestOctaviaHandlers(test_utils.PatchHelper): {'heartbeat-key': fake_uuid4}) self.uuid4.assert_called_once_with() + def test_neutron_lbaas_proxy(self): + octavia_charm = mock.MagicMock() + self.patch_object(handlers.charm, 'provide_charm_instance', + new=mock.MagicMock()) + self.provide_charm_instance().__enter__.return_value = octavia_charm + self.provide_charm_instance().__exit__.return_value = None + + self.patch('charms.reactive.endpoint_from_flag', 'endpoint_from_flag') + endpoint = mock.MagicMock() + self.endpoint_from_flag.return_value = endpoint + self.patch('charms_openstack.ip.canonical_url', 'canonical_url') + self.canonical_url.return_value = 'http://1.2.3.4' + octavia_charm.api_port.return_value = '1234' + handlers.setup_neutron_lbaas_proxy() + self.canonical_url.assert_called_with(endpoint_type='int') + endpoint.publish_load_balancer_info.assert_called_with( + 'octavia', 'http://1.2.3.4:1234') + def test_render(self): self.patch('charms.reactive.set_state', 'set_state') handlers.render('arg1', 'arg2')