Do not specify iface when creating ha vip resource
Pacemaker VIP resources are able to automatically detect and configure correct iface and netmask parameters based on local configuration of the unit. The hacluster interface will use this approach if nic and netmask are omitted when setting up the vip. If nic and netmask cannot be automatically detected then fallback to the old behaviour. If new behaviour is being used then ensure the old vip resource name is removed. Change-Id: Id2fbb71328572bada939d432030d9d7ab4814f1b
This commit is contained in:
parent
43ac4c90d0
commit
69d6e5462a
|
@ -10,6 +10,7 @@ import subprocess
|
||||||
import charmhelpers.contrib.network.ip as ch_ip
|
import charmhelpers.contrib.network.ip as ch_ip
|
||||||
import charmhelpers.contrib.openstack.utils as os_utils
|
import charmhelpers.contrib.openstack.utils as os_utils
|
||||||
import charmhelpers.contrib.openstack.ha as os_ha
|
import charmhelpers.contrib.openstack.ha as os_ha
|
||||||
|
import charmhelpers.contrib.openstack.ha.utils as os_ha_utils
|
||||||
import charmhelpers.contrib.openstack.cert_utils as cert_utils
|
import charmhelpers.contrib.openstack.cert_utils as cert_utils
|
||||||
import charmhelpers.core.hookenv as hookenv
|
import charmhelpers.core.hookenv as hookenv
|
||||||
import charmhelpers.core.host as ch_host
|
import charmhelpers.core.host as ch_host
|
||||||
|
@ -682,12 +683,19 @@ class HAOpenStackCharm(OpenStackAPICharm):
|
||||||
if not self.config.get(VIP_KEY):
|
if not self.config.get(VIP_KEY):
|
||||||
return
|
return
|
||||||
for vip in self.config[VIP_KEY].split():
|
for vip in self.config[VIP_KEY].split():
|
||||||
iface = (ch_ip.get_iface_for_address(vip) or
|
iface, netmask, fallback = os_ha_utils.get_vip_settings(vip)
|
||||||
self.config.get(IFACE_KEY))
|
if fallback:
|
||||||
netmask = (ch_ip.get_netmask_for_address(vip) or
|
hacluster.add_vip(
|
||||||
self.config.get(CIDR_KEY))
|
self.name,
|
||||||
if iface is not None:
|
vip,
|
||||||
hacluster.add_vip(self.name, vip, iface, netmask)
|
iface,
|
||||||
|
netmask)
|
||||||
|
else:
|
||||||
|
hacluster.add_vip(self.name, vip)
|
||||||
|
if iface:
|
||||||
|
# Remove vip resource using old raw nic name.
|
||||||
|
old_vip_key = 'res_{}_{}_vip'.format(self.name, iface)
|
||||||
|
hacluster.delete_resource(old_vip_key)
|
||||||
|
|
||||||
def _add_ha_haproxy_config(self, hacluster):
|
def _add_ha_haproxy_config(self, hacluster):
|
||||||
"""Add a InitService object for haproxy to self.resources
|
"""Add a InitService object for haproxy to self.resources
|
||||||
|
|
|
@ -31,6 +31,8 @@ sys.modules['charmhelpers.contrib'] = charmhelpers.contrib
|
||||||
sys.modules['charmhelpers.contrib.openstack'] = charmhelpers.contrib.openstack
|
sys.modules['charmhelpers.contrib.openstack'] = charmhelpers.contrib.openstack
|
||||||
sys.modules['charmhelpers.contrib.openstack.ha'] = (
|
sys.modules['charmhelpers.contrib.openstack.ha'] = (
|
||||||
charmhelpers.contrib.openstack.ha)
|
charmhelpers.contrib.openstack.ha)
|
||||||
|
sys.modules['charmhelpers.contrib.openstack.ha.utils'] = (
|
||||||
|
charmhelpers.contrib.openstack.ha.utils)
|
||||||
sys.modules['charmhelpers.contrib.openstack.cert_utils'] = (
|
sys.modules['charmhelpers.contrib.openstack.cert_utils'] = (
|
||||||
charmhelpers.contrib.openstack.cert_utils)
|
charmhelpers.contrib.openstack.cert_utils)
|
||||||
sys.modules['charmhelpers.contrib.openstack.utils'] = (
|
sys.modules['charmhelpers.contrib.openstack.utils'] = (
|
||||||
|
|
|
@ -481,42 +481,39 @@ class TestHAOpenStackCharm(BaseOpenStackCharmTest):
|
||||||
interface_mock.bind_resources.assert_called_once_with(iface='ens12')
|
interface_mock.bind_resources.assert_called_once_with(iface='ens12')
|
||||||
|
|
||||||
def test__add_ha_vips_config(self):
|
def test__add_ha_vips_config(self):
|
||||||
ifaces = {
|
nics = {
|
||||||
'vip1': 'eth1',
|
'vip1': ('eth1', 'netmask1', False),
|
||||||
'vip2': 'eth2'}
|
'vip2': ('eth2', 'netmask2', False)}
|
||||||
masks = {
|
|
||||||
'vip1': 'netmask1',
|
|
||||||
'vip2': 'netmask2'}
|
|
||||||
interface_mock = mock.Mock()
|
interface_mock = mock.Mock()
|
||||||
self.patch_target('name', new='myservice')
|
self.patch_target('name', new='myservice')
|
||||||
self.patch_target('config', new={'vip': 'vip1 vip2'})
|
self.patch_target('config', new={'vip': 'vip1 vip2'})
|
||||||
self.patch_object(chm.ch_ip, 'get_iface_for_address')
|
self.patch_object(chm.os_ha_utils, 'get_vip_settings')
|
||||||
self.get_iface_for_address.side_effect = lambda x: ifaces[x]
|
self.get_vip_settings.side_effect = lambda x: nics[x]
|
||||||
self.patch_object(chm.ch_ip, 'get_netmask_for_address')
|
|
||||||
self.get_netmask_for_address.side_effect = lambda x: masks[x]
|
|
||||||
self.target._add_ha_vips_config(interface_mock)
|
self.target._add_ha_vips_config(interface_mock)
|
||||||
calls = [
|
add_vip_calls = [
|
||||||
mock.call('myservice', 'vip1', 'eth1', 'netmask1'),
|
mock.call('myservice', 'vip1'),
|
||||||
mock.call('myservice', 'vip2', 'eth2', 'netmask2')]
|
mock.call('myservice', 'vip2')]
|
||||||
interface_mock.add_vip.assert_has_calls(calls)
|
interface_mock.add_vip.assert_has_calls(add_vip_calls)
|
||||||
|
add_vip_calls = [
|
||||||
|
mock.call('res_myservice_eth1_vip'),
|
||||||
|
mock.call('res_myservice_eth2_vip')]
|
||||||
|
interface_mock.delete_resource.assert_has_calls(add_vip_calls)
|
||||||
|
|
||||||
def test__add_ha_vips_config_fallback(self):
|
def test__add_ha_vips_config_fallback(self):
|
||||||
config = {
|
nics = {
|
||||||
'vip_cidr': 'user_cidr',
|
'vip1': ('eth1', 'netmask1', True),
|
||||||
'vip_iface': 'user_iface',
|
'vip2': ('eth2', 'netmask2', True)}
|
||||||
'vip': 'vip1 vip2'}
|
|
||||||
interface_mock = mock.Mock()
|
interface_mock = mock.Mock()
|
||||||
self.patch_target('name', new='myservice')
|
self.patch_target('name', new='myservice')
|
||||||
self.patch_target('config', new=config)
|
self.patch_target('config', new={'vip': 'vip1 vip2'})
|
||||||
self.patch_object(chm.ch_ip, 'get_iface_for_address')
|
self.patch_object(chm.os_ha_utils, 'get_vip_settings')
|
||||||
self.patch_object(chm.ch_ip, 'get_netmask_for_address')
|
self.get_vip_settings.side_effect = lambda x: nics[x]
|
||||||
self.get_iface_for_address.return_value = None
|
|
||||||
self.get_netmask_for_address.return_value = None
|
|
||||||
self.target._add_ha_vips_config(interface_mock)
|
self.target._add_ha_vips_config(interface_mock)
|
||||||
calls = [
|
add_vip_calls = [
|
||||||
mock.call('myservice', 'vip1', 'user_iface', 'user_cidr'),
|
mock.call('myservice', 'vip1', 'eth1', 'netmask1'),
|
||||||
mock.call('myservice', 'vip2', 'user_iface', 'user_cidr')]
|
mock.call('myservice', 'vip2', 'eth2', 'netmask2')]
|
||||||
interface_mock.add_vip.assert_has_calls(calls)
|
interface_mock.add_vip.assert_has_calls(add_vip_calls)
|
||||||
|
self.assertFalse(interface_mock.delete_resource.called)
|
||||||
|
|
||||||
def test__add_ha_vips_config_novip(self):
|
def test__add_ha_vips_config_novip(self):
|
||||||
config = {'vip': None}
|
config = {'vip': None}
|
||||||
|
|
Loading…
Reference in New Issue