17
17
# under the License.
20
Network Hosts are responsible for allocating ips and setting up network
20
Network Hosts are responsible for allocating ips and setting up network.
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`.
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
41
:fixed_ip_disassociate_timeout: Seconds after which a deallocated ip
65
88
class AddressAlreadyAllocated(exception.Error):
66
"""Address was already allocated"""
89
"""Address was already allocated."""
70
93
class NetworkManager(manager.Manager):
71
"""Implements common network manager functionality
94
"""Implements common network manager functionality.
73
This class must be subclassed.
96
This class must be subclassed to support specific topologies.
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'])
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,
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()
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()
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()
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()
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()
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,
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,
130
154
self.driver.ensure_floating_forward(floating_address, fixed_address)
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)
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)
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)
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'])
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()
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()
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
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
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?
224
248
class FlatManager(NetworkManager):
225
"""Basic network where no vlans are used"""
249
"""Basic network where no vlans are used."""
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
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)
246
270
def setup_compute_network(self, context, instance_id):
247
"""Network is created manually"""
271
"""Network is created manually."""
250
274
def setup_fixed_ip(self, context, address):
251
"""Currently no setup"""
275
"""Currently no setup."""
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'])
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)
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."""
285
309
net['injected'] = True
286
310
net['bridge'] = FLAGS.flat_network_bridge
291
315
class FlatDHCPManager(NetworkManager):
292
"""Flat networking with dhcp"""
316
"""Flat networking with dhcp."""
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'])
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})
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,
315
339
class VlanManager(NetworkManager):
316
"""Vlan network with dhcp"""
340
"""Vlan network with dhcp."""
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
331
355
def init_host(self):
332
356
"""Do any initialization that needs to be run if this is a
335
359
super(VlanManager, self).init_host()
336
360
self.driver.init_host()
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.
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})
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'])
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'])
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
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'])
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)
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)
418
442
net['vpn_public_address'] = FLAGS.vpn_ip
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
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