charms.openstack/charms_openstack/ip.py

83 lines
2.7 KiB
Python

# need/want absolute imports for the package imports to work properly
from __future__ import absolute_import
import charmhelpers.core.hookenv as hookenv
import charmhelpers.contrib.network.ip as net_ip
import charmhelpers.contrib.hahelpers.cluster
PUBLIC = 'public'
INTERNAL = 'int'
ADMIN = 'admin'
_ADDRESS_MAP = {
PUBLIC: {
'config': 'os-public-network',
'fallback': 'public-address'
},
INTERNAL: {
'config': 'os-internal-network',
'fallback': 'private-address'
},
ADMIN: {
'config': 'os-admin-network',
'fallback': 'private-address'
}
}
def canonical_url(endpoint_type=PUBLIC):
"""
Returns the correct HTTP URL to this host given the state of HTTPS
configuration, hacluster and charm configuration.
:param endpoint_type str: The endpoint type to resolve.
:returns str: Base URL for services on the current service unit.
"""
scheme = 'http'
# if 'https' in configs.complete_contexts():
# scheme = 'https'
address = resolve_address(endpoint_type)
if net_ip.is_ipv6(address):
address = "[{}]".format(address)
return "{0}://{1}".format(scheme, address)
def resolve_address(endpoint_type=PUBLIC):
"""Return the address from the config() using endpoint_type to determine
which address to return.
It returns either the vip if the unit is clustered and there is no specific
config() item for the specified address type.
If the unit is not clustered then it attempts to return either the ipv6 or
ipv4 address for the unit.
"""
resolved_address = None
if charmhelpers.contrib.hahelpers.cluster.is_clustered():
if hookenv.config(_ADDRESS_MAP[endpoint_type]['config']) is None:
# Assume vip is simple and pass back directly
resolved_address = hookenv.config('vip')
else:
for vip in hookenv.config('vip').split():
if net_ip.is_address_in_network(
hookenv.config(_ADDRESS_MAP[endpoint_type]['config']),
vip):
resolved_address = vip
else:
if hookenv.config('prefer-ipv6'):
fallback_addr = net_ip.get_ipv6_addr(
exc_list=[hookenv.config('vip')])[0]
else:
fallback_addr = hookenv.unit_get(
_ADDRESS_MAP[endpoint_type]['fallback'])
resolved_address = net_ip.get_address_in_network(
hookenv.config(_ADDRESS_MAP[endpoint_type]['config']),
fallback_addr)
if resolved_address is None:
raise ValueError('Unable to resolve a suitable IP address'
' based on charm state and configuration')
else:
return resolved_address