~bjornt/charms/trusty/swift-storage/forward-port-bug-1350049-fix

« back to all changes in this revision

Viewing changes to hooks/charmhelpers/contrib/openstack/context.py

  • Committer: james.page at ubuntu
  • Date: 2014-07-28 11:54:32 UTC
  • mfrom: (32.1.3 swift-storage)
  • Revision ID: james.page@ubuntu.com-20140728115432-em4ntc388qe058e3
[corey.bryant,r=james-page] Add amulet tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
    relation_get,
22
22
    relation_ids,
23
23
    related_units,
 
24
    relation_set,
24
25
    unit_get,
25
26
    unit_private_ip,
26
27
    ERROR,
 
28
    INFO
27
29
)
28
30
 
29
31
from charmhelpers.contrib.hahelpers.cluster import (
42
44
    neutron_plugin_attribute,
43
45
)
44
46
 
 
47
from charmhelpers.contrib.network.ip import get_address_in_network
 
48
 
45
49
CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'
46
50
 
47
51
 
134
138
                'Missing required charm config options. '
135
139
                '(database name and user)')
136
140
            raise OSContextError
 
141
 
137
142
        ctxt = {}
138
143
 
 
144
        # NOTE(jamespage) if mysql charm provides a network upon which
 
145
        # access to the database should be made, reconfigure relation
 
146
        # with the service units local address and defer execution
 
147
        access_network = relation_get('access-network')
 
148
        if access_network is not None:
 
149
            if self.relation_prefix is not None:
 
150
                hostname_key = "{}_hostname".format(self.relation_prefix)
 
151
            else:
 
152
                hostname_key = "hostname"
 
153
            access_hostname = get_address_in_network(access_network,
 
154
                                                     unit_get('private-address'))
 
155
            set_hostname = relation_get(attribute=hostname_key,
 
156
                                        unit=local_unit())
 
157
            if set_hostname != access_hostname:
 
158
                relation_set(relation_settings={hostname_key: access_hostname})
 
159
                return ctxt  # Defer any further hook execution for now....
 
160
 
139
161
        password_setting = 'password'
140
162
        if self.relation_prefix:
141
163
            password_setting = self.relation_prefix + '_password'
243
265
 
244
266
 
245
267
class AMQPContext(OSContextGenerator):
246
 
    interfaces = ['amqp']
247
268
 
248
 
    def __init__(self, ssl_dir=None):
 
269
    def __init__(self, ssl_dir=None, rel_name='amqp', relation_prefix=None):
249
270
        self.ssl_dir = ssl_dir
 
271
        self.rel_name = rel_name
 
272
        self.relation_prefix = relation_prefix
 
273
        self.interfaces = [rel_name]
250
274
 
251
275
    def __call__(self):
252
276
        log('Generating template context for amqp')
253
277
        conf = config()
 
278
        user_setting = 'rabbit-user'
 
279
        vhost_setting = 'rabbit-vhost'
 
280
        if self.relation_prefix:
 
281
            user_setting = self.relation_prefix + '-rabbit-user'
 
282
            vhost_setting = self.relation_prefix + '-rabbit-vhost'
 
283
 
254
284
        try:
255
 
            username = conf['rabbit-user']
256
 
            vhost = conf['rabbit-vhost']
 
285
            username = conf[user_setting]
 
286
            vhost = conf[vhost_setting]
257
287
        except KeyError as e:
258
288
            log('Could not generate shared_db context. '
259
289
                'Missing required charm config options: %s.' % e)
260
290
            raise OSContextError
261
291
        ctxt = {}
262
 
        for rid in relation_ids('amqp'):
 
292
        for rid in relation_ids(self.rel_name):
263
293
            ha_vip_only = False
264
294
            for unit in related_units(rid):
265
295
                if relation_get('clustered', rid=rid, unit=unit):
332
362
        use_syslog = str(config('use-syslog')).lower()
333
363
        for rid in relation_ids('ceph'):
334
364
            for unit in related_units(rid):
335
 
                mon_hosts.append(relation_get('private-address', rid=rid,
336
 
                                              unit=unit))
337
365
                auth = relation_get('auth', rid=rid, unit=unit)
338
366
                key = relation_get('key', rid=rid, unit=unit)
 
367
                ceph_addr = \
 
368
                    relation_get('ceph-public-address', rid=rid, unit=unit) or \
 
369
                    relation_get('private-address', rid=rid, unit=unit)
 
370
                mon_hosts.append(ceph_addr)
339
371
 
340
372
        ctxt = {
341
373
            'mon_hosts': ' '.join(mon_hosts),
369
401
 
370
402
        cluster_hosts = {}
371
403
        l_unit = local_unit().replace('/', '-')
372
 
        cluster_hosts[l_unit] = unit_get('private-address')
 
404
        cluster_hosts[l_unit] = \
 
405
            get_address_in_network(config('os-internal-network'),
 
406
                                   unit_get('private-address'))
373
407
 
374
408
        for rid in relation_ids('cluster'):
375
409
            for unit in related_units(rid):
418
452
    """
419
453
    Generates a context for an apache vhost configuration that configures
420
454
    HTTPS reverse proxying for one or many endpoints.  Generated context
421
 
    looks something like:
422
 
    {
423
 
        'namespace': 'cinder',
424
 
        'private_address': 'iscsi.mycinderhost.com',
425
 
        'endpoints': [(8776, 8766), (8777, 8767)]
426
 
    }
 
455
    looks something like::
 
456
 
 
457
        {
 
458
            'namespace': 'cinder',
 
459
            'private_address': 'iscsi.mycinderhost.com',
 
460
            'endpoints': [(8776, 8766), (8777, 8767)]
 
461
        }
427
462
 
428
463
    The endpoints list consists of a tuples mapping external ports
429
464
    to internal ports.
541
576
 
542
577
        return nvp_ctxt
543
578
 
 
579
    def n1kv_ctxt(self):
 
580
        driver = neutron_plugin_attribute(self.plugin, 'driver',
 
581
                                          self.network_manager)
 
582
        n1kv_config = neutron_plugin_attribute(self.plugin, 'config',
 
583
                                               self.network_manager)
 
584
        n1kv_ctxt = {
 
585
            'core_plugin': driver,
 
586
            'neutron_plugin': 'n1kv',
 
587
            'neutron_security_groups': self.neutron_security_groups,
 
588
            'local_ip': unit_private_ip(),
 
589
            'config': n1kv_config,
 
590
            'vsm_ip': config('n1kv-vsm-ip'),
 
591
            'vsm_username': config('n1kv-vsm-username'),
 
592
            'vsm_password': config('n1kv-vsm-password'),
 
593
            'restrict_policy_profiles': config(
 
594
                'n1kv_restrict_policy_profiles'),
 
595
        }
 
596
 
 
597
        return n1kv_ctxt
 
598
 
544
599
    def neutron_ctxt(self):
545
600
        if https():
546
601
            proto = 'https'
572
627
            ctxt.update(self.ovs_ctxt())
573
628
        elif self.plugin in ['nvp', 'nsx']:
574
629
            ctxt.update(self.nvp_ctxt())
 
630
        elif self.plugin == 'n1kv':
 
631
            ctxt.update(self.n1kv_ctxt())
575
632
 
576
633
        alchemy_flags = config('neutron-alchemy-flags')
577
634
        if alchemy_flags:
611
668
    The subordinate interface allows subordinates to export their
612
669
    configuration requirements to the principle for multiple config
613
670
    files and multiple serivces.  Ie, a subordinate that has interfaces
614
 
    to both glance and nova may export to following yaml blob as json:
 
671
    to both glance and nova may export to following yaml blob as json::
615
672
 
616
673
        glance:
617
674
            /etc/glance/glance-api.conf:
630
687
 
631
688
    It is then up to the principle charms to subscribe this context to
632
689
    the service+config file it is interestd in.  Configuration data will
633
 
    be available in the template context, in glance's case, as:
 
690
    be available in the template context, in glance's case, as::
 
691
 
634
692
        ctxt = {
635
693
            ... other context ...
636
694
            'subordinate_config': {
657
715
        self.interface = interface
658
716
 
659
717
    def __call__(self):
660
 
        ctxt = {}
 
718
        ctxt = {'sections': {}}
661
719
        for rid in relation_ids(self.interface):
662
720
            for unit in related_units(rid):
663
721
                sub_config = relation_get('subordinate_configuration',
683
741
 
684
742
                    sub_config = sub_config[self.config_file]
685
743
                    for k, v in sub_config.iteritems():
686
 
                        ctxt[k] = v
687
 
 
688
 
        if not ctxt:
689
 
            ctxt['sections'] = {}
690
 
 
 
744
                        if k == 'sections':
 
745
                            for section, config_dict in v.iteritems():
 
746
                                log("adding section '%s'" % (section))
 
747
                                ctxt[k][section] = config_dict
 
748
                        else:
 
749
                            ctxt[k] = v
 
750
 
 
751
        log("%d section(s) found" % (len(ctxt['sections'])), level=INFO)
 
752
 
 
753
        return ctxt
 
754
 
 
755
 
 
756
class LogLevelContext(OSContextGenerator):
 
757
 
 
758
    def __call__(self):
 
759
        ctxt = {}
 
760
        ctxt['debug'] = \
 
761
            False if config('debug') is None else config('debug')
 
762
        ctxt['verbose'] = \
 
763
            False if config('verbose') is None else config('verbose')
691
764
        return ctxt
692
765
 
693
766