Check for IP addresses assigned to multiple hosts
added a check in dynamic_inventory to discover ip addresses assigned to more than one host in openstack_user_config and warn users in case of any. Change-Id: I5fc9c6441e82ccd37ab23ba2e194e30ae7918f00
This commit is contained in:
parent
1b4550b0b8
commit
3a5672beb3
@ -49,6 +49,22 @@ REQUIRED_HOSTVARS = [
|
||||
]
|
||||
|
||||
|
||||
class MultipleHostsWithOneIPError(Exception):
|
||||
def __init__(self, ip, assigned_host, new_host):
|
||||
self.ip = ip
|
||||
self.assigned_host = assigned_host
|
||||
self.new_host = new_host
|
||||
|
||||
error_msg = ("ip address:{} has already been "
|
||||
"assigned to host:{}, cannot "
|
||||
"assign same ip to host:{}")
|
||||
|
||||
self.message = error_msg.format(ip, assigned_host, new_host)
|
||||
|
||||
def __str__(self):
|
||||
return self.message
|
||||
|
||||
|
||||
def args():
|
||||
"""Setup argument Parsing."""
|
||||
parser = argparse.ArgumentParser(
|
||||
@ -855,6 +871,26 @@ def _extra_config(user_defined_config, base_dir):
|
||||
)
|
||||
|
||||
|
||||
def _check_same_ip_to_multiple_host(config):
|
||||
"""Check for IPs assigned to multiple hosts
|
||||
|
||||
: param: config: ``dict`` User provided configuration
|
||||
"""
|
||||
|
||||
ips_to_hostnames_mapping = dict()
|
||||
for key, value in config.iteritems():
|
||||
if key.endswith('hosts'):
|
||||
for _key, _value in value.iteritems():
|
||||
hostname = _key
|
||||
ip = _value['ip']
|
||||
if not (ip in ips_to_hostnames_mapping):
|
||||
ips_to_hostnames_mapping[ip] = hostname
|
||||
else:
|
||||
if ips_to_hostnames_mapping[ip] != hostname:
|
||||
info = (ip, ips_to_hostnames_mapping[ip], hostname)
|
||||
raise MultipleHostsWithOneIPError(*info)
|
||||
|
||||
|
||||
def _check_config_settings(cidr_networks, config, container_skel):
|
||||
"""check preciseness of config settings
|
||||
|
||||
@ -896,6 +932,8 @@ def _check_config_settings(cidr_networks, config, container_skel):
|
||||
raise SystemExit(
|
||||
"can't find " + q_name + " in cidr_networks"
|
||||
)
|
||||
# look for same ip address assigned to different hosts
|
||||
_check_same_ip_to_multiple_host(config)
|
||||
|
||||
|
||||
def load_environment(config_path):
|
||||
|
@ -329,8 +329,8 @@ class TestIps(unittest.TestCase):
|
||||
|
||||
|
||||
class TestConfigChecks(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.config_changed = False
|
||||
self.user_defined_config = dict()
|
||||
with open(USER_CONFIG_FILE, 'rb') as f:
|
||||
self.user_defined_config.update(yaml.safe_load(f.read()) or {})
|
||||
@ -351,6 +351,7 @@ class TestConfigChecks(unittest.TestCase):
|
||||
self.write_config()
|
||||
|
||||
def write_config(self):
|
||||
self.config_changed = True
|
||||
# rename temporarily our user_config_file so we can use the new one
|
||||
os.rename(USER_CONFIG_FILE, USER_CONFIG_FILE + ".tmp")
|
||||
# Save new user_config_file
|
||||
@ -380,6 +381,14 @@ class TestConfigChecks(unittest.TestCase):
|
||||
expectedLog = "No container CIDR specified in user config"
|
||||
self.assertEqual(context.exception.message, expectedLog)
|
||||
|
||||
def set_new_hostname(self, user_defined_config, group,
|
||||
old_hostname, new_hostname):
|
||||
self.config_changed = True
|
||||
# set a new name for the specified hostname
|
||||
old_hostname_settings = user_defined_config[group].pop(old_hostname)
|
||||
user_defined_config[group][new_hostname] = old_hostname_settings
|
||||
self.write_config()
|
||||
|
||||
def test_provider_networks_check(self):
|
||||
# create config file without provider networks
|
||||
self.delete_config_key(self.user_defined_config, 'provider_networks')
|
||||
@ -398,10 +407,42 @@ class TestConfigChecks(unittest.TestCase):
|
||||
expectedLog = "global_overrides can't be found in user config"
|
||||
self.assertEqual(context.exception.message, expectedLog)
|
||||
|
||||
def test_two_hosts_same_ip(self):
|
||||
# Use an OrderedDict to be certain our testing order is preserved
|
||||
# Even with the same hash seed, different OSes get different results,
|
||||
# eg. local OS X vs gate's Linux
|
||||
config = collections.OrderedDict()
|
||||
config['infra_hosts'] = {
|
||||
'host1': {
|
||||
'ip': '192.168.1.1'
|
||||
}
|
||||
}
|
||||
config['compute_hosts'] = {
|
||||
'host2': {
|
||||
'ip': '192.168.1.1'
|
||||
}
|
||||
}
|
||||
|
||||
with self.assertRaises(di.MultipleHostsWithOneIPError) as context:
|
||||
di._check_same_ip_to_multiple_host(config)
|
||||
self.assertEqual(context.exception.ip, '192.168.1.1')
|
||||
self.assertEqual(context.exception.assigned_host, 'host1')
|
||||
self.assertEqual(context.exception.new_host, 'host2')
|
||||
|
||||
def test_two_hosts_same_ip_externally(self):
|
||||
self.set_new_hostname(self.user_defined_config, "haproxy_hosts",
|
||||
"aio1", "hap")
|
||||
with self.assertRaises(di.MultipleHostsWithOneIPError) as context:
|
||||
get_inventory()
|
||||
expectedLog = ("ip address:172.29.236.100 has already been assigned"
|
||||
" to host:aio1, cannot assign same ip to host:hap")
|
||||
self.assertEqual(context.exception.message, expectedLog)
|
||||
|
||||
def tearDown(self):
|
||||
# get back our initial user config file
|
||||
os.remove(USER_CONFIG_FILE)
|
||||
os.rename(USER_CONFIG_FILE + ".tmp", USER_CONFIG_FILE)
|
||||
if self.config_changed:
|
||||
# get back our initial user config file
|
||||
os.remove(USER_CONFIG_FILE)
|
||||
os.rename(USER_CONFIG_FILE + ".tmp", USER_CONFIG_FILE)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
Reference in New Issue
Block a user