~openstack-charmers/charms/trusty/nova-compute/snabbswitch

« back to all changes in this revision

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

  • Committer: Edward Hope-Morley
  • Date: 2014-10-03 10:20:18 UTC
  • Revision ID: edward.hope-morley@canonical.com-20141003102018-yf5cm11spsuc3331
synced lp:~openstack-charmers/charm-helpers/snabbswitch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
import json
2
2
import os
 
3
import base64
 
4
import bz2
3
5
import time
 
6
import pwd
4
7
 
5
8
from base64 import b64decode
6
9
 
52
55
from charmhelpers.contrib.network.ip import (
53
56
    get_address_in_network,
54
57
    get_ipv6_addr,
 
58
    get_netmask_for_address,
55
59
    format_ipv6_addr,
56
60
    is_address_in_network
57
61
)
408
412
        return ctxt
409
413
 
410
414
 
 
415
ADDRESS_TYPES = ['admin', 'internal', 'public']
 
416
 
 
417
 
411
418
class HAProxyContext(OSContextGenerator):
412
419
    interfaces = ['cluster']
413
420
 
420
427
        if not relation_ids('cluster'):
421
428
            return {}
422
429
 
423
 
        cluster_hosts = {}
424
430
        l_unit = local_unit().replace('/', '-')
425
431
 
426
432
        if config('prefer-ipv6'):
428
434
        else:
429
435
            addr = unit_get('private-address')
430
436
 
431
 
        cluster_hosts[l_unit] = get_address_in_network(config('os-internal-network'),
432
 
                                                       addr)
433
 
 
434
 
        for rid in relation_ids('cluster'):
435
 
            for unit in related_units(rid):
436
 
                _unit = unit.replace('/', '-')
437
 
                addr = relation_get('private-address', rid=rid, unit=unit)
438
 
                cluster_hosts[_unit] = addr
 
437
        cluster_hosts = {}
 
438
 
 
439
        # NOTE(jamespage): build out map of configured network endpoints
 
440
        # and associated backends
 
441
        for addr_type in ADDRESS_TYPES:
 
442
            laddr = get_address_in_network(
 
443
                config('os-{}-network'.format(addr_type)))
 
444
            if laddr:
 
445
                cluster_hosts[laddr] = {}
 
446
                cluster_hosts[laddr]['network'] = "{}/{}".format(
 
447
                    laddr,
 
448
                    get_netmask_for_address(laddr)
 
449
                )
 
450
                cluster_hosts[laddr]['backends'] = {}
 
451
                cluster_hosts[laddr]['backends'][l_unit] = laddr
 
452
                for rid in relation_ids('cluster'):
 
453
                    for unit in related_units(rid):
 
454
                        _unit = unit.replace('/', '-')
 
455
                        _laddr = relation_get('{}-address'.format(addr_type),
 
456
                                              rid=rid, unit=unit)
 
457
                        if _laddr:
 
458
                            cluster_hosts[laddr]['backends'][_unit] = _laddr
 
459
 
 
460
        # NOTE(jamespage) no split configurations found, just use
 
461
        # private addresses
 
462
        if not cluster_hosts:
 
463
            cluster_hosts[addr] = {}
 
464
            cluster_hosts[addr]['network'] = "{}/{}".format(
 
465
                addr,
 
466
                get_netmask_for_address(addr)
 
467
            )
 
468
            cluster_hosts[addr]['backends'] = {}
 
469
            cluster_hosts[addr]['backends'][l_unit] = addr
 
470
            for rid in relation_ids('cluster'):
 
471
                for unit in related_units(rid):
 
472
                    _unit = unit.replace('/', '-')
 
473
                    _laddr = relation_get('private-address',
 
474
                                          rid=rid, unit=unit)
 
475
                    if _laddr:
 
476
                        cluster_hosts[addr]['backends'][_unit] = _laddr
439
477
 
440
478
        ctxt = {
441
 
            'units': cluster_hosts,
 
479
            'frontends': cluster_hosts,
442
480
        }
443
481
 
444
482
        if config('haproxy-server-timeout'):
455
493
            ctxt['haproxy_host'] = '0.0.0.0'
456
494
            ctxt['stat_port'] = ':8888'
457
495
 
458
 
        if len(cluster_hosts.keys()) > 1:
459
 
            # Enable haproxy when we have enough peers.
460
 
            log('Ensuring haproxy enabled in /etc/default/haproxy.')
461
 
            with open('/etc/default/haproxy', 'w') as out:
462
 
                out.write('ENABLED=1\n')
463
 
            return ctxt
 
496
        for frontend in cluster_hosts:
 
497
            if len(cluster_hosts[frontend]['backends']) > 1:
 
498
                # Enable haproxy when we have enough peers.
 
499
                log('Ensuring haproxy enabled in /etc/default/haproxy.')
 
500
                with open('/etc/default/haproxy', 'w') as out:
 
501
                    out.write('ENABLED=1\n')
 
502
                return ctxt
464
503
        log('HAProxy context is incomplete, this unit has no peers.')
465
504
        return {}
466
505
 
616
655
    def neutron_security_groups(self):
617
656
        return None
618
657
 
 
658
    @property
 
659
    def neutron_type_drivers(self):
 
660
        return 'gre,vxlan,vlan,flat'
 
661
 
 
662
    @property
 
663
    def mechanism_drivers(self):
 
664
        return "openvswitch,hyperv"
 
665
 
619
666
    def _ensure_packages(self):
620
667
        [ensure_packages(pkgs) for pkgs in self.packages]
621
668
 
677
724
 
678
725
        return n1kv_ctxt
679
726
 
 
727
    def _snabb_init_zones_file(self, zones_file):
 
728
        if zones_file:
 
729
            log("Configuring zones file '%s'" % (zones_file), level=INFO)
 
730
 
 
731
            dirname = os.path.dirname(zones_file)
 
732
            if dirname and not os.path.isdir(dirname):
 
733
                os.makedirs(dirname)
 
734
 
 
735
            encoded_defs = config('snabbswitch-zone-definitions')
 
736
            if encoded_defs:
 
737
                # File is expected to be bzipped
 
738
                out = bz2.decompress(base64.b64decode(encoded_defs))
 
739
                with open(zones_file, 'w') as fd:
 
740
                    fd.write(out)
 
741
 
 
742
                log("Created zones file '%s'" % (zones_file), level=INFO)
 
743
            else:
 
744
                log("No zones definitions provided", level=INFO)
 
745
 
 
746
                # Make sure a zones file exists if a path is set.
 
747
                if not os.path.isfile(zones_file):
 
748
                    with open(zones_file, 'w') as fd:
 
749
                        pass
 
750
 
 
751
            # Make sure neutron user can read file.
 
752
            user = pwd.getpwnam('neutron')
 
753
            uid, gid = user.pw_uid, user.pw_gid
 
754
            os.chown(zones_file, uid, gid)
 
755
 
 
756
    def snabb_ctxt(self):
 
757
        driver = neutron_plugin_attribute(self.plugin, 'driver',
 
758
                                          self.network_manager)
 
759
        snabb_config = neutron_plugin_attribute(self.plugin, 'config',
 
760
                                                self.network_manager)
 
761
        snabb_ctxt = {
 
762
            'core_plugin': driver,
 
763
            'neutron_security_groups': self.neutron_security_groups,
 
764
            'local_ip': unit_private_ip(),
 
765
            'config': snabb_config,
 
766
        }
 
767
 
 
768
        zf = config('snabbswitch-zone-definitions-file')
 
769
        if zf:
 
770
            snabb_ctxt['zone_definition_file'] = zf
 
771
            self._snabb_init_zones_file(zf)
 
772
 
 
773
        return snabb_ctxt
 
774
 
680
775
    def neutron_ctxt(self):
681
776
        if https():
682
777
            proto = 'https'
690
785
        ctxt = {
691
786
            'network_manager': self.network_manager,
692
787
            'neutron_url': url,
 
788
            'type_drivers': self.neutron_type_drivers,
 
789
            'mechanism_drivers': self.mechanism_drivers
693
790
        }
694
791
        return ctxt
695
792
 
710
807
            ctxt.update(self.nvp_ctxt())
711
808
        elif self.plugin == 'n1kv':
712
809
            ctxt.update(self.n1kv_ctxt())
 
810
        elif self.plugin == 'snabb':
 
811
            ctxt.update(self.snabb_ctxt())
713
812
 
714
813
        alchemy_flags = config('neutron-alchemy-flags')
715
814
        if alchemy_flags:
722
821
 
723
822
class OSConfigFlagContext(OSContextGenerator):
724
823
 
725
 
        """
726
 
        Responsible for adding user-defined config-flags in charm config to a
727
 
        template context.
728
 
 
729
 
        NOTE: the value of config-flags may be a comma-separated list of
730
 
              key=value pairs and some Openstack config files support
731
 
              comma-separated lists as values.
732
 
        """
733
 
 
734
 
        def __call__(self):
735
 
            config_flags = config('config-flags')
736
 
            if not config_flags:
737
 
                return {}
738
 
 
739
 
            flags = config_flags_parser(config_flags)
740
 
            return {'user_config_flags': flags}
 
824
    """
 
825
    Responsible for adding user-defined config-flags in charm config to a
 
826
    template context.
 
827
 
 
828
    NOTE: the value of config-flags may be a comma-separated list of
 
829
          key=value pairs and some Openstack config files support
 
830
          comma-separated lists as values.
 
831
    """
 
832
 
 
833
    def __call__(self):
 
834
        config_flags = config('config-flags')
 
835
        if not config_flags:
 
836
            return {}
 
837
 
 
838
        flags = config_flags_parser(config_flags)
 
839
        return {'user_config_flags': flags}
741
840
 
742
841
 
743
842
class SubordinateConfigContext(OSContextGenerator):