~james-page/charms/trusty/swift-proxy/trunk

« back to all changes in this revision

Viewing changes to lib/swift_context.py

  • Committer: Corey Bryant
  • Date: 2016-01-04 21:31:31 UTC
  • Revision ID: corey.bryant@canonical.com-20160104213131-ywhbmp447m30d4xf
[corey.bryant,r=trivial] Sync charm-helpers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import os
 
2
import uuid
 
3
 
 
4
from charmhelpers.core.hookenv import (
 
5
    config,
 
6
    log,
 
7
    relation_ids,
 
8
    related_units,
 
9
    relation_get,
 
10
    unit_get,
 
11
    service_name,
 
12
)
 
13
from charmhelpers.contrib.openstack.context import (
 
14
    OSContextGenerator,
 
15
    ApacheSSLContext as SSLContext,
 
16
    context_complete,
 
17
    IdentityServiceContext,
 
18
)
 
19
from charmhelpers.contrib.hahelpers.cluster import (
 
20
    determine_api_port,
 
21
    determine_apache_port,
 
22
)
 
23
from charmhelpers.contrib.network.ip import (
 
24
    format_ipv6_addr,
 
25
    get_ipv6_addr,
 
26
)
 
27
from charmhelpers.contrib.openstack.utils import get_host_ip
 
28
 
 
29
 
 
30
SWIFT_HASH_FILE = '/var/lib/juju/swift-hash-path.conf'
 
31
WWW_DIR = '/var/www/swift-rings'
 
32
 
 
33
 
 
34
class HAProxyContext(OSContextGenerator):
 
35
    interfaces = ['cluster']
 
36
 
 
37
    def __call__(self):
 
38
        """Extends the main charmhelpers HAProxyContext with a port mapping
 
39
        specific to this charm.
 
40
        Also used to extend cinder.conf context with correct api_listening_port
 
41
        """
 
42
        haproxy_port = config('bind-port')
 
43
        api_port = determine_apache_port(config('bind-port'),
 
44
                                         singlenode_mode=True)
 
45
 
 
46
        ctxt = {
 
47
            'service_ports': {'swift_api': [haproxy_port, api_port]},
 
48
        }
 
49
        return ctxt
 
50
 
 
51
 
 
52
class ApacheSSLContext(SSLContext):
 
53
    interfaces = ['https']
 
54
    service_namespace = 'swift'
 
55
 
 
56
    # We make this a property so that we avoid import-time
 
57
    # dependencies on config()
 
58
 
 
59
    @property
 
60
    def external_ports(self):
 
61
        return [config('bind-port')]
 
62
 
 
63
 
 
64
class SwiftRingContext(OSContextGenerator):
 
65
 
 
66
    def __call__(self):
 
67
        allowed_hosts = []
 
68
        for relid in relation_ids('swift-storage'):
 
69
            for unit in related_units(relid):
 
70
                host = relation_get('private-address', unit, relid)
 
71
                if config('prefer-ipv6'):
 
72
                    host_ip = get_ipv6_addr(exc_list=[config('vip')])[0]
 
73
                else:
 
74
                    host_ip = get_host_ip(host)
 
75
 
 
76
                allowed_hosts.append(host_ip)
 
77
 
 
78
        ctxt = {
 
79
            'www_dir': WWW_DIR,
 
80
            'allowed_hosts': allowed_hosts
 
81
        }
 
82
        return ctxt
 
83
 
 
84
 
 
85
class SwiftIdentityContext(OSContextGenerator):
 
86
    interfaces = ['identity-service']
 
87
 
 
88
    def __call__(self):
 
89
        bind_port = config('bind-port')
 
90
        workers = config('workers')
 
91
        if workers == 0:
 
92
            import multiprocessing
 
93
            workers = multiprocessing.cpu_count()
 
94
        if config('prefer-ipv6'):
 
95
            proxy_ip = '[%s]' % get_ipv6_addr(exc_list=[config('vip')])[0]
 
96
            memcached_ip = 'ip6-localhost'
 
97
        else:
 
98
            proxy_ip = get_host_ip(unit_get('private-address'))
 
99
            memcached_ip = get_host_ip(unit_get('private-address'))
 
100
 
 
101
        ctxt = {
 
102
            'proxy_ip': proxy_ip,
 
103
            'memcached_ip': memcached_ip,
 
104
            'bind_port': determine_api_port(bind_port, singlenode_mode=True),
 
105
            'workers': workers,
 
106
            'operator_roles': config('operator-roles'),
 
107
            'delay_auth_decision': config('delay-auth-decision'),
 
108
            'node_timeout': config('node-timeout'),
 
109
            'recoverable_node_timeout': config('recoverable-node-timeout'),
 
110
            'log_headers': config('log-headers')
 
111
        }
 
112
 
 
113
        if config('debug'):
 
114
            ctxt['log_level'] = 'DEBUG'
 
115
        else:
 
116
            ctxt['log_level'] = 'INFO'
 
117
 
 
118
        # Instead of duplicating code lets use charm-helpers to set signing_dir
 
119
        # TODO(hopem): refactor this context handler to use charm-helpers
 
120
        #              code.
 
121
        _ctxt = IdentityServiceContext(service='swift', service_user='swift')()
 
122
        signing_dir = _ctxt.get('signing_dir')
 
123
        if signing_dir:
 
124
            ctxt['signing_dir'] = signing_dir
 
125
 
 
126
        ctxt['ssl'] = False
 
127
 
 
128
        auth_type = config('auth-type')
 
129
        auth_host = config('keystone-auth-host')
 
130
        admin_user = config('keystone-admin-user')
 
131
        admin_password = config('keystone-admin-user')
 
132
        if (auth_type == 'keystone' and auth_host and
 
133
                admin_user and admin_password):
 
134
            log('Using user-specified Keystone configuration.')
 
135
            ks_auth = {
 
136
                'auth_type': 'keystone',
 
137
                'auth_protocol': config('keystone-auth-protocol'),
 
138
                'keystone_host': auth_host,
 
139
                'auth_port': config('keystone-auth-port'),
 
140
                'service_user': admin_user,
 
141
                'service_password': admin_password,
 
142
                'service_tenant': config('keystone-admin-tenant-name')
 
143
            }
 
144
            ctxt.update(ks_auth)
 
145
 
 
146
        for relid in relation_ids('identity-service'):
 
147
            log('Using Keystone configuration from identity-service.')
 
148
            for unit in related_units(relid):
 
149
                ks_auth = {
 
150
                    'auth_type': 'keystone',
 
151
                    'auth_protocol': relation_get('auth_protocol',
 
152
                                                  unit, relid) or 'http',
 
153
                    'service_protocol': relation_get('service_protocol',
 
154
                                                     unit, relid) or 'http',
 
155
                    'keystone_host': relation_get('auth_host',
 
156
                                                  unit, relid),
 
157
                    'service_host': relation_get('service_host',
 
158
                                                 unit, relid),
 
159
                    'auth_port': relation_get('auth_port',
 
160
                                              unit, relid),
 
161
                    'service_user': relation_get('service_username',
 
162
                                                 unit, relid),
 
163
                    'service_password': relation_get('service_password',
 
164
                                                     unit, relid),
 
165
                    'service_tenant': relation_get('service_tenant',
 
166
                                                   unit, relid),
 
167
                    'service_port': relation_get('service_port',
 
168
                                                 unit, relid),
 
169
                    'admin_token': relation_get('admin_token',
 
170
                                                unit, relid),
 
171
                }
 
172
                if context_complete(ks_auth):
 
173
                    ctxt.update(ks_auth)
 
174
 
 
175
        if config('prefer-ipv6'):
 
176
            for key in ['keystone_host', 'service_host']:
 
177
                host = ctxt.get(key)
 
178
                if host:
 
179
                    ctxt[key] = format_ipv6_addr(host)
 
180
 
 
181
        return ctxt
 
182
 
 
183
 
 
184
class MemcachedContext(OSContextGenerator):
 
185
 
 
186
    def __call__(self):
 
187
        ctxt = {}
 
188
        if config('prefer-ipv6'):
 
189
            ctxt['memcached_ip'] = 'ip6-localhost'
 
190
        else:
 
191
            ctxt['memcached_ip'] = get_host_ip(unit_get('private-address'))
 
192
 
 
193
        return ctxt
 
194
 
 
195
 
 
196
def get_swift_hash():
 
197
    if os.path.isfile(SWIFT_HASH_FILE):
 
198
        with open(SWIFT_HASH_FILE, 'r') as hashfile:
 
199
            swift_hash = hashfile.read().strip()
 
200
    elif config('swift-hash'):
 
201
        swift_hash = config('swift-hash')
 
202
        with open(SWIFT_HASH_FILE, 'w') as hashfile:
 
203
            hashfile.write(swift_hash)
 
204
    else:
 
205
        swift_hash = str(uuid.uuid3(uuid.UUID(os.environ.get("JUJU_ENV_UUID")),
 
206
                                    service_name()))
 
207
        with open(SWIFT_HASH_FILE, 'w') as hashfile:
 
208
            hashfile.write(swift_hash)
 
209
 
 
210
    return swift_hash
 
211
 
 
212
 
 
213
class SwiftHashContext(OSContextGenerator):
 
214
 
 
215
    def __call__(self):
 
216
        ctxt = {
 
217
            'swift_hash': get_swift_hash()
 
218
        }
 
219
        return ctxt