Merge "Add disable-neutron-lbaas option"

This commit is contained in:
Zuul 2020-07-03 10:21:08 +00:00 committed by Gerrit Code Review
commit 6dcc8e3ae1
5 changed files with 143 additions and 8 deletions

View File

@ -356,3 +356,9 @@ options:
order to support kernels with limited namespace support. i.e. Trusty. order to support kernels with limited namespace support. i.e. Trusty.
Changing the value after neutron DHCP agents are created will break Changing the value after neutron DHCP agents are created will break
access. The charm will go into a blocked state if this is attempted. access. The charm will go into a blocked state if this is attempted.
disable-neutron-lbaas:
type: boolean
default: False
description: |
Manually disable lbaas services. Set this option to True if Octavia
is used with neutron. This option is ignored for Train+ OpenStack.

View File

@ -71,7 +71,9 @@ from neutron_utils import (
pause_unit_helper, pause_unit_helper,
resume_unit_helper, resume_unit_helper,
remove_legacy_nova_metadata, remove_legacy_nova_metadata,
remove_legacy_neutron_lbaas,
disable_nova_metadata, disable_nova_metadata,
disable_neutron_lbaas,
remove_old_packages, remove_old_packages,
deprecated_services, deprecated_services,
) )
@ -127,6 +129,12 @@ def install():
# n-gateway and n-cloud-controller services. # n-gateway and n-cloud-controller services.
install_systemd_override() install_systemd_override()
# LP #1825906: prefer to install the lbaas package and then mask it
# instead of checking if we need to install that package on each
# config-changed hook
if disable_neutron_lbaas():
remove_legacy_neutron_lbaas()
@hooks.hook('config-changed') @hooks.hook('config-changed')
@restart_on_change(restart_map) @restart_on_change(restart_map)
@ -185,6 +193,8 @@ def config_changed():
# Disable nova metadata if possible, # Disable nova metadata if possible,
if disable_nova_metadata(): if disable_nova_metadata():
remove_legacy_nova_metadata() remove_legacy_nova_metadata()
if disable_neutron_lbaas():
remove_legacy_neutron_lbaas()
@hooks.hook('upgrade-charm') @hooks.hook('upgrade-charm')

View File

@ -684,11 +684,18 @@ def resolve_config_files(plugin, release):
drop_config.extend([NEUTRON_LBAAS_AA_PROFILE_PATH]) drop_config.extend([NEUTRON_LBAAS_AA_PROFILE_PATH])
# Drop lbaasv2 at train # Drop lbaasv2 at train
if cmp_os_release >= 'train': # or drop if disable-lbaas option is true
if disable_neutron_lbaas():
if cmp_os_release >= 'newton':
drop_config.extend([ drop_config.extend([
NEUTRON_LBAASV2_AA_PROFILE_PATH, NEUTRON_LBAASV2_AA_PROFILE_PATH,
NEUTRON_LBAAS_AGENT_CONF, NEUTRON_LBAAS_AGENT_CONF,
]) ])
else:
drop_config.extend([
NEUTRON_LBAAS_AA_PROFILE_PATH,
NEUTRON_LBAAS_AGENT_CONF,
])
if disable_nova_metadata(cmp_os_release): if disable_nova_metadata(cmp_os_release):
drop_config.extend(get_nova_config_files().keys()) drop_config.extend(get_nova_config_files().keys())
@ -770,6 +777,11 @@ def restart_map(release=None):
svcs.add('neutron-lbaasv2-agent') svcs.add('neutron-lbaasv2-agent')
if cmp_release >= 'train' and 'neutron-lbaasv2-agent' in svcs: if cmp_release >= 'train' and 'neutron-lbaasv2-agent' in svcs:
svcs.remove('neutron-lbaasv2-agent') svcs.remove('neutron-lbaasv2-agent')
if disable_neutron_lbaas():
if cmp_release < 'newton' and 'neutron-lbaas-agent' in svcs:
svcs.remove('neutron-lbaas-agent')
elif cmp_release >= 'newton' and 'neutron-lbaasv2-agent' in svcs:
svcs.remove('neutron-lbaasv2-agent')
if svcs: if svcs:
_map[f] = list(svcs) _map[f] = list(svcs)
return _map return _map
@ -930,8 +942,21 @@ def remove_legacy_nova_metadata():
remove_file(f) remove_file(f)
def remove_legacy_neutron_lbaas():
"""Remove neutron lbaas files."""
cmp_os_source = CompareOpenStackReleases(os_release('neutron-common'))
service_name = 'neutron-lbaas-agent'
if cmp_os_source >= 'train':
return
if cmp_os_source >= 'newton':
service_name = 'neutron-lbaasv2-agent'
service_stop(service_name)
service('disable', service_name)
service('mask', service_name)
def disable_nova_metadata(cmp_os_source=None): def disable_nova_metadata(cmp_os_source=None):
"""Check whether nova mnetadata service should be disabled.""" """Check whether nova metadata service should be disabled."""
if not cmp_os_source: if not cmp_os_source:
cmp_os_source = CompareOpenStackReleases(os_release('neutron-common')) cmp_os_source = CompareOpenStackReleases(os_release('neutron-common'))
if cmp_os_source >= 'rocky': if cmp_os_source >= 'rocky':
@ -951,6 +976,15 @@ def disable_nova_metadata(cmp_os_source=None):
return disable return disable
def disable_neutron_lbaas(cmp_os_source=None):
"""Check whether neutron lbaas service should be disabled."""
if not cmp_os_source:
cmp_os_source = CompareOpenStackReleases(os_release('neutron-common'))
if cmp_os_source >= 'train':
return True
return config('disable-neutron-lbaas') or False
def cache_env_data(): def cache_env_data():
env = NetworkServiceContext()() env = NetworkServiceContext()()
if not env: if not env:
@ -1127,7 +1161,10 @@ def deprecated_services():
services = [] services = []
if disable_nova_metadata(): if disable_nova_metadata():
services.append('nova-api-metadata') services.append('nova-api-metadata')
if cmp_release >= 'train': if disable_neutron_lbaas():
if cmp_release >= 'newton':
services.append('neutron-lbaasv2-agent') services.append('neutron-lbaasv2-agent')
else:
services.append('neutron-lbaas-agent')
return services return services

View File

@ -54,7 +54,9 @@ TO_PATCH = [
'install_systemd_override', 'install_systemd_override',
'configure_apparmor', 'configure_apparmor',
'disable_nova_metadata', 'disable_nova_metadata',
'disable_neutron_lbaas',
'remove_legacy_nova_metadata', 'remove_legacy_nova_metadata',
'remove_legacy_neutron_lbaas',
'services', 'services',
'remove_old_packages', 'remove_old_packages',
'is_container', 'is_container',
@ -110,12 +112,14 @@ class TestQuantumHooks(CharmTestCase):
@patch('sys.exit') @patch('sys.exit')
def test_install_hook_invalid_plugin(self, _exit): def test_install_hook_invalid_plugin(self, _exit):
self.valid_plugin.return_value = False self.valid_plugin.return_value = False
self.disable_neutron_lbaas.return_value = False
self._call_hook('install') self._call_hook('install')
self.assertTrue(self.log.called) self.assertTrue(self.log.called)
_exit.assert_called_with(1) _exit.assert_called_with(1)
def test_config_changed(self): def test_config_changed(self):
self.disable_nova_metadata.return_value = False self.disable_nova_metadata.return_value = False
self.disable_neutron_lbaas.return_value = False
def mock_relids(rel): def mock_relids(rel):
return ['relid'] return ['relid']
@ -143,8 +147,26 @@ class TestQuantumHooks(CharmTestCase):
self.modprobe.assert_called_with( self.modprobe.assert_called_with(
'foo-bar') 'foo-bar')
def test_config_change_disable_lbaas(self):
self.disable_nova_metadata.return_value = False
self.disable_neutron_lbaas.return_value = True
def mock_relids(rel):
return ['relid']
self.test_config.set(
'sysctl',
'{foo : bar}'
)
self.openstack_upgrade_available.return_value = True
self.valid_plugin.return_value = True
self.relation_ids.side_effect = mock_relids
self._call_hook('config-changed')
self.assertTrue(self.disable_neutron_lbaas.called)
self.assertTrue(self.remove_legacy_neutron_lbaas.called)
def test_config_changed_in_container(self): def test_config_changed_in_container(self):
self.disable_nova_metadata.return_value = False self.disable_nova_metadata.return_value = False
self.disable_neutron_lbaas.return_value = False
def mock_relids(rel): def mock_relids(rel):
return ['relid'] return ['relid']
@ -167,6 +189,7 @@ class TestQuantumHooks(CharmTestCase):
def test_config_changed_upgrade(self): def test_config_changed_upgrade(self):
self.disable_nova_metadata.return_value = False self.disable_nova_metadata.return_value = False
self.disable_neutron_lbaas.return_value = False
self.openstack_upgrade_available.return_value = True self.openstack_upgrade_available.return_value = True
self.valid_plugin.return_value = True self.valid_plugin.return_value = True
self._call_hook('config-changed') self._call_hook('config-changed')
@ -176,6 +199,7 @@ class TestQuantumHooks(CharmTestCase):
def test_config_changed_n1kv(self): def test_config_changed_n1kv(self):
self.openstack_upgrade_available.return_value = False self.openstack_upgrade_available.return_value = False
self.valid_plugin.return_value = True self.valid_plugin.return_value = True
self.disable_neutron_lbaas.return_value = False
self.filter_installed_packages.side_effect = lambda p: p self.filter_installed_packages.side_effect = lambda p: p
self.test_config.set('plugin', 'n1kv') self.test_config.set('plugin', 'n1kv')
self._call_hook('config-changed') self._call_hook('config-changed')
@ -186,6 +210,7 @@ class TestQuantumHooks(CharmTestCase):
@patch('sys.exit') @patch('sys.exit')
def test_config_changed_invalid_plugin(self, _exit): def test_config_changed_invalid_plugin(self, _exit):
self.disable_neutron_lbaas.return_value = False
self.disable_nova_metadata.return_value = False self.disable_nova_metadata.return_value = False
self.valid_plugin.return_value = False self.valid_plugin.return_value = False
self._call_hook('config-changed') self._call_hook('config-changed')
@ -255,6 +280,7 @@ class TestQuantumHooks(CharmTestCase):
def test_nm_changed(self): def test_nm_changed(self):
self.disable_nova_metadata.return_value = False self.disable_nova_metadata.return_value = False
self.disable_neutron_lbaas.return_value = False
def _relation_get(key): def _relation_get(key):
data = { data = {
@ -278,6 +304,7 @@ class TestQuantumHooks(CharmTestCase):
mock_get_packages): mock_get_packages):
'''Ensure first set of restart_trigger restarts nova-api-metadata''' '''Ensure first set of restart_trigger restarts nova-api-metadata'''
self.disable_nova_metadata.return_value = False self.disable_nova_metadata.return_value = False
self.disable_neutron_lbaas.return_value = False
# as restart_map is embedded into the decorator, we have to mock out # as restart_map is embedded into the decorator, we have to mock out
# the bits in the restart_map to be able to make it pass. # the bits in the restart_map to be able to make it pass.
mock_os_release.return_value = 'mitaka' mock_os_release.return_value = 'mitaka'
@ -316,6 +343,7 @@ class TestQuantumHooks(CharmTestCase):
mock_get_packages): mock_get_packages):
'''Ensure change of restart_trigger restarts nova-api-metadata''' '''Ensure change of restart_trigger restarts nova-api-metadata'''
self.disable_nova_metadata.return_value = False self.disable_nova_metadata.return_value = False
self.disable_neutron_lbaas.return_value = False
# as restart_map is embedded into the decorator, we have to mock out # as restart_map is embedded into the decorator, we have to mock out
# the bits in the restart_map to be able to make it pass. # the bits in the restart_map to be able to make it pass.
mock_os_release.return_value = 'mitaka' mock_os_release.return_value = 'mitaka'
@ -355,6 +383,7 @@ class TestQuantumHooks(CharmTestCase):
'''Ensure no change in restart_trigger skips restarts''' '''Ensure no change in restart_trigger skips restarts'''
self.patch_object(hooks, 'disable_nova_metadata', self.patch_object(hooks, 'disable_nova_metadata',
return_value=False) return_value=False)
self.disable_neutron_lbaas.return_value = False
# as restart_map is embedded into the decorator, we have to mock out # as restart_map is embedded into the decorator, we have to mock out
# the bits in the restart_map to be able to make it pass. # the bits in the restart_map to be able to make it pass.
mock_os_release.return_value = 'mitaka' mock_os_release.return_value = 'mitaka'
@ -383,6 +412,7 @@ class TestQuantumHooks(CharmTestCase):
def test_nm_changed_disable_meta(self): def test_nm_changed_disable_meta(self):
self.disable_nova_metadata.return_value = True self.disable_nova_metadata.return_value = True
self.disable_neutron_lbaas.return_value = False
def _relation_get(key): def _relation_get(key):
data = { data = {
@ -427,6 +457,7 @@ class TestQuantumHooks(CharmTestCase):
def test_quantum_network_service_relation_changed(self): def test_quantum_network_service_relation_changed(self):
self.patch_object(hooks, 'disable_nova_metadata', self.patch_object(hooks, 'disable_nova_metadata',
return_value=False) return_value=False)
self.disable_neutron_lbaas.return_value = False
self.test_config.set('ha-legacy-mode', True) self.test_config.set('ha-legacy-mode', True)
self._call_hook('quantum-network-service-relation-changed') self._call_hook('quantum-network-service-relation-changed')
self.assertTrue(self.cache_env_data.called) self.assertTrue(self.cache_env_data.called)

View File

@ -44,6 +44,7 @@ TO_PATCH = [
'NeutronAPIContext', 'NeutronAPIContext',
'enable_ipfix', 'enable_ipfix',
'disable_ipfix', 'disable_ipfix',
'disable_neutron_lbaas',
] ]
@ -152,6 +153,7 @@ class TestNeutronUtils(CharmTestCase):
self.patch_object(neutron_utils, 'disable_nova_metadata', self.patch_object(neutron_utils, 'disable_nova_metadata',
return_value=False) return_value=False)
self.config.return_value = 'ovs' self.config.return_value = 'ovs'
self.disable_neutron_lbaas.return_value = False
self.os_release.return_value = 'newton' self.os_release.return_value = 'newton'
packages = neutron_utils.get_packages() packages = neutron_utils.get_packages()
self.assertTrue('neutron-metering-agent' in packages) self.assertTrue('neutron-metering-agent' in packages)
@ -241,6 +243,7 @@ class TestNeutronUtils(CharmTestCase):
self.patch_object(neutron_utils, 'disable_nova_metadata', self.patch_object(neutron_utils, 'disable_nova_metadata',
return_value=False) return_value=False)
self.config.return_value = 'ovs-odl' self.config.return_value = 'ovs-odl'
self.disable_neutron_lbaas.return_value = False
self.os_release.return_value = 'icehouse' self.os_release.return_value = 'icehouse'
packages = neutron_utils.get_packages() packages = neutron_utils.get_packages()
self.assertTrue('neutron-metering-agent' in packages) self.assertTrue('neutron-metering-agent' in packages)
@ -253,6 +256,7 @@ class TestNeutronUtils(CharmTestCase):
self.patch_object(neutron_utils, 'disable_nova_metadata', self.patch_object(neutron_utils, 'disable_nova_metadata',
return_value=False) return_value=False)
self.config.return_value = 'ovs-odl' self.config.return_value = 'ovs-odl'
self.disable_neutron_lbaas.return_value = False
self.os_release.return_value = 'newton' self.os_release.return_value = 'newton'
packages = neutron_utils.get_packages() packages = neutron_utils.get_packages()
self.assertTrue('neutron-metering-agent' in packages) self.assertTrue('neutron-metering-agent' in packages)
@ -513,6 +517,7 @@ class TestNeutronUtils(CharmTestCase):
self.patch_object(neutron_utils, 'disable_nova_metadata', self.patch_object(neutron_utils, 'disable_nova_metadata',
return_value=False) return_value=False)
self.config.return_value = 'ovs' self.config.return_value = 'ovs'
self.disable_neutron_lbaas.return_value = False
self.get_os_codename_install_source.return_value = 'havana' self.get_os_codename_install_source.return_value = 'havana'
mock_get_packages.return_value = ['neutron-vpn-agent'] mock_get_packages.return_value = ['neutron-vpn-agent']
self.os_release.return_value = 'icehouse' self.os_release.return_value = 'icehouse'
@ -560,6 +565,7 @@ class TestNeutronUtils(CharmTestCase):
self.patch_object(neutron_utils, 'disable_nova_metadata', self.patch_object(neutron_utils, 'disable_nova_metadata',
return_value=False) return_value=False)
self.config.return_value = 'ovs' self.config.return_value = 'ovs'
self.disable_neutron_lbaas.return_value = False
mock_get_packages.return_value = ['neutron-vpn-agent'] mock_get_packages.return_value = ['neutron-vpn-agent']
self.os_release.return_value = 'mitaka' self.os_release.return_value = 'mitaka'
ex_map = { ex_map = {
@ -605,6 +611,7 @@ class TestNeutronUtils(CharmTestCase):
self.patch_object(neutron_utils, 'disable_nova_metadata', self.patch_object(neutron_utils, 'disable_nova_metadata',
return_value=False) return_value=False)
self.config.return_value = 'ovs' self.config.return_value = 'ovs'
self.disable_neutron_lbaas.return_value = False
mock_get_packages.return_value = ['neutron-vpn-agent'] mock_get_packages.return_value = ['neutron-vpn-agent']
self.os_release.return_value = 'newton' self.os_release.return_value = 'newton'
ex_map = { ex_map = {
@ -645,6 +652,47 @@ class TestNeutronUtils(CharmTestCase):
} }
self.assertEqual(neutron_utils.restart_map(), ex_map) self.assertEqual(neutron_utils.restart_map(), ex_map)
@patch.object(neutron_utils, 'get_packages')
def test_restart_map_ovs_stein_disable_lbaas(self, mock_get_packages):
self.patch_object(neutron_utils, 'disable_nova_metadata',
return_value=False)
self.config.return_value = 'ovs'
self.disable_neutron_lbaas.return_value = True
mock_get_packages.return_value = ['neutron-vpn-agent']
self.os_release.return_value = 'stein'
ex_map = {
neutron_utils.NEUTRON_CONF: ['neutron-vpn-agent',
'neutron-dhcp-agent',
'neutron-metering-agent',
'neutron-metadata-agent',
'neutron-openvswitch-agent'],
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
neutron_utils.NEUTRON_OVS_AGENT_CONF:
['neutron-openvswitch-agent'],
neutron_utils.NEUTRON_METADATA_AGENT_CONF:
['neutron-metadata-agent'],
neutron_utils.NEUTRON_VPNAAS_AGENT_CONF: ['neutron-vpn-agent'],
neutron_utils.NEUTRON_L3_AGENT_CONF: ['neutron-vpn-agent'],
neutron_utils.NEUTRON_DHCP_AGENT_CONF: ['neutron-dhcp-agent'],
neutron_utils.NEUTRON_FWAAS_CONF: ['neutron-vpn-agent'],
neutron_utils.NEUTRON_METERING_AGENT_CONF:
['neutron-metering-agent'],
neutron_utils.NOVA_CONF: ['nova-api-metadata'],
neutron_utils.EXT_PORT_CONF: ['ext-port'],
neutron_utils.PHY_NIC_MTU_CONF: ['os-charm-phy-nic-mtu'],
neutron_utils.NEUTRON_DHCP_AA_PROFILE_PATH: ['neutron-dhcp-agent'],
neutron_utils.NEUTRON_OVS_AA_PROFILE_PATH:
['neutron-openvswitch-agent'],
neutron_utils.NEUTRON_L3_AA_PROFILE_PATH: ['neutron-vpn-agent'],
neutron_utils.NEUTRON_METADATA_AA_PROFILE_PATH:
['neutron-metadata-agent'],
neutron_utils.NEUTRON_METERING_AA_PROFILE_PATH:
['neutron-metering-agent'],
neutron_utils.NOVA_API_METADATA_AA_PROFILE_PATH:
['nova-api-metadata'],
}
self.assertEqual(neutron_utils.restart_map(), ex_map)
@patch.object(neutron_utils, 'get_packages') @patch.object(neutron_utils, 'get_packages')
def test_restart_map_ovs_train(self, mock_get_packages): def test_restart_map_ovs_train(self, mock_get_packages):
self.patch_object(neutron_utils, 'disable_nova_metadata', self.patch_object(neutron_utils, 'disable_nova_metadata',
@ -702,6 +750,7 @@ class TestNeutronUtils(CharmTestCase):
self.patch_object(neutron_utils, 'disable_nova_metadata', self.patch_object(neutron_utils, 'disable_nova_metadata',
return_value=False) return_value=False)
self.config.return_value = 'ovs-odl' self.config.return_value = 'ovs-odl'
self.disable_neutron_lbaas.return_value = False
mock_get_packages.return_value = ['neutron-vpn-agent'] mock_get_packages.return_value = ['neutron-vpn-agent']
self.os_release.return_value = 'icehouse' self.os_release.return_value = 'icehouse'
ex_map = { ex_map = {
@ -741,6 +790,7 @@ class TestNeutronUtils(CharmTestCase):
def test_restart_map_ovs_odl_newton(self, mock_get_packages): def test_restart_map_ovs_odl_newton(self, mock_get_packages):
self.patch_object(neutron_utils, 'disable_nova_metadata', self.patch_object(neutron_utils, 'disable_nova_metadata',
return_value=False) return_value=False)
self.disable_neutron_lbaas.return_value = False
self.config.return_value = 'ovs-odl' self.config.return_value = 'ovs-odl'
mock_get_packages.return_value = ['neutron-vpn-agent'] mock_get_packages.return_value = ['neutron-vpn-agent']
self.os_release.return_value = 'newton' self.os_release.return_value = 'newton'
@ -897,6 +947,7 @@ class TestNeutronUtils(CharmTestCase):
self._set_distrib_codename('trusty') self._set_distrib_codename('trusty')
self.os_release.return_value = 'mitaka' self.os_release.return_value = 'mitaka'
self.is_relation_made = False self.is_relation_made = False
self.disable_neutron_lbaas.return_value = False
actual_map = neutron_utils.resolve_config_files(neutron_utils.OVS, actual_map = neutron_utils.resolve_config_files(neutron_utils.OVS,
'mitaka') 'mitaka')
actual_configs = actual_map[neutron_utils.OVS].keys() actual_configs = actual_map[neutron_utils.OVS].keys()