~junaidali/charms/trusty/plumgrid-director/pg-restart

« back to all changes in this revision

Viewing changes to hooks/charmhelpers-pl/contrib/openstack/ip.py

  • Committer: bbaqar at plumgrid
  • Date: 2015-05-19 21:05:20 UTC
  • Revision ID: bbaqar@plumgrid.com-20150519210520-8nymqswwgdu7qygg
PLUMgrid director initial charm

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2014-2015 Canonical Limited.
 
2
#
 
3
# This file is part of charm-helpers.
 
4
#
 
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.
 
8
#
 
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.
 
13
#
 
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/>.
 
16
 
 
17
from charmhelpers.core.hookenv import (
 
18
    config,
 
19
    unit_get,
 
20
)
 
21
from charmhelpers.contrib.network.ip import (
 
22
    get_address_in_network,
 
23
    is_address_in_network,
 
24
    is_ipv6,
 
25
    get_ipv6_addr,
 
26
)
 
27
from charmhelpers.contrib.hahelpers.cluster import is_clustered
 
28
 
 
29
from functools import partial
 
30
 
 
31
PUBLIC = 'public'
 
32
INTERNAL = 'int'
 
33
ADMIN = 'admin'
 
34
 
 
35
ADDRESS_MAP = {
 
36
    PUBLIC: {
 
37
        'config': 'os-public-network',
 
38
        'fallback': 'public-address'
 
39
    },
 
40
    INTERNAL: {
 
41
        'config': 'os-internal-network',
 
42
        'fallback': 'private-address'
 
43
    },
 
44
    ADMIN: {
 
45
        'config': 'os-admin-network',
 
46
        'fallback': 'private-address'
 
47
    }
 
48
}
 
49
 
 
50
 
 
51
def canonical_url(configs, endpoint_type=PUBLIC):
 
52
    """Returns the correct HTTP URL to this host given the state of HTTPS
 
53
    configuration, hacluster and charm configuration.
 
54
 
 
55
    :param configs: OSTemplateRenderer config templating object to inspect
 
56
                    for a complete https context.
 
57
    :param endpoint_type: str endpoint type to resolve.
 
58
    :param returns: str base URL for services on the current service unit.
 
59
    """
 
60
    scheme = 'http'
 
61
    if 'https' in configs.complete_contexts():
 
62
        scheme = 'https'
 
63
    address = resolve_address(endpoint_type)
 
64
    if is_ipv6(address):
 
65
        address = "[{}]".format(address)
 
66
    return '%s://%s' % (scheme, address)
 
67
 
 
68
 
 
69
def resolve_address(endpoint_type=PUBLIC):
 
70
    """Return unit address depending on net config.
 
71
 
 
72
    If unit is clustered with vip(s) and has net splits defined, return vip on
 
73
    correct network. If clustered with no nets defined, return primary vip.
 
74
 
 
75
    If not clustered, return unit address ensuring address is on configured net
 
76
    split if one is configured.
 
77
 
 
78
    :param endpoint_type: Network endpoing type
 
79
    """
 
80
    resolved_address = None
 
81
    vips = config('vip')
 
82
    if vips:
 
83
        vips = vips.split()
 
84
 
 
85
    net_type = ADDRESS_MAP[endpoint_type]['config']
 
86
    net_addr = config(net_type)
 
87
    net_fallback = ADDRESS_MAP[endpoint_type]['fallback']
 
88
    clustered = is_clustered()
 
89
    if clustered:
 
90
        if not net_addr:
 
91
            # If no net-splits defined, we expect a single vip
 
92
            resolved_address = vips[0]
 
93
        else:
 
94
            for vip in vips:
 
95
                if is_address_in_network(net_addr, vip):
 
96
                    resolved_address = vip
 
97
                    break
 
98
    else:
 
99
        if config('prefer-ipv6'):
 
100
            fallback_addr = get_ipv6_addr(exc_list=vips)[0]
 
101
        else:
 
102
            fallback_addr = unit_get(net_fallback)
 
103
 
 
104
        resolved_address = get_address_in_network(net_addr, fallback_addr)
 
105
 
 
106
    if resolved_address is None:
 
107
        raise ValueError("Unable to resolve a suitable IP address based on "
 
108
                         "charm state and configuration. (net_type=%s, "
 
109
                         "clustered=%s)" % (net_type, clustered))
 
110
 
 
111
    return resolved_address
 
112
 
 
113
 
 
114
def endpoint_url(configs, url_template, port, endpoint_type=PUBLIC,
 
115
                 override=None):
 
116
    """Returns the correct endpoint URL to advertise to Keystone.
 
117
 
 
118
    This method provides the correct endpoint URL which should be advertised to
 
119
    the keystone charm for endpoint creation. This method allows for the url to
 
120
    be overridden to force a keystone endpoint to have specific URL for any of
 
121
    the defined scopes (admin, internal, public).
 
122
 
 
123
    :param configs: OSTemplateRenderer config templating object to inspect
 
124
                    for a complete https context.
 
125
    :param url_template: str format string for creating the url template. Only
 
126
                         two values will be passed - the scheme+hostname
 
127
                        returned by the canonical_url and the port.
 
128
    :param endpoint_type: str endpoint type to resolve.
 
129
    :param override: str the name of the config option which overrides the
 
130
                     endpoint URL defined by the charm itself. None will
 
131
                     disable any overrides (default).
 
132
    """
 
133
    if override:
 
134
        # Return any user-defined overrides for the keystone endpoint URL.
 
135
        user_value = config(override)
 
136
        if user_value:
 
137
            return user_value.strip()
 
138
 
 
139
    return url_template % (canonical_url(configs, endpoint_type), port)
 
140
 
 
141
 
 
142
public_endpoint = partial(endpoint_url, endpoint_type=PUBLIC)
 
143
 
 
144
internal_endpoint = partial(endpoint_url, endpoint_type=INTERNAL)
 
145
 
 
146
admin_endpoint = partial(endpoint_url, endpoint_type=ADMIN)