~citrix-openstack/nova/xenapi

« back to all changes in this revision

Viewing changes to nova/network/manager.py

  • Committer: Tarmac
  • Author(s): Todd Willey, root, Vishvananda Ishaya, Joe Heck, root, Andy Smith, Anne Gentle, Dean Troyer, Devin Carlen
  • Date: 2010-11-16 02:34:47 UTC
  • mfrom: (386.2.71 trunkdoc)
  • Revision ID: hudson@openstack.org-20101116023447-pz7n6ps5rf0fnjea
Lots of documentation and docstring updates.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#    under the License.
18
18
 
19
19
"""
20
 
Network Hosts are responsible for allocating ips and setting up network
 
20
Network Hosts are responsible for allocating ips and setting up network.
 
21
 
 
22
There are multiple backend drivers that handle specific types of networking
 
23
topologies.  All of the network commands are issued to a subclass of
 
24
:class:`NetworkManager`.
 
25
 
 
26
**Related Flags**
 
27
 
 
28
:network_driver:  Driver to use for network creation
 
29
:flat_network_bridge:  Bridge device for simple network instances
 
30
:flat_network_dns:  Dns for simple network
 
31
:flat_network_dhcp_start:  Dhcp start for FlatDhcp
 
32
:vlan_start:  First VLAN for private networks
 
33
:vpn_ip:  Public IP for the cloudpipe VPN servers
 
34
:vpn_start:  First Vpn port for private networks
 
35
:cnt_vpn_clients:  Number of addresses reserved for vpn clients
 
36
:network_size:  Number of addresses in each private subnet
 
37
:floating_range:  Floating IP address block
 
38
:fixed_range:  Fixed IP address block
 
39
:date_dhcp_on_disassociate:  Whether to update dhcp when fixed_ip
 
40
                             is disassociated
 
41
:fixed_ip_disassociate_timeout:  Seconds after which a deallocated ip
 
42
                                 is disassociated
 
43
 
21
44
"""
22
45
 
23
46
import datetime
63
86
 
64
87
 
65
88
class AddressAlreadyAllocated(exception.Error):
66
 
    """Address was already allocated"""
 
89
    """Address was already allocated."""
67
90
    pass
68
91
 
69
92
 
70
93
class NetworkManager(manager.Manager):
71
 
    """Implements common network manager functionality
 
94
    """Implements common network manager functionality.
72
95
 
73
 
    This class must be subclassed.
 
96
    This class must be subclassed to support specific topologies.
74
97
    """
 
98
 
75
99
    def __init__(self, network_driver=None, *args, **kwargs):
76
100
        if not network_driver:
77
101
            network_driver = FLAGS.network_driver
86
110
            self._on_set_network_host(ctxt, network['id'])
87
111
 
88
112
    def set_network_host(self, context, network_id):
89
 
        """Safely sets the host of the network"""
 
113
        """Safely sets the host of the network."""
90
114
        logging.debug("setting network host")
91
115
        host = self.db.network_set_host(context,
92
116
                                        network_id,
95
119
        return host
96
120
 
97
121
    def allocate_fixed_ip(self, context, instance_id, *args, **kwargs):
98
 
        """Gets a fixed ip from the pool"""
 
122
        """Gets a fixed ip from the pool."""
99
123
        raise NotImplementedError()
100
124
 
101
125
    def deallocate_fixed_ip(self, context, address, *args, **kwargs):
102
 
        """Returns a fixed ip to the pool"""
 
126
        """Returns a fixed ip to the pool."""
103
127
        raise NotImplementedError()
104
128
 
105
129
    def setup_fixed_ip(self, context, address):
106
 
        """Sets up rules for fixed ip"""
 
130
        """Sets up rules for fixed ip."""
107
131
        raise NotImplementedError()
108
132
 
109
133
    def _on_set_network_host(self, context, network_id):
110
 
        """Called when this host becomes the host for a network"""
 
134
        """Called when this host becomes the host for a network."""
111
135
        raise NotImplementedError()
112
136
 
113
137
    def setup_compute_network(self, context, instance_id):
114
 
        """Sets up matching network for compute hosts"""
 
138
        """Sets up matching network for compute hosts."""
115
139
        raise NotImplementedError()
116
140
 
117
141
    def allocate_floating_ip(self, context, project_id):
118
 
        """Gets an floating ip from the pool"""
 
142
        """Gets an floating ip from the pool."""
119
143
        # TODO(vish): add floating ips through manage command
120
144
        return self.db.floating_ip_allocate_address(context,
121
145
                                                    self.host,
122
146
                                                    project_id)
123
147
 
124
148
    def associate_floating_ip(self, context, floating_address, fixed_address):
125
 
        """Associates an floating ip to a fixed ip"""
 
149
        """Associates an floating ip to a fixed ip."""
126
150
        self.db.floating_ip_fixed_ip_associate(context,
127
151
                                               floating_address,
128
152
                                               fixed_address)
130
154
        self.driver.ensure_floating_forward(floating_address, fixed_address)
131
155
 
132
156
    def disassociate_floating_ip(self, context, floating_address):
133
 
        """Disassociates a floating ip"""
 
157
        """Disassociates a floating ip."""
134
158
        fixed_address = self.db.floating_ip_disassociate(context,
135
159
                                                         floating_address)
136
160
        self.driver.unbind_floating_ip(floating_address)
137
161
        self.driver.remove_floating_forward(floating_address, fixed_address)
138
162
 
139
163
    def deallocate_floating_ip(self, context, floating_address):
140
 
        """Returns an floating ip to the pool"""
 
164
        """Returns an floating ip to the pool."""
141
165
        self.db.floating_ip_deallocate(context, floating_address)
142
166
 
143
167
    def lease_fixed_ip(self, context, mac, address):
144
 
        """Called by dhcp-bridge when ip is leased"""
 
168
        """Called by dhcp-bridge when ip is leased."""
145
169
        logging.debug("Leasing IP %s", address)
146
170
        fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
147
171
        instance_ref = fixed_ip_ref['instance']
158
182
            logging.warn("IP %s leased that was already deallocated", address)
159
183
 
160
184
    def release_fixed_ip(self, context, mac, address):
161
 
        """Called by dhcp-bridge when ip is released"""
 
185
        """Called by dhcp-bridge when ip is released."""
162
186
        logging.debug("Releasing IP %s", address)
163
187
        fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
164
188
        instance_ref = fixed_ip_ref['instance']
183
207
                self.driver.update_dhcp(context, network_ref['id'])
184
208
 
185
209
    def get_network(self, context):
186
 
        """Get the network for the current context"""
 
210
        """Get the network for the current context."""
187
211
        raise NotImplementedError()
188
212
 
189
213
    def create_networks(self, context, num_networks, network_size,
190
214
                        *args, **kwargs):
191
 
        """Create networks based on parameters"""
 
215
        """Create networks based on parameters."""
192
216
        raise NotImplementedError()
193
217
 
194
218
    @property
195
219
    def _bottom_reserved_ips(self):  # pylint: disable-msg=R0201
196
 
        """Number of reserved ips at the bottom of the range"""
 
220
        """Number of reserved ips at the bottom of the range."""
197
221
        return 2  # network, gateway
198
222
 
199
223
    @property
200
224
    def _top_reserved_ips(self):  # pylint: disable-msg=R0201
201
 
        """Number of reserved ips at the top of the range"""
 
225
        """Number of reserved ips at the top of the range."""
202
226
        return 1  # broadcast
203
227
 
204
228
    def _create_fixed_ips(self, context, network_id):
205
 
        """Create all fixed ips for network"""
 
229
        """Create all fixed ips for network."""
206
230
        network_ref = self.db.network_get(context, network_id)
207
231
        # NOTE(vish): Should these be properties of the network as opposed
208
232
        #             to properties of the manager class?
222
246
 
223
247
 
224
248
class FlatManager(NetworkManager):
225
 
    """Basic network where no vlans are used"""
 
249
    """Basic network where no vlans are used."""
226
250
 
227
251
    def allocate_fixed_ip(self, context, instance_id, *args, **kwargs):
228
 
        """Gets a fixed ip from the pool"""
 
252
        """Gets a fixed ip from the pool."""
229
253
        # TODO(vish): when this is called by compute, we can associate compute
230
254
        #             with a network, or a cluster of computes with a network
231
255
        #             and use that network here with a method like
239
263
        return address
240
264
 
241
265
    def deallocate_fixed_ip(self, context, address, *args, **kwargs):
242
 
        """Returns a fixed ip to the pool"""
 
266
        """Returns a fixed ip to the pool."""
243
267
        self.db.fixed_ip_update(context, address, {'allocated': False})
244
268
        self.db.fixed_ip_disassociate(context.elevated(), address)
245
269
 
246
270
    def setup_compute_network(self, context, instance_id):
247
 
        """Network is created manually"""
 
271
        """Network is created manually."""
248
272
        pass
249
273
 
250
274
    def setup_fixed_ip(self, context, address):
251
 
        """Currently no setup"""
 
275
        """Currently no setup."""
252
276
        pass
253
277
 
254
278
    def create_networks(self, context, cidr, num_networks, network_size,
255
279
                        *args, **kwargs):
256
 
        """Create networks based on parameters"""
 
280
        """Create networks based on parameters."""
257
281
        fixed_net = IPy.IP(cidr)
258
282
        for index in range(num_networks):
259
283
            start = index * network_size
271
295
                self._create_fixed_ips(context, network_ref['id'])
272
296
 
273
297
    def get_network(self, context):
274
 
        """Get the network for the current context"""
 
298
        """Get the network for the current context."""
275
299
        # NOTE(vish): To support mutilple network hosts, This could randomly
276
300
        #             select from multiple networks instead of just
277
301
        #             returning the one. It could also potentially be done
280
304
                                             FLAGS.flat_network_bridge)
281
305
 
282
306
    def _on_set_network_host(self, context, network_id):
283
 
        """Called when this host becomes the host for a network"""
 
307
        """Called when this host becomes the host for a network."""
284
308
        net = {}
285
309
        net['injected'] = True
286
310
        net['bridge'] = FLAGS.flat_network_bridge
289
313
 
290
314
 
291
315
class FlatDHCPManager(NetworkManager):
292
 
    """Flat networking with dhcp"""
 
316
    """Flat networking with dhcp."""
293
317
 
294
318
    def setup_fixed_ip(self, context, address):
295
 
        """Setup dhcp for this network"""
 
319
        """Setup dhcp for this network."""
296
320
        network_ref = db.fixed_ip_get_by_address(context, address)
297
321
        self.driver.update_dhcp(context, network_ref['id'])
298
322
 
299
323
    def deallocate_fixed_ip(self, context, address, *args, **kwargs):
300
 
        """Returns a fixed ip to the pool"""
 
324
        """Returns a fixed ip to the pool."""
301
325
        self.db.fixed_ip_update(context, address, {'allocated': False})
302
326
 
303
327
    def _on_set_network_host(self, context, network_id):
304
 
        """Called when this host becomes the host for a project"""
 
328
        """Called when this host becomes the host for a project."""
305
329
        super(FlatDHCPManager, self)._on_set_network_host(context, network_id)
306
330
        network_ref = self.db.network_get(context, network_id)
307
331
        self.db.network_update(context,
313
337
 
314
338
 
315
339
class VlanManager(NetworkManager):
316
 
    """Vlan network with dhcp"""
 
340
    """Vlan network with dhcp."""
317
341
 
318
342
    @defer.inlineCallbacks
319
343
    def periodic_tasks(self, context=None):
320
 
        """Tasks to be run at a periodic interval"""
 
344
        """Tasks to be run at a periodic interval."""
321
345
        yield super(VlanManager, self).periodic_tasks(context)
322
346
        now = datetime.datetime.utcnow()
323
347
        timeout = FLAGS.fixed_ip_disassociate_timeout
330
354
 
331
355
    def init_host(self):
332
356
        """Do any initialization that needs to be run if this is a
333
 
           standalone service.
 
357
        standalone service.
334
358
        """
335
359
        super(VlanManager, self).init_host()
336
360
        self.driver.init_host()
337
361
 
338
362
    def allocate_fixed_ip(self, context, instance_id, *args, **kwargs):
339
 
        """Gets a fixed ip from the pool"""
 
363
        """Gets a fixed ip from the pool."""
340
364
        # TODO(vish): This should probably be getting project_id from
341
365
        #             the instance, but it is another trip to the db.
342
366
        #             Perhaps this method should take an instance_ref.
356
380
        return address
357
381
 
358
382
    def deallocate_fixed_ip(self, context, address, *args, **kwargs):
359
 
        """Returns a fixed ip to the pool"""
 
383
        """Returns a fixed ip to the pool."""
360
384
        self.db.fixed_ip_update(context, address, {'allocated': False})
361
385
 
362
386
    def setup_fixed_ip(self, context, address):
363
 
        """Sets forwarding rules and dhcp for fixed ip"""
 
387
        """Sets forwarding rules and dhcp for fixed ip."""
364
388
        fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
365
389
        network_ref = self.db.fixed_ip_get_network(context, address)
366
390
        if self.db.instance_is_vpn(context, fixed_ip_ref['instance_id']):
370
394
        self.driver.update_dhcp(context, network_ref['id'])
371
395
 
372
396
    def setup_compute_network(self, context, instance_id):
373
 
        """Sets up matching network for compute hosts"""
 
397
        """Sets up matching network for compute hosts."""
374
398
        network_ref = db.network_get_by_instance(context, instance_id)
375
399
        self.driver.ensure_vlan_bridge(network_ref['vlan'],
376
400
                                       network_ref['bridge'])
377
401
 
378
402
    def restart_nets(self):
379
 
        """Ensure the network for each user is enabled"""
 
403
        """Ensure the network for each user is enabled."""
380
404
        # TODO(vish): Implement this
381
405
        pass
382
406
 
383
407
    def create_networks(self, context, cidr, num_networks, network_size,
384
408
                        vlan_start, vpn_start):
385
 
        """Create networks based on parameters"""
 
409
        """Create networks based on parameters."""
386
410
        fixed_net = IPy.IP(cidr)
387
411
        for index in range(num_networks):
388
412
            vlan = vlan_start + index
407
431
                self._create_fixed_ips(context, network_ref['id'])
408
432
 
409
433
    def get_network(self, context):
410
 
        """Get the network for the current context"""
 
434
        """Get the network for the current context."""
411
435
        return self.db.project_get_network(context.elevated(),
412
436
                                           context.project_id)
413
437
 
414
438
    def _on_set_network_host(self, context, network_id):
415
 
        """Called when this host becomes the host for a network"""
 
439
        """Called when this host becomes the host for a network."""
416
440
        network_ref = self.db.network_get(context, network_id)
417
441
        net = {}
418
442
        net['vpn_public_address'] = FLAGS.vpn_ip
424
448
 
425
449
    @property
426
450
    def _bottom_reserved_ips(self):
427
 
        """Number of reserved ips at the bottom of the range"""
 
451
        """Number of reserved ips at the bottom of the range."""
428
452
        return super(VlanManager, self)._bottom_reserved_ips + 1  # vpn server
429
453
 
430
454
    @property
431
455
    def _top_reserved_ips(self):
432
 
        """Number of reserved ips at the top of the range"""
 
456
        """Number of reserved ips at the top of the range."""
433
457
        parent_reserved = super(VlanManager, self)._top_reserved_ips
434
458
        return parent_reserved + FLAGS.cnt_vpn_clients