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

« back to all changes in this revision

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

  • Committer: bbaqar at plumgrid
  • Date: 2015-07-29 18:07:31 UTC
  • Revision ID: bbaqar@plumgrid.com-20150729180731-ioynar8x3u5pxytc
Addressed reviews by Charmers

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
 
# Various utilies for dealing with Neutron and the renaming from Quantum.
18
 
 
19
 
import six
20
 
from subprocess import check_output
21
 
 
22
 
from charmhelpers.core.hookenv import (
23
 
    config,
24
 
    log,
25
 
    ERROR,
26
 
)
27
 
 
28
 
from charmhelpers.contrib.openstack.utils import os_release
29
 
 
30
 
 
31
 
def headers_package():
32
 
    """Ensures correct linux-headers for running kernel are installed,
33
 
    for building DKMS package"""
34
 
    kver = check_output(['uname', '-r']).decode('UTF-8').strip()
35
 
    return 'linux-headers-%s' % kver
36
 
 
37
 
QUANTUM_CONF_DIR = '/etc/quantum'
38
 
 
39
 
 
40
 
def kernel_version():
41
 
    """ Retrieve the current major kernel version as a tuple e.g. (3, 13) """
42
 
    kver = check_output(['uname', '-r']).decode('UTF-8').strip()
43
 
    kver = kver.split('.')
44
 
    return (int(kver[0]), int(kver[1]))
45
 
 
46
 
 
47
 
def determine_dkms_package():
48
 
    """ Determine which DKMS package should be used based on kernel version """
49
 
    # NOTE: 3.13 kernels have support for GRE and VXLAN native
50
 
    if kernel_version() >= (3, 13):
51
 
        return []
52
 
    else:
53
 
        return ['openvswitch-datapath-dkms']
54
 
 
55
 
 
56
 
# legacy
57
 
 
58
 
 
59
 
def quantum_plugins():
60
 
    from charmhelpers.contrib.openstack import context
61
 
    return {
62
 
        'ovs': {
63
 
            'config': '/etc/quantum/plugins/openvswitch/'
64
 
                      'ovs_quantum_plugin.ini',
65
 
            'driver': 'quantum.plugins.openvswitch.ovs_quantum_plugin.'
66
 
                      'OVSQuantumPluginV2',
67
 
            'contexts': [
68
 
                context.SharedDBContext(user=config('neutron-database-user'),
69
 
                                        database=config('neutron-database'),
70
 
                                        relation_prefix='neutron',
71
 
                                        ssl_dir=QUANTUM_CONF_DIR)],
72
 
            'services': ['quantum-plugin-openvswitch-agent'],
73
 
            'packages': [[headers_package()] + determine_dkms_package(),
74
 
                         ['quantum-plugin-openvswitch-agent']],
75
 
            'server_packages': ['quantum-server',
76
 
                                'quantum-plugin-openvswitch'],
77
 
            'server_services': ['quantum-server']
78
 
        },
79
 
        'nvp': {
80
 
            'config': '/etc/quantum/plugins/nicira/nvp.ini',
81
 
            'driver': 'quantum.plugins.nicira.nicira_nvp_plugin.'
82
 
                      'QuantumPlugin.NvpPluginV2',
83
 
            'contexts': [
84
 
                context.SharedDBContext(user=config('neutron-database-user'),
85
 
                                        database=config('neutron-database'),
86
 
                                        relation_prefix='neutron',
87
 
                                        ssl_dir=QUANTUM_CONF_DIR)],
88
 
            'services': [],
89
 
            'packages': [],
90
 
            'server_packages': ['quantum-server',
91
 
                                'quantum-plugin-nicira'],
92
 
            'server_services': ['quantum-server']
93
 
        }
94
 
    }
95
 
 
96
 
NEUTRON_CONF_DIR = '/etc/neutron'
97
 
 
98
 
 
99
 
def neutron_plugins():
100
 
    from charmhelpers.contrib.openstack import context
101
 
    release = os_release('nova-common')
102
 
    plugins = {
103
 
        'ovs': {
104
 
            'config': '/etc/neutron/plugins/openvswitch/'
105
 
                      'ovs_neutron_plugin.ini',
106
 
            'driver': 'neutron.plugins.openvswitch.ovs_neutron_plugin.'
107
 
                      'OVSNeutronPluginV2',
108
 
            'contexts': [
109
 
                context.SharedDBContext(user=config('neutron-database-user'),
110
 
                                        database=config('neutron-database'),
111
 
                                        relation_prefix='neutron',
112
 
                                        ssl_dir=NEUTRON_CONF_DIR)],
113
 
            'services': ['neutron-plugin-openvswitch-agent'],
114
 
            'packages': [[headers_package()] + determine_dkms_package(),
115
 
                         ['neutron-plugin-openvswitch-agent']],
116
 
            'server_packages': ['neutron-server',
117
 
                                'neutron-plugin-openvswitch'],
118
 
            'server_services': ['neutron-server']
119
 
        },
120
 
        'nvp': {
121
 
            'config': '/etc/neutron/plugins/nicira/nvp.ini',
122
 
            'driver': 'neutron.plugins.nicira.nicira_nvp_plugin.'
123
 
                      'NeutronPlugin.NvpPluginV2',
124
 
            'contexts': [
125
 
                context.SharedDBContext(user=config('neutron-database-user'),
126
 
                                        database=config('neutron-database'),
127
 
                                        relation_prefix='neutron',
128
 
                                        ssl_dir=NEUTRON_CONF_DIR)],
129
 
            'services': [],
130
 
            'packages': [],
131
 
            'server_packages': ['neutron-server',
132
 
                                'neutron-plugin-nicira'],
133
 
            'server_services': ['neutron-server']
134
 
        },
135
 
        'nsx': {
136
 
            'config': '/etc/neutron/plugins/vmware/nsx.ini',
137
 
            'driver': 'vmware',
138
 
            'contexts': [
139
 
                context.SharedDBContext(user=config('neutron-database-user'),
140
 
                                        database=config('neutron-database'),
141
 
                                        relation_prefix='neutron',
142
 
                                        ssl_dir=NEUTRON_CONF_DIR)],
143
 
            'services': [],
144
 
            'packages': [],
145
 
            'server_packages': ['neutron-server',
146
 
                                'neutron-plugin-vmware'],
147
 
            'server_services': ['neutron-server']
148
 
        },
149
 
        'n1kv': {
150
 
            'config': '/etc/neutron/plugins/cisco/cisco_plugins.ini',
151
 
            'driver': 'neutron.plugins.cisco.network_plugin.PluginV2',
152
 
            'contexts': [
153
 
                context.SharedDBContext(user=config('neutron-database-user'),
154
 
                                        database=config('neutron-database'),
155
 
                                        relation_prefix='neutron',
156
 
                                        ssl_dir=NEUTRON_CONF_DIR)],
157
 
            'services': [],
158
 
            'packages': [[headers_package()] + determine_dkms_package(),
159
 
                         ['neutron-plugin-cisco']],
160
 
            'server_packages': ['neutron-server',
161
 
                                'neutron-plugin-cisco'],
162
 
            'server_services': ['neutron-server']
163
 
        },
164
 
        'Calico': {
165
 
            'config': '/etc/neutron/plugins/ml2/ml2_conf.ini',
166
 
            'driver': 'neutron.plugins.ml2.plugin.Ml2Plugin',
167
 
            'contexts': [
168
 
                context.SharedDBContext(user=config('neutron-database-user'),
169
 
                                        database=config('neutron-database'),
170
 
                                        relation_prefix='neutron',
171
 
                                        ssl_dir=NEUTRON_CONF_DIR)],
172
 
            'services': ['calico-felix',
173
 
                         'bird',
174
 
                         'neutron-dhcp-agent',
175
 
                         'nova-api-metadata'],
176
 
            'packages': [[headers_package()] + determine_dkms_package(),
177
 
                         ['calico-compute',
178
 
                          'bird',
179
 
                          'neutron-dhcp-agent',
180
 
                          'nova-api-metadata']],
181
 
            'server_packages': ['neutron-server', 'calico-control'],
182
 
            'server_services': ['neutron-server']
183
 
        },
184
 
        'vsp': {
185
 
            'config': '/etc/neutron/plugins/nuage/nuage_plugin.ini',
186
 
            'driver': 'neutron.plugins.nuage.plugin.NuagePlugin',
187
 
            'contexts': [
188
 
                context.SharedDBContext(user=config('neutron-database-user'),
189
 
                                        database=config('neutron-database'),
190
 
                                        relation_prefix='neutron',
191
 
                                        ssl_dir=NEUTRON_CONF_DIR)],
192
 
            'services': [],
193
 
            'packages': [],
194
 
            'server_packages': ['neutron-server', 'neutron-plugin-nuage'],
195
 
            'server_services': ['neutron-server']
196
 
        },
197
 
        'plumgrid': {
198
 
            'config': '/etc/neutron/plugins/plumgrid/plumgrid.ini',
199
 
            'driver': 'neutron.plugins.plumgrid.plumgrid_plugin.plumgrid_plugin.NeutronPluginPLUMgridV2',
200
 
            'contexts': [
201
 
                context.SharedDBContext(user=config('database-user'),
202
 
                                        database=config('database'),
203
 
                                        ssl_dir=NEUTRON_CONF_DIR)],
204
 
            'services': [],
205
 
            'packages': [['plumgrid-lxc'],
206
 
                         ['iovisor-dkms'],
207
 
                         ['plumgrid-puppet']],
208
 
            'server_packages': ['neutron-server',
209
 
                                'neutron-plugin-plumgrid'],
210
 
            'server_services': ['neutron-server']
211
 
        }
212
 
    }
213
 
    if release >= 'icehouse':
214
 
        # NOTE: patch in ml2 plugin for icehouse onwards
215
 
        plugins['ovs']['config'] = '/etc/neutron/plugins/ml2/ml2_conf.ini'
216
 
        plugins['ovs']['driver'] = 'neutron.plugins.ml2.plugin.Ml2Plugin'
217
 
        plugins['ovs']['server_packages'] = ['neutron-server',
218
 
                                             'neutron-plugin-ml2']
219
 
        # NOTE: patch in vmware renames nvp->nsx for icehouse onwards
220
 
        plugins['nvp'] = plugins['nsx']
221
 
    return plugins
222
 
 
223
 
 
224
 
def neutron_plugin_attribute(plugin, attr, net_manager=None):
225
 
    manager = net_manager or network_manager()
226
 
    if manager == 'quantum':
227
 
        plugins = quantum_plugins()
228
 
    elif manager == 'neutron':
229
 
        plugins = neutron_plugins()
230
 
    else:
231
 
        log("Network manager '%s' does not support plugins." % (manager),
232
 
            level=ERROR)
233
 
        raise Exception
234
 
 
235
 
    try:
236
 
        _plugin = plugins[plugin]
237
 
    except KeyError:
238
 
        log('Unrecognised plugin for %s: %s' % (manager, plugin), level=ERROR)
239
 
        raise Exception
240
 
 
241
 
    try:
242
 
        return _plugin[attr]
243
 
    except KeyError:
244
 
        return None
245
 
 
246
 
 
247
 
def network_manager():
248
 
    '''
249
 
    Deals with the renaming of Quantum to Neutron in H and any situations
250
 
    that require compatability (eg, deploying H with network-manager=quantum,
251
 
    upgrading from G).
252
 
    '''
253
 
    release = os_release('nova-common')
254
 
    manager = config('network-manager').lower()
255
 
 
256
 
    if manager not in ['quantum', 'neutron']:
257
 
        return manager
258
 
 
259
 
    if release in ['essex']:
260
 
        # E does not support neutron
261
 
        log('Neutron networking not supported in Essex.', level=ERROR)
262
 
        raise Exception
263
 
    elif release in ['folsom', 'grizzly']:
264
 
        # neutron is named quantum in F and G
265
 
        return 'quantum'
266
 
    else:
267
 
        # ensure accurate naming for all releases post-H
268
 
        return 'neutron'
269
 
 
270
 
 
271
 
def parse_mappings(mappings):
272
 
    parsed = {}
273
 
    if mappings:
274
 
        mappings = mappings.split(' ')
275
 
        for m in mappings:
276
 
            p = m.partition(':')
277
 
            if p[1] == ':':
278
 
                parsed[p[0].strip()] = p[2].strip()
279
 
 
280
 
    return parsed
281
 
 
282
 
 
283
 
def parse_bridge_mappings(mappings):
284
 
    """Parse bridge mappings.
285
 
 
286
 
    Mappings must be a space-delimited list of provider:bridge mappings.
287
 
 
288
 
    Returns dict of the form {provider:bridge}.
289
 
    """
290
 
    return parse_mappings(mappings)
291
 
 
292
 
 
293
 
def parse_data_port_mappings(mappings, default_bridge='br-data'):
294
 
    """Parse data port mappings.
295
 
 
296
 
    Mappings must be a space-delimited list of bridge:port mappings.
297
 
 
298
 
    Returns dict of the form {bridge:port}.
299
 
    """
300
 
    _mappings = parse_mappings(mappings)
301
 
    if not _mappings:
302
 
        if not mappings:
303
 
            return {}
304
 
 
305
 
        # For backwards-compatibility we need to support port-only provided in
306
 
        # config.
307
 
        _mappings = {default_bridge: mappings.split(' ')[0]}
308
 
 
309
 
    bridges = _mappings.keys()
310
 
    ports = _mappings.values()
311
 
    if len(set(bridges)) != len(bridges):
312
 
        raise Exception("It is not allowed to have more than one port "
313
 
                        "configured on the same bridge")
314
 
 
315
 
    if len(set(ports)) != len(ports):
316
 
        raise Exception("It is not allowed to have the same port configured "
317
 
                        "on more than one bridge")
318
 
 
319
 
    return _mappings
320
 
 
321
 
 
322
 
def parse_vlan_range_mappings(mappings):
323
 
    """Parse vlan range mappings.
324
 
 
325
 
    Mappings must be a space-delimited list of provider:start:end mappings.
326
 
 
327
 
    Returns dict of the form {provider: (start, end)}.
328
 
    """
329
 
    _mappings = parse_mappings(mappings)
330
 
    if not _mappings:
331
 
        return {}
332
 
 
333
 
    mappings = {}
334
 
    for p, r in six.iteritems(_mappings):
335
 
        mappings[p] = tuple(r.split(':'))
336
 
 
337
 
    return mappings