~zulcss/ubuntu/precise/quantum/trunk

« back to all changes in this revision

Viewing changes to quantum/plugins/cisco/l2network_plugin.py

  • Committer: Chuck Short
  • Date: 2012-11-26 19:51:11 UTC
  • mfrom: (26.1.1 raring-proposed)
  • Revision ID: zulcss@ubuntu.com-20121126195111-jnz2cr4xi6whemw2
* New upstream release for the Ubuntu Cloud Archive.
* debian/patches/*: Refreshed for opening of Grizzly.
* New upstream release.
* debian/rules: FTFBS if there is missing binaries.
* debian/quantum-server.install: Add quantum-debug.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
 
#
3
 
# Copyright 2011 Cisco Systems, Inc.  All rights reserved.
4
 
#
5
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
6
 
#    not use this file except in compliance with the License. You may obtain
7
 
#    a copy of the License at
8
 
#
9
 
#         http://www.apache.org/licenses/LICENSE-2.0
10
 
#
11
 
#    Unless required by applicable law or agreed to in writing, software
12
 
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
 
#    License for the specific language governing permissions and limitations
15
 
#    under the License.
16
 
#
17
 
# @author: Sumit Naiksatam, Cisco Systems, Inc.
18
 
 
19
 
import inspect
20
 
import logging
21
 
 
22
 
from quantum.common import exceptions as exc
23
 
from quantum.openstack.common import importutils
24
 
from quantum.plugins.cisco.common import cisco_constants as const
25
 
from quantum.plugins.cisco.common import cisco_credentials as cred
26
 
from quantum.plugins.cisco.common import cisco_exceptions as cexc
27
 
from quantum.plugins.cisco.common import cisco_utils as cutil
28
 
from quantum.plugins.cisco.db import api as db
29
 
from quantum.plugins.cisco.db import l2network_db as cdb
30
 
from quantum.plugins.cisco import l2network_plugin_configuration as conf
31
 
from quantum.quantum_plugin_base import QuantumPluginBase
32
 
 
33
 
 
34
 
LOG = logging.getLogger(__name__)
35
 
 
36
 
 
37
 
class L2Network(QuantumPluginBase):
38
 
    """ L2 Network Framework Plugin """
39
 
    supported_extension_aliases = ["Cisco Multiport", "Cisco Credential",
40
 
                                   "Cisco Port Profile", "Cisco qos",
41
 
                                   "Cisco Nova Tenant"]
42
 
 
43
 
    def __init__(self):
44
 
        cdb.initialize()
45
 
        cred.Store.initialize()
46
 
        self._model = importutils.import_object(conf.MODEL_CLASS)
47
 
        self._vlan_mgr = importutils.import_object(conf.MANAGER_CLASS)
48
 
        LOG.debug("L2Network plugin initialization done successfully\n")
49
 
 
50
 
    """
51
 
    Core API implementation
52
 
    """
53
 
    def get_all_networks(self, tenant_id, **kwargs):
54
 
        """
55
 
        Returns a dictionary containing all
56
 
        <network_uuid, network_name> for
57
 
        the specified tenant.
58
 
        """
59
 
        LOG.debug("get_all_networks() called\n")
60
 
        self._invoke_device_plugins(self._func_name(), [tenant_id])
61
 
        networks_list = db.network_list(tenant_id)
62
 
        new_networks_list = []
63
 
        for network in networks_list:
64
 
            new_network_dict = cutil.make_net_dict(network[const.UUID],
65
 
                                                   network[const.NETWORKNAME],
66
 
                                                   [])
67
 
            new_networks_list.append(new_network_dict)
68
 
 
69
 
        return new_networks_list
70
 
 
71
 
    def create_network(self, tenant_id, net_name, **kwargs):
72
 
        """
73
 
        Creates a new Virtual Network, and assigns it
74
 
        a symbolic name.
75
 
        """
76
 
        LOG.debug("create_network() called\n")
77
 
        new_network = db.network_create(tenant_id, net_name)
78
 
        new_net_id = new_network[const.UUID]
79
 
        vlan_id = self._get_vlan_for_tenant(tenant_id, net_name)
80
 
        vlan_name = self._get_vlan_name(new_net_id, str(vlan_id))
81
 
        self._invoke_device_plugins(self._func_name(), [tenant_id, net_name,
82
 
                                                        new_net_id, vlan_name,
83
 
                                                        vlan_id])
84
 
        cdb.add_vlan_binding(vlan_id, vlan_name, new_net_id)
85
 
        new_net_dict = {const.NET_ID: new_net_id,
86
 
                        const.NET_NAME: net_name,
87
 
                        const.NET_PORTS: []}
88
 
        return new_net_dict
89
 
 
90
 
    def delete_network(self, tenant_id, net_id):
91
 
        """
92
 
        Deletes the network with the specified network identifier
93
 
        belonging to the specified tenant.
94
 
        """
95
 
        LOG.debug("delete_network() called\n")
96
 
        db.validate_network_ownership(tenant_id, net_id)
97
 
        net = db.network_get(net_id)
98
 
        if net:
99
 
            if len(net[const.NETWORKPORTS]) > 0:
100
 
                ports_on_net = db.port_list(net_id)
101
 
                for port in ports_on_net:
102
 
                    if port[const.INTERFACEID]:
103
 
                        raise exc.NetworkInUse(net_id=net_id)
104
 
                for port in ports_on_net:
105
 
                    self.delete_port(tenant_id, net_id, port[const.UUID])
106
 
 
107
 
            self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
108
 
            net_dict = cutil.make_net_dict(net[const.UUID],
109
 
                                           net[const.NETWORKNAME],
110
 
                                           [])
111
 
            self._release_vlan_for_tenant(tenant_id, net_id)
112
 
            cdb.remove_vlan_binding(net_id)
113
 
            db.network_destroy(net_id)
114
 
            return net_dict
115
 
        # Network not found
116
 
        raise exc.NetworkNotFound(net_id=net_id)
117
 
 
118
 
    def get_network_details(self, tenant_id, net_id):
119
 
        """
120
 
        Gets the details of a particular network
121
 
        """
122
 
        LOG.debug("get_network_details() called\n")
123
 
        db.validate_network_ownership(tenant_id, net_id)
124
 
        network = db.network_get(net_id)
125
 
        self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
126
 
        ports_list = network[const.NETWORKPORTS]
127
 
        ports_on_net = []
128
 
        for port in ports_list:
129
 
            new_port = cutil.make_port_dict(port[const.UUID],
130
 
                                            port[const.PORTSTATE],
131
 
                                            port[const.NETWORKID],
132
 
                                            port[const.INTERFACEID])
133
 
            ports_on_net.append(new_port)
134
 
 
135
 
        new_network = cutil.make_net_dict(network[const.UUID],
136
 
                                          network[const.NETWORKNAME],
137
 
                                          ports_on_net)
138
 
 
139
 
        return new_network
140
 
 
141
 
    def update_network(self, tenant_id, net_id, **kwargs):
142
 
        """
143
 
        Updates the symbolic name belonging to a particular
144
 
        Virtual Network.
145
 
        """
146
 
        LOG.debug("update_network() called\n")
147
 
        db.validate_network_ownership(tenant_id, net_id)
148
 
        network = db.network_update(net_id, tenant_id, **kwargs)
149
 
        self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
150
 
                                                        kwargs])
151
 
        net_dict = cutil.make_net_dict(network[const.UUID],
152
 
                                       network[const.NETWORKNAME],
153
 
                                       [])
154
 
        return net_dict
155
 
 
156
 
    def get_all_ports(self, tenant_id, net_id, **kwargs):
157
 
        """
158
 
        Retrieves all port identifiers belonging to the
159
 
        specified Virtual Network.
160
 
        """
161
 
        LOG.debug("get_all_ports() called\n")
162
 
        db.validate_network_ownership(tenant_id, net_id)
163
 
        network = db.network_get(net_id)
164
 
        self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
165
 
        ports_list = network[const.NETWORKPORTS]
166
 
        ports_on_net = []
167
 
        for port in ports_list:
168
 
            new_port = cutil.make_port_dict(port[const.UUID],
169
 
                                            port[const.PORTSTATE],
170
 
                                            port[const.NETWORKID],
171
 
                                            port[const.INTERFACEID])
172
 
            ports_on_net.append(new_port)
173
 
 
174
 
        return ports_on_net
175
 
 
176
 
    def create_port(self, tenant_id, net_id, port_state=None, **kwargs):
177
 
        """
178
 
        Creates a port on the specified Virtual Network.
179
 
        """
180
 
        LOG.debug("create_port() called\n")
181
 
 
182
 
        db.validate_network_ownership(tenant_id, net_id)
183
 
        port = db.port_create(net_id, port_state)
184
 
        unique_port_id_string = port[const.UUID]
185
 
        self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
186
 
                                                        port_state,
187
 
                                                        unique_port_id_string])
188
 
        new_port_dict = cutil.make_port_dict(port[const.UUID],
189
 
                                             port[const.PORTSTATE],
190
 
                                             port[const.NETWORKID],
191
 
                                             port[const.INTERFACEID])
192
 
        return new_port_dict
193
 
 
194
 
    def delete_port(self, tenant_id, net_id, port_id):
195
 
        """
196
 
        Deletes a port on a specified Virtual Network,
197
 
        if the port contains a remote interface attachment,
198
 
        the remote interface should first be un-plugged and
199
 
        then the port can be deleted.
200
 
        """
201
 
        LOG.debug("delete_port() called\n")
202
 
        db.validate_port_ownership(tenant_id, net_id, port_id)
203
 
        network = db.network_get(net_id)
204
 
        port = db.port_get(net_id, port_id)
205
 
        attachment_id = port[const.INTERFACEID]
206
 
        if not attachment_id:
207
 
            self._invoke_device_plugins(self._func_name(), [tenant_id,
208
 
                                                            net_id,
209
 
                                                            port_id])
210
 
            db.port_destroy(net_id, port_id)
211
 
            new_port_dict = cutil.make_port_dict(port_id, None, None, None)
212
 
            return new_port_dict
213
 
        else:
214
 
            raise exc.PortInUse(port_id=port_id, net_id=net_id,
215
 
                                att_id=attachment_id)
216
 
 
217
 
    def update_port(self, tenant_id, net_id, port_id, **kwargs):
218
 
        """
219
 
        Updates the state of a port on the specified Virtual Network.
220
 
        """
221
 
        LOG.debug("update_port() called\n")
222
 
        db.validate_port_ownership(tenant_id, net_id, port_id)
223
 
        network = db.network_get(net_id)
224
 
        self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
225
 
                                                        port_id, kwargs])
226
 
        self._validate_port_state(kwargs["state"])
227
 
        db.port_update(port_id, net_id, **kwargs)
228
 
 
229
 
        new_port_dict = cutil.make_port_dict(port_id, kwargs["state"], net_id,
230
 
                                             None)
231
 
        return new_port_dict
232
 
 
233
 
    def get_port_details(self, tenant_id, net_id, port_id):
234
 
        """
235
 
        This method allows the user to retrieve a remote interface
236
 
        that is attached to this particular port.
237
 
        """
238
 
        LOG.debug("get_port_details() called\n")
239
 
        db.validate_port_ownership(tenant_id, net_id, port_id)
240
 
        network = db.network_get(net_id)
241
 
        self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
242
 
                                                        port_id])
243
 
        port = db.port_get(net_id, port_id)
244
 
        new_port_dict = cutil.make_port_dict(port[const.UUID],
245
 
                                             port[const.PORTSTATE],
246
 
                                             port[const.NETWORKID],
247
 
                                             port[const.INTERFACEID])
248
 
        return new_port_dict
249
 
 
250
 
    def plug_interface(self, tenant_id, net_id, port_id,
251
 
                       remote_interface_id):
252
 
        """
253
 
        Provides connectivity to a remote interface to the
254
 
        specified Virtual Network.
255
 
        """
256
 
        LOG.debug("plug_interface() called\n")
257
 
        db.validate_port_ownership(tenant_id, net_id, port_id)
258
 
        network = db.network_get(net_id)
259
 
        port = db.port_get(net_id, port_id)
260
 
        attachment_id = port[const.INTERFACEID]
261
 
        if attachment_id is None:
262
 
            raise cexc.InvalidAttach(port_id=port_id, net_id=net_id,
263
 
                                     att_id=remote_interface_id)
264
 
        attachment_id = attachment_id[:const.UUID_LENGTH]
265
 
        remote_interface_id = remote_interface_id[:const.UUID_LENGTH]
266
 
        if remote_interface_id != attachment_id:
267
 
            LOG.debug("Existing attachment_id:%s, remote_interface_id:%s" %
268
 
                      (attachment_id, remote_interface_id))
269
 
            raise exc.PortInUse(port_id=port_id, net_id=net_id,
270
 
                                att_id=attachment_id)
271
 
        self._invoke_device_plugins(self._func_name(), [tenant_id,
272
 
                                                        net_id, port_id,
273
 
                                                        attachment_id])
274
 
        db.port_unset_attachment(net_id, port_id)
275
 
        db.port_set_attachment(net_id, port_id, attachment_id)
276
 
        #Note: The remote_interface_id gets associated with the port
277
 
        # when the VM is instantiated. The plug interface call results
278
 
        # in putting the port on the VLAN associated with this network
279
 
 
280
 
    def unplug_interface(self, tenant_id, net_id, port_id):
281
 
        """
282
 
        Removes connectivity of a remote interface to the
283
 
        specified Virtual Network.
284
 
        """
285
 
        LOG.debug("unplug_interface() called\n")
286
 
        db.validate_port_ownership(tenant_id, net_id, port_id)
287
 
        network = db.network_get(net_id)
288
 
        port = db.port_get(net_id, port_id)
289
 
        attachment_id = port[const.INTERFACEID]
290
 
        if attachment_id is None:
291
 
            raise cexc.InvalidDetach(port_id=port_id, net_id=net_id,
292
 
                                     att_id=remote_interface_id)
293
 
        self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
294
 
                                                        port_id])
295
 
        attachment_id = attachment_id[:const.UUID_LENGTH]
296
 
        attachment_id = attachment_id + const.UNPLUGGED
297
 
        db.port_unset_attachment(net_id, port_id)
298
 
        db.port_set_attachment(net_id, port_id, attachment_id)
299
 
 
300
 
    """
301
 
    Extension API implementation
302
 
    """
303
 
    def get_all_portprofiles(self, tenant_id):
304
 
        """Get all port profiles"""
305
 
        LOG.debug("get_all_portprofiles() called\n")
306
 
        pplist = cdb.get_all_portprofiles()
307
 
        new_pplist = []
308
 
        for portprofile in pplist:
309
 
            new_pp = cutil.make_portprofile_dict(tenant_id,
310
 
                                                 portprofile[const.UUID],
311
 
                                                 portprofile[const.PPNAME],
312
 
                                                 portprofile[const.PPQOS])
313
 
            new_pplist.append(new_pp)
314
 
 
315
 
        return new_pplist
316
 
 
317
 
    def get_portprofile_details(self, tenant_id, profile_id):
318
 
        """Get port profile details"""
319
 
        LOG.debug("get_portprofile_details() called\n")
320
 
        try:
321
 
            portprofile = cdb.get_portprofile(tenant_id, profile_id)
322
 
        except Exception:
323
 
            raise cexc.PortProfileNotFound(tenant_id=tenant_id,
324
 
                                           portprofile_id=profile_id)
325
 
 
326
 
        new_pp = cutil.make_portprofile_dict(tenant_id,
327
 
                                             portprofile[const.UUID],
328
 
                                             portprofile[const.PPNAME],
329
 
                                             portprofile[const.PPQOS])
330
 
        return new_pp
331
 
 
332
 
    def create_portprofile(self, tenant_id, profile_name, qos):
333
 
        """Create port profile"""
334
 
        LOG.debug("create_portprofile() called\n")
335
 
        portprofile = cdb.add_portprofile(tenant_id, profile_name,
336
 
                                          const.NO_VLAN_ID, qos)
337
 
        new_pp = cutil.make_portprofile_dict(tenant_id,
338
 
                                             portprofile[const.UUID],
339
 
                                             portprofile[const.PPNAME],
340
 
                                             portprofile[const.PPQOS])
341
 
        return new_pp
342
 
 
343
 
    def delete_portprofile(self, tenant_id, profile_id):
344
 
        """Delete portprofile"""
345
 
        LOG.debug("delete_portprofile() called\n")
346
 
        try:
347
 
            portprofile = cdb.get_portprofile(tenant_id, profile_id)
348
 
        except Exception:
349
 
            raise cexc.PortProfileNotFound(tenant_id=tenant_id,
350
 
                                           portprofile_id=profile_id)
351
 
 
352
 
        plist = cdb.get_pp_binding(tenant_id, profile_id)
353
 
        if plist:
354
 
            raise cexc.PortProfileInvalidDelete(tenant_id=tenant_id,
355
 
                                                profile_id=profile_id)
356
 
        else:
357
 
            cdb.remove_portprofile(tenant_id, profile_id)
358
 
 
359
 
    def rename_portprofile(self, tenant_id, profile_id, new_name):
360
 
        """Rename port profile"""
361
 
        LOG.debug("rename_portprofile() called\n")
362
 
        try:
363
 
            portprofile = cdb.get_portprofile(tenant_id, profile_id)
364
 
        except Exception:
365
 
            raise cexc.PortProfileNotFound(tenant_id=tenant_id,
366
 
                                           portprofile_id=profile_id)
367
 
        portprofile = cdb.update_portprofile(tenant_id, profile_id, new_name)
368
 
        new_pp = cutil.make_portprofile_dict(tenant_id,
369
 
                                             portprofile[const.UUID],
370
 
                                             portprofile[const.PPNAME],
371
 
                                             portprofile[const.PPQOS])
372
 
        return new_pp
373
 
 
374
 
    def associate_portprofile(self, tenant_id, net_id,
375
 
                              port_id, portprofile_id):
376
 
        """Associate port profile"""
377
 
        LOG.debug("associate_portprofile() called\n")
378
 
        try:
379
 
            portprofile = cdb.get_portprofile(tenant_id, portprofile_id)
380
 
        except Exception:
381
 
            raise cexc.PortProfileNotFound(tenant_id=tenant_id,
382
 
                                           portprofile_id=portprofile_id)
383
 
 
384
 
        cdb.add_pp_binding(tenant_id, port_id, portprofile_id, False)
385
 
 
386
 
    def disassociate_portprofile(self, tenant_id, net_id,
387
 
                                 port_id, portprofile_id):
388
 
        """Disassociate port profile"""
389
 
        LOG.debug("disassociate_portprofile() called\n")
390
 
        try:
391
 
            portprofile = cdb.get_portprofile(tenant_id, portprofile_id)
392
 
        except Exception:
393
 
            raise cexc.PortProfileNotFound(tenant_id=tenant_id,
394
 
                                           portprofile_id=portprofile_id)
395
 
 
396
 
        cdb.remove_pp_binding(tenant_id, port_id, portprofile_id)
397
 
 
398
 
    def get_all_qoss(self, tenant_id):
399
 
        """Get all QoS levels"""
400
 
        LOG.debug("get_all_qoss() called\n")
401
 
        qoslist = cdb.get_all_qoss(tenant_id)
402
 
        return qoslist
403
 
 
404
 
    def get_qos_details(self, tenant_id, qos_id):
405
 
        """Get QoS Details"""
406
 
        LOG.debug("get_qos_details() called\n")
407
 
        try:
408
 
            qos_level = cdb.get_qos(tenant_id, qos_id)
409
 
        except Exception:
410
 
            raise cexc.QosNotFound(tenant_id=tenant_id,
411
 
                                   qos_id=qos_id)
412
 
        return qos_level
413
 
 
414
 
    def create_qos(self, tenant_id, qos_name, qos_desc):
415
 
        """Create a QoS level"""
416
 
        LOG.debug("create_qos() called\n")
417
 
        qos = cdb.add_qos(tenant_id, qos_name, str(qos_desc))
418
 
        return qos
419
 
 
420
 
    def delete_qos(self, tenant_id, qos_id):
421
 
        """Delete a QoS level"""
422
 
        LOG.debug("delete_qos() called\n")
423
 
        try:
424
 
            qos_level = cdb.get_qos(tenant_id, qos_id)
425
 
        except Exception:
426
 
            raise cexc.QosNotFound(tenant_id=tenant_id,
427
 
                                   qos_id=qos_id)
428
 
        return cdb.remove_qos(tenant_id, qos_id)
429
 
 
430
 
    def rename_qos(self, tenant_id, qos_id, new_name):
431
 
        """Rename QoS level"""
432
 
        LOG.debug("rename_qos() called\n")
433
 
        try:
434
 
            qos_level = cdb.get_qos(tenant_id, qos_id)
435
 
        except Exception:
436
 
            raise cexc.QosNotFound(tenant_id=tenant_id,
437
 
                                   qos_id=qos_id)
438
 
        qos = cdb.update_qos(tenant_id, qos_id, new_name)
439
 
        return qos
440
 
 
441
 
    def get_all_credentials(self, tenant_id):
442
 
        """Get all credentials"""
443
 
        LOG.debug("get_all_credentials() called\n")
444
 
        credential_list = cdb.get_all_credentials(tenant_id)
445
 
        return credential_list
446
 
 
447
 
    def get_credential_details(self, tenant_id, credential_id):
448
 
        """Get a particular credential"""
449
 
        LOG.debug("get_credential_details() called\n")
450
 
        try:
451
 
            credential = cdb.get_credential(tenant_id, credential_id)
452
 
        except Exception:
453
 
            raise cexc.CredentialNotFound(tenant_id=tenant_id,
454
 
                                          credential_id=credential_id)
455
 
        return credential
456
 
 
457
 
    def create_credential(self, tenant_id, credential_name, user_name,
458
 
                          password):
459
 
        """Create a new credential"""
460
 
        LOG.debug("create_credential() called\n")
461
 
        credential = cdb.add_credential(tenant_id, credential_name,
462
 
                                        user_name, password)
463
 
        return credential
464
 
 
465
 
    def delete_credential(self, tenant_id, credential_id):
466
 
        """Delete a credential"""
467
 
        LOG.debug("delete_credential() called\n")
468
 
        try:
469
 
            credential = cdb.get_credential(tenant_id, credential_id)
470
 
        except Exception:
471
 
            raise cexc.CredentialNotFound(tenant_id=tenant_id,
472
 
                                          credential_id=credential_id)
473
 
        credential = cdb.remove_credential(tenant_id, credential_id)
474
 
        return credential
475
 
 
476
 
    def rename_credential(self, tenant_id, credential_id, new_name):
477
 
        """Rename the particular credential resource"""
478
 
        LOG.debug("rename_credential() called\n")
479
 
        try:
480
 
            credential = cdb.get_credential(tenant_id, credential_id)
481
 
        except Exception:
482
 
            raise cexc.CredentialNotFound(tenant_id=tenant_id,
483
 
                                          credential_id=credential_id)
484
 
        credential = cdb.update_credential(tenant_id, credential_id, new_name)
485
 
        return credential
486
 
 
487
 
    def schedule_host(self, tenant_id, instance_id, instance_desc):
488
 
        """Provides the hostname on which a dynamic vnic is reserved"""
489
 
        LOG.debug("schedule_host() called\n")
490
 
        host_list = self._invoke_device_plugins(self._func_name(),
491
 
                                                [tenant_id,
492
 
                                                 instance_id,
493
 
                                                 instance_desc])
494
 
        return host_list
495
 
 
496
 
    def associate_port(self, tenant_id, instance_id, instance_desc):
497
 
        """
498
 
        Get the portprofile name and the device name for the dynamic vnic
499
 
        """
500
 
        LOG.debug("associate_port() called\n")
501
 
        return self._invoke_device_plugins(self._func_name(), [tenant_id,
502
 
                                                               instance_id,
503
 
                                                               instance_desc])
504
 
 
505
 
    def detach_port(self, tenant_id, instance_id, instance_desc):
506
 
        """
507
 
        Remove the association of the VIF with the dynamic vnic
508
 
        """
509
 
        LOG.debug("detach_port() called\n")
510
 
        return self._invoke_device_plugins(self._func_name(), [tenant_id,
511
 
                                                               instance_id,
512
 
                                                               instance_desc])
513
 
 
514
 
    def create_multiport(self, tenant_id, net_id_list, port_state, ports_desc):
515
 
        """
516
 
        Creates multiple ports on the specified Virtual Network.
517
 
        """
518
 
        LOG.debug("create_ports() called\n")
519
 
        ports_num = len(net_id_list)
520
 
        ports_id_list = []
521
 
        ports_dict_list = []
522
 
 
523
 
        for net_id in net_id_list:
524
 
            db.validate_network_ownership(tenant_id, net_id)
525
 
            port = db.port_create(net_id, port_state)
526
 
            ports_id_list.append(port[const.UUID])
527
 
            port_dict = {const.PORT_ID: port[const.UUID]}
528
 
            ports_dict_list.append(port_dict)
529
 
 
530
 
        self._invoke_device_plugins(self._func_name(), [tenant_id,
531
 
                                                        net_id_list,
532
 
                                                        ports_num,
533
 
                                                        ports_id_list])
534
 
        return ports_dict_list
535
 
 
536
 
    """
537
 
    Private functions
538
 
    """
539
 
    def _invoke_device_plugins(self, function_name, args):
540
 
        """
541
 
        All device-specific calls are delegated to the model
542
 
        """
543
 
        return getattr(self._model, function_name)(args)
544
 
 
545
 
    def _get_vlan_for_tenant(self, tenant_id, net_name):
546
 
        """Get vlan ID"""
547
 
        return self._vlan_mgr.reserve_segmentation_id(tenant_id, net_name)
548
 
 
549
 
    def _release_vlan_for_tenant(self, tenant_id, net_id):
550
 
        """Relase VLAN"""
551
 
        return self._vlan_mgr.release_segmentation_id(tenant_id, net_id)
552
 
 
553
 
    def _get_vlan_name(self, net_id, vlan):
554
 
        """Getting the vlan name from the tenant and vlan"""
555
 
        vlan_name = conf.VLAN_NAME_PREFIX + vlan
556
 
        return vlan_name
557
 
 
558
 
    def _validate_port_state(self, port_state):
559
 
        """Checking the port state"""
560
 
        if port_state.upper() not in (const.PORT_UP, const.PORT_DOWN):
561
 
            raise exc.StateInvalid(port_state=port_state)
562
 
        return True
563
 
 
564
 
    def _func_name(self, offset=0):
565
 
        """Getting the name of the calling funciton"""
566
 
        return inspect.stack()[1 + offset][3]