Add support for indicating preference for IPv6
People, such as Infra, would like to use IPv6 when it's there, but don't want to need to write the "if ipv6, awesome, else, ipv4" code all the time. Change-Id: I870955863f1e8851c684dc604584c1ef3e20dd6b
This commit is contained in:
parent
b631da86fe
commit
65dd84515b
31
README.rst
31
README.rst
@ -185,6 +185,37 @@ are connecting to OpenStack can share a cache should you desire.
|
||||
dns_service_type: hpext:dns
|
||||
|
||||
|
||||
IPv6
|
||||
----
|
||||
|
||||
IPv6 may be a thing you would prefer to use not only if the cloud supports it,
|
||||
but also if your local machine support it. A simple boolean flag is settable
|
||||
either in an environment variable, `OS_PREFER_IPV6`, or in the client section
|
||||
of the clouds.yaml.
|
||||
|
||||
::
|
||||
client:
|
||||
prefer_ipv6: true
|
||||
clouds:
|
||||
mordred:
|
||||
profile: hp
|
||||
auth:
|
||||
username: mordred@inaugust.com
|
||||
password: XXXXXXXXX
|
||||
project_name: mordred@inaugust.com
|
||||
region_name: region-b.geo-1
|
||||
monty:
|
||||
profile: rax
|
||||
auth:
|
||||
username: mordred@inaugust.com
|
||||
password: XXXXXXXXX
|
||||
project_name: mordred@inaugust.com
|
||||
region_name: DFW
|
||||
|
||||
The above snippet will tell client programs to prefer returning an IPv6
|
||||
address. This will result in calls to, for instance, `shade`'s `get_public_ip`
|
||||
to return an IPv4 address on HP, and an IPv6 address on Rackspace.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
|
@ -16,10 +16,11 @@ import warnings
|
||||
|
||||
|
||||
class CloudConfig(object):
|
||||
def __init__(self, name, region, config):
|
||||
def __init__(self, name, region, config, prefer_ipv6=False):
|
||||
self.name = name
|
||||
self.region = region
|
||||
self.config = config
|
||||
self._prefer_ipv6 = prefer_ipv6
|
||||
|
||||
def __getattr__(self, key):
|
||||
"""Return arbitrary attributes."""
|
||||
@ -96,3 +97,7 @@ class CloudConfig(object):
|
||||
def get_service_name(self, service_type):
|
||||
key = '{service_type}_service_name'.format(service_type=service_type)
|
||||
return self.config.get(key, service_type)
|
||||
|
||||
@property
|
||||
def prefer_ipv6(self):
|
||||
return self._prefer_ipv6
|
||||
|
@ -68,6 +68,8 @@ def set_default(key, value):
|
||||
|
||||
|
||||
def get_boolean(value):
|
||||
if type(value) is bool:
|
||||
return value
|
||||
if value.lower() == 'true':
|
||||
return True
|
||||
return False
|
||||
@ -116,6 +118,14 @@ class OpenStackConfig(object):
|
||||
if 'clouds' not in self.cloud_config:
|
||||
self.cloud_config['clouds'] = {}
|
||||
|
||||
# Grab ipv6 preference settings from env
|
||||
client_config = self.cloud_config.get('client', {})
|
||||
self.prefer_ipv6 = get_boolean(
|
||||
os.environ.pop(
|
||||
'OS_PREFER_IPV6', client_config.get(
|
||||
'prefer_ipv6', client_config.get(
|
||||
'prefer-ipv6', False))))
|
||||
|
||||
# Next, process environment variables and add them to the mix
|
||||
self.envvar_key = os.environ.pop('OS_CLOUD_NAME', 'envvars')
|
||||
if self.envvar_key in self.cloud_config['clouds']:
|
||||
@ -427,13 +437,16 @@ class OpenStackConfig(object):
|
||||
if hasattr(value, 'format'):
|
||||
config[key] = value.format(**config)
|
||||
|
||||
prefer_ipv6 = config.pop('prefer_ipv6', self.prefer_ipv6)
|
||||
|
||||
if cloud is None:
|
||||
cloud_name = ''
|
||||
else:
|
||||
cloud_name = str(cloud)
|
||||
return cloud_config.CloudConfig(
|
||||
name=cloud_name, region=config['region_name'],
|
||||
config=self._normalize_keys(config))
|
||||
config=self._normalize_keys(config),
|
||||
prefer_ipv6=prefer_ipv6)
|
||||
|
||||
@staticmethod
|
||||
def set_one_cloud(config_file, cloud, set_config=None):
|
||||
|
@ -38,6 +38,9 @@ VENDOR_CONF = {
|
||||
}
|
||||
}
|
||||
USER_CONF = {
|
||||
'client': {
|
||||
'prefer_ipv6': True,
|
||||
},
|
||||
'clouds': {
|
||||
'_test-cloud_': {
|
||||
'profile': '_test_cloud_in_our_cloud',
|
||||
|
@ -39,6 +39,9 @@ class TestCloudConfig(base.TestCase):
|
||||
# Lookup mystery attribute
|
||||
self.assertIsNone(cc.x)
|
||||
|
||||
# Test default ipv6
|
||||
self.assertFalse(cc.prefer_ipv6)
|
||||
|
||||
def test_iteration(self):
|
||||
cc = cloud_config.CloudConfig("test1", "region-al", fake_config_dict)
|
||||
self.assertTrue('a' in cc)
|
||||
@ -100,3 +103,8 @@ class TestCloudConfig(base.TestCase):
|
||||
cc = cloud_config.CloudConfig("test1", "region-xx", config_dict)
|
||||
(verify, cert) = cc.get_requests_verify_args()
|
||||
self.assertEqual(("cert", "key"), cert)
|
||||
|
||||
def test_ipv6(self):
|
||||
cc = cloud_config.CloudConfig(
|
||||
"test1", "region-al", fake_config_dict, prefer_ipv6=True)
|
||||
self.assertTrue(cc.prefer_ipv6)
|
||||
|
@ -107,6 +107,18 @@ class TestConfig(base.TestCase):
|
||||
self.useFixture(fixtures.EnvironmentVariable(k))
|
||||
c.get_one_cloud(cloud='defaults')
|
||||
|
||||
def test_prefer_ipv6_true(self):
|
||||
c = config.OpenStackConfig(config_files=[self.cloud_yaml],
|
||||
vendor_files=[self.vendor_yaml])
|
||||
cc = c.get_one_cloud(cloud='_test-cloud_')
|
||||
self.assertTrue(cc.prefer_ipv6)
|
||||
|
||||
def test_prefer_ipv6_false(self):
|
||||
c = config.OpenStackConfig(config_files=[self.no_yaml],
|
||||
vendor_files=[self.no_yaml])
|
||||
cc = c.get_one_cloud(cloud='defaults')
|
||||
self.assertFalse(cc.prefer_ipv6)
|
||||
|
||||
def test_get_one_cloud_auth_merge(self):
|
||||
c = config.OpenStackConfig(config_files=[self.cloud_yaml])
|
||||
cc = c.get_one_cloud(cloud='_test-cloud_', auth={'username': 'user'})
|
||||
|
@ -51,6 +51,14 @@ class TestEnviron(base.TestCase):
|
||||
cc = c.get_one_cloud('override')
|
||||
self._assert_cloud_details(cc)
|
||||
|
||||
def test_envvar_prefer_ipv6_override(self):
|
||||
self.useFixture(
|
||||
fixtures.EnvironmentVariable('OS_PREFER_IPV6', 'false'))
|
||||
c = config.OpenStackConfig(config_files=[self.cloud_yaml],
|
||||
vendor_files=[self.vendor_yaml])
|
||||
cc = c.get_one_cloud('_test-cloud_')
|
||||
self.assertFalse(cc.prefer_ipv6)
|
||||
|
||||
def test_environ_exists(self):
|
||||
c = config.OpenStackConfig(config_files=[self.cloud_yaml],
|
||||
vendor_files=[self.vendor_yaml])
|
||||
|
Loading…
x
Reference in New Issue
Block a user