~ubuntu-branches/ubuntu/quantal/nova/quantal-proposed

« back to all changes in this revision

Viewing changes to nova/network/quantum/quantum_connection.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-08-16 14:04:11 UTC
  • mto: This revision was merged to the branch mainline in revision 84.
  • Revision ID: package-import@ubuntu.com-20120816140411-0mr4n241wmk30t9l
Tags: upstream-2012.2~f3
ImportĀ upstreamĀ versionĀ 2012.2~f3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
 
 
3
 
# Copyright 2011 Nicira Networks
4
 
# All Rights Reserved.
5
 
#
6
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
7
 
#    not use this file except in compliance with the License. You may obtain
8
 
#    a copy of the License at
9
 
#
10
 
#         http://www.apache.org/licenses/LICENSE-2.0
11
 
#
12
 
#    Unless required by applicable law or agreed to in writing, software
13
 
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
 
#    License for the specific language governing permissions and limitations
16
 
#    under the License.
17
 
 
18
 
from nova import flags
19
 
from nova.network.quantum import client as quantum_client
20
 
from nova.openstack.common import cfg
21
 
from nova.openstack.common import log as logging
22
 
 
23
 
 
24
 
LOG = logging.getLogger(__name__)
25
 
 
26
 
quantum_opts = [
27
 
    cfg.StrOpt('quantum_connection_host',
28
 
               default='127.0.0.1',
29
 
               help='HOST for connecting to quantum'),
30
 
    cfg.IntOpt('quantum_connection_port',
31
 
               default=9696,
32
 
               help='PORT for connecting to quantum'),
33
 
    cfg.StrOpt('quantum_default_tenant_id',
34
 
               default="default",
35
 
               help='Default tenant id when creating quantum networks'),
36
 
    cfg.IntOpt('quantum_request_timeout',
37
 
               default=20,
38
 
               help='Maximum amount of time to wait for quantum request'),
39
 
    ]
40
 
 
41
 
FLAGS = flags.FLAGS
42
 
FLAGS.register_opts(quantum_opts)
43
 
 
44
 
 
45
 
class QuantumClientConnection(object):
46
 
    """Abstracts connection to Quantum service into higher level
47
 
       operations performed by the QuantumManager.
48
 
 
49
 
       Separating this out as a class also let's us create a 'fake'
50
 
       version of this class for unit tests.
51
 
    """
52
 
 
53
 
    def __init__(self, client=None):
54
 
        """Initialize Quantum client class based on flags."""
55
 
        if client:
56
 
            self.client = client
57
 
        else:
58
 
            self.client = quantum_client.Client(FLAGS.quantum_connection_host,
59
 
                                        FLAGS.quantum_connection_port,
60
 
                                        timeout=FLAGS.quantum_request_timeout,
61
 
                                        format="json",
62
 
                                        logger=LOG)
63
 
 
64
 
    def create_network(self, tenant_id, network_name, **kwargs):
65
 
        """Create network using specified name, return Quantum
66
 
           network UUID.
67
 
        """
68
 
        data = {'network': {'name': network_name}}
69
 
        for kw in kwargs:
70
 
            data['network'][kw] = kwargs[kw]
71
 
        resdict = self.client.create_network(data, tenant=tenant_id)
72
 
        return resdict["network"]["id"]
73
 
 
74
 
    def get_network_name(self, tenant_id, network_id):
75
 
        net = self.client.show_network_details(network_id, tenant=tenant_id)
76
 
        return net["network"]["name"]
77
 
 
78
 
    def delete_network(self, tenant_id, net_id):
79
 
        """Deletes Quantum network with specified UUID."""
80
 
        self.client.delete_network(net_id, tenant=tenant_id)
81
 
 
82
 
    def network_exists(self, tenant_id, net_id):
83
 
        """Determine if a Quantum network exists for the
84
 
           specified tenant.
85
 
        """
86
 
        try:
87
 
            self.client.show_network_details(net_id, tenant=tenant_id)
88
 
            return True
89
 
        except quantum_client.QuantumNotFoundException:
90
 
            # Not really an error.  Real errors will be propogated to caller
91
 
            return False
92
 
 
93
 
    def get_networks(self, tenant_id):
94
 
        """Retrieve all networks for this tenant"""
95
 
        return self.client.list_networks(tenant=tenant_id)
96
 
 
97
 
    def create_and_attach_port(self, tenant_id, net_id, interface_id,
98
 
                               **kwargs):
99
 
        """Creates a Quantum port on the specified network, sets
100
 
           status to ACTIVE to enable traffic, and attaches the
101
 
           vNIC with the specified interface-id.
102
 
        """
103
 
        LOG.debug(_("Connecting interface %(interface_id)s to "
104
 
                    "net %(net_id)s for %(tenant_id)s"), locals())
105
 
        port_data = {'port': {'state': 'ACTIVE'}}
106
 
        for kw in kwargs:
107
 
            port_data['port'][kw] = kwargs[kw]
108
 
        resdict = self.client.create_port(net_id, port_data, tenant=tenant_id)
109
 
        port_id = resdict["port"]["id"]
110
 
 
111
 
        attach_data = {'attachment': {'id': interface_id}}
112
 
        self.client.attach_resource(net_id, port_id, attach_data,
113
 
                                    tenant=tenant_id)
114
 
 
115
 
    def detach_and_delete_port(self, tenant_id, net_id, port_id):
116
 
        """Detach and delete the specified Quantum port."""
117
 
        LOG.debug(_("Deleting port %(port_id)s on net %(net_id)s"
118
 
                    " for %(tenant_id)s"), locals())
119
 
 
120
 
        self.client.detach_resource(net_id, port_id, tenant=tenant_id)
121
 
        self.client.delete_port(net_id, port_id, tenant=tenant_id)
122
 
 
123
 
    def get_port_by_attachment(self, tenant_id, net_id, attachment_id):
124
 
        """Given a tenant and network, search for the port UUID that
125
 
           has the specified interface-id attachment.
126
 
        """
127
 
        port_list = []
128
 
        try:
129
 
            port_list_resdict = self.client.list_ports(net_id,
130
 
                tenant=tenant_id,
131
 
                filter_ops={'attachment': attachment_id})
132
 
            port_list = port_list_resdict["ports"]
133
 
        except quantum_client.QuantumNotFoundException:
134
 
            return None
135
 
 
136
 
        port_list_len = len(port_list)
137
 
        if port_list_len == 1:
138
 
            return port_list[0]['id']
139
 
        elif port_list_len > 1:
140
 
            raise Exception("Expected single port with attachment "
141
 
                 "%(attachment_id)s, found %(port_list_len)s" % locals())
142
 
        return None
143
 
 
144
 
    def get_attached_ports(self, tenant_id, network_id):
145
 
        rv = []
146
 
        port_list = self.client.list_ports(network_id, tenant=tenant_id)
147
 
        for p in port_list["ports"]:
148
 
            try:
149
 
                port_id = p["id"]
150
 
                port = self.client.show_port_attachment(network_id,
151
 
                                port_id, tenant=tenant_id)
152
 
                # Skip ports without an attachment
153
 
                if "id" not in port["attachment"]:
154
 
                    continue
155
 
                rv.append({'port-id': port_id,
156
 
                           'attachment': port["attachment"]["id"]})
157
 
            except quantum_client.QuantumNotFoundException:
158
 
                pass
159
 
        return rv