1
# Copyright 2014-2015 Canonical Limited.
3
# This file is part of charm-helpers.
5
# charm-helpers is free software: you can redistribute it and/or modify
6
# it under the terms of the GNU Lesser General Public License version 3 as
7
# published by the Free Software Foundation.
9
# charm-helpers is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU Lesser General Public License for more details.
14
# You should have received a copy of the GNU Lesser General Public License
15
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
17
from charmhelpers.core.hookenv import (
22
from charmhelpers.contrib.network.ip import (
23
get_address_in_network,
24
is_address_in_network,
28
from charmhelpers.contrib.hahelpers.cluster import is_clustered
36
'config': 'os-public-network',
37
'fallback': 'public-address',
38
'override': 'os-public-hostname',
41
'config': 'os-internal-network',
42
'fallback': 'private-address',
43
'override': 'os-internal-hostname',
46
'config': 'os-admin-network',
47
'fallback': 'private-address',
48
'override': 'os-admin-hostname',
53
def canonical_url(configs, endpoint_type=PUBLIC):
54
"""Returns the correct HTTP URL to this host given the state of HTTPS
55
configuration, hacluster and charm configuration.
57
:param configs: OSTemplateRenderer config templating object to inspect
58
for a complete https context.
59
:param endpoint_type: str endpoint type to resolve.
60
:param returns: str base URL for services on the current service unit.
62
scheme = _get_scheme(configs)
64
address = resolve_address(endpoint_type)
66
address = "[{}]".format(address)
68
return '%s://%s' % (scheme, address)
71
def _get_scheme(configs):
72
"""Returns the scheme to use for the url (either http or https)
73
depending upon whether https is in the configs value.
75
:param configs: OSTemplateRenderer config templating object to inspect
76
for a complete https context.
77
:returns: either 'http' or 'https' depending on whether https is
78
configured within the configs context.
81
if configs and 'https' in configs.complete_contexts():
86
def _get_address_override(endpoint_type=PUBLIC):
87
"""Returns any address overrides that the user has defined based on the
90
Note: this function allows for the service name to be inserted into the
91
address if the user specifies {service_name}.somehost.org.
93
:param endpoint_type: the type of endpoint to retrieve the override
95
:returns: any endpoint address or hostname that the user has overridden
96
or None if an override is not present.
98
override_key = ADDRESS_MAP[endpoint_type]['override']
99
addr_override = config(override_key)
100
if not addr_override:
103
return addr_override.format(service_name=service_name())
106
def resolve_address(endpoint_type=PUBLIC):
107
"""Return unit address depending on net config.
109
If unit is clustered with vip(s) and has net splits defined, return vip on
110
correct network. If clustered with no nets defined, return primary vip.
112
If not clustered, return unit address ensuring address is on configured net
113
split if one is configured.
115
:param endpoint_type: Network endpoing type
117
resolved_address = _get_address_override(endpoint_type)
119
return resolved_address
125
net_type = ADDRESS_MAP[endpoint_type]['config']
126
net_addr = config(net_type)
127
net_fallback = ADDRESS_MAP[endpoint_type]['fallback']
128
clustered = is_clustered()
131
# If no net-splits defined, we expect a single vip
132
resolved_address = vips[0]
135
if is_address_in_network(net_addr, vip):
136
resolved_address = vip
139
if config('prefer-ipv6'):
140
fallback_addr = get_ipv6_addr(exc_list=vips)[0]
142
fallback_addr = unit_get(net_fallback)
144
resolved_address = get_address_in_network(net_addr, fallback_addr)
146
if resolved_address is None:
147
raise ValueError("Unable to resolve a suitable IP address based on "
148
"charm state and configuration. (net_type=%s, "
149
"clustered=%s)" % (net_type, clustered))
151
return resolved_address