~celebdor/charms/trusty/neutron-agents-midonet/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#
# Copyright (c) 2015 Midokura SARL, All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from charmhelpers.contrib.openstack import context
from charmhelpers.contrib.openstack import templating
from charmhelpers.contrib.openstack import utils
from charmhelpers.core import hookenv
from charmhelpers.core import host
from charmhelpers.core import unitdata
from charmhelpers.core.services import base
from charmhelpers.core.services import helpers
from midonet_helpers import puppet
from midonet_helpers import relations as common_relations
from midonet_helpers import repositories
import relations

TEMPLATES = 'templates/'


def get_shared_secret():
    db = unitdata.kv()
    if not db.get('shared-secret'):
        db.set('shared-secret', host.pwgen(32))
        db.flush()
    return db.get('shared-secret')


class Charm(dict):
    def __init__(self, *args):
        self['config'] = hookenv.config()
        self['unit'] = {
            'shared-secret': get_shared_secret()
        }


class OSTRenderer(base.ManagerCallback):
    def __init__(self, dest, ctxts, release=None):
        release = release or utils.os_release('neutron-common')
        self._configs = templating.OSConfigRenderer(templates_dir=TEMPLATES,
                                                    openstack_release=release)
        self._configs.register(dest, ctxts)

    def __call__(self, manager, service_name, event_name):
        self._configs.write_all()


class MidonetNetworkServiceContext(context.NetworkServiceContext):

    def __call__(self):
        ctxt = super(MidonetNetworkServiceContext, self).__call__()
        ctxt['shared_secret'] = get_shared_secret()
        return ctxt


def manage():
    nova = relations.NovaRelation()
    charm = Charm()
    hookenv.status_set('maintenance', 'reconfiguring charm')
    ost_origin = charm['config'].get('openstack-origin')
    midonet_origin = charm['config'].get('midonet-origin')
    if None in (ost_origin, midonet_origin):
        hookenv.status_set('maintenance', 'Lacking repository configuration')
        return
    ost_release = utils.get_os_codename_install_source(ost_origin)
    try:
        repo = repositories.config('%s/%s' % (ost_release, midonet_origin),
                                   charm['config'].get('mem-username'),
                                   charm['config'].get('mem-password'))
    except ValueError as ver:
        hookenv.status_set('maintenance',
                           'Wrong repository configuration: {}'.format(ver))
        return

    amqp = context.AMQPContext()
    network_service = MidonetNetworkServiceContext(rel_name='neutron_agents')
    midonet = common_relations.MidonetApiRelation()
    if ost_release in ('juno', 'kilo'):
        midonet_plugin = 'python-neutron-plugin-midonet'
    else:
        midonet_plugin = 'python-networking-midonet'

    manager = base.ServiceManager([
        {
            'service': 'neutron-dhcp-agent',
            'required_data': [repo,
                              nova,
                              midonet,
                              amqp()],
            'data_ready': [
                helpers.render_template(
                    source='common.yaml',
                    target='/var/lib/hiera/neutron_agents/common.yaml'),
                helpers.render_template(
                    source='dhcp_agent.ini',
                    target='/etc/neutron/dhcp_agent.ini'),
                puppet.InstallPackagesCallback(
                    (midonet_plugin,)),
                OSTRenderer('/etc/neutron/neutron.conf',
                            [amqp]),
            ],
        },
        {
            'service': 'neutron-metadata-agent',
            'required_data': [charm,
                              nova],
            'data_ready': [
                helpers.render_template(
                    source='metadata_agent.ini',
                    target='/etc/neutron/metadata_agent.ini'),
            ],
        },
        {
            'service': 'nova-api-metadata',
            'required_data': [network_service(),
                              amqp()],
            'data_ready': [
                OSTRenderer('/etc/nova/nova.conf',
                            [network_service, amqp]),
            ],
        },
    ])
    manager.manage()
    if (host.service_running('neutron-dhcp-agent') and
            host.service_running('neutron-metadata-agent') and
            host.service_running('nova-api-metadata')):
        hookenv.status_set('active', 'All nova and neutron agents up and running')