Merge lp:~midokura/nova/network-service into lp:~ntt-pf-lab/nova/network-service

Proposed by Ryu Ishimoto
Status: Merged
Merged at revision: 768
Proposed branch: lp:~midokura/nova/network-service
Merge into: lp:~ntt-pf-lab/nova/network-service
Diff against target: 7670 lines (+1105/-5848)
92 files modified
bin/nova-dhcpbridge-flat-dhcp (+0/-70)
bin/nova-dhcpbridge-flat-vlan (+71/-0)
bin/nova-dhcpbridge-vlan (+0/-69)
bin/nova-net-serv (+50/-0)
bin/nova-net-vlan (+0/-50)
nova/network/flat/__init__.py (+0/-39)
nova/network/flat/api/__init__.py (+0/-44)
nova/network/flat/api/openstack/__init__.py (+0/-45)
nova/network/flat/api/openstack/networks.py (+0/-78)
nova/network/flat/api/openstack/ports.py (+0/-35)
nova/network/flat/api/openstack/virtual_nics.py (+0/-68)
nova/network/flat/common.py (+0/-36)
nova/network/flat/compute.py (+0/-157)
nova/network/flat/db/__init__.py (+0/-21)
nova/network/flat/db/api.py (+0/-143)
nova/network/flat/db/manager.py (+0/-121)
nova/network/flat/db/sqlalchemy/__init__.py (+0/-16)
nova/network/flat/db/sqlalchemy/api.py (+0/-94)
nova/network/flat/db/sqlalchemy/migrate_repo/README (+0/-4)
nova/network/flat/db/sqlalchemy/migrate_repo/__init__.py (+0/-16)
nova/network/flat/db/sqlalchemy/migrate_repo/manage.py (+0/-4)
nova/network/flat/db/sqlalchemy/migrate_repo/migrate.cfg (+0/-20)
nova/network/flat/db/sqlalchemy/migrate_repo/versions/001_diablo.py (+0/-107)
nova/network/flat/db/sqlalchemy/migrate_repo/versions/__init__.py (+0/-16)
nova/network/flat/db/sqlalchemy/migration.py (+0/-65)
nova/network/flat/db/sqlalchemy/models.py (+0/-314)
nova/network/flat/db/sqlalchemy/session.py (+0/-62)
nova/network/flat/network.py (+0/-61)
nova/network/flat_dhcp/__init__.py (+0/-40)
nova/network/flat_dhcp/api/__init__.py (+0/-44)
nova/network/flat_dhcp/api/openstack/__init__.py (+0/-44)
nova/network/flat_dhcp/api/openstack/networks.py (+0/-80)
nova/network/flat_dhcp/api/openstack/ports.py (+0/-35)
nova/network/flat_dhcp/api/openstack/virtual_nics.py (+0/-68)
nova/network/flat_dhcp/common.py (+0/-39)
nova/network/flat_dhcp/compute.py (+0/-186)
nova/network/flat_dhcp/db/__init__.py (+0/-20)
nova/network/flat_dhcp/db/api.py (+0/-219)
nova/network/flat_dhcp/db/manager.py (+0/-129)
nova/network/flat_dhcp/db/sqlalchemy/__init__.py (+0/-16)
nova/network/flat_dhcp/db/sqlalchemy/api.py (+0/-62)
nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/README (+0/-4)
nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/__init__.py (+0/-16)
nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/manage.py (+0/-4)
nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/migrate.cfg (+0/-20)
nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/versions/001_diablo.py (+0/-137)
nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/versions/__init__.py (+0/-16)
nova/network/flat_dhcp/db/sqlalchemy/models.py (+0/-354)
nova/network/flat_dhcp/db/sqlalchemy/session.py (+0/-63)
nova/network/flat_dhcp/dhcp.py (+0/-80)
nova/network/flat_dhcp/network.py (+0/-255)
nova/network/flat_vlan/compute.py (+4/-3)
nova/network/flat_vlan/db/api.py (+7/-1)
nova/network/flat_vlan/db/sqlalchemy/api.py (+1/-3)
nova/network/flat_vlan/db/sqlalchemy/models.py (+15/-1)
nova/network/flat_vlan/driver/__init__.py (+16/-0)
nova/network/flat_vlan/driver/linux/__init__.py (+16/-0)
nova/network/flat_vlan/driver/linux/dhcp.py (+151/-0)
nova/network/flat_vlan/driver/linux/filter.py (+391/-0)
nova/network/flat_vlan/driver/linux/network.py (+149/-0)
nova/network/flat_vlan/driver/linux/ra.py (+107/-0)
nova/network/flat_vlan/flags.py (+95/-17)
nova/network/flat_vlan/manager.py (+1/-1)
nova/network/flat_vlan/network.py (+23/-22)
nova/network/linux_dhcp.py (+0/-157)
nova/network/linux_net.py (+1/-7)
nova/network/linux_ra.py (+0/-106)
nova/network/manager.py (+6/-2)
nova/network/service.py (+1/-2)
nova/network/vlan/__init__.py (+0/-39)
nova/network/vlan/api/__init__.py (+0/-57)
nova/network/vlan/api/openstack/__init__.py (+0/-45)
nova/network/vlan/api/openstack/networks.py (+0/-80)
nova/network/vlan/api/openstack/ports.py (+0/-35)
nova/network/vlan/api/openstack/virtual_nics.py (+0/-68)
nova/network/vlan/common.py (+0/-39)
nova/network/vlan/compute.py (+0/-188)
nova/network/vlan/db/__init__.py (+0/-20)
nova/network/vlan/db/api.py (+0/-254)
nova/network/vlan/db/manager.py (+0/-150)
nova/network/vlan/db/sqlalchemy/__init__.py (+0/-16)
nova/network/vlan/db/sqlalchemy/api.py (+0/-63)
nova/network/vlan/db/sqlalchemy/migrate_repo/README (+0/-4)
nova/network/vlan/db/sqlalchemy/migrate_repo/__init__.py (+0/-16)
nova/network/vlan/db/sqlalchemy/migrate_repo/manage.py (+0/-4)
nova/network/vlan/db/sqlalchemy/migrate_repo/migrate.cfg (+0/-20)
nova/network/vlan/db/sqlalchemy/migrate_repo/versions/001_diablo.py (+0/-148)
nova/network/vlan/db/sqlalchemy/migrate_repo/versions/__init__.py (+0/-16)
nova/network/vlan/db/sqlalchemy/models.py (+0/-172)
nova/network/vlan/db/sqlalchemy/session.py (+0/-63)
nova/network/vlan/dhcp.py (+0/-80)
nova/network/vlan/network.py (+0/-263)
To merge this branch: bzr merge lp:~midokura/nova/network-service
Reviewer Review Type Date Requested Status
NTT PF Lab. Pending
Review via email: mp+56093@code.launchpad.net

Commit message

Finished up the merging of three plugins(vlan, dhcp, flat) into one flat_vlan.

Description of the change

Finished up the merging of three plugins(vlan, dhcp, flat) into one flat_vlan.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed file 'bin/nova-dhcpbridge-flat-dhcp'
2--- bin/nova-dhcpbridge-flat-dhcp 2011-03-24 10:27:45 +0000
3+++ bin/nova-dhcpbridge-flat-dhcp 1970-01-01 00:00:00 +0000
4@@ -1,70 +0,0 @@
5-#!/usr/bin/env python
6-# vim: tabstop=4 shiftwidth=4 softtabstop=4
7-
8-# Copyright (c) 2011 NTT.
9-# All Rights Reserved.
10-#
11-# Licensed under the Apache License, Version 2.0 (the "License"); you may
12-# not use this file except in compliance with the License. You may obtain
13-# a copy of the License at
14-#
15-# http://www.apache.org/licenses/LICENSE-2.0
16-#
17-# Unless required by applicable law or agreed to in writing, software
18-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
20-# License for the specific language governing permissions and limitations
21-# under the License.
22-
23-"""
24-Handle lease database updates from DHCP servers.
25-"""
26-
27-import gettext
28-import os
29-import sys
30-
31-# If ../nova/__init__.py exists, add ../ to Python search path, so that
32-# it will override what happens to be installed in /usr/(local/)lib/python...
33-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
34- os.pardir,
35- os.pardir))
36-if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
37- sys.path.insert(0, possible_topdir)
38-
39-gettext.install('nova', unicode=1)
40-
41-from nova import flags
42-from nova import log as logging
43-from nova import utils
44-
45-from nova.network.flat_dhcp.dhcp import DHCPEventHandler
46-
47-FLAGS = flags.FLAGS
48-
49-def main():
50- """Parse environment and arguments and call the approproate action."""
51- flagfile = os.environ.get('FLAGFILE',
52- FLAGS.ns_flat_dhcp_dhcpbridge_flagfile)
53- utils.default_flagfile(flagfile)
54- argv = FLAGS(sys.argv)
55- logging.setup()
56- interface = os.environ.get('DNSMASQ_INTERFACE', 'br0')
57- if int(os.environ.get('TESTING', '0')):
58- from nova.tests import fake_flags
59- action = argv[1]
60- if action in ['add', 'del', 'old']:
61- mac = argv[2]
62- ip = argv[3]
63- hostname = argv[4]
64- msg = _("Called %(action)s for mac %(mac)s with ip %(ip)s and"
65- " hostname %(hostname)s on interface %(interface)s") % locals()
66- LOG.debug(msg)
67- method = getattr(DHCPEventHandler, "%s_lease" % action)
68- method(mac, ip, hostname, interface)
69- else:
70- print DHCPEventHandler.init_leases(interface)
71-
72-if __name__ == "__main__":
73- main()
74-
75
76=== added file 'bin/nova-dhcpbridge-flat-vlan'
77--- bin/nova-dhcpbridge-flat-vlan 1970-01-01 00:00:00 +0000
78+++ bin/nova-dhcpbridge-flat-vlan 2011-04-04 00:58:27 +0000
79@@ -0,0 +1,71 @@
80+#!/usr/bin/env python
81+# vim: tabstop=4 shiftwidth=4 softtabstop=4
82+
83+# Copyright (c) 2011 NTT.
84+# All Rights Reserved.
85+#
86+# Licensed under the Apache License, Version 2.0 (the "License"); you may
87+# not use this file except in compliance with the License. You may obtain
88+# a copy of the License at
89+#
90+# http://www.apache.org/licenses/LICENSE-2.0
91+#
92+# Unless required by applicable law or agreed to in writing, software
93+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
94+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
95+# License for the specific language governing permissions and limitations
96+# under the License.
97+
98+"""
99+Handle lease database updates from DHCP servers.
100+"""
101+
102+import gettext
103+import os
104+import sys
105+
106+# If ../nova/__init__.py exists, add ../ to Python search path, so that
107+# it will override what happens to be installed in /usr/(local/)lib/python...
108+possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
109+ os.pardir,
110+ os.pardir))
111+if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
112+ sys.path.insert(0, possible_topdir)
113+
114+gettext.install('nova', unicode=1)
115+
116+from nova import flags
117+from nova import log as logging
118+from nova import utils
119+
120+from nova.network.flat_vlan import flags as net_flags
121+from nova.network.flat_vlan.dhcp import DHCPEventHandler
122+
123+NET_FLAGS = net_flags.FlagAccessor()
124+
125+def main():
126+ """Parse environment and arguments and call the approproate action."""
127+ flagfile = os.environ.get('FLAGFILE',
128+ NET_FLAGS.net_flat_vlan_dhcpbridge_flagfile)
129+ utils.default_flagfile(flagfile)
130+ argv = flags.FLAGS(sys.argv)
131+ logging.setup()
132+ interface = os.environ.get('DNSMASQ_INTERFACE', 'br0')
133+ if int(os.environ.get('TESTING', '0')):
134+ from nova.tests import fake_flags
135+ action = argv[1]
136+ if action in ['add', 'del', 'old']:
137+ mac = argv[2]
138+ ip = argv[3]
139+ hostname = argv[4]
140+ msg = _("Called %(action)s for mac %(mac)s with ip %(ip)s and"
141+ " hostname %(hostname)s on interface %(interface)s") % locals()
142+ LOG.debug(msg)
143+ method = getattr(DHCPEventHandler, "%s_lease" % action)
144+ method(mac, ip, hostname, interface)
145+ else:
146+ print DHCPEventHandler.init_leases(interface)
147+
148+if __name__ == "__main__":
149+ main()
150+
151
152=== removed file 'bin/nova-dhcpbridge-vlan'
153--- bin/nova-dhcpbridge-vlan 2011-03-24 10:27:45 +0000
154+++ bin/nova-dhcpbridge-vlan 1970-01-01 00:00:00 +0000
155@@ -1,69 +0,0 @@
156-#!/usr/bin/env python
157-# vim: tabstop=4 shiftwidth=4 softtabstop=4
158-
159-# Copyright (c) 2011 NTT.
160-# All Rights Reserved.
161-#
162-# Licensed under the Apache License, Version 2.0 (the "License"); you may
163-# not use this file except in compliance with the License. You may obtain
164-# a copy of the License at
165-#
166-# http://www.apache.org/licenses/LICENSE-2.0
167-#
168-# Unless required by applicable law or agreed to in writing, software
169-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
170-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
171-# License for the specific language governing permissions and limitations
172-# under the License.
173-
174-"""
175-Handle lease database updates from DHCP servers.
176-"""
177-
178-import gettext
179-import os
180-import sys
181-
182-# If ../nova/__init__.py exists, add ../ to Python search path, so that
183-# it will override what happens to be installed in /usr/(local/)lib/python...
184-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
185- os.pardir,
186- os.pardir))
187-if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
188- sys.path.insert(0, possible_topdir)
189-
190-gettext.install('nova', unicode=1)
191-
192-from nova import flags
193-from nova import log as logging
194-from nova import utils
195-
196-from nova.network.vlan.dhcp import DHCPEventHandler
197-
198-FLAGS = flags.FLAGS
199-
200-def main():
201- """Parse environment and arguments and call the approproate action."""
202- flagfile = os.environ.get('FLAGFILE', FLAGS.ns_vlan_dhcpbridge_flagfile)
203- utils.default_flagfile(flagfile)
204- argv = FLAGS(sys.argv)
205- logging.setup()
206- interface = os.environ.get('DNSMASQ_INTERFACE', 'br0')
207- if int(os.environ.get('TESTING', '0')):
208- from nova.tests import fake_flags
209- action = argv[1]
210- if action in ['add', 'del', 'old']:
211- mac = argv[2]
212- ip = argv[3]
213- hostname = argv[4]
214- msg = _("Called %(action)s for mac %(mac)s with ip %(ip)s and"
215- " hostname %(hostname)s on interface %(interface)s") % locals()
216- LOG.debug(msg)
217- method = getattr(DHCPEventHandler, "%s_lease" % action)
218- method(mac, ip, hostname, interface)
219- else:
220- print DHCPEventHandler.init_leases(interface)
221-
222-if __name__ == "__main__":
223- main()
224-
225
226=== added file 'bin/nova-net-serv'
227--- bin/nova-net-serv 1970-01-01 00:00:00 +0000
228+++ bin/nova-net-serv 2011-04-04 00:58:27 +0000
229@@ -0,0 +1,50 @@
230+#!/usr/bin/env python
231+# vim: tabstop=4 shiftwidth=4 softtabstop=4
232+
233+# Copyright (c) 2011 NTT.
234+# All Rights Reserved.
235+#
236+# Licensed under the Apache License, Version 2.0 (the "License"); you may
237+# not use this file except in compliance with the License. You may obtain
238+# a copy of the License at
239+#
240+# http://www.apache.org/licenses/LICENSE-2.0
241+#
242+# Unless required by applicable law or agreed to in writing, software
243+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
244+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
245+# License for the specific language governing permissions and limitations
246+# under the License.
247+
248+"""Starter script for Nova Network."""
249+
250+import eventlet
251+eventlet.monkey_patch()
252+
253+import gettext
254+import os
255+import sys
256+
257+# If ../nova/__init__.py exists, add ../ to Python search path, so that
258+# it will override what happens to be installed in /usr/(local/)lib/python...
259+possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
260+ os.pardir,
261+ os.pardir))
262+if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
263+ sys.path.insert(0, possible_topdir)
264+
265+gettext.install('nova', unicode=1)
266+
267+from nova import flags
268+from nova import log as logging
269+from nova import service
270+from nova import utils
271+
272+if __name__ == '__main__':
273+ utils.default_flagfile()
274+ flags.FLAGS(sys.argv)
275+ logging.setup()
276+ manager_cls = 'nova.network.flat_vlan.network.NetworkService'
277+ net_service = service.Service.create(manager=manager_cls)
278+ service.serve(net_service)
279+ service.wait()
280
281=== removed file 'bin/nova-net-vlan'
282--- bin/nova-net-vlan 2011-03-24 10:27:45 +0000
283+++ bin/nova-net-vlan 1970-01-01 00:00:00 +0000
284@@ -1,50 +0,0 @@
285-#!/usr/bin/env python
286-# vim: tabstop=4 shiftwidth=4 softtabstop=4
287-
288-# Copyright (c) 2011 NTT.
289-# All Rights Reserved.
290-#
291-# Licensed under the Apache License, Version 2.0 (the "License"); you may
292-# not use this file except in compliance with the License. You may obtain
293-# a copy of the License at
294-#
295-# http://www.apache.org/licenses/LICENSE-2.0
296-#
297-# Unless required by applicable law or agreed to in writing, software
298-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
299-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
300-# License for the specific language governing permissions and limitations
301-# under the License.
302-
303-"""Starter script for Nova Network."""
304-
305-import eventlet
306-eventlet.monkey_patch()
307-
308-import gettext
309-import os
310-import sys
311-
312-# If ../nova/__init__.py exists, add ../ to Python search path, so that
313-# it will override what happens to be installed in /usr/(local/)lib/python...
314-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
315- os.pardir,
316- os.pardir))
317-if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
318- sys.path.insert(0, possible_topdir)
319-
320-gettext.install('nova', unicode=1)
321-
322-from nova import flags
323-from nova import log as logging
324-from nova import service
325-from nova import utils
326-
327-if __name__ == '__main__':
328- utils.default_flagfile()
329- flags.FLAGS(sys.argv)
330- logging.setup()
331- manager_cls = 'nova.network.vlan.network.NetworkService'
332- net_service = service.Service.create(manager=manager_cls)
333- service.serve(net_service)
334- service.wait()
335
336=== removed directory 'nova/network/flat'
337=== removed file 'nova/network/flat/__init__.py'
338--- nova/network/flat/__init__.py 2011-03-30 10:33:12 +0000
339+++ nova/network/flat/__init__.py 1970-01-01 00:00:00 +0000
340@@ -1,39 +0,0 @@
341-# vim: tabstop=4 shiftwidth=4 softtabstop=4
342-
343-# Copyright (c) 2011 NTT.
344-# All Rights Reserved.
345-#
346-# Licensed under the Apache License, Version 2.0 (the "License"); you may
347-# not use this file except in compliance with the License. You may obtain
348-# a copy of the License at
349-#
350-# http://www.apache.org/licenses/LICENSE-2.0
351-#
352-# Unless required by applicable law or agreed to in writing, software
353-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
354-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
355-# License for the specific language governing permissions and limitations
356-# under the License.
357-from zope import interface
358-
359-from nova.network import service
360-from nova.network.flat_dhcp.compute import NetworkAgentService
361-from nova.network.flat.api import NetworkApiService
362-from nova.network.flat.api.openstack import NetworkOpenStackApiService
363-
364-class NetworkServiceFactory(object):
365- """Factory for network services"""
366-
367- interface.implements(service.INetworkServiceFactory)
368-
369- def get_api_service(self):
370- """Gets the API service for this plugin."""
371- return NetworkApiService()
372-
373- def get_os_api_service(self):
374- """Gets OS API service for this plugin."""
375- return NetworkOpenStackApiService()
376-
377- def get_net_agent(self):
378- """Gets the net agent for this plugin."""
379- return NetworkAgentService()
380
381=== removed directory 'nova/network/flat/api'
382=== removed file 'nova/network/flat/api/__init__.py'
383--- nova/network/flat/api/__init__.py 2011-03-30 10:11:03 +0000
384+++ nova/network/flat/api/__init__.py 1970-01-01 00:00:00 +0000
385@@ -1,44 +0,0 @@
386-# vim: tabstop=4 shiftwidth=4 softtabstop=4
387-
388-# Copyright (c) 2011 NTT.
389-# All Rights Reserved.
390-#
391-# Licensed under the Apache License, Version 2.0 (the "License"); you may
392-# not use this file except in compliance with the License. You may obtain
393-# a copy of the License at
394-#
395-# http://www.apache.org/licenses/LICENSE-2.0
396-#
397-# Unless required by applicable law or agreed to in writing, software
398-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
399-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
400-# License for the specific language governing permissions and limitations
401-# under the License.
402-from zope import interface
403-
404-from nova.network import service
405-from nova.network.flat.db import api as db_api
406-from nova.network.flat.db import manager as db_manager
407-
408-class NetworkApiService(object):
409- """Network API Service for this plugin."""
410-
411- interface.implements(service.INetworkApiService)
412-
413- def create_vnic(self, context):
414- """Generic API to retrieve the default VNIC ID.
415- For flat simple network, create a new vNIC and return its ID.
416-
417- Args:
418- context: Nova context object needed to access the DB.
419-
420- Returns:
421- The ID of the new VNIC.
422- """
423- # Create a new VNIC
424- vnic = db_manager.ethernet_card_create_with_random_mac(context)
425- return vnic.id
426-
427- def get_project_vpn_address_and_port(self, _context, _project_id):
428- """Does not apply."""
429- return (None, None)
430
431=== removed directory 'nova/network/flat/api/openstack'
432=== removed file 'nova/network/flat/api/openstack/__init__.py'
433--- nova/network/flat/api/openstack/__init__.py 2011-03-30 10:11:03 +0000
434+++ nova/network/flat/api/openstack/__init__.py 1970-01-01 00:00:00 +0000
435@@ -1,45 +0,0 @@
436-# vim: tabstop=4 shiftwidth=4 softtabstop=4
437-
438-# Copyright (c) 2011 NTT.
439-# All Rights Reserved.
440-#
441-# Licensed under the Apache License, Version 2.0 (the "License"); you may
442-# not use this file except in compliance with the License. You may obtain
443-# a copy of the License at
444-#
445-# http://www.apache.org/licenses/LICENSE-2.0
446-#
447-# Unless required by applicable law or agreed to in writing, software
448-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
449-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
450-# License for the specific language governing permissions and limitations
451-# under the License.
452-from zope import interface
453-
454-from nova.network import service
455-from nova.network.flat.api.openstack import networks
456-from nova.network.flat.api.openstack import ports
457-from nova.network.flat.api.openstack import virtual_nics
458-
459-class NetworkOpenStackApiService(object):
460- """OpenStack API service object for this plugin."""
461-
462- interface.implements(service.INetworkOpenStackApiService)
463-
464- def set_routes(self, route_map):
465- """Generic API method to set up all the routes.
466-
467- Args:
468- route_map: NetworkServiceRouteMap object to add the routes to.
469- """
470- # Set up VNIC
471- route_map.resource("vnics", "/vnics",
472- controller=virtual_nics.Controller())
473-
474- # Set up networks
475- route_map.resource("networks", "/networks",
476- controller=networks.Controller())
477-
478- # Set up ports
479- route_map.resource("ports", "/ports",
480- controller=ports.Controller())
481
482=== removed file 'nova/network/flat/api/openstack/networks.py'
483--- nova/network/flat/api/openstack/networks.py 2011-03-24 10:27:45 +0000
484+++ nova/network/flat/api/openstack/networks.py 1970-01-01 00:00:00 +0000
485@@ -1,78 +0,0 @@
486-# vim: tabstop=4 shiftwidth=4 softtabstop=4
487-
488-# Copyright (c) 2011 NTT.
489-# All Rights Reserved.
490-#
491-# Licensed under the Apache License, Version 2.0 (the "License"); you may
492-# not use this file except in compliance with the License. You may obtain
493-# a copy of the License at
494-#
495-# http://www.apache.org/licenses/LICENSE-2.0
496-#
497-# Unless required by applicable law or agreed to in writing, software
498-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
499-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
500-# License for the specific language governing permissions and limitations
501-# under the License.
502-from webob import exc
503-
504-from nova import exception
505-from nova import wsgi
506-from nova.api.openstack import faults
507-from nova.db import base
508-from nova.network.flat import common
509-from nova.network.flat import db
510-from nova.network.flat.db import manager
511-
512-class Controller(wsgi.Controller):
513- """ The Networks API controller for the OpenStack API """
514-
515- def __init__(self):
516- super(Controller, self).__init__()
517-
518- def create(self, req):
519- """ Creates a new network. """
520- env = self._deserialize(req.body, req.get_content_type())
521- if not env:
522- return faults.Fault(exc.HTTPUnprocessableEntity())
523-
524- networks = manager.network_create(req.environ['nova.context'],
525- env['cidr'],
526- int(env['num_networks']),
527- int(env['network_size']),
528- env['cidr_v6'])
529- items = [common.filter_keys(item, ('id', 'cidr'))
530- for item in networks]
531- return dict(ids=items)
532-
533- def update(self, req, id):
534- """Updates a network."""
535- env = self._deserialize(req.body, req.get_content_type())
536- if not env:
537- return faults.Fault(exc.HTTPUnprocessableEntity())
538-
539- # Currently only host can be updated.
540- if 'host' in env:
541- try:
542- manager.network_update_host(req.environ['nova.context'], id,
543- env['host'])
544- except exception.NotFound:
545- return faults.Fault(exc.HTTPNotFound())
546-
547- return exc.HTTPNoContent()
548-
549- def show(self, req, id):
550- """ Gets the network with ID given """
551- try:
552- network = db.api.network_get(req.environ['nova.context'], id)
553- return dict(id=network.id, cidr=network.cidr)
554- except exception.NotFound:
555- return faults.Fault(exc.HTTPNotFound())
556-
557- def delete(self, req, id):
558- """ Destroys a network """
559- try:
560- db.api.network_delete(req.environ['nova.context'], id)
561- except exception.NotFound:
562- return faults.Fault(exc.HTTPNotFound())
563- return exc.HTTPAccepted()
564
565=== removed file 'nova/network/flat/api/openstack/ports.py'
566--- nova/network/flat/api/openstack/ports.py 2011-03-24 10:27:45 +0000
567+++ nova/network/flat/api/openstack/ports.py 1970-01-01 00:00:00 +0000
568@@ -1,35 +0,0 @@
569-# vim: tabstop=4 shiftwidth=4 softtabstop=4
570-
571-# Copyright (c) 2011 NTT.
572-# All Rights Reserved.
573-#
574-# Licensed under the Apache License, Version 2.0 (the "License"); you may
575-# not use this file except in compliance with the License. You may obtain
576-# a copy of the License at
577-#
578-# http://www.apache.org/licenses/LICENSE-2.0
579-#
580-# Unless required by applicable law or agreed to in writing, software
581-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
582-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
583-# License for the specific language governing permissions and limitations
584-# under the License.
585-
586-from nova import wsgi
587-from nova.api.openstack import common as nova_common
588-from nova.api.openstack import faults
589-from nova.network.flat import common
590-from nova.network.flat import db
591-
592-class Controller(wsgi.Controller):
593- """ The Ports API controller for the OpenStack API """
594-
595- def __init__(self):
596- super(Controller, self).__init__()
597-
598- def index(self, req):
599- """Return all port/IPs in brief"""
600- items = db.api.ip_address_get_all(req.environ['nova.context'])
601- items = nova_common.limited(items, req)
602- items = [common.filter_keys(item, ('id', 'address')) for item in items]
603- return dict(ports=items)
604
605=== removed file 'nova/network/flat/api/openstack/virtual_nics.py'
606--- nova/network/flat/api/openstack/virtual_nics.py 2011-03-24 10:27:45 +0000
607+++ nova/network/flat/api/openstack/virtual_nics.py 1970-01-01 00:00:00 +0000
608@@ -1,68 +0,0 @@
609-# vim: tabstop=4 shiftwidth=4 softtabstop=4
610-
611-# Copyright (c) 2011 NTT.
612-# All Rights Reserved.
613-#
614-# Licensed under the Apache License, Version 2.0 (the "License"); you may
615-# not use this file except in compliance with the License. You may obtain
616-# a copy of the License at
617-#
618-# http://www.apache.org/licenses/LICENSE-2.0
619-#
620-# Unless required by applicable law or agreed to in writing, software
621-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
622-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
623-# License for the specific language governing permissions and limitations
624-# under the License.
625-from webob import exc
626-
627-from nova.api.openstack import common as nova_common
628-from nova import exception
629-from nova import wsgi
630-from nova.api.openstack import faults
631-from nova.db import base
632-from nova.network.flat import common
633-from nova.network.flat import db
634-from nova.network.flat.db import manager
635-
636-class Controller(wsgi.Controller):
637- """ The Virtual NICs API controller for the OpenStack API """
638-
639- def __init__(self):
640- super(Controller, self).__init__()
641-
642- def index(self, req):
643- """Return all ethernet cards in brief"""
644- items = db.api.ethernet_card_get_all(req.environ['nova.context'])
645- items = nova_common.limited(items, req)
646- items = [common.filter_keys(item, ('id', 'mac_address'))
647- for item in items]
648- return dict(ethernet_cards=items)
649-
650- def create(self, req):
651- """ Creates a new ethernet card. """
652- ethernet_card = manager.ethernet_card_create_with_random_mac(
653- req.environ['nova.context'])
654- return dict(id=ethernet_card.id)
655-
656- def update(self, req, id):
657- """Update an ethernet card"""
658- return exc.HTTPNoContent()
659-
660- def show(self, req, id):
661- """ Gets the ethernet card with ID given """
662- try:
663- ethernet_card = db.api.ethernet_card_get(
664- req.environ['nova.context'], id)
665- return dict(id=ethernet_card.id,
666- mac_address=ethernet_card.mac_address)
667- except exception.NotFound:
668- return faults.Fault(exc.HTTPNotFound())
669-
670- def delete(self, req, id):
671- """ Destroys an ethernet card """
672- try:
673- db.api.ethernet_card_delete(req.environ['nova.context'], id)
674- except exception.NotFound:
675- return faults.Fault(exc.HTTPNotFound())
676- return exc.HTTPAccepted()
677
678=== removed file 'nova/network/flat/common.py'
679--- nova/network/flat/common.py 2011-03-24 10:27:45 +0000
680+++ nova/network/flat/common.py 1970-01-01 00:00:00 +0000
681@@ -1,36 +0,0 @@
682-# vim: tabstop=4 shiftwidth=4 softtabstop=4
683-
684-# Copyright (c) 2011 NTT.
685-# All Rights Reserved.
686-#
687-# Licensed under the Apache License, Version 2.0 (the "License"); you may
688-# not use this file except in compliance with the License. You may obtain
689-# a copy of the License at
690-#
691-# http://www.apache.org/licenses/LICENSE-2.0
692-#
693-# Unless required by applicable law or agreed to in writing, software
694-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
695-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
696-# License for the specific language governing permissions and limitations
697-# under the License.
698-
699-#
700-# Common utility methods and classes are defined here.
701-#
702-
703-import IPy
704-
705-def filter_keys(item, keys):
706- """
707- Filters all model attributes except for keys
708- item is a dict
709- """
710- return dict((k, v) for k, v in item.iteritems() if k in keys)
711-
712-def get_net_and_mask(cidr):
713- """
714- Gets network IP and netmask from cidr.
715- """
716- net = IPy.IP(cidr)
717- return str(net.net()), str(net.netmask())
718
719=== removed file 'nova/network/flat/compute.py'
720--- nova/network/flat/compute.py 2011-03-30 10:33:12 +0000
721+++ nova/network/flat/compute.py 1970-01-01 00:00:00 +0000
722@@ -1,157 +0,0 @@
723-# vim: tabstop=4 shiftwidth=4 softtabstop=4
724-
725-# Copyright (c) 2011 NTT.
726-# All Rights Reserved.
727-#
728-# Licensed under the Apache License, Version 2.0 (the "License"); you may
729-# not use this file except in compliance with the License. You may obtain
730-# a copy of the License at
731-#
732-# http://www.apache.org/licenses/LICENSE-2.0
733-#
734-# Unless required by applicable law or agreed to in writing, software
735-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
736-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
737-# License for the specific language governing permissions and limitations
738-# under the License.
739-import socket
740-from zope import interface
741-
742-from nova import flags
743-from nova import rpc
744-from nova import utils
745-from nova.network import service
746-from nova.network.flat import common
747-from nova.network.flat.db import api as db_api
748-
749-FLAGS = flags.FLAGS
750-flags.DEFINE_string('ns_flat_network_host', socket.gethostname(),
751- 'Network host to use for ip allocation in flat modes')
752-flags.DEFINE_string('ns_flat_network_topic', 'net-flat',
753- 'the topic network nodes listen on')
754-flags.DEFINE_string('ns_flat_network_bridge', 'br100',
755- 'Bridge for simple network instances')
756-flags.DEFINE_bool('ns_flat_network_fake_call', False,
757- 'If True, skip using the queue and make local calls')
758-
759-def _queue_get_for(topic, physical_node_id):
760- return "%s.%s" % (topic, physical_node_id)
761-
762-def _get_network_topic(context, **kwargs):
763- """Retrieves the network host for a project on this host"""
764- if FLAGS.stub_network:
765- host = FLAGS.ns_flat_network_host
766- else:
767- host = _get_network_host(context)
768- return _queue_get_for(FLAGS.ns_flat_network_topic,
769- host)
770-
771-def _get_network_host(context):
772- """Get the network host for the current context."""
773- network_ref = db_api.network_get_by_bridge(context,
774- FLAGS.ns_flat_network_bridge)
775- host = network_ref['host']
776- if not host:
777- topic = _queue_get_for(FLAGS.ns_flat_network_topic,
778- FLAGS.ns_flat_network_host)
779- if FLAGS.ns_flat_network_fake_call:
780- return _set_network_host(context, network_ref['id'])
781- host = rpc.call(context,
782- FLAGS.ns_flat_network_topic,
783- {"method": "set_network_host",
784- "args": {"network_id": network_ref['id']}})
785- return host
786-
787-def _set_network_host(context, network_id):
788- """Safely sets the host of the network."""
789- db_api.network_update(context,
790- network_id,
791- {"host":FLAGS.host,
792- "dns": FLAGS.ns_flat_dns})
793- return FLAGS.host
794-
795-class NetworkAgentService(object):
796- """An OpenStack network agent service object."""
797-
798- interface.implements(service.INetworkOpenStackApiService)
799-
800- def bind_vnics_to_ports(self, context, vnic_ids, _is_vpn):
801- """Gets a fixed ips from the pool.
802-
803- Args:
804- context: Nova context needed for DB access.
805- vnic_ids: list of VNIC IDs
806- is_vpn: Boolean to check if the call is for VPN.
807- """
808- rpc.call(context,
809- _get_network_topic(context),
810- {"method": "allocate_fixed_ips",
811- "args": {"vnic_ids": vnic_ids}})
812-
813- def setup_compute_network(self, context, vnic_ids):
814- """Nothing needs to be done.
815- """
816- pass
817-
818- def teardown_compute_network(self, context, vnic_ids):
819- """Clean up the compute node.
820-
821- Args:
822- context: Nova context needed for DB access.
823- vnic_ids: list of VNIC IDs
824- """
825- ctxt = context.elevated()
826- for vnic_id in vnic_ids:
827- ip = vnic_id.get('fixed_ip')
828- if not FLAGS.stub_network and ip:
829-
830- address = ip['address']
831- db_api.ip_address_update(ctxt, address,
832- {'allocated': False})
833- db_api.ip_address_disassociate(ctxt, address)
834-
835- def requires_file_injection(self):
836- """This service requires file injection.
837- """
838- return True
839-
840- def get_network_info(self, context, vnic_id):
841- """Gets network data for a given VNIC.
842-
843- Args:
844- context: Nova context needed for DB access.
845- vnic_id: VNIC ID to get the network information for.
846-
847- Returns:
848- A dictionary containing the following keys:
849- cidr, cidrv6, netmask, netmask_v6 gateway, gateway_v6,
850- dhcp_server, broadcast, dns, ra_server, mac_address,
851- ip_address, bridge, and address_v6
852- """
853- ethernet_card = db_api.ethernet_card_get(context, vnic_id)
854- if not ethernet_card:
855- raise ValueError("Invalid vnic ID!")
856-
857- # Get the IP address associated with this VNIC
858- ip_address = db_api.ip_address_get_by_ethernet_card(context,
859- ethernet_card.id)
860- if not ip_address:
861- raise ValueError("VNIC is not mapped to IP!")
862-
863- network = ip_address.network
864- if network['cidr_v6']:
865- ipv6_addr = utils.to_global_ipv6(network['cidr_v6'],
866- ethernet_card['mac_address'])
867- else:
868- ipv6_addr = None
869-
870- net, mask = common.get_net_and_mask(network['cidr'])
871- return dict(mac_address=ethernet_card['mac_address'],
872- ip_address=ip_address['address'], bridge=network['bridge'],
873- cidr=network['cidr'], netmask=network['netmask'],
874- gateway=network['gateway'], broadcast=network['broadcast'],
875- dns=network['dns'], dhcp_server=None,
876- cidr_v6=network['cidr_v6'], address_v6=ipv6_addr,
877- ra_server=None, netmask_v6=None, gateway_v6=None,
878- net=net, mask=mask)
879-
880
881=== removed directory 'nova/network/flat/db'
882=== removed file 'nova/network/flat/db/__init__.py'
883--- nova/network/flat/db/__init__.py 2011-03-24 10:27:45 +0000
884+++ nova/network/flat/db/__init__.py 1970-01-01 00:00:00 +0000
885@@ -1,21 +0,0 @@
886-# vim: tabstop=4 shiftwidth=4 softtabstop=4
887-# vim: tabstop=4 shiftwidth=4 softtabstop=4
888-
889-# Copyright (c) 2011 NTT.
890-# All Rights Reserved.
891-#
892-# Licensed under the Apache License, Version 2.0 (the "License"); you may
893-# not use this file except in compliance with the License. You may obtain
894-# a copy of the License at
895-#
896-# http://www.apache.org/licenses/LICENSE-2.0
897-#
898-# Unless required by applicable law or agreed to in writing, software
899-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
900-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
901-# License for the specific language governing permissions and limitations
902-# under the License.
903-"""
904-DB abstraction for Nova
905-"""
906-
907
908=== removed file 'nova/network/flat/db/api.py'
909--- nova/network/flat/db/api.py 2011-03-24 13:55:17 +0000
910+++ nova/network/flat/db/api.py 1970-01-01 00:00:00 +0000
911@@ -1,143 +0,0 @@
912-# vim: tabstop=4 shiftwidth=4 softtabstop=4
913-
914-# Copyright (c) 2011 NTT.
915-# All Rights Reserved.
916-#
917-# Licensed under the Apache License, Version 2.0 (the "License"); you may
918-# not use this file except in compliance with the License. You may obtain
919-# a copy of the License at
920-#
921-# http://www.apache.org/licenses/LICENSE-2.0
922-#
923-# Unless required by applicable law or agreed to in writing, software
924-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
925-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
926-# License for the specific language governing permissions and limitations
927-# under the License.
928-"""
929-Defines interface for DB access.
930-
931-The underlying driver is loaded as a :class:`LazyPluggable`.
932-"""
933-from nova import flags
934-from nova import utils
935-
936-FLAGS = flags.FLAGS
937-flags.DEFINE_string('ns_flat_db_backend',
938- 'sqlalchemy',
939- 'Default backend to use for SQL.')
940-
941-IMPL = utils.LazyPluggable(FLAGS['ns_flat_db_backend'],
942- sqlalchemy='nova.network.flat.db.sqlalchemy.api')
943-
944-###################
945-
946-def ethernet_card_get(context, id):
947- """Get ethernet card by id."""
948- return IMPL.dao_factory.get_dao(context).\
949- ethernet_card_get(id)
950-
951-def ethernet_card_create(context, values):
952- """Create a new ethernet card."""
953- return IMPL.dao_factory.get_dao(context).\
954- ethernet_card_create(values)
955-
956-def ethernet_card_get_all(context):
957- """Get all ethernet cards."""
958- return IMPL.dao_factory.get_dao(context).\
959- ethernet_card_get_all()
960-
961-def ethernet_card_update(context, ethernet_card_id, values):
962- """Update ethernet card."""
963- return IMPL.dao_factory.get_dao(context).\
964- ethernet_card_update(ethernet_card_id, values)
965-
966-def ethernet_card_delete(context, ethernet_card_id):
967- """Delete ethernet card."""
968- return IMPL.dao_factory.get_dao(context).\
969- ethernet_card_delete(ethernet_card_id)
970-
971-def network_get(context, id):
972- """Get network by id."""
973- return IMPL.dao_factory.get_dao(context).\
974- network_get(id)
975-
976-def network_get_by_bridge(context, bridge):
977- """Get a network by bridge or raise if it does not exist."""
978- return IMPL.dao_factory.get_dao(context).\
979- network_get_by_bridge(bridge)
980-
981-def host_get_networks(context, host):
982- """Get networks for a given host."""
983- return IMPL.dao_factory.get_dao(context).\
984- host_get_networks(host)
985-
986-def network_create(context, values):
987- """Create a new network."""
988- return IMPL.dao_factory.get_dao(context).\
989- network_create(values)
990-
991-def network_create_safe(context, values):
992- """Create a new network. Returns None when there is an exception"""
993- return IMPL.dao_factory.get_dao(context).\
994- network_create_safe(values)
995-
996-def network_get_all(context):
997- """Get all networks."""
998- return IMPL.dao_factory.get_dao(context).\
999- network_get_all()
1000-
1001-def network_update(context, network_id, values):
1002- """Update network."""
1003- return IMPL.dao_factory.get_dao(context).\
1004- network_update(network_id, values)
1005-
1006-def network_delete(context, network_id):
1007- """Delete network."""
1008- return IMPL.dao_factory.get_dao(context).\
1009- network_delete(network_id)
1010-
1011-def ip_address_get(context, id):
1012- """Get IP address by id."""
1013- return IMPL.dao_factory.get_dao(context).\
1014- ip_address_get(id)
1015-
1016-def ip_address_get_by_ethernet_card(context, ethernet_card_id):
1017- """Get IP address by ethernet card id."""
1018- return IMPL.dao_factory.get_dao(context).\
1019- ip_address_get_by_ethernet_card(ethernet_card_id)
1020-
1021-def ip_address_disassociate(context, address):
1022- """Disassocaites IP from ethernet card."""
1023- return IMPL.dao_factory.get_dao(context).\
1024- ip_address_disassociate(address)
1025-
1026-def ip_address_get_by_address(self, address):
1027- """Get IP record by IP address."""
1028- return IMPL.dao_factory.get_dao(context).\
1029- ip_address_get_by_address(address)
1030-
1031-def ip_address_create(context, values):
1032- """Create a new IP address."""
1033- return IMPL.dao_factory.get_dao(context).\
1034- ip_address_create(values)
1035-
1036-def ip_address_get_all(context):
1037- """Get all IP addresses."""
1038- return IMPL.dao_factory.get_dao(context).\
1039- ip_address_get_all()
1040-
1041-def ip_address_update(context, ip_address_id, values):
1042- """Update IP address."""
1043- return IMPL.dao_factory.get_dao(context).\
1044- ip_address_update(ip_address_id, values)
1045-
1046-def ip_address_delete(context, ip_address_id):
1047- """Delete IP address."""
1048- return IMPL.dao_factory.get_dao(context).\
1049- ip_address_delete(ip_address_id)
1050-
1051-def ip_address_associate_pool(context, network_id, ethernet_card_id):
1052- """Associate IP address to network and ethernet card."""
1053- return IMPL.dao_factory.get_dao(context).\
1054- ip_address_associate_pool(network_id, ethernet_card_id)
1055
1056=== removed file 'nova/network/flat/db/manager.py'
1057--- nova/network/flat/db/manager.py 2011-03-24 10:27:45 +0000
1058+++ nova/network/flat/db/manager.py 1970-01-01 00:00:00 +0000
1059@@ -1,121 +0,0 @@
1060-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1061-
1062-# Copyright (c) 2011 NTT.
1063-# All Rights Reserved.
1064-#
1065-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1066-# not use this file except in compliance with the License. You may obtain
1067-# a copy of the License at
1068-#
1069-# http://www.apache.org/licenses/LICENSE-2.0
1070-#
1071-# Unless required by applicable law or agreed to in writing, software
1072-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1073-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1074-# License for the specific language governing permissions and limitations
1075-# under the License.
1076-
1077-"""
1078-Wrapper APIs for DB models should be defined here.
1079-"""
1080-import IPy
1081-import math
1082-
1083-from nova import flags
1084-from nova import utils
1085-
1086-from nova.network.flat.db import api
1087-
1088-FLAGS = flags.FLAGS
1089-flags.DEFINE_string('ns_flat_bridge',
1090- 'br100',
1091- 'Bridge for simple network instances')
1092-
1093-BOTTOM_RESERVED_IPS = 2
1094-TOP_RESERVED_IPS = 1
1095-
1096-def _create_fixed_ips(context, network_id):
1097- """Create all fixed ips for network."""
1098- network_ref = api.network_get(context, network_id)
1099- net = IPy.IP(network_ref['cidr'])
1100- num_ips = len(net)
1101- for index in range(num_ips):
1102- address = str(net[index])
1103- if index < BOTTOM_RESERVED_IPS or num_ips - index < TOP_RESERVED_IPS:
1104- reserved = True
1105- else:
1106- reserved = False
1107-
1108- api.ip_address_create(context,
1109- {'network_id': network_id,
1110- 'address': address,
1111- 'reserved': reserved})
1112-
1113-def network_create(context, cidr, num_networks, network_size,
1114- cidr_v6, *args, **kwargs):
1115- """Create networks based on parameters."""
1116- fixed_net = IPy.IP(cidr)
1117- fixed_net_v6 = IPy.IP(cidr_v6)
1118- significant_bits_v6 = 64
1119- networks = []
1120- for index in range(num_networks):
1121- start = index * network_size
1122- significant_bits = 32 - int(math.log(network_size, 2))
1123- cidr = "%s/%s" % (fixed_net[start], significant_bits)
1124- project_net = IPy.IP(cidr)
1125- net = {}
1126- net['bridge'] = FLAGS.ns_flat_bridge
1127- net['cidr'] = cidr
1128- net['netmask'] = str(project_net.netmask())
1129- net['gateway'] = str(project_net[1])
1130- net['broadcast'] = str(project_net.broadcast())
1131-
1132- if(FLAGS.use_ipv6):
1133- cidr_v6 = "%s/%s" % (fixed_net_v6[0], significant_bits_v6)
1134- net['cidr_v6'] = cidr_v6
1135-
1136- network_ref = api.network_create_safe(context, net)
1137-
1138- if network_ref:
1139- networks.append(network_ref)
1140- _create_fixed_ips(context, network_ref['id'])
1141-
1142- return networks
1143-
1144-def allocate_ip(context, ethernet_card_id, *args, **kwargs):
1145- """Gets an IP from the pool."""
1146- network_ref = api.network_get_by_bridge(context,
1147- FLAGS.ns_flat_bridge)
1148- ip = api.ip_address_associate_pool(context.elevated(),
1149- network_ref['id'],
1150- ethernet_card_id)
1151- api.ip_address_update(context, ip.id, {'allocated': True})
1152- return ip
1153-
1154-def bind_ip_to_ethernet_card(context, ethernet_card_id):
1155- """Assigns IP to ethernet card."""
1156-
1157- # Get the ethernet card
1158- ethernet_card = api.ethernet_card_get(context, ethernet_card_id)
1159- # TODO: Throw a better exception.
1160- if not ethernet_card:
1161- raise ValueError("There is not VNIC with ID %s" % ethernet_card_id)
1162-
1163- ip_address = api.ip_address_get_by_ethernet_card(context,
1164- ethernet_card_id)
1165- # Check to see if this ethernet card does not have IP allocated.
1166- if not ip_address:
1167- ip_address = allocate_ip(context, ethernet_card_id)
1168-
1169- return ip_address
1170-
1171-def network_update_host(context, id, host):
1172- """Updates network host"""
1173- return api.network_update(context, id, dict(host=host))
1174-
1175-def ethernet_card_create_with_random_mac(context):
1176- """Creates a new ethernet card"""
1177- mac_address = utils.generate_mac()
1178- return api.ethernet_card_create(context, dict(mac_address=mac_address))
1179-
1180-
1181
1182=== removed directory 'nova/network/flat/db/sqlalchemy'
1183=== removed file 'nova/network/flat/db/sqlalchemy/__init__.py'
1184--- nova/network/flat/db/sqlalchemy/__init__.py 2011-03-24 10:27:45 +0000
1185+++ nova/network/flat/db/sqlalchemy/__init__.py 1970-01-01 00:00:00 +0000
1186@@ -1,16 +0,0 @@
1187-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1188-
1189-# Copyright (c) 2011 NTT.
1190-# All Rights Reserved.
1191-#
1192-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1193-# not use this file except in compliance with the License. You may obtain
1194-# a copy of the License at
1195-#
1196-# http://www.apache.org/licenses/LICENSE-2.0
1197-#
1198-# Unless required by applicable law or agreed to in writing, software
1199-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1200-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1201-# License for the specific language governing permissions and limitations
1202-# under the License.
1203
1204=== removed file 'nova/network/flat/db/sqlalchemy/api.py'
1205--- nova/network/flat/db/sqlalchemy/api.py 2011-03-24 15:29:16 +0000
1206+++ nova/network/flat/db/sqlalchemy/api.py 1970-01-01 00:00:00 +0000
1207@@ -1,94 +0,0 @@
1208-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1209-
1210-# Copyright (c) 2011 NTT.
1211-# All Rights Reserved.
1212-#
1213-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1214-# not use this file except in compliance with the License. You may obtain
1215-# a copy of the License at
1216-#
1217-# http://www.apache.org/licenses/LICENSE-2.0
1218-#
1219-# Unless required by applicable law or agreed to in writing, software
1220-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1221-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1222-# License for the specific language governing permissions and limitations
1223-# under the License.
1224-"""
1225-Implementation of SQLAlchemy backend.
1226-"""
1227-from sqlalchemy import or_
1228-from sqlalchemy.exc import IntegrityError
1229-import warnings
1230-
1231-from nova import exception
1232-from nova.db import api as nova_db
1233-from nova.db.sqlalchemy import api as nova_api
1234-from nova.network.flat.db.sqlalchemy import models
1235-from nova.network.flat.db.sqlalchemy.session import get_session
1236-
1237-
1238-class DataAccessCache(object):
1239- """A cache of Data Access Objects specific to sessions and contexts.
1240-
1241- Creates one DAO object per session and set of context parameter
1242- values, and caches it. The parameters currently used in the
1243- context are:
1244- - nova.db.sqlalchemy.api.is_admin_context(context)
1245- - nova.db.sqlalchemy.api.can_read_deleted(context)
1246- """
1247-
1248- def __init__(self, dao_class):
1249- self._dao_class = dao_class
1250- self._cached_daos = {}
1251-
1252- def get_dao(self, context, session):
1253- """Get a DataAccess object.
1254-
1255- If no cached DAO has been created for this session and this
1256- context's parameter, a new DAO is created and
1257- cached. Otherwise, the cached DAO is returned.
1258-
1259- :param context: The request context.
1260- :param session: The SQLAlchemy session to use as the Data
1261- Access Object's data source.
1262- """
1263- is_admin = nova_api.is_admin_context(context)
1264- can_read_deleted = nova_api.can_read_deleted(context)
1265- key = (session, is_admin, can_read_deleted)
1266- dao = self._cached_daos.get(key)
1267- if dao is None:
1268- dao = self._dao_class(session, is_admin, can_read_deleted)
1269- self._cached_daos[key] = dao
1270- return dao
1271-
1272-
1273-class DefaultSessionFlatNetworkDataAccessFactory(object):
1274- """A DAO factory that lazily uses the default session.
1275-
1276- This factory uses the default session for the flat network
1277- service, which it creates lazily when creating the first DAO.
1278- """
1279-
1280- def __init__(self):
1281- self._dao_cache = DataAccessCache(models.FlatNetworkDataAccess)
1282- self._session = None
1283-
1284- def get_session(self):
1285- if self._session is None:
1286- self._session = get_session()
1287- return self._session
1288-
1289- def get_dao(self, context):
1290- """Get a DataAccess object.
1291-
1292- If no cached DAO has been created for this context's
1293- parameter, a new DAO is created and cached. Otherwise, the
1294- cached DAO is returned.
1295-
1296- :param context: The request context.
1297- """
1298- return self._dao_cache.get_dao(context, self.get_session())
1299-
1300-
1301-dao_factory = DefaultSessionFlatNetworkDataAccessFactory()
1302
1303=== removed directory 'nova/network/flat/db/sqlalchemy/migrate_repo'
1304=== removed file 'nova/network/flat/db/sqlalchemy/migrate_repo/README'
1305--- nova/network/flat/db/sqlalchemy/migrate_repo/README 2011-03-15 04:26:43 +0000
1306+++ nova/network/flat/db/sqlalchemy/migrate_repo/README 1970-01-01 00:00:00 +0000
1307@@ -1,4 +0,0 @@
1308-This is a database migration repository.
1309-
1310-More information at
1311-http://code.google.com/p/sqlalchemy-migrate/
1312
1313=== removed file 'nova/network/flat/db/sqlalchemy/migrate_repo/__init__.py'
1314--- nova/network/flat/db/sqlalchemy/migrate_repo/__init__.py 2011-03-24 10:27:45 +0000
1315+++ nova/network/flat/db/sqlalchemy/migrate_repo/__init__.py 1970-01-01 00:00:00 +0000
1316@@ -1,16 +0,0 @@
1317-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1318-
1319-# Copyright (c) 2011 NTT.
1320-# All Rights Reserved.
1321-#
1322-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1323-# not use this file except in compliance with the License. You may obtain
1324-# a copy of the License at
1325-#
1326-# http://www.apache.org/licenses/LICENSE-2.0
1327-#
1328-# Unless required by applicable law or agreed to in writing, software
1329-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1330-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1331-# License for the specific language governing permissions and limitations
1332-# under the License.
1333\ No newline at end of file
1334
1335=== removed file 'nova/network/flat/db/sqlalchemy/migrate_repo/manage.py'
1336--- nova/network/flat/db/sqlalchemy/migrate_repo/manage.py 2011-03-15 04:26:43 +0000
1337+++ nova/network/flat/db/sqlalchemy/migrate_repo/manage.py 1970-01-01 00:00:00 +0000
1338@@ -1,4 +0,0 @@
1339-#!/usr/bin/env python
1340-from migrate.versioning.shell import main
1341-if __name__ == '__main__':
1342- main(debug='False', repository='.')
1343
1344=== removed file 'nova/network/flat/db/sqlalchemy/migrate_repo/migrate.cfg'
1345--- nova/network/flat/db/sqlalchemy/migrate_repo/migrate.cfg 2011-03-15 04:26:43 +0000
1346+++ nova/network/flat/db/sqlalchemy/migrate_repo/migrate.cfg 1970-01-01 00:00:00 +0000
1347@@ -1,20 +0,0 @@
1348-[db_settings]
1349-# Used to identify which repository this database is versioned under.
1350-# You can use the name of your project.
1351-repository_id=nova_network_flat
1352-
1353-# The name of the database table used to track the schema version.
1354-# This name shouldn't already be used by your project.
1355-# If this is changed once a database is under version control, you'll need to
1356-# change the table name in each database too.
1357-version_table=migrate_version
1358-
1359-# When committing a change script, Migrate will attempt to generate the
1360-# sql for all supported databases; normally, if one of them fails - probably
1361-# because you don't have that database installed - it is ignored and the
1362-# commit continues, perhaps ending successfully.
1363-# Databases in this list MUST compile successfully during a commit, or the
1364-# entire commit will fail. List the databases your application will actually
1365-# be using to ensure your updates to that database work properly.
1366-# This must be a list; example: ['postgres','sqlite']
1367-required_dbs=[]
1368
1369=== removed directory 'nova/network/flat/db/sqlalchemy/migrate_repo/versions'
1370=== removed file 'nova/network/flat/db/sqlalchemy/migrate_repo/versions/001_diablo.py'
1371--- nova/network/flat/db/sqlalchemy/migrate_repo/versions/001_diablo.py 2011-03-24 10:27:45 +0000
1372+++ nova/network/flat/db/sqlalchemy/migrate_repo/versions/001_diablo.py 1970-01-01 00:00:00 +0000
1373@@ -1,107 +0,0 @@
1374-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1375-
1376-# Copyright (c) 2011 NTT.
1377-# All Rights Reserved.
1378-#
1379-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1380-# not use this file except in compliance with the License. You may obtain
1381-# a copy of the License at
1382-#
1383-# http://www.apache.org/licenses/LICENSE-2.0
1384-#
1385-# Unless required by applicable law or agreed to in writing, software
1386-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1387-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1388-# License for the specific language governing permissions and limitations
1389-# under the License.
1390-
1391-from sqlalchemy import *
1392-from migrate import *
1393-
1394-from nova import log as logging
1395-
1396-meta = MetaData()
1397-
1398-#
1399-# New Tables
1400-#
1401-ip_addresses = Table(
1402- 'ip_addresses', meta,
1403- Column('created_at', DateTime(timezone=False)),
1404- Column('updated_at', DateTime(timezone=False)),
1405- Column('deleted_at', DateTime(timezone=False)),
1406- Column('deleted', Boolean(create_constraint=True, name=None)),
1407- Column('id', Integer(), primary_key=True, nullable=False),
1408- Column('address',
1409- String(length=255, convert_unicode=False, assert_unicode=None,
1410- unicode_error=None, _warn_on_bytestring=False)),
1411- Column('network_id', Integer(), ForeignKey('networks.id'),
1412- nullable=True),
1413- Column('allocated', Boolean(create_constraint=True, name=None)),
1414- Column('reserved', Boolean(create_constraint=True, name=None)),
1415- Column('ethernet_card_id', Integer(), ForeignKey('ethernet_cards.id'),
1416- nullable=True),
1417- Column("addressV6",
1418- String(length=255, convert_unicode=False, assert_unicode=None,
1419- unicode_error=None, _warn_on_bytestring=False)),
1420- Column("netmaskV6",
1421- String(length=3, convert_unicode=False, assert_unicode=None,
1422- unicode_error=None, _warn_on_bytestring=False)),
1423- Column("gatewayV6",
1424- String(length=255, convert_unicode=False, assert_unicode=None,
1425- unicode_error=None, _warn_on_bytestring=False)),
1426- )
1427-
1428-ethernet_cards = Table(
1429- 'ethernet_cards', meta,
1430- Column('created_at', DateTime(timezone=False)),
1431- Column('updated_at', DateTime(timezone=False)),
1432- Column('deleted_at', DateTime(timezone=False)),
1433- Column('deleted', Boolean(create_constraint=True, name=None)),
1434- Column('id', Integer(), primary_key=True, nullable=False),
1435- Column('mac_address', String(255), nullable=False),
1436- )
1437-
1438-networks = Table(
1439- 'networks', meta,
1440- Column('created_at', DateTime(timezone=False)),
1441- Column('updated_at', DateTime(timezone=False)),
1442- Column('deleted_at', DateTime(timezone=False)),
1443- Column('deleted', Boolean(create_constraint=True, name=None)),
1444- Column('id', Integer(), primary_key=True),
1445- Column('cidr', String(255)),
1446- Column('netmask', String(255)),
1447- Column('bridge', String(255)),
1448- Column('gateway', String(255)),
1449- Column('broadcast', String(255)),
1450- Column('dns',
1451- String(length=255, convert_unicode=False, assert_unicode=None,
1452- unicode_error=None, _warn_on_bytestring=False)),
1453- Column('cidr_v6',
1454- String(length=255, convert_unicode=False, assert_unicode=None,
1455- unicode_error=None, _warn_on_bytestring=False)),
1456- Column('host', String(255)),
1457- )
1458-
1459-def upgrade(migrate_engine):
1460- meta.bind = migrate_engine
1461-
1462- for table in (ethernet_cards, networks, ip_addresses):
1463- try:
1464- table.create()
1465- except Exception:
1466- logging.info(repr(table))
1467- logging.exception('Exception while creating table')
1468- raise
1469-
1470-def downgrade(migrate_engine):
1471- meta.bind = migrate_engine
1472-
1473- for table in (ip_addresses, networks, ethernet_cards):
1474- try:
1475- table.drop()
1476- except Exception:
1477- logging.info(repr(table))
1478- logging.exception('Exception while dropping table')
1479- raise
1480-
1481
1482=== removed file 'nova/network/flat/db/sqlalchemy/migrate_repo/versions/__init__.py'
1483--- nova/network/flat/db/sqlalchemy/migrate_repo/versions/__init__.py 2011-03-24 10:27:45 +0000
1484+++ nova/network/flat/db/sqlalchemy/migrate_repo/versions/__init__.py 1970-01-01 00:00:00 +0000
1485@@ -1,16 +0,0 @@
1486-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1487-
1488-# Copyright (c) 2011 NTT.
1489-# All Rights Reserved.
1490-#
1491-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1492-# not use this file except in compliance with the License. You may obtain
1493-# a copy of the License at
1494-#
1495-# http://www.apache.org/licenses/LICENSE-2.0
1496-#
1497-# Unless required by applicable law or agreed to in writing, software
1498-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1499-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1500-# License for the specific language governing permissions and limitations
1501-# under the License.
1502\ No newline at end of file
1503
1504=== removed file 'nova/network/flat/db/sqlalchemy/migration.py'
1505--- nova/network/flat/db/sqlalchemy/migration.py 2011-03-24 10:27:45 +0000
1506+++ nova/network/flat/db/sqlalchemy/migration.py 1970-01-01 00:00:00 +0000
1507@@ -1,65 +0,0 @@
1508-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1509-
1510-# Copyright (c) 2011 NTT.
1511-# All Rights Reserved.
1512-#
1513-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1514-# not use this file except in compliance with the License. You may obtain
1515-# a copy of the License at
1516-#
1517-# http://www.apache.org/licenses/LICENSE-2.0
1518-#
1519-# Unless required by applicable law or agreed to in writing, software
1520-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1521-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1522-# License for the specific language governing permissions and limitations
1523-# under the License.
1524-
1525-import os
1526-
1527-from nova import flags
1528-
1529-import sqlalchemy
1530-from migrate.versioning import api as versioning_api
1531-from migrate.versioning import exceptions as versioning_exceptions
1532-
1533-FLAGS = flags.FLAGS
1534-
1535-
1536-def db_sync(version=None):
1537- db_version()
1538- repo_path = _find_migrate_repo()
1539- return versioning_api.upgrade(FLAGS.sql_connection, repo_path, version)
1540-
1541-
1542-def db_version():
1543- repo_path = _find_migrate_repo()
1544- try:
1545- return versioning_api.db_version(FLAGS.sql_connection, repo_path)
1546- except versioning_exceptions.DatabaseNotControlledError:
1547- # If we aren't version controlled we may already have the database
1548- # in the state from before we started version control, check for that
1549- # and set up version_control appropriately
1550- meta = sqlalchemy.MetaData()
1551- engine = sqlalchemy.create_engine(FLAGS.sql_connection, echo=False)
1552- meta.reflect(bind=engine)
1553- try:
1554- for table in ('ethernet_cards', 'networks'):
1555- assert table in meta.tables
1556- return db_version_control(1)
1557- except AssertionError:
1558- return db_version_control(0)
1559-
1560-
1561-def db_version_control(version=None):
1562- repo_path = _find_migrate_repo()
1563- versioning_api.version_control(FLAGS.sql_connection, repo_path, version)
1564- return version
1565-
1566-
1567-def _find_migrate_repo():
1568- """Get the path for the migrate repository."""
1569- path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
1570- 'migrate_repo')
1571- assert os.path.exists(path)
1572- return path
1573
1574=== removed file 'nova/network/flat/db/sqlalchemy/models.py'
1575--- nova/network/flat/db/sqlalchemy/models.py 2011-03-25 00:04:43 +0000
1576+++ nova/network/flat/db/sqlalchemy/models.py 1970-01-01 00:00:00 +0000
1577@@ -1,314 +0,0 @@
1578-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1579-
1580-# Copyright (c) 2011 NTT.
1581-# All Rights Reserved.
1582-#
1583-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1584-# not use this file except in compliance with the License. You may obtain
1585-# a copy of the License at
1586-#
1587-# http://www.apache.org/licenses/LICENSE-2.0
1588-#
1589-# Unless required by applicable law or agreed to in writing, software
1590-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1591-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1592-# License for the specific language governing permissions and limitations
1593-# under the License.
1594-"""
1595-SQLAlchemy models for flat network service data.
1596-"""
1597-from sqlalchemy import or_
1598-
1599-from sqlalchemy.orm import relationship, backref
1600-from sqlalchemy.orm import joinedload
1601-from sqlalchemy import Column, Boolean, Integer, String
1602-from sqlalchemy import ForeignKey
1603-from sqlalchemy.ext.declarative import declarative_base
1604-
1605-from nova import exception
1606-from nova.db.sqlalchemy.models import NovaBase
1607-
1608-
1609-BASE = declarative_base()
1610-
1611-
1612-# ----------------------
1613-# Data Transfer Objects.
1614-# ----------------------
1615-
1616-class EthernetCard(BASE, NovaBase):
1617- """Represents an ethernet card."""
1618- __tablename__ = 'ethernet_cards'
1619- id = Column(Integer, primary_key=True)
1620- mac_address = Column(String(255), nullable=False, unique=True)
1621-
1622-
1623-class Network(BASE, NovaBase):
1624- """Represents a simple IP network."""
1625- __tablename__ = 'networks'
1626- id = Column(Integer, primary_key=True)
1627- cidr = Column(String(255))
1628- netmask = Column(String(255))
1629- bridge = Column(String(255))
1630- gateway = Column(String(255))
1631- broadcast = Column(String(255))
1632- dns = Column(String(255))
1633- cidr_v6 = Column(String(255), unique=True)
1634- host = Column(String(255)) # , ForeignKey('hosts.id'))
1635-
1636-
1637-class IpAddress(BASE, NovaBase):
1638- """Represents a ip address for an ethernet card."""
1639- __tablename__ = 'ip_addresses'
1640- id = Column(Integer, primary_key=True)
1641- address = Column(String(255))
1642- network_id = Column(Integer, ForeignKey('networks.id'), nullable=True)
1643- network = relationship(Network, backref=backref('ip_addresses'))
1644- allocated = Column(Boolean, default=False)
1645- reserved = Column(Boolean, default=False)
1646- ethernet_card_id = Column(Integer, ForeignKey('ethernet_cards.id'))
1647- ethernet_card = relationship(EthernetCard, backref=backref('ip_addresses'))
1648- addressV6 = Column(String(255))
1649- netmaskV6 = Column(String(3))
1650- gatewayV6 = Column(String(255))
1651-
1652-
1653-# ----------------------
1654-# Data Access Objects.
1655-# ----------------------
1656-
1657-class DataAccess(object):
1658- """The base class to implement Data Access Objects.
1659- """
1660-
1661- def __init__(self, session, is_admin, can_read_deleted):
1662- """Initialize this Data Access Object.
1663-
1664- :param session: The SQLAlchemy session to use as this Data
1665- Access Object's data source.
1666- :param is_admin: Indicates if the request context is an
1667- administrator.
1668- :param can_read_deleted: Indicates if the request context has
1669- access to deleted objects.
1670- """
1671- self._session = session
1672- self._is_admin = is_admin
1673- self._can_read_deleted = can_read_deleted
1674-
1675-
1676-class EthernetCardDataAccess(DataAccess):
1677- """A Data Access Object to access ethernet cards.
1678- """
1679-
1680- ethernet_card_dto_class = EthernetCard
1681-
1682- def ethernet_card_get(self, id):
1683- result = self._session.query(self.ethernet_card_dto_class).\
1684- filter_by(deleted=False).\
1685- filter_by(id=id).\
1686- first()
1687-
1688- if not result:
1689- raise exception.NotFound(_("No ethernet_card with id %s") % id)
1690-
1691- return result
1692-
1693- def ethernet_card_get_all(self):
1694- return self._session.query(self.ethernet_card_dto_class).\
1695- filter_by(deleted=self._can_read_deleted).\
1696- all()
1697-
1698- def ethernet_card_create(self, values):
1699- ethernet_card_ref = self.ethernet_card_dto_class()
1700- ethernet_card_ref.update(values)
1701- ethernet_card_ref.save(session=self._session)
1702- return ethernet_card_ref
1703-
1704- def ethernet_card_update(self, ethernet_card_id, values):
1705- with self._session.begin():
1706- ethernet_card_ref = self.ethernet_card_get(ethernet_card_id)
1707- ethernet_card_ref.update(values)
1708- ethernet_card_ref.save(session=self._session)
1709-
1710- def ethernet_card_delete(self, id):
1711- with self._session.begin():
1712- ethernet_card_ref = self.ethernet_card_get(id)
1713- ethernet_card_ref.delete(session=self._session)
1714-
1715-
1716-class NetworkDataAccess(DataAccess):
1717- """A Data Access Object to access networks.
1718- """
1719-
1720- network_dto_class = Network
1721-
1722- def network_get(self, id):
1723- result = self._session.query(self.network_dto_class).\
1724- filter_by(deleted=False).\
1725- filter_by(id=id).\
1726- first()
1727-
1728- if not result:
1729- raise exception.NotFound(_("No network with id %s") % id)
1730-
1731- return result
1732-
1733- def network_get_by_bridge(self, bridge):
1734- if not self._is_admin:
1735- raise exception.NotAuthorized()
1736- result = self._session.query(self.network_dto_class).\
1737- filter_by(bridge=bridge).\
1738- filter_by(deleted=False).\
1739- first()
1740-
1741- if not result:
1742- raise exception.NotFound(_('No network for bridge %s') % bridge)
1743-
1744- return result
1745-
1746- def network_get_by_ethernet_card(self, ethernet_card_id):
1747- if not self._is_admin:
1748- raise exception.NotAuthorized()
1749- rv = self._session.query(self.network_dto_class).\
1750- filter_by(deleted=False).\
1751- join(self.network_dto_class.fixed_ips).\
1752- filter_by(ethernet_card_id=ethernet_card_id).\
1753- filter_by(deleted=False).\
1754- first()
1755- if not rv:
1756- raise exception.NotFound(_('No network for ethernet card %s') %
1757- ethernet_card_id)
1758- return rv
1759-
1760- def host_get_networks(self, host):
1761- with self._session.begin():
1762- return self._session.query(self.network_dto_class).\
1763- filter_by(deleted=False).\
1764- filter_by(host=host).\
1765- all()
1766-
1767- def network_get_all(self):
1768- return self._session.query(self.network_dto_class).\
1769- filter_by(deleted=self._can_read_deleted).\
1770- all()
1771-
1772- def network_create(self, values):
1773- network_ref = self.network_dto_class()
1774- network_ref.update(values)
1775- network_ref.save(session=self._session)
1776- return network_ref
1777-
1778- def network_create_safe(self, values):
1779- if not self._is_admin:
1780- raise exception.NotAuthorized()
1781- try:
1782- return self.network_create(values)
1783- except IntegrityError:
1784- return None
1785-
1786- def network_update(self, network_id, values):
1787- with self._session.begin():
1788- network_ref = self.network_get(network_id)
1789- network_ref.update(values)
1790- network_ref.save(session=self._session)
1791-
1792- def network_delete(self, id):
1793- with self._session.begin():
1794- network_ref = self.network_get(id)
1795- network_ref.delete(session=self._session)
1796-
1797-
1798-class IpAddressDataAccess(DataAccess):
1799- """A Data Access Object to access IP addresses.
1800- """
1801-
1802- ip_address_dto_class = IpAddress
1803-
1804- def ip_address_get(self, id):
1805- result = self._session.query(self.ip_address_dto_class).\
1806- filter_by(deleted=False).\
1807- filter_by(id=id).\
1808- first()
1809-
1810- if not result:
1811- raise exception.NotFound(_("No ip address with id %s") % id)
1812-
1813- return result
1814-
1815- def ip_address_get_by_ethernet_card(self, ethernet_card_id):
1816- result = self._session.query(self.ip_address_dto_class).\
1817- filter_by(deleted=False).\
1818- filter_by(ethernet_card_id=ethernet_card_id).\
1819- first()
1820- return result
1821-
1822- def ip_address_get_all(self):
1823- return self._session.query(self.ip_address_dto_class).\
1824- filter_by(deleted=self._can_read_deleted).\
1825- all()
1826-
1827- def ip_address_create(self, values):
1828- ip_address_ref = self.ip_address_dto_class()
1829- ip_address_ref.update(values)
1830- ip_address_ref.save(session=self._session)
1831- return ip_address_ref
1832-
1833- def ip_address_update(self, ip_address_id, values):
1834- with self._session.begin():
1835- ip_address_ref = self.ip_address_get(ip_address_id)
1836- ip_address_ref.update(values)
1837- ip_address_ref.save(session=self._session)
1838-
1839- def ip_address_delete(self, id):
1840- with self._session.begin():
1841- ip_address_ref = self.ip_address_get(id)
1842- ip_address_ref.delete(session=self._session)
1843-
1844- def ip_address_get_by_address(self, address):
1845- result = self._session.query(self.ip_address_dto_class).\
1846- filter_by(address=address).\
1847- filter_by(deleted=self._can_read_deleted).\
1848- options(joinedload('network')).\
1849- options(joinedload('ethernet_card')).\
1850- first()
1851- if not result:
1852- raise exception.NotFound(_('No fixed ip for address %s') % address)
1853-
1854- return result
1855-
1856- def ip_address_disassociate(self, address):
1857- with self._session.begin():
1858- ip_address_ref = self.ip_address_get_by_address(context, address,
1859- session=self._session)
1860- ip_address_ref.ethernet_card = None
1861- ip_address.save(session=self._session)
1862-
1863-
1864-class FlatNetworkDataAccess(EthernetCardDataAccess, NetworkDataAccess,
1865- IpAddressDataAccess):
1866- """A Data Access Object to access all data for the flat network service.
1867-
1868- Also access IP address associations.
1869- """
1870-
1871- def ip_address_associate_pool(self, network_id, ethernet_card_id):
1872- if not self._is_admin:
1873- raise exception.NotAuthorized()
1874- with self._session.begin():
1875- network_or_none = or_(
1876- self.ip_address_dto_class.network_id == network_id,
1877- self.ip_address_dto_class.network_id == None)
1878- ip_ref = self._session.query(self.ip_address_dto_class).\
1879- filter(network_or_none).\
1880- filter_by(reserved=False).\
1881- filter_by(deleted=False).\
1882- filter_by(ethernet_card=None).\
1883- with_lockmode('update').\
1884- first()
1885- if not ip_ref:
1886- raise nova_db.NoMoreAddresses()
1887- if not ip_ref.network:
1888- ip_ref.network = self.network_get(network_id)
1889- ip_ref.ethernet_card = self.ethernet_card_get(ethernet_card_id)
1890- self._session.add(ip_ref)
1891- return ip_ref
1892
1893=== removed file 'nova/network/flat/db/sqlalchemy/session.py'
1894--- nova/network/flat/db/sqlalchemy/session.py 2011-03-24 10:27:45 +0000
1895+++ nova/network/flat/db/sqlalchemy/session.py 1970-01-01 00:00:00 +0000
1896@@ -1,62 +0,0 @@
1897-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1898-
1899-# Copyright (c) 2011 NTT.
1900-# All Rights Reserved.
1901-#
1902-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1903-# not use this file except in compliance with the License. You may obtain
1904-# a copy of the License at
1905-#
1906-# http://www.apache.org/licenses/LICENSE-2.0
1907-#
1908-# Unless required by applicable law or agreed to in writing, software
1909-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1910-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1911-# License for the specific language governing permissions and limitations
1912-# under the License.
1913-"""
1914-Session Handling for SQLAlchemy backend
1915-"""
1916-
1917-from sqlalchemy import create_engine
1918-from sqlalchemy import pool
1919-from sqlalchemy.orm import sessionmaker
1920-
1921-from nova import exception
1922-from nova import flags
1923-
1924-FLAGS = flags.FLAGS
1925-flags.DEFINE_integer('ns_flat_sql_idle_timeout',
1926- 3600,
1927- 'timeout for idle sql database connections')
1928-flags.DEFINE_string('ns_flat_sql_connection',
1929- 'sqlite:///$state_path/nova_flat_network.sqlite',
1930- 'connection string for flat network sql database')
1931-
1932-_FLAT_NETWORK_ENGINE = None
1933-_FLAT_NETWORK_MAKER = None
1934-
1935-def get_session(autocommit=True, expire_on_commit=False):
1936- """Helper method to grab session"""
1937- global _FLAT_NETWORK_ENGINE
1938- global _FLAT_NETWORK_MAKER
1939- if not _FLAT_NETWORK_MAKER:
1940- if not _FLAT_NETWORK_ENGINE:
1941- kwargs = {'pool_recycle': FLAGS.ns_flat_sql_idle_timeout,
1942- 'echo': False}
1943-
1944- if FLAGS.ns_flat_sql_connection.startswith('sqlite'):
1945- kwargs['poolclass'] = pool.NullPool
1946-
1947- _FLAT_NETWORK_ENGINE = create_engine(
1948- FLAGS.ns_flat_sql_connection,
1949- **kwargs)
1950-
1951- _FLAT_NETWORK_MAKER = (sessionmaker(bind=_FLAT_NETWORK_ENGINE,
1952- autocommit=autocommit,
1953- expire_on_commit=expire_on_commit))
1954-
1955- session = _FLAT_NETWORK_MAKER()
1956- session.query = exception.wrap_db_error(session.query)
1957- session.flush = exception.wrap_db_error(session.flush)
1958- return session
1959
1960=== removed file 'nova/network/flat/network.py'
1961--- nova/network/flat/network.py 2011-03-24 10:27:45 +0000
1962+++ nova/network/flat/network.py 1970-01-01 00:00:00 +0000
1963@@ -1,61 +0,0 @@
1964-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1965-
1966-# Copyright (c) 2011 NTT.
1967-# All Rights Reserved.
1968-#
1969-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1970-# not use this file except in compliance with the License. You may obtain
1971-# a copy of the License at
1972-#
1973-# http://www.apache.org/licenses/LICENSE-2.0
1974-#
1975-# Unless required by applicable law or agreed to in writing, software
1976-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1977-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1978-# License for the specific language governing permissions and limitations
1979-# under the License.
1980-
1981-from nova import context
1982-from nova import flags
1983-from nova import manager
1984-from nova import utils
1985-
1986-from nova.network.flat.db import manager as db_manager
1987-
1988-FLAGS = flags.FLAGS
1989-flags.DEFINE_string('ns_flat_network_driver', 'nova.network.linux_net',
1990- 'Driver to use for network creation')
1991-flags.DEFINE_string('ns_flat_dns', '8.8.4.4',
1992- 'Dns for simple network')
1993-
1994-class NetworkService(manager.Manager):
1995-
1996- def __init__(self, network_driver=None, *args, **kwargs):
1997- """Initializes flat network service."""
1998- if not network_driver:
1999- network_driver = FLAGS.ns_flat_network_driver
2000- self.driver = utils.import_object(network_driver)
2001- kwargs['db_driver'] = 'nova.network.flat.db.api'
2002- super(NetworkService, self).__init__(*args, **kwargs)
2003-
2004- def init_host(self):
2005- """Do any initialization that needs to be run if this is a
2006- standalone service.
2007- """
2008- ctxt = context.get_admin_context()
2009- for network in self.db.host_get_networks(ctxt, self.host):
2010- self.set_network_host(ctxt, network['id'])
2011-
2012- def set_network_host(self, context, network_id):
2013- """Called when this host becomes the host for a network."""
2014- net = {}
2015- net['dns'] = FLAGS.ns_flat_dns
2016- net['host'] = self.host
2017- self.db.network_update(context, network_id, net)
2018- return self.host
2019-
2020- def allocate_fixed_ips(self, context, vnic_ids):
2021- """Gets a fixed ip from the pool."""
2022- for vnic_id in vnic_ids:
2023- db_manager.bind_ip_to_ethernet_card(context, vnic_id)
2024-
2025
2026=== removed directory 'nova/network/flat_dhcp'
2027=== removed file 'nova/network/flat_dhcp/__init__.py'
2028--- nova/network/flat_dhcp/__init__.py 2011-03-30 10:33:12 +0000
2029+++ nova/network/flat_dhcp/__init__.py 1970-01-01 00:00:00 +0000
2030@@ -1,40 +0,0 @@
2031-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2032-
2033-# Copyright (c) 2011 NTT.
2034-# All Rights Reserved.
2035-#
2036-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2037-# not use this file except in compliance with the License. You may obtain
2038-# a copy of the License at
2039-#
2040-# http://www.apache.org/licenses/LICENSE-2.0
2041-#
2042-# Unless required by applicable law or agreed to in writing, software
2043-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2044-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2045-# License for the specific language governing permissions and limitations
2046-# under the License.
2047-from zope import interface
2048-
2049-from nova.network import service
2050-from nova.network.flat_dhcp.compute import NetworkAgentService
2051-from nova.network.flat_dhcp.api import NetworkApiService
2052-from nova.network.flat_dhcp.api.openstack import NetworkOpenStackApiService
2053-
2054-class NetworkServiceFactory(object):
2055- """Factory for network services"""
2056-
2057- interface.implements(service.INetworkServiceFactory)
2058-
2059- def get_api_service(self):
2060- """Gets the API service for this plugin."""
2061- return NetworkApiService()
2062-
2063- def get_os_api_service(self):
2064- """Gets OS API service for this plugin."""
2065- return NetworkOpenStackApiService()
2066-
2067- def get_net_agent(self):
2068- """Gets the net agent for this plugin."""
2069- return NetworkAgentService()
2070-
2071
2072=== removed directory 'nova/network/flat_dhcp/api'
2073=== removed file 'nova/network/flat_dhcp/api/__init__.py'
2074--- nova/network/flat_dhcp/api/__init__.py 2011-03-30 10:11:03 +0000
2075+++ nova/network/flat_dhcp/api/__init__.py 1970-01-01 00:00:00 +0000
2076@@ -1,44 +0,0 @@
2077-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2078-
2079-# Copyright 2010 OpenStack LLC.
2080-# All Rights Reserved.
2081-#
2082-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2083-# not use this file except in compliance with the License. You may obtain
2084-# a copy of the License at
2085-#
2086-# http://www.apache.org/licenses/LICENSE-2.0
2087-#
2088-# Unless required by applicable law or agreed to in writing, software
2089-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2090-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2091-# License for the specific language governing permissions and limitations
2092-# under the License.
2093-from zope import interface
2094-
2095-from nova.network import service
2096-from nova.network.flat_dhcp.db import api as db_api
2097-from nova.network.flat_dhcp.db import manager as db_manager
2098-
2099-class NetworkApiService(object):
2100- """Network API Service for this plugin."""
2101-
2102- interface.implements(service.INetworkApiService)
2103-
2104- def create_vnic(self, context):
2105- """Generic API to retrieve the default VNIC ID.
2106- For flat simple network, create a new vNIC and return its ID.
2107-
2108- Args:
2109- context: Nova context object needed to access the DB.
2110-
2111- Returns:
2112- The ID of the new VNIC.
2113- """
2114- # Create a new VNIC
2115- vnic = db_manager.ethernet_card_create_with_random_mac(context)
2116- return vnic.id
2117-
2118- def get_project_vpn_address_and_port(self, _context, _project_id):
2119- """Does not apply."""
2120- return (None, None)
2121
2122=== removed directory 'nova/network/flat_dhcp/api/openstack'
2123=== removed file 'nova/network/flat_dhcp/api/openstack/__init__.py'
2124--- nova/network/flat_dhcp/api/openstack/__init__.py 2011-03-31 06:43:59 +0000
2125+++ nova/network/flat_dhcp/api/openstack/__init__.py 1970-01-01 00:00:00 +0000
2126@@ -1,44 +0,0 @@
2127-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2128-# Copyright (c) 2011 NTT.
2129-# All Rights Reserved.
2130-#
2131-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2132-# not use this file except in compliance with the License. You may obtain
2133-# a copy of the License at
2134-#
2135-# http://www.apache.org/licenses/LICENSE-2.0
2136-#
2137-# Unless required by applicable law or agreed to in writing, software
2138-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2139-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2140-# License for the specific language governing permissions and limitations
2141-# under the License.
2142-from zope import interface
2143-
2144-from nova.network import service
2145-from nova.network.flat_dhcp.api.openstack import networks
2146-from nova.network.flat_dhcp.api.openstack import ports
2147-from nova.network.flat_dhcp.api.openstack import virtual_nics
2148-
2149-class NetworkOpenStackApiService(object):
2150- """OpenStack API service object for this plugin."""
2151-
2152- interface.implements(service.INetworkOpenStackApiService)
2153-
2154- def set_routes(self, route_map):
2155- """Generic API method to set up all the routes.
2156-
2157- Args:
2158- route_map: NetworkServiceRouteMap object to add the routes to.
2159- """
2160- # Set up VNIC
2161- route_map.resource("vnics", "/vnics",
2162- controller=virtual_nics.Controller())
2163-
2164- # Set up networks
2165- route_map.resource("networks", "/networks",
2166- controller=networks.Controller())
2167-
2168- # Set up ports
2169- route_map.resource("ports", "/ports",
2170- controller=ports.Controller())
2171
2172=== removed file 'nova/network/flat_dhcp/api/openstack/networks.py'
2173--- nova/network/flat_dhcp/api/openstack/networks.py 2011-03-16 18:03:44 +0000
2174+++ nova/network/flat_dhcp/api/openstack/networks.py 1970-01-01 00:00:00 +0000
2175@@ -1,80 +0,0 @@
2176-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2177-
2178-# Copyright 2010 OpenStack LLC.
2179-# All Rights Reserved.
2180-#
2181-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2182-# not use this file except in compliance with the License. You may obtain
2183-# a copy of the License at
2184-#
2185-# http://www.apache.org/licenses/LICENSE-2.0
2186-#
2187-# Unless required by applicable law or agreed to in writing, software
2188-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2189-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2190-# License for the specific language governing permissions and limitations
2191-# under the License.
2192-from webob import exc
2193-
2194-from nova import exception
2195-from nova import wsgi
2196-from nova.api.openstack import faults
2197-from nova.db import base
2198-from nova.network.flat_dhcp import common
2199-from nova.network.flat_dhcp import db
2200-from nova.network.flat_dhcp.db import manager
2201-
2202-class Controller(wsgi.Controller):
2203- """ The Networks API controller for the OpenStack API """
2204-
2205- def __init__(self):
2206- super(Controller, self).__init__()
2207-
2208- def create(self, req):
2209- """ Creates a new network. """
2210- env = self._deserialize(req.body, req.get_content_type())
2211- if not env:
2212- return faults.Fault(exc.HTTPUnprocessableEntity())
2213-
2214- label = env['label'] if 'label' in env else 'public'
2215- networks = manager.network_create(req.environ['nova.context'],
2216- env['cidr'],
2217- int(env['num_networks']),
2218- int(env['network_size']),
2219- env['cidr_v6'],
2220- label)
2221- items = [common.filter_keys(item, ('id', 'cidr'))
2222- for item in networks]
2223- return dict(ids=items)
2224-
2225- def update(self, req, id):
2226- """Updates a network."""
2227- env = self._deserialize(req.body, req.get_content_type())
2228- if not env:
2229- return faults.Fault(exc.HTTPUnprocessableEntity())
2230-
2231- # Currently only host can be updated.
2232- if 'host' in env:
2233- try:
2234- manager.network_update_host(req.environ['nova.context'], id,
2235- env['host'])
2236- except exception.NotFound:
2237- return faults.Fault(exc.HTTPNotFound())
2238-
2239- return exc.HTTPNoContent()
2240-
2241- def show(self, req, id):
2242- """ Gets the network with ID given """
2243- try:
2244- network = db.api.network_get(req.environ['nova.context'], id)
2245- return dict(id=network.id, cidr=network.cidr)
2246- except exception.NotFound:
2247- return faults.Fault(exc.HTTPNotFound())
2248-
2249- def delete(self, req, id):
2250- """ Destroys a network """
2251- try:
2252- db.api.network_delete(req.environ['nova.context'], id)
2253- except exception.NotFound:
2254- return faults.Fault(exc.HTTPNotFound())
2255- return exc.HTTPAccepted()
2256
2257=== removed file 'nova/network/flat_dhcp/api/openstack/ports.py'
2258--- nova/network/flat_dhcp/api/openstack/ports.py 2011-03-31 06:43:59 +0000
2259+++ nova/network/flat_dhcp/api/openstack/ports.py 1970-01-01 00:00:00 +0000
2260@@ -1,35 +0,0 @@
2261-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2262-
2263-# Copyright (c) 2011 NTT.
2264-# All Rights Reserved.
2265-#
2266-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2267-# not use this file except in compliance with the License. You may obtain
2268-# a copy of the License at
2269-#
2270-# http://www.apache.org/licenses/LICENSE-2.0
2271-#
2272-# Unless required by applicable law or agreed to in writing, software
2273-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2274-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2275-# License for the specific language governing permissions and limitations
2276-# under the License.
2277-
2278-from nova import wsgi
2279-from nova.api.openstack import common as nova_common
2280-from nova.api.openstack import faults
2281-from nova.network.flat_dhcp import common
2282-from nova.network.flat_dhcp import db
2283-
2284-class Controller(wsgi.Controller):
2285- """ The Ports API controller for the OpenStack API """
2286-
2287- def __init__(self):
2288- super(Controller, self).__init__()
2289-
2290- def index(self, req):
2291- """Return all port/IPs in brief"""
2292- items = db.api.fixed_ip_get_all(req.environ['nova.context'])
2293- items = nova_common.limited(items, req)
2294- items = [common.filter_keys(item, ('id', 'address')) for item in items]
2295- return dict(ports=items)
2296
2297=== removed file 'nova/network/flat_dhcp/api/openstack/virtual_nics.py'
2298--- nova/network/flat_dhcp/api/openstack/virtual_nics.py 2011-03-31 06:43:59 +0000
2299+++ nova/network/flat_dhcp/api/openstack/virtual_nics.py 1970-01-01 00:00:00 +0000
2300@@ -1,68 +0,0 @@
2301-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2302-
2303-# Copyright (c) 2011 NTT.
2304-# All Rights Reserved.
2305-#
2306-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2307-# not use this file except in compliance with the License. You may obtain
2308-# a copy of the License at
2309-#
2310-# http://www.apache.org/licenses/LICENSE-2.0
2311-#
2312-# Unless required by applicable law or agreed to in writing, software
2313-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2314-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2315-# License for the specific language governing permissions and limitations
2316-# under the License.
2317-from webob import exc
2318-
2319-from nova.api.openstack import common as nova_common
2320-from nova import exception
2321-from nova import wsgi
2322-from nova.api.openstack import faults
2323-from nova.db import base
2324-from nova.network.flat_dhcp import common
2325-from nova.network.flat_dhcp import db
2326-from nova.network.flat_dhcp.db import manager
2327-
2328-class Controller(wsgi.Controller):
2329- """ The Virtual NICs API controller for the OpenStack API """
2330-
2331- def __init__(self):
2332- super(Controller, self).__init__()
2333-
2334- def index(self, req):
2335- """Return all ethernet cards in brief"""
2336- items = db.api.ethernet_card_get_all(req.environ['nova.context'])
2337- items = nova_common.limited(items, req)
2338- items = [common.filter_keys(item, ('id', 'mac_address'))
2339- for item in items]
2340- return dict(ethernet_cards=items)
2341-
2342- def create(self, req):
2343- """ Creates a new ethernet card. """
2344- ethernet_card = manager.ethernet_card_create_with_random_mac(
2345- req.environ['nova.context'])
2346- return dict(id=ethernet_card.id)
2347-
2348- def update(self, req, id):
2349- """Update an ethernet card"""
2350- return exc.HTTPNoContent()
2351-
2352- def show(self, req, id):
2353- """ Gets the ethernet card with ID given """
2354- try:
2355- ethernet_card = db.api.ethernet_card_get(
2356- req.environ['nova.context'], id)
2357- return dict(id=ethernet_card.id,
2358- mac_address=ethernet_card.mac_address)
2359- except exception.NotFound:
2360- return faults.Fault(exc.HTTPNotFound())
2361-
2362- def delete(self, req, id):
2363- """ Destroys an ethernet card """
2364- try:
2365- db.api.ethernet_card_delete(req.environ['nova.context'], id)
2366- except exception.NotFound:
2367- return faults.Fault(exc.HTTPNotFound())
2368- return exc.HTTPAccepted()
2369
2370=== removed file 'nova/network/flat_dhcp/common.py'
2371--- nova/network/flat_dhcp/common.py 2011-03-31 09:36:36 +0000
2372+++ nova/network/flat_dhcp/common.py 1970-01-01 00:00:00 +0000
2373@@ -1,39 +0,0 @@
2374-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2375-
2376-# Copyright (c) 2011 NTT.
2377-# All Rights Reserved.
2378-#
2379-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2380-# not use this file except in compliance with the License. You may obtain
2381-# a copy of the License at
2382-#
2383-# http://www.apache.org/licenses/LICENSE-2.0
2384-#
2385-# Unless required by applicable law or agreed to in writing, software
2386-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2387-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2388-# License for the specific language governing permissions and limitations
2389-# under the License.
2390-
2391-#
2392-# Common utility methods and classes are defined here.
2393-#
2394-
2395-def filter_keys(item, keys):
2396- """
2397- Filters all model attributes except for keys
2398- item is a dict
2399- """
2400- return dict((k, v) for k, v in item.iteritems() if k in keys)
2401-
2402-def get_net_and_mask(cidr):
2403- """Gets network IP and netmask from cidr.
2404-
2405- Args:
2406- cidr: network CIDR.
2407-
2408- Returns:
2409- A tuple of network IP address and network mask.
2410- """
2411- net = IPy.IP(cidr)
2412- return str(net.net()), str(net.netmask())
2413\ No newline at end of file
2414
2415=== removed file 'nova/network/flat_dhcp/compute.py'
2416--- nova/network/flat_dhcp/compute.py 2011-03-31 09:36:36 +0000
2417+++ nova/network/flat_dhcp/compute.py 1970-01-01 00:00:00 +0000
2418@@ -1,186 +0,0 @@
2419-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2420-
2421-# Copyright (c) 2011 NTT.
2422-# All Rights Reserved.
2423-#
2424-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2425-# not use this file except in compliance with the License. You may obtain
2426-# a copy of the License at
2427-#
2428-# http://www.apache.org/licenses/LICENSE-2.0
2429-#
2430-# Unless required by applicable law or agreed to in writing, software
2431-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2432-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2433-# License for the specific language governing permissions and limitations
2434-# under the License.
2435-import socket
2436-from zope import interface
2437-
2438-from nova import flags
2439-from nova import rpc
2440-from nova import utils
2441-from nova.network import service
2442-from nova.network.flat_dhcp import common
2443-from nova.network.flat_dhcp.db import api as db_api
2444-
2445-FLAGS = flags.FLAGS
2446-flags.DEFINE_string('ns_flat_dhcp_network_host', socket.gethostname(),
2447- 'Network host to use for ip allocation in flat modes')
2448-flags.DEFINE_string('ns_flat_dhcp_network_topic', 'net-dhcp',
2449- 'the topic network nodes listen on')
2450-flags.DEFINE_string('ns_flat_dhcp_network_bridge', 'br100',
2451- 'Bridge for simple network instances')
2452-flags.DEFINE_bool('ns_flat_dhcp_network_fake_call', False,
2453- 'If True, skip using the queue and make local calls')
2454-flags.DEFINE_string('ns_flat_dhcp_network_agent_driver',
2455- 'nova.network.linux_net',
2456- 'Driver to use for network creation')
2457-flags.DEFINE_string('ns_flat_dhcp_agent_interface', None,
2458- 'FlatDhcp will bridge into this interface if set')
2459-
2460-def _queue_get_for(topic, physical_node_id):
2461- return "%s.%s" % (topic, physical_node_id)
2462-
2463-def _get_network_topic(context, **kwargs):
2464- """Retrieves the network host for a project on this host"""
2465- if FLAGS.stub_network:
2466- host = FLAGS.ns_flat_dhcp_network_host
2467- else:
2468- host = _get_network_host(context)
2469- return _queue_get_for(FLAGS.ns_flat_dhcp_network_topic,
2470- host)
2471-
2472-def _set_network_host(context, network_id):
2473- """Safely sets the host of the network."""
2474- db_api.network_update(context,
2475- network_id,
2476- {"host":FLAGS.host,
2477- "dns": FLAGS.ns_flat_dhcp_dns})
2478- return FLAGS.host
2479-
2480-def _get_network_host(context):
2481- """Get the network host for the current context."""
2482- network_ref = db_api.network_get_by_bridge(context,
2483- FLAGS.ns_flat_dhcp_network_bridge)
2484- host = network_ref['host']
2485- if not host:
2486- topic = _queue_get_for(FLAGS.ns_flat_dhcp_network_topic,
2487- FLAGS.ns_flat_dhcp_network_host)
2488- if FLAGS.ns_flat_dhcp_network_fake_call:
2489- return _set_network_host(context, network_ref['id'])
2490- host = rpc.call(context,
2491- FLAGS.ns_flat_dhcp_network_topic,
2492- {"method": "set_network_host",
2493- "args": {"network_id": network_ref['id']}})
2494- return host
2495-
2496-class NetworkAgentService(object):
2497- """An OpenStack network agent service object."""
2498-
2499- interface.implements(service.INetworkOpenStackApiService)
2500-
2501- def bind_vnics_to_ports(self, context, vnic_ids, _is_vpn):
2502- """Gets a fixed ips from the pool.
2503-
2504- Args:
2505- context: Nova context needed for DB access.
2506- vnic_ids: list of VNIC IDs
2507- is_vpn: Boolean to check if the call is for VPN.
2508- """
2509- rpc.call(context,
2510- _get_network_topic(context),
2511- {"method": "allocate_fixed_ips",
2512- "args": {"vnic_ids": vnic_ids}})
2513-
2514- def setup_compute_network(self, context, vnic_ids):
2515- """Set up the compute node for networking.
2516-
2517- Args:
2518- context: Nova context needed for DB access.
2519- vnic_ids: list of VNIC IDs
2520- is_vpn: Boolean to check if the call is for VPN.
2521- """
2522- driver = utils.import_object(FLAGS.ns_flat_dhcp_network_agent_driver)
2523- for vnic_id in vnic_ids:
2524- network_ref = db_api.network_get_by_ethernet_card(context, vnic_id)
2525- driver.ensure_bridge(network_ref['bridge'],
2526- FLAGS.ns_flat_dhcp_agent_interface)
2527-
2528- def teardown_compute_network(self, context, vnic_ids):
2529- """Clean up the compute node.
2530-
2531- Args:
2532- context: Nova context needed for DB access.
2533- vnic_ids: list of VNIC IDs
2534- """
2535- for vnic_id in vnic_ids:
2536- fixed_ip = vnic_id.get('fixed_ip')
2537- if not FLAGS.stub_network and fixed_ip:
2538- floating_ips = fixed_ip.get('floating_ips') or []
2539-
2540- for floating_ip in floating_ips:
2541- address = floating_ip['address']
2542-
2543- network_topic = _queue_get_for(context,
2544- FLAGS.ns_flat_dhcp_network_topic,
2545- floating_ip['host'])
2546-
2547- rpc.cast(context,
2548- network_topic,
2549- {"method": "disassociate_floating_ip",
2550- "args": {"floating_address": address}})
2551-
2552- address = fixed_ip['address']
2553- if address:
2554- # NOTE(vish): Currently, nothing needs to be done on the
2555- # network node until release. If this changes,
2556- # we will need to cast here.
2557- db_api.fixed_ip_update(context.elevated(), address,
2558- {'allocated':False})
2559-
2560- def requires_file_injection(self):
2561- """This service does not requires file injection.
2562- """
2563- return False
2564-
2565- def get_network_info(self, context, vnic_id):
2566- """Gets network data for a given VNIC.
2567-
2568- Args:
2569- context: Nova context needed for DB access.
2570- vnic_id: VNIC ID to get the network information for.
2571-
2572- Returns:
2573- A dictionary containing the following keys:
2574- cidr, cidrv6, netmask, netmask_v6 gateway, gateway_v6,
2575- dhcp_server, broadcast, dns, ra_server, mac_address,
2576- ip_address, bridge, and address_v6
2577- """
2578- ethernet_card = db_api.ethernet_card_get(context, vnic_id)
2579- if not ethernet_card:
2580- raise ValueError("Invalid vnic ID!")
2581-
2582- # Get the IP address associated with this VNIC
2583- ip_address = db_api.fixed_ip_get_by_ethernet_card(context,
2584- ethernet_card.id)
2585- if not ip_address:
2586- raise ValueError("VNIC is not mapped to IP!")
2587-
2588- network = ip_address.network
2589- if network['cidr_v6']:
2590- ipv6_addr = utils.to_global_ipv6(network['cidr_v6'],
2591- ethernet_card['mac_address'])
2592- else:
2593- ipv6_addr = None
2594-
2595- net, mask = common.get_net_and_mask(network['cidr'])
2596- return dict(mac_address=ethernet_card['mac_address'],
2597- ip_address=ip_address['address'], bridge=network['bridge'],
2598- cidr=network['cidr'], netmask=network['netmask'],
2599- gateway=network['gateway'], broadcast=network['broadcast'],
2600- dns=network['dns'], dhcp_server=network['gateway'],
2601- cidr_v6=network['cidr_v6'], address_v6=ipv6_addr,
2602- ra_server=network['ra_server'], netmask_v6=None,
2603- gateway_v6=None, net=net, mask=mask)
2604-
2605
2606=== removed directory 'nova/network/flat_dhcp/db'
2607=== removed file 'nova/network/flat_dhcp/db/__init__.py'
2608--- nova/network/flat_dhcp/db/__init__.py 2011-03-24 10:27:45 +0000
2609+++ nova/network/flat_dhcp/db/__init__.py 1970-01-01 00:00:00 +0000
2610@@ -1,20 +0,0 @@
2611-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2612-
2613-# Copyright (c) 2011 NTT.
2614-# All Rights Reserved.
2615-#
2616-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2617-# not use this file except in compliance with the License. You may obtain
2618-# a copy of the License at
2619-#
2620-# http://www.apache.org/licenses/LICENSE-2.0
2621-#
2622-# Unless required by applicable law or agreed to in writing, software
2623-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2624-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2625-# License for the specific language governing permissions and limitations
2626-# under the License.
2627-"""
2628-DB abstraction for Nova
2629-"""
2630-
2631
2632=== removed file 'nova/network/flat_dhcp/db/api.py'
2633--- nova/network/flat_dhcp/db/api.py 2011-03-24 15:46:07 +0000
2634+++ nova/network/flat_dhcp/db/api.py 1970-01-01 00:00:00 +0000
2635@@ -1,219 +0,0 @@
2636-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2637-
2638-# Copyright (c) 2011 NTT.
2639-# All Rights Reserved.
2640-#
2641-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2642-# not use this file except in compliance with the License. You may obtain
2643-# a copy of the License at
2644-#
2645-# http://www.apache.org/licenses/LICENSE-2.0
2646-#
2647-# Unless required by applicable law or agreed to in writing, software
2648-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2649-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2650-# License for the specific language governing permissions and limitations
2651-# under the License.
2652-"""
2653-Defines interface for DB access.
2654-
2655-The underlying driver is loaded as a :class:`LazyPluggable`.
2656-"""
2657-from nova import flags
2658-from nova import utils
2659-
2660-FLAGS = flags.FLAGS
2661-flags.DEFINE_string('ns_flat_dhcp_db_backend',
2662- 'sqlalchemy',
2663- 'Default backend to use for SQL.')
2664-flags.DEFINE_string('ns_flat_dhcp_sqlalchemy_api',
2665- 'nova.network.flat_dhcp.db.sqlalchemy.ap',
2666- 'SQL Alchemy module to use.')
2667-
2668-IMPL = utils.LazyPluggable(FLAGS['ns_flat_dhcp_db_backend'],
2669- sqlalchemy='nova.network.flat_dhcp.db.sqlalchemy.api')
2670-
2671-###################
2672-
2673-def ethernet_card_get(context, id):
2674- """Get ethernet card by id."""
2675- return IMPL.dao_factory.get_dao(context).\
2676- ethernet_card_get(id)
2677-
2678-def ethernet_card_create(context, values):
2679- """Create a new ethernet card."""
2680- return IMPL.dao_factory.get_dao(context).\
2681- ethernet_card_create(values)
2682-
2683-def ethernet_card_get_all(context):
2684- """Get all ethernet cards."""
2685- return IMPL.dao_factory.get_dao(context).\
2686- ethernet_card_get_all()
2687-
2688-def ethernet_card_update(context, ethernet_card_id, values):
2689- """Update ethernet card."""
2690- return IMPL.dao_factory.get_dao(context).\
2691- ethernet_card_update(ethernet_card_id, values)
2692-
2693-def ethernet_card_delete(context, ethernet_card_id):
2694- """Delete ethernet card."""
2695- return IMPL.dao_factory.get_dao(context).\
2696- ethernet_card_delete(ethernet_card_id)
2697-
2698-def network_get(context, id):
2699- """Get network by id."""
2700- return IMPL.dao_factory.get_dao(context).\
2701- network_get(id)
2702-
2703-def network_get_by_ethernet_card(context, ethernet_card_id):
2704- """Get network by ethernet card."""
2705- return IMPL.dao_factory.get_dao(context).\
2706- network_get_by_ethernet_card(ethernet_card_id)
2707-
2708-def network_get_associated_fixed_ips(context, network_id):
2709- """Get fixed IPs that are associated with ethernet for a given network."""
2710- return IMPL.dao_factory.get_dao(context).\
2711- network_get_associated_fixed_ips(network_id)
2712-
2713-def network_get_by_bridge(context, bridge):
2714- """Get a network by bridge or raise if it does not exist."""
2715- return IMPL.dao_factory.get_dao(context).\
2716- network_get_by_bridge(bridge)
2717-
2718-def host_get_networks(context, host):
2719- """Get networks for a given host."""
2720- return IMPL.dao_factory.get_dao(context).\
2721- host_get_networks(host)
2722-
2723-def network_create(context, values):
2724- """Create a new network."""
2725- return IMPL.dao_factory.get_dao(context).\
2726- network_create(values)
2727-
2728-def network_create_safe(context, values):
2729- """Create a new network. Returns None when there is an exception"""
2730- return IMPL.dao_factory.get_dao(context).\
2731- network_create_safe(values)
2732-
2733-def network_get_all(context):
2734- """Get all networks."""
2735- return IMPL.dao_factory.get_dao(context).\
2736- network_get_all()
2737-
2738-def network_update(context, network_id, values):
2739- """Update network."""
2740- return IMPL.dao_factory.get_dao(context).\
2741- network_update(network_id, values)
2742-
2743-def network_delete(context, network_id):
2744- """Delete network."""
2745- return IMPL.dao_factory.get_dao(context).\
2746- network_delete(network_id)
2747-
2748-def fixed_ip_create(context, values):
2749- """Create a new fixed IP address."""
2750- return IMPL.dao_factory.get_dao(context).\
2751- fixed_ip_create(values)
2752-
2753-def fixed_ip_get(context, fixed_ip_id):
2754- """Gets fixed IP with ID."""
2755- return IMPL.dao_factory.get_dao(context).\
2756- fixed_ip_get(fixed_ip_id)
2757-
2758-def fixed_ip_get_by_ethernet_card(context, ethernet_card_id):
2759- """Get IP address by ethernet card id."""
2760- return IMPL.dao_factory.get_dao(context).\
2761- fixed_ip_get_by_ethernet_card(ethernet_card_id)
2762-
2763-def fixed_ip_get_all(context):
2764- """Get all the fixed IP addresses."""
2765- return IMPL.dao_factory.get_dao(context).\
2766- fixed_ip_get_all()
2767-
2768-def fixed_ip_update(context, fixed_ip_id, values):
2769- """Update fixed IP."""
2770- return IMPL.dao_factory.get_dao(context).\
2771- fixed_ip_update(fixed_ip_id, values)
2772-
2773-def fixed_ip_get_by_address(context, address):
2774- """Get fixed IP by address."""
2775- return IMPL.dao_factory.get_dao(context).\
2776- fixed_ip_get_by_address(address)
2777-
2778-def floating_ip_get_all_by_host(context, host):
2779- """Get all the floating IPs for a host."""
2780- return IMPL.dao_factory.get_dao(context).\
2781- floating_ip_get_all_by_host(host)
2782-
2783-def floating_ip_allocate_address(context, host, project_id):
2784- """Allocate free floating ip and return the address.
2785-
2786- Raises if one is not available.
2787-
2788- """
2789- return IMPL.dao_factory.get_dao(context).\
2790- floating_ip_allocate_address(host, project_id)
2791-
2792-def floating_ip_create(context, values):
2793- """Create a floating ip from the values dictionary."""
2794- return IMPL.dao_factory.get_dao(context).\
2795- floating_ip_create(values)
2796-
2797-def floating_ip_count_by_project(context, project_id):
2798- """Count floating ips used by project."""
2799- return IMPL.dao_factory.get_dao(context).\
2800- floating_ip_count_by_project(project_id)
2801-
2802-def floating_ip_deallocate(context, address):
2803- """Deallocate an floating ip by address"""
2804- return IMPL.dao_factory.get_dao(context).\
2805- floating_ip_deallocate(address)
2806-
2807-def floating_ip_destroy(context, address):
2808- """Destroy the floating_ip or raise if it does not exist."""
2809- return IMPL.dao_factory.get_dao(context).\
2810- floating_ip_destroy(address)
2811-
2812-def floating_ip_disassociate(context, address):
2813- """Disassociate an floating ip from a fixed ip by address.
2814-
2815- Returns the address of the existing fixed ip.
2816-
2817- """
2818- return IMPL.dao_factory.get_dao(context).\
2819- floating_ip_disassociate(address)
2820-
2821-def floating_ip_fixed_ip_associate(context, floating_address, fixed_address):
2822- """Associate an floating ip to a fixed_ip by address."""
2823- return IMPL.dao_factory.get_dao(context).\
2824- floating_ip_fixed_ip_associate(floating_address, fixed_address)
2825-
2826-def floating_ip_get_all(context):
2827- """Get all floating ips."""
2828- return IMPL.dao_factory.get_dao(context).\
2829- floating_ip_get_all()
2830-
2831-def floating_ip_get_all_by_project(context, project_id):
2832- """Get all floating ips by project."""
2833- return IMPL.dao_factory.get_dao(context).\
2834- floating_ip_get_all_by_project(project_id)
2835-
2836-def floating_ip_get_by_address(context, address):
2837- """Get a floating ip by address or raise if it doesn't exist."""
2838- return IMPL.dao_factory.get_dao(context).\
2839- floating_ip_get_by_address(address)
2840-
2841-def floating_ip_update(context, address, values):
2842- """Update a floating ip by address or raise if it doesn't exist."""
2843- return IMPL.dao_factory.get_dao(context).\
2844- floating_ip_update(address, values)
2845-
2846-def fixed_ip_disassociate(context, fixed_ip_id):
2847- """Removes reference to ethernet card from IP."""
2848- return IMPL.dao_factory.get_dao(context).\
2849- fixed_ip_disassociate(fixed_ip_id)
2850-
2851-def fixed_ip_associate_pool(context, network_id, ethernet_card_id):
2852- """Associates an IP to an ethernet card."""
2853- return IMPL.dao_factory.get_dao(context).\
2854- fixed_ip_associate_pool(network_id, ethernet_card_id)
2855
2856=== removed file 'nova/network/flat_dhcp/db/manager.py'
2857--- nova/network/flat_dhcp/db/manager.py 2011-03-24 10:27:45 +0000
2858+++ nova/network/flat_dhcp/db/manager.py 1970-01-01 00:00:00 +0000
2859@@ -1,129 +0,0 @@
2860-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2861-
2862-# Copyright (c) 2011 NTT.
2863-# All Rights Reserved.
2864-#
2865-# Licensed under the Apache License, Version 2.0 (the "License"); you may
2866-# not use this file except in compliance with the License. You may obtain
2867-# a copy of the License at
2868-#
2869-# http://www.apache.org/licenses/LICENSE-2.0
2870-#
2871-# Unless required by applicable law or agreed to in writing, software
2872-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2873-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2874-# License for the specific language governing permissions and limitations
2875-# under the License.
2876-
2877-"""
2878-Wrapper APIs for DB models should be defined here.
2879-"""
2880-import collections
2881-import IPy
2882-import math
2883-
2884-from nova import exception
2885-from nova import flags
2886-from nova import utils
2887-
2888-from nova.network.flat_dhcp.db import api
2889-
2890-FLAGS = flags.FLAGS
2891-flags.DEFINE_string('ns_flat_dhcp_bridge',
2892- 'br100',
2893- 'Bridge for simple network instances')
2894-flags.DEFINE_string('ns_flat_dhcp_dns', '8.8.4.4',
2895- 'Dns for simple network')
2896-
2897-BOTTOM_RESERVED_IPS = 2
2898-TOP_RESERVED_IPS = 1
2899-
2900-def _create_fixed_ips(context, network_id):
2901- """Create all fixed ips for network."""
2902- network_ref = api.network_get(context, network_id)
2903- net = IPy.IP(network_ref['cidr'])
2904- num_ips = len(net)
2905- for index in range(num_ips):
2906- address = str(net[index])
2907- if index < BOTTOM_RESERVED_IPS or num_ips - index < TOP_RESERVED_IPS:
2908- reserved = True
2909- else:
2910- reserved = False
2911-
2912- api.fixed_ip_create(context,
2913- {'network_id': network_id,
2914- 'address': address,
2915- 'reserved': reserved})
2916-
2917-def network_create(context, cidr, num_networks, network_size,
2918- cidr_v6, label, *args, **kwargs):
2919- """Create networks based on parameters."""
2920- fixed_net = IPy.IP(cidr)
2921- fixed_net_v6 = IPy.IP(cidr_v6)
2922- significant_bits_v6 = 64
2923- networks = []
2924- count = 1
2925- for index in range(num_networks):
2926- start = index * network_size
2927- significant_bits = 32 - int(math.log(network_size, 2))
2928- cidr = "%s/%s" % (fixed_net[start], significant_bits)
2929- project_net = IPy.IP(cidr)
2930- net = {}
2931- net['bridge'] = FLAGS.ns_flat_dhcp_bridge
2932- net['cidr'] = cidr
2933- net['netmask'] = str(project_net.netmask())
2934- net['gateway'] = str(project_net[1])
2935- net['broadcast'] = str(project_net.broadcast())
2936- net['dns'] = FLAGS.ns_flat_dhcp_dns
2937- net['dhcp_start'] = str(project_net[2])
2938- if num_networks > 1:
2939- net['label'] = "%s_%d" % (label, count)
2940- else:
2941- net['label'] = label
2942- count += 1
2943-
2944- if(FLAGS.use_ipv6):
2945- cidr_v6 = "%s/%s" % (fixed_net_v6[0], significant_bits_v6)
2946- net['cidr_v6'] = cidr_v6
2947-
2948- network_ref = api.network_create_safe(context, net)
2949-
2950- networks.append(network_ref)
2951- if network_ref:
2952- _create_fixed_ips(context, network_ref['id'])
2953-
2954- return networks
2955-
2956-def allocate_ip(context, ethernet_card_id, *args, **kwargs):
2957- """Gets an IP from the pool."""
2958- network_ref = api.network_get_by_bridge(context,
2959- FLAGS.ns_flat_dhcp_bridge)
2960- ip = api.fixed_ip_associate_pool(context.elevated(),
2961- network_ref['id'],
2962- ethernet_card_id)
2963- api.fixed_ip_update(context, ip.id, {'allocated': True})
2964- return ip
2965-
2966-def bind_ip_to_ethernet_card(context, ethernet_card_id):
2967- """Assigns IP to ethernet card."""
2968-
2969- # Get the ethernet card
2970- ethernet_card = api.ethernet_card_get(context, ethernet_card_id)
2971- # TODO: Throw a better exception.
2972- if not ethernet_card:
2973- raise ValueError("There is not VNIC with ID %s" % ethernet_card_id)
2974-
2975- ip_address = api.fixed_ip_get_by_ethernet_card(context,
2976- ethernet_card_id)
2977- # Check to see if this ethernet card does not have IP allocated.
2978- if not ip_address:
2979- ip_address = allocate_ip(context, ethernet_card_id)
2980-
2981- return ip_address
2982-
2983-def ethernet_card_create_with_random_mac(context):
2984- """Creates a new ethernet card"""
2985- mac_address = utils.generate_mac()
2986- return api.ethernet_card_create(context, dict(mac_address=mac_address))
2987-
2988-
2989
2990=== removed directory 'nova/network/flat_dhcp/db/sqlalchemy'
2991=== removed file 'nova/network/flat_dhcp/db/sqlalchemy/__init__.py'
2992--- nova/network/flat_dhcp/db/sqlalchemy/__init__.py 2011-03-24 10:27:45 +0000
2993+++ nova/network/flat_dhcp/db/sqlalchemy/__init__.py 1970-01-01 00:00:00 +0000
2994@@ -1,16 +0,0 @@
2995-# vim: tabstop=4 shiftwidth=4 softtabstop=4
2996-
2997-# Copyright (c) 2011 NTT.
2998-# All Rights Reserved.
2999-#
3000-# Licensed under the Apache License, Version 2.0 (the "License"); you may
3001-# not use this file except in compliance with the License. You may obtain
3002-# a copy of the License at
3003-#
3004-# http://www.apache.org/licenses/LICENSE-2.0
3005-#
3006-# Unless required by applicable law or agreed to in writing, software
3007-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
3008-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
3009-# License for the specific language governing permissions and limitations
3010-# under the License.
3011
3012=== removed file 'nova/network/flat_dhcp/db/sqlalchemy/api.py'
3013--- nova/network/flat_dhcp/db/sqlalchemy/api.py 2011-03-24 21:53:30 +0000
3014+++ nova/network/flat_dhcp/db/sqlalchemy/api.py 1970-01-01 00:00:00 +0000
3015@@ -1,62 +0,0 @@
3016-# vim: tabstop=4 shiftwidth=4 softtabstop=4
3017-
3018-# Copyright (c) 2011 NTT.
3019-# All Rights Reserved.
3020-#
3021-# Licensed under the Apache License, Version 2.0 (the "License"); you may
3022-# not use this file except in compliance with the License. You may obtain
3023-# a copy of the License at
3024-#
3025-# http://www.apache.org/licenses/LICENSE-2.0
3026-#
3027-# Unless required by applicable law or agreed to in writing, software
3028-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
3029-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
3030-# License for the specific language governing permissions and limitations
3031-# under the License.
3032-"""
3033-Implementation of SQLAlchemy backend.
3034-"""
3035-
3036-from sqlalchemy import or_
3037-from sqlalchemy.orm import joinedload_all
3038-import warnings
3039-
3040-from nova import exception
3041-from nova.db import api as nova_db
3042-from nova.db.sqlalchemy import api as nova_api
3043-from nova.network.flat.db.sqlalchemy import api as flat_api
3044-from nova.network.flat_dhcp.db.sqlalchemy import models
3045-from nova.network.flat_dhcp.db.sqlalchemy.session import get_session
3046-
3047-
3048-class DefaultSessionFlatDhcpNetworkDataAccessFactory(object):
3049- """A DAO factory that lazily uses the default session.
3050-
3051- This factory uses the default session for the flat DHCP network
3052- service, which it creates lazily when creating the first DAO.
3053- """
3054-
3055- def __init__(self):
3056- self._dao_cache = flat_api.DataAccessCache(
3057- models.FlatDhcpNetworkDataAccess)
3058- self._session = None
3059-
3060- def get_session(self):
3061- if self._session is None:
3062- self._session = get_session()
3063- return self._session
3064-
3065- def get_dao(self, context):
3066- """Get a DataAccess object.
3067-
3068- If no cached DAO has been created for this context's
3069- parameter, a new DAO is created and cached. Otherwise, the
3070- cached DAO is returned.
3071-
3072- :param context: The request context.
3073- """
3074- return self._dao_cache.get_dao(context, self.get_session())
3075-
3076-
3077-dao_factory = DefaultSessionFlatDhcpNetworkDataAccessFactory()
3078
3079=== removed directory 'nova/network/flat_dhcp/db/sqlalchemy/migrate_repo'
3080=== removed file 'nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/README'
3081--- nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/README 2011-03-15 15:01:10 +0000
3082+++ nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/README 1970-01-01 00:00:00 +0000
3083@@ -1,4 +0,0 @@
3084-This is a database migration repository.
3085-
3086-More information at
3087-http://code.google.com/p/sqlalchemy-migrate/
3088
3089=== removed file 'nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/__init__.py'
3090--- nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/__init__.py 2011-03-24 10:27:45 +0000
3091+++ nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/__init__.py 1970-01-01 00:00:00 +0000
3092@@ -1,16 +0,0 @@
3093-# vim: tabstop=4 shiftwidth=4 softtabstop=4
3094-
3095-# Copyright (c) 2011 NTT.
3096-# All Rights Reserved.
3097-#
3098-# Licensed under the Apache License, Version 2.0 (the "License"); you may
3099-# not use this file except in compliance with the License. You may obtain
3100-# a copy of the License at
3101-#
3102-# http://www.apache.org/licenses/LICENSE-2.0
3103-#
3104-# Unless required by applicable law or agreed to in writing, software
3105-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
3106-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
3107-# License for the specific language governing permissions and limitations
3108-# under the License.
3109
3110=== removed file 'nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/manage.py'
3111--- nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/manage.py 2011-03-15 15:01:10 +0000
3112+++ nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/manage.py 1970-01-01 00:00:00 +0000
3113@@ -1,4 +0,0 @@
3114-#!/usr/bin/env python
3115-from migrate.versioning.shell import main
3116-if __name__ == '__main__':
3117- main(debug='False', repository='.')
3118
3119=== removed file 'nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/migrate.cfg'
3120--- nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/migrate.cfg 2011-03-15 15:01:10 +0000
3121+++ nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/migrate.cfg 1970-01-01 00:00:00 +0000
3122@@ -1,20 +0,0 @@
3123-[db_settings]
3124-# Used to identify which repository this database is versioned under.
3125-# You can use the name of your project.
3126-repository_id=nova_network_flat_dhcp
3127-
3128-# The name of the database table used to track the schema version.
3129-# This name shouldn't already be used by your project.
3130-# If this is changed once a database is under version control, you'll need to
3131-# change the table name in each database too.
3132-version_table=migrate_version
3133-
3134-# When committing a change script, Migrate will attempt to generate the
3135-# sql for all supported databases; normally, if one of them fails - probably
3136-# because you don't have that database installed - it is ignored and the
3137-# commit continues, perhaps ending successfully.
3138-# Databases in this list MUST compile successfully during a commit, or the
3139-# entire commit will fail. List the databases your application will actually
3140-# be using to ensure your updates to that database work properly.
3141-# This must be a list; example: ['postgres','sqlite']
3142-required_dbs=[]
3143
3144=== removed directory 'nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/versions'
3145=== removed file 'nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/versions/001_diablo.py'
3146--- nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/versions/001_diablo.py 2011-03-24 10:27:45 +0000
3147+++ nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/versions/001_diablo.py 1970-01-01 00:00:00 +0000
3148@@ -1,137 +0,0 @@
3149-# vim: tabstop=4 shiftwidth=4 softtabstop=4
3150-
3151-# Copyright (c) 2011 NTT.
3152-# All Rights Reserved.
3153-#
3154-# Licensed under the Apache License, Version 2.0 (the "License"); you may
3155-# not use this file except in compliance with the License. You may obtain
3156-# a copy of the License at
3157-#
3158-# http://www.apache.org/licenses/LICENSE-2.0
3159-#
3160-# Unless required by applicable law or agreed to in writing, software
3161-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
3162-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
3163-# License for the specific language governing permissions and limitations
3164-# under the License.
3165-
3166-from sqlalchemy import *
3167-from migrate import *
3168-
3169-from nova import log as logging
3170-
3171-meta = MetaData()
3172-
3173-#
3174-# New Tables
3175-#
3176-fixed_ips = Table('fixed_ips', meta,
3177- Column('created_at', DateTime(timezone=False)),
3178- Column('updated_at', DateTime(timezone=False)),
3179- Column('deleted_at', DateTime(timezone=False)),
3180- Column('deleted', Boolean(create_constraint=True, name=None)),
3181- Column('id', Integer(), primary_key=True, nullable=False),
3182- Column('address',
3183- String(length=255, convert_unicode=False, assert_unicode=None,
3184- unicode_error=None, _warn_on_bytestring=False)),
3185- Column('network_id', Integer(), ForeignKey('networks.id'),
3186- nullable=True),
3187- Column('allocated', Boolean(create_constraint=True, name=None)),
3188- Column('leased', Boolean(create_constraint=True, name=None)),
3189- Column('reserved', Boolean(create_constraint=True, name=None)),
3190- Column("addressV6",
3191- String(length=255, convert_unicode=False, assert_unicode=None,
3192- unicode_error=None, _warn_on_bytestring=False)),
3193- Column("netmaskV6",
3194- String(length=3, convert_unicode=False, assert_unicode=None,
3195- unicode_error=None, _warn_on_bytestring=False)),
3196- Column("gatewayV6",
3197- String(length=255, convert_unicode=False, assert_unicode=None,
3198- unicode_error=None, _warn_on_bytestring=False)),
3199- Column('ethernet_card_id', Integer(), ForeignKey('ethernet_cards.id'),
3200- nullable=True),
3201- )
3202-
3203-floating_ips = Table('floating_ips', meta,
3204- Column('created_at', DateTime(timezone=False)),
3205- Column('updated_at', DateTime(timezone=False)),
3206- Column('deleted_at', DateTime(timezone=False)),
3207- Column('deleted', Boolean(create_constraint=True, name=None)),
3208- Column('id', Integer(), primary_key=True, nullable=False),
3209- Column('address',
3210- String(length=255, convert_unicode=False, assert_unicode=None,
3211- unicode_error=None, _warn_on_bytestring=False)),
3212- Column('fixed_ip_id',
3213- Integer(),
3214- ForeignKey('fixed_ips.id'),
3215- nullable=True),
3216- Column('project_id',
3217- String(length=255, convert_unicode=False, assert_unicode=None,
3218- unicode_error=None, _warn_on_bytestring=False)),
3219- Column('host',
3220- String(length=255, convert_unicode=False, assert_unicode=None,
3221- unicode_error=None, _warn_on_bytestring=False)),
3222- )
3223-
3224-ethernet_cards = Table(
3225- 'ethernet_cards', meta,
3226- Column('created_at', DateTime(timezone=False)),
3227- Column('updated_at', DateTime(timezone=False)),
3228- Column('deleted_at', DateTime(timezone=False)),
3229- Column('deleted', Boolean(create_constraint=True, name=None)),
3230- Column('id', Integer(), primary_key=True, nullable=False),
3231- Column('mac_address', String(255), nullable=False),
3232- )
3233-
3234-networks = Table(
3235- 'networks', meta,
3236- Column('created_at', DateTime(timezone=False)),
3237- Column('updated_at', DateTime(timezone=False)),
3238- Column('deleted_at', DateTime(timezone=False)),
3239- Column('deleted', Boolean(create_constraint=True, name=None)),
3240- Column('id', Integer(), primary_key=True),
3241- Column('cidr', String(255)),
3242- Column('netmask', String(255)),
3243- Column('bridge', String(255)),
3244- Column('gateway', String(255)),
3245- Column('broadcast', String(255)),
3246- Column('dns',
3247- String(length=255, convert_unicode=False, assert_unicode=None,
3248- unicode_error=None, _warn_on_bytestring=False)),
3249- Column('dhcp_start',
3250- String(length=255, convert_unicode=False, assert_unicode=None,
3251- unicode_error=None, _warn_on_bytestring=False)),
3252- Column('cidr_v6',
3253- String(length=255, convert_unicode=False, assert_unicode=None,
3254- unicode_error=None, _warn_on_bytestring=False)),
3255- Column('ra_server',
3256- String(length=255, convert_unicode=False, assert_unicode=None,
3257- unicode_error=None, _warn_on_bytestring=False)),
3258- Column('label',
3259- String(length=255, convert_unicode=False, assert_unicode=None,
3260- unicode_error=None, _warn_on_bytestring=False)),
3261- Column('host', String(255)),
3262- )
3263-
3264-def upgrade(migrate_engine):
3265- meta.bind = migrate_engine
3266-
3267- for table in (ethernet_cards, networks, fixed_ips, floating_ips):
3268- try:
3269- table.create()
3270- except Exception:
3271- logging.info(repr(table))
3272- logging.exception('Exception while creating table')
3273- raise
3274-
3275-def downgrade(migrate_engine):
3276- meta.bind = migrate_engine
3277-
3278- for table in (floating_ips, fixed_ips, networks, ethernet_cards):
3279- try:
3280- table.drop()
3281- except Exception:
3282- logging.info(repr(table))
3283- logging.exception('Exception while dropping table')
3284- raise
3285-
3286
3287=== removed file 'nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/versions/__init__.py'
3288--- nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/versions/__init__.py 2011-03-24 10:27:45 +0000
3289+++ nova/network/flat_dhcp/db/sqlalchemy/migrate_repo/versions/__init__.py 1970-01-01 00:00:00 +0000
3290@@ -1,16 +0,0 @@
3291-# vim: tabstop=4 shiftwidth=4 softtabstop=4
3292-
3293-# Copyright (c) 2011 NTT.
3294-# All Rights Reserved.
3295-#
3296-# Licensed under the Apache License, Version 2.0 (the "License"); you may
3297-# not use this file except in compliance with the License. You may obtain
3298-# a copy of the License at
3299-#
3300-# http://www.apache.org/licenses/LICENSE-2.0
3301-#
3302-# Unless required by applicable law or agreed to in writing, software
3303-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
3304-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
3305-# License for the specific language governing permissions and limitations
3306-# under the License.
3307
3308=== removed file 'nova/network/flat_dhcp/db/sqlalchemy/models.py'
3309--- nova/network/flat_dhcp/db/sqlalchemy/models.py 2011-03-24 21:53:30 +0000
3310+++ nova/network/flat_dhcp/db/sqlalchemy/models.py 1970-01-01 00:00:00 +0000
3311@@ -1,354 +0,0 @@
3312-# vim: tabstop=4 shiftwidth=4 softtabstop=4
3313-
3314-# Copyright (c) 2011 NTT.
3315-# All Rights Reserved.
3316-#
3317-# Licensed under the Apache License, Version 2.0 (the "License"); you may
3318-# not use this file except in compliance with the License. You may obtain
3319-# a copy of the License at
3320-#
3321-# http://www.apache.org/licenses/LICENSE-2.0
3322-#
3323-# Unless required by applicable law or agreed to in writing, software
3324-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
3325-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
3326-# License for the specific language governing permissions and limitations
3327-# under the License.
3328-"""
3329-SQLAlchemy models for flat DHCP network service data.
3330-"""
3331-
3332-from sqlalchemy.orm import joinedload_all
3333-from sqlalchemy.orm import relationship, backref
3334-from sqlalchemy import Column, Boolean, Integer, String
3335-from sqlalchemy import ForeignKey
3336-from sqlalchemy.ext.declarative import declarative_base
3337-
3338-from nova.db.sqlalchemy.models import NovaBase
3339-from nova.network.flat.db.sqlalchemy import models as flat_models
3340-
3341-
3342-BASE = declarative_base()
3343-
3344-
3345-# ----------------------
3346-# Data Transfer Objects.
3347-# ----------------------
3348-
3349-class EthernetCard(BASE, NovaBase):
3350- """Represents an ethernet card."""
3351- __tablename__ = 'ethernet_cards'
3352- id = Column(Integer, primary_key=True)
3353- mac_address = Column(String(255), nullable=False, unique=True)
3354-
3355-class Network(BASE, NovaBase):
3356- """Represents a simple IP network with DHCP service."""
3357- __tablename__ = 'networks'
3358- id = Column(Integer, primary_key=True)
3359- cidr = Column(String(255))
3360- netmask = Column(String(255))
3361- bridge = Column(String(255))
3362- gateway = Column(String(255))
3363- broadcast = Column(String(255))
3364- dns = Column(String(255))
3365- cidr_v6 = Column(String(255), unique=True)
3366- host = Column(String(255)) # , ForeignKey('hosts.id'))
3367-
3368- dhcp_start = Column(String(255))
3369- ra_server = Column(String(255))
3370- label = Column(String(255))
3371-
3372-
3373-class FixedIp(BASE, NovaBase):
3374- """Represents a fixed ip for an instance."""
3375- __tablename__ = 'fixed_ips'
3376- id = Column(Integer, primary_key=True)
3377- address = Column(String(255))
3378- network_id = Column(Integer, ForeignKey('networks.id'), nullable=True)
3379- network = relationship(Network, backref=backref('fixed_ips'))
3380- ethernet_card_id = Column(Integer, ForeignKey('ethernet_cards.id'))
3381- ethernet_card = relationship(EthernetCard,
3382- backref=backref('fixed_ips'))
3383- allocated = Column(Boolean, default=False)
3384- leased = Column(Boolean, default=False)
3385- reserved = Column(Boolean, default=False)
3386- addressV6 = Column(String(255))
3387- netmaskV6 = Column(String(3))
3388- gatewayV6 = Column(String(255))
3389-
3390-
3391-class FloatingIp(BASE, NovaBase):
3392- """Represents a floating ip that dynamically forwards to a fixed ip."""
3393- __tablename__ = 'floating_ips'
3394- id = Column(Integer, primary_key=True)
3395- address = Column(String(255))
3396- fixed_ip_id = Column(Integer, ForeignKey('fixed_ips.id'), nullable=True)
3397- fixed_ip = relationship(FixedIp,
3398- backref=backref('floating_ips'),
3399- foreign_keys=fixed_ip_id,
3400- primaryjoin='and_('
3401- 'FloatingIp.fixed_ip_id == FixedIp.id,'
3402- 'FloatingIp.deleted == False)')
3403- project_id = Column(String(255))
3404- host = Column(String(255)) # , ForeignKey('hosts.id'))
3405-
3406-
3407-# ----------------------
3408-# Data Access Objects.
3409-# ----------------------
3410-
3411-class EthernetCardDataAccess(flat_models.EthernetCardDataAccess):
3412- """A Data Access Object to access networks.
3413- """
3414-
3415- ethernet_card_dto_class = EthernetCard
3416-
3417-
3418-class NetworkDataAccess(flat_models.NetworkDataAccess):
3419- """A Data Access Object to access networks.
3420- """
3421-
3422- network_dto_class = Network
3423-
3424-
3425-class FixedIpDataAccess(flat_models.DataAccess):
3426- """A Data Access Object to access fixed IPs.
3427- """
3428-
3429- fixed_ip_dto_class = FixedIp
3430-
3431- def fixed_ip_create(self, values):
3432- fixed_ip_ref = self.fixed_ip_dto_class()
3433- fixed_ip_ref.update(values)
3434- fixed_ip_ref.save(session=self._session)
3435- return fixed_ip_ref['address']
3436-
3437- def fixed_ip_update(self, fixed_ip_id, values):
3438- with self._session.begin():
3439- fixed_ip_ref = self.fixed_ip_get(fixed_ip_id)
3440- fixed_ip_ref.update(values)
3441- fixed_ip_ref.save(session=self._session)
3442-
3443- def fixed_ip_get(self, fixed_ip_id):
3444- result = self._session.query(self.fixed_ip_dto_class).\
3445- filter_by(deleted=False).\
3446- filter_by(id=fixed_ip_id).\
3447- first()
3448-
3449- if not result:
3450- raise exception.NotFound(_("No Fixed IP with id %s") % id)
3451-
3452- return result
3453-
3454- def fixed_ip_get_all(self):
3455- result = self._session.query(self.fixed_ip_dto_class).all()
3456- if not result:
3457- raise exception.NotFound(_('No fixed ips defined'))
3458-
3459- return result
3460-
3461- def network_get_associated_fixed_ips(self, network_id):
3462- if not self._is_admin:
3463- raise exception.NotAuthorized()
3464- return self._session.query(self.fixed_ip_dto_class).\
3465- options(joinedload_all('ethernet_card')).\
3466- filter_by(network_id=network_id).\
3467- filter(self.fixed_ip_dto_class.ethernet_card_id != None).\
3468- filter_by(deleted=False).\
3469- all()
3470-
3471- network_get_associated_ips = network_get_associated_fixed_ips
3472-
3473- def fixed_ip_get_by_address(self, address):
3474- result = self._session.query(self.fixed_ip_dto_class).\
3475- filter_by(address=address).\
3476- filter_by(deleted=self._can_read_deleted).\
3477- options(joinedload('network')).\
3478- options(joinedload('ethernet_card')).\
3479- first()
3480- if not result:
3481- raise exception.NotFound(_('No fixed ip for address %s') % address)
3482-
3483- return result
3484-
3485- def fixed_ip_disassociate(self, fixed_ip_id):
3486- with self._session.begin():
3487- fixed_ip_ref = self.fixed_ip_get(fixed_ip_id)
3488- fixed_ip_ref.ethernet_card = None
3489- fixed_ip_ref.save(session=self._session)
3490-
3491- def fixed_ip_get_by_ethernet_card(self, ethernet_card_id):
3492- result = self._session.query(self.fixed_ip_dto_class).\
3493- filter_by(ethernet_card_id=ethernet_card_id).\
3494- filter_by(deleted=self._can_read_deleted).\
3495- first()
3496- return result
3497-
3498-
3499-class FloatingIpDataAccess(flat_models.DataAccess):
3500- """A Data Access Object to access floating IPs.
3501- """
3502-
3503- floating_ip_dto_class = FloatingIp
3504-
3505- def floating_ip_allocate_address(self, host, project_id):
3506- # TODO: Check authorizations much earlier before calling
3507- # this. Doing that in DB layer is way too late.
3508- # nova_api.authorize_project_context(context, project_id)
3509- with self._session.begin():
3510- floating_ip_ref = self._session.query(self.floating_ip_dto_class).\
3511- filter_by(host=host).\
3512- filter_by(fixed_ip_id=None).\
3513- filter_by(project_id=None).\
3514- filter_by(deleted=False).\
3515- with_lockmode('update').\
3516- first()
3517- # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
3518- # then this has concurrency issues
3519- if not floating_ip_ref:
3520- raise nova_db.NoMoreAddresses()
3521- floating_ip_ref['project_id'] = project_id
3522- self._session.add(floating_ip_ref)
3523- return floating_ip_ref['address']
3524-
3525- def floating_ip_count_by_project(self, project_id):
3526- # TODO: Check authorizations much earlier before calling
3527- # this. Doing that in DB layer is way too late.
3528- # nova_api.authorize_project_context(context, project_id)
3529- return self._session.query(self.floating_ip_dto_class).\
3530- filter_by(project_id=project_id).\
3531- filter_by(deleted=False).\
3532- count()
3533-
3534- def floating_ip_deallocate(self, address):
3535- with self._session.begin():
3536- # TODO(devcamcar): How to ensure floating id belongs to user?
3537- floating_ip_ref = self.floating_ip_get_by_address(address)
3538- floating_ip_ref['project_id'] = None
3539- floating_ip_ref.save(session=self._session)
3540-
3541- def floating_ip_destroy(self, address):
3542- with self._session.begin():
3543- # TODO(devcamcar): Ensure address belongs to user.
3544- floating_ip_ref = self.floating_ip_get_by_address(address)
3545- floating_ip_ref.delete(session=self._session)
3546-
3547- def floating_ip_disassociate_by_address(self, address):
3548- with self._session.begin():
3549- # TODO(devcamcar): Ensure address belongs to user.
3550- # Does get_floating_ip_by_address handle this?
3551- floating_ip_ref = self.floating_ip_get_by_address(address)
3552- fixed_ip_ref = floating_ip_ref.fixed_ip
3553- if fixed_ip_ref:
3554- fixed_ip_address = fixed_ip_ref['address']
3555- else:
3556- fixed_ip_address = None
3557- floating_ip_ref.fixed_ip = None
3558- floating_ip_ref.save(session=self._session)
3559- return fixed_ip_address
3560-
3561- def floating_ip_get_all(self):
3562- if not self._is_admin:
3563- raise exception.NotAuthorized()
3564- return self._session.query(self.floating_ip_dto_class).\
3565- options(joinedload_all('fixed_ip.ethernet_card')).\
3566- filter_by(deleted=False).\
3567- all()
3568-
3569- def floating_ip_get_all_by_project(self, project_id):
3570- # TODO: Check authorizations much earlier before calling
3571- # this. Doing that in DB layer is way too late.
3572- # nova_api.authorize_project_context(context, project_id)
3573- return self._session.query(self.floating_ip_dto_class).\
3574- options(joinedload_all('fixed_ip.ethernet_card')).\
3575- filter_by(project_id=project_id).\
3576- filter_by(deleted=False).\
3577- all()
3578-
3579- def floating_ip_get_by_address(self, address):
3580- # TODO(devcamcar): Ensure the address belongs to user.
3581- result = session.query(self.floating_ip_dto_class).\
3582- options(joinedload_all('fixed_ip.network')).\
3583- filter_by(address=address).\
3584- filter_by(deleted=self._can_read_deleted).\
3585- first()
3586- if not result:
3587- raise exception.NotFound('No floating ip for address %s' % address)
3588-
3589- return result
3590-
3591- def floating_ip_update(self, address, values):
3592- with self._session.begin():
3593- floating_ip_ref = self.floating_ip_get_by_address(address)
3594- for (key, value) in values.iteritems():
3595- floating_ip_ref[key] = value
3596- floating_ip_ref.save(session=self._session)
3597-
3598- def floating_ip_create(self, values):
3599- floating_ip_ref = self.floating_ip_dto_class()
3600- floating_ip_ref.update(values)
3601- floating_ip_ref.save(session=self._session)
3602- return floating_ip_ref
3603-
3604- def floating_ip_disassociate(self, address):
3605- with self._session.begin():
3606- # TODO(devcamcar): Ensure address belongs to user.
3607- # Does get_floating_ip_by_address handle this?
3608- floating_ip_ref = self.floating_ip_get_by_address(address)
3609- fixed_ip_ref = floating_ip_ref.fixed_ip
3610- if fixed_ip_ref:
3611- fixed_ip_address = fixed_ip_ref['address']
3612- else:
3613- fixed_ip_address = None
3614- floating_ip_ref.fixed_ip = None
3615- floating_ip_ref.save(session=self._session)
3616- return fixed_ip_address
3617-
3618- def floating_ip_get_all_by_host(self, host):
3619- if not self._is_admin:
3620- raise exception.NotAuthorized()
3621- return self._session.query(self.floating_ip_dto_class).\
3622- options(joinedload_all('fixed_ip.ethernet_card')).\
3623- filter_by(host=host).\
3624- filter_by(deleted=False).\
3625- all()
3626-
3627-
3628-class FlatDhcpNetworkDataAccess(
3629- EthernetCardDataAccess, NetworkDataAccess, FixedIpDataAccess,
3630- FloatingIpDataAccess):
3631- """A Data Access Object to access all data for the flat DHCP network
3632- service.
3633-
3634- Also access fixed IP address associations.
3635- """
3636-
3637- def floating_ip_fixed_ip_associate(self, floating_address, fixed_address):
3638- with self._session.begin():
3639- # TODO(devcamcar): How to ensure floating_id belongs to user?
3640- floating_ip_ref = self.floating_ip_get_by_address(floating_address)
3641- fixed_ip_ref = self.fixed_ip_get_by_address(fixed_address)
3642- floating_ip_ref.fixed_ip = fixed_ip_ref
3643- floating_ip_ref.save(session=self._session)
3644-
3645- def fixed_ip_associate_pool(self, network_id, ethernet_card_id):
3646- if not self._is_admin:
3647- raise exception.NotAuthorized()
3648- with self._session.begin():
3649- network_or_none = or_(
3650- self.fixed_ip_dto_class.network_id == network_id,
3651- self.fixed_ip_dto_class.network_id == None)
3652- ip_ref = self._session.query(self.fixed_ip_dto_class).\
3653- filter(network_or_none).\
3654- filter_by(reserved=False).\
3655- filter_by(deleted=False).\
3656- filter_by(ethernet_card=None).\
3657- with_lockmode('update').\
3658- first()
3659- if not ip_ref:
3660- raise nova_db.NoMoreAddresses()
3661- if not ip_ref.network:
3662- ip_ref.network = self.network_get(network_id)
3663- ip_ref.ethernet_card = self.ethernet_card_get(ethernet_card_id)
3664- self._session.add(ip_ref)
3665- return ip_ref
3666
3667=== removed file 'nova/network/flat_dhcp/db/sqlalchemy/session.py'
3668--- nova/network/flat_dhcp/db/sqlalchemy/session.py 2011-03-24 10:27:45 +0000
3669+++ nova/network/flat_dhcp/db/sqlalchemy/session.py 1970-01-01 00:00:00 +0000
3670@@ -1,63 +0,0 @@
3671-# vim: tabstop=4 shiftwidth=4 softtabstop=4
3672-
3673-# Copyright (c) 2011 NTT.
3674-# All Rights Reserved.
3675-#
3676-# Licensed under the Apache License, Version 2.0 (the "License"); you may
3677-# not use this file except in compliance with the License. You may obtain
3678-# a copy of the License at
3679-#
3680-# http://www.apache.org/licenses/LICENSE-2.0
3681-#
3682-# Unless required by applicable law or agreed to in writing, software
3683-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
3684-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
3685-# License for the specific language governing permissions and limitations
3686-# under the License.
3687-"""
3688-Session Handling for SQLAlchemy backend
3689-"""
3690-
3691-from sqlalchemy import create_engine
3692-from sqlalchemy import pool
3693-from sqlalchemy.orm import sessionmaker
3694-
3695-from nova import exception
3696-from nova import flags
3697-
3698-FLAGS = flags.FLAGS
3699-flags.DEFINE_integer('ns_flat_dhcp_sql_idle_timeout',
3700- 3600,
3701- 'timeout for idle sql database connections')
3702-flags.DEFINE_string('ns_flat_dhcp_sql_connection',
3703- 'sqlite:///$state_path/nova_flat_dhcp_network.sqlite',
3704- 'connection string for flat DHCP network sql database')
3705-
3706-_FLAT_DHCP_NETWORK_ENGINE = None
3707-_FLAT_DHCP_NETWORK_MAKER = None
3708-
3709-def get_session(autocommit=True, expire_on_commit=False):
3710- """Helper method to grab session"""
3711- global _FLAT_DHCP_NETWORK_ENGINE
3712- global _FLAT_DHCP_NETWORK_MAKER
3713- if not _FLAT_DHCP_NETWORK_MAKER:
3714- if not _FLAT_DHCP_NETWORK_ENGINE:
3715- kwargs = {'pool_recycle': FLAGS.ns_flat_dhcp_sql_idle_timeout,
3716- 'echo': False}
3717-
3718- if FLAGS.ns_flat_dhcp_sql_connection.startswith('sqlite'):
3719- kwargs['poolclass'] = pool.NullPool
3720-
3721- _FLAT_DHCP_NETWORK_ENGINE = create_engine(
3722- FLAGS.ns_flat_dhcp_sql_connection,
3723- **kwargs)
3724-
3725- _FLAT_DHCP_NETWORK_MAKER = (sessionmaker(
3726- bind=_FLAT_DHCP_NETWORK_ENGINE,
3727- autocommit=autocommit,
3728- expire_on_commit=expire_on_commit))
3729-
3730- session = _FLAT_DHCP_NETWORK_MAKER()
3731- session.query = exception.wrap_db_error(session.query)
3732- session.flush = exception.wrap_db_error(session.flush)
3733- return session
3734
3735=== removed file 'nova/network/flat_dhcp/dhcp.py'
3736--- nova/network/flat_dhcp/dhcp.py 2011-03-31 09:36:36 +0000
3737+++ nova/network/flat_dhcp/dhcp.py 1970-01-01 00:00:00 +0000
3738@@ -1,80 +0,0 @@
3739-# vim: tabstop=4 shiftwidth=4 softtabstop=4
3740-
3741-# Copyright (c) 2011 NTT.
3742-# All Rights Reserved.
3743-#
3744-# Licensed under the Apache License, Version 2.0 (the "License"); you may
3745-# not use this file except in compliance with the License. You may obtain
3746-# a copy of the License at
3747-#
3748-# http://www.apache.org/licenses/LICENSE-2.0
3749-#
3750-# Unless required by applicable law or agreed to in writing, software
3751-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
3752-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
3753-# License for the specific language governing permissions and limitations
3754-# under the License.
3755-
3756-from nova import context
3757-from nova import flags
3758-from nova import log as logging
3759-from nova import rpc
3760-
3761-from nova.network.flat_dhcp.network import NetworkService
3762-
3763-FLAGS = flags.FLAGS
3764-
3765-LOG = logging.getLogger('nova.dhcpbridge-flat-dhcp')
3766-
3767-class DHCPEventHandler(object):
3768-
3769- @classmethod
3770- def init_leases(cls, interface):
3771- """Get the list of hosts for an interface."""
3772- ctxt = context.get_admin_context()
3773- if FLAGS.fake_rabbit:
3774- LOG.debug(_("initializing leases"))
3775- return NetworkService().get_dhcp_host_leases(ctxt, interface)
3776- else:
3777- return rpc.call(ctxt,
3778- "%s.%s" % (FLAGS.ns_flat_dhcp_network_topic,
3779- FLAGS.host),
3780- {"method": "get_dhcp_host_leases",
3781- "args": {"interface": interface}})
3782-
3783- @classmethod
3784- def add_lease(cls, mac, ip_address, _hostname, _interface):
3785- """Set the IP that was assigned by the DHCP server."""
3786- ctxt = context.get_admin_context()
3787- if FLAGS.fake_rabbit:
3788- LOG.debug(_("leasing ip"))
3789- return NetworkService().lease_fixed_ip(ctxt, mac, ip_address)
3790- else:
3791- rpc.cast(ctxt,
3792- "%s.%s" % (FLAGS.ns_flat_dhcp_network_topic,
3793- FLAGS.host),
3794- {"method": "lease_fixed_ip",
3795- "args": {"mac": mac,
3796- "address": ip_address}})
3797-
3798- @classmethod
3799- def old_lease(cls, mac, ip_address, hostname, interface):
3800- """Update just as add lease."""
3801- LOG.debug(_("Adopted old lease or got a change of mac/hostname"))
3802- cls.add_lease(mac, ip_address, hostname, interface)
3803-
3804- @classmethod
3805- def del_lease(cls, mac, ip_address, _hostname, _interface):
3806- """Called when a lease expires."""
3807- ctxt = context.get_admin_context()
3808- if FLAGS.fake_rabbit:
3809- LOG.debug(_("releasing ip"))
3810- NetworkService().release_fixed_ip(ctxt, mac, ip_address)
3811- else:
3812- rpc.cast(ctxt,
3813- "%s.%s" % (FLAGS.ns_flat_dhcp_network_topic,
3814- FLAGS.host),
3815- {"method": "release_fixed_ip",
3816- "args": {"mac": mac,
3817- "address": ip_address}})
3818-
3819
3820=== removed file 'nova/network/flat_dhcp/network.py'
3821--- nova/network/flat_dhcp/network.py 2011-03-24 10:27:45 +0000
3822+++ nova/network/flat_dhcp/network.py 1970-01-01 00:00:00 +0000
3823@@ -1,255 +0,0 @@
3824-# vim: tabstop=4 shiftwidth=4 softtabstop=4
3825-
3826-# Copyright (c) 2011 NTT.
3827-# All Rights Reserved.
3828-#
3829-# Licensed under the Apache License, Version 2.0 (the "License"); you may
3830-# not use this file except in compliance with the License. You may obtain
3831-# a copy of the License at
3832-#
3833-# http://www.apache.org/licenses/LICENSE-2.0
3834-#
3835-# Unless required by applicable law or agreed to in writing, software
3836-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
3837-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
3838-# License for the specific language governing permissions and limitations
3839-# under the License.
3840-
3841-import collections
3842-import os
3843-
3844-from nova import context
3845-from nova import flags
3846-from nova import log as logging
3847-from nova import manager
3848-from nova import utils
3849-from nova.db import api as nova_db_api
3850-from nova.network.flat_dhcp.db import manager as db_manager
3851-
3852-def _bin_file(script):
3853- """Return the absolute path to scipt in the bin directory"""
3854- return os.path.abspath(os.path.join(__file__, "../../../../bin", script))
3855-
3856-FLAGS = flags.FLAGS
3857-flags.DEFINE_string('ns_flat_dhcp_network_driver', 'nova.network.linux_net',
3858- 'Driver to use for network creation')
3859-flags.DEFINE_string('ns_flat_dhcp_dhcp_driver', 'nova.network.linux_dhcp',
3860- 'Driver to use for DHCP')
3861-flags.DEFINE_string('ns_flat_dhcp_ra_driver', 'nova.network.linux_ra',
3862- 'Driver to use for RA')
3863-flags.DEFINE_string('ns_flat_dhcp_network_dhcp_start', '10.0.0.2',
3864- 'Dhcp start for FlatDhcp')
3865-flags.DEFINE_string('ns_flat_dhcp_interface', None,
3866- 'FlatDhcp will bridge into this interface if set')
3867-flags.DEFINE_string('ns_flat_dhcp_dhcpbridge',
3868- _bin_file('nova-dhcpbridge-flat-dhcp'),
3869- 'location of nova-dhcpbridge')
3870-flags.DEFINE_string('ns_flat_dhcp_dhcpbridge_flagfile',
3871- '/etc/nova/nova-dhcpbridge.conf',
3872- 'location of flagfile for dhcpbridge')
3873-flags.DEFINE_bool('ns_flat_dhcp_update_dhcp_on_disassociate', False,
3874- 'Whether to update dhcp when fixed_ip is disassociated')
3875-
3876-LOG = logging.getLogger("nova.net_dhcp")
3877-
3878-DhcpHost = collections.namedtuple('DhcpHost',
3879- 'mac_address, hostname, ip_address, timestamp')
3880-
3881-class NetworkService(manager.Manager):
3882-
3883- def __init__(self, network_driver=None, dhcp_driver=None, ra_driver=None,
3884- *args, **kwargs):
3885- """Initializes flat network service."""
3886- if not network_driver:
3887- network_driver = FLAGS.ns_flat_dhcp_network_driver
3888- if not dhcp_driver:
3889- dhcp_driver = FLAGS.ns_flat_dhcp_dhcp_driver
3890- if not ra_driver:
3891- ra_driver = FLAGS.ns_flat_dhcp_ra_driver
3892-
3893- kwargs['db_driver'] = 'nova.network.flat_dhcp.db.api'
3894- self.driver = utils.import_object(network_driver)
3895- self.dhcp_driver = utils.import_object(dhcp_driver)
3896- self.ra_driver = utils.import_object(ra_driver)
3897- super(NetworkService, self).__init__(*args, **kwargs)
3898-
3899- def init_host(self):
3900- """Do any initialization that needs to be run if this is a
3901- standalone service.
3902- """
3903- self.driver.init_host()
3904- # Set up networking for the projects for which we're already
3905- # the designated network host.
3906- ctxt = context.get_admin_context()
3907- for network in self.db.host_get_networks(ctxt, self.host):
3908- self.set_network_host(ctxt, network['id'])
3909- floating_ips = self.db.floating_ip_get_all_by_host(ctxt,
3910- self.host)
3911- for floating_ip in floating_ips:
3912- if floating_ip.get('fixed_ip', None):
3913- fixed_address = floating_ip['fixed_ip']['address']
3914- # NOTE(vish): The False here is because we ignore the case
3915- # that the ip is already bound.
3916- self.driver.bind_floating_ip(floating_ip['address'], False)
3917- self.driver.ensure_floating_forward(floating_ip['address'],
3918- fixed_address)
3919- self.driver.metadata_forward()
3920-
3921- def set_network_host(self, context, network_id):
3922- """Called when this host becomes the host for a project."""
3923- net = {}
3924- net['host'] = self.host
3925- net['dhcp_start'] = FLAGS.ns_flat_dhcp_network_dhcp_start
3926- self.db.network_update(context, network_id, net)
3927-
3928- network_ref = self.db.network_get(context, network_id)
3929- bridge = network_ref['bridge']
3930- self.driver.ensure_bridge(bridge,
3931- FLAGS.ns_flat_dhcp_interface,
3932- network_ref)
3933- if not FLAGS.fake_network:
3934- hosts = self._get_dhcp_hosts(context, network_id)
3935- self.dhcp_driver.update_dhcp(bridge,
3936- network_ref['gateway'],
3937- network_ref['dhcp_start'],
3938- hosts,
3939- dhcp_script=FLAGS.\
3940- ns_flat_dhcp_dhcpbridge)
3941- if(FLAGS.use_ipv6):
3942- self.ra_driver.update_ra(bridge,
3943- network_ref['cidr_v6'])
3944- self.db.network_update(context, network_id,
3945- {"ra_server":
3946- utils.get_my_linklocal(bridge)})
3947-
3948- def _get_dhcp_hosts(self, context, network_id):
3949- """Get a list containing a network's hosts"""
3950- hosts = []
3951- for fixed_ip_ref in self.db.\
3952- network_get_associated_fixed_ips(context,
3953- network_id):
3954- ethernet_card = fixed_ip_ref['ethernet_card']
3955- instance = nova_db_api.\
3956- instance_get_by_virtual_nic(context,
3957- ethernet_card['id'])
3958- if instance:
3959- hosts.append(DhcpHost(mac_address=ethernet_card['mac_address'],
3960- hostname=instance['hostname'],
3961- ip_address=fixed_ip_ref['address'],
3962- timestamp=None))
3963- return hosts
3964-
3965-
3966- def allocate_fixed_ips(self, context, vnic_ids):
3967- """Gets a fixed ip from the pool."""
3968- for vnic_id in vnic_ids:
3969- ip_address = db_manager.bind_ip_to_ethernet_card(context, vnic_id)
3970-
3971- if not FLAGS.fake_network:
3972- network_id = ip_address['network_id']
3973- network_ref = self.db.network_get(context, network_id)
3974- hosts = self._get_dhcp_hosts(context, network_id)
3975- self.dhcp_driver.update_dhcp(network_ref['bridge'],
3976- network_ref['gateway'],
3977- network_ref['dhcp_start'],
3978- hosts,
3979- dhcp_script=FLAGS.\
3980- ns_flat_dhcp_dhcpbridge)
3981-
3982- def lease_fixed_ip(self, context, mac, address):
3983- """Called by dhcp-bridge when ip is leased."""
3984- LOG.debug(_("Leasing IP %s"), address, context=context)
3985- fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
3986- ethernet_card = fixed_ip_ref['ethernet_card']
3987- instance = nova_db_api.instance_get_by_virtual_nic(context,
3988- ethernet_card['id'])
3989- if not instance:
3990- raise exception.Error(_("IP %s leased that isn't associated") %
3991- address)
3992-
3993- if nova_db_api.is_user_context(context):
3994- # Get the project for this IP
3995- nova_db_api.authorize_project_context(context, instance.project_id)
3996-
3997- if ethernet_card['mac_address'] != mac:
3998- raise exception.Error(_("IP %(address)s leased to bad"
3999- " mac %s vs %s") % (ethernet_card['mac_address'], mac))
4000- now = datetime.datetime.utcnow()
4001- self.db.fixed_ip_update(context,
4002- fixed_ip_ref['id'],
4003- {'leased': True,
4004- 'updated_at': now})
4005- if not fixed_ip_ref['allocated']:
4006- LOG.warn(_("IP %s leased that was already deallocated"), address,
4007- context=context)
4008-
4009- def get_dhcp_host_leases(self, context, interface):
4010- """Gets a list of leased hosts."""
4011- network_ref = self.db.network_get_by_bridge(context, interface)
4012- hosts = []
4013- for fixed_ip_ref in self.db.\
4014- network_get_associated_fixed_ips(context,
4015- network_ref['id']):
4016- ethernet_card = fixed_ip_ref['ethernet_card']
4017- instance = nova_db_api.\
4018- instance_get_by_virtual_nic(context,
4019- ethernet_card['id'])
4020-
4021- if instance['updated_at']:
4022- timestamp = instance['updated_at']
4023- else:
4024- timestamp = instance['created_at']
4025-
4026- hosts.append(DhcpHost(mac_address=ethernet_card['mac_address'],
4027- hostname=instance['hostname'],
4028- ip_address=fixed_ip_ref['address'],
4029- timestamp=timestamp))
4030- return self.dhcp_driver.get_dhcp_leases(hosts)
4031-
4032- def release_fixed_ip(self, context, mac, address):
4033- """Called by dhcp-bridge when ip is released."""
4034- LOG.debug(_("Releasing IP %s"), address, context=context)
4035- fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
4036- ethernet_card = fixed_ip_ref['ethernet_card']
4037- instance = nova_db_api.instance_get_by_virtual_nic(context,
4038- ethernet_card['id'])
4039- if not instance:
4040- raise exception.Error(_("IP %s released that isn't associated") %
4041- address)
4042-
4043- if nova_db_api.is_user_context(context):
4044- # Get the project for this IP
4045- nova_db_api.authorize_project_context(context, instance.project_id)
4046-
4047- if ethernet_card['mac_address'] != mac:
4048- raise exception.Error(_("IP %(address)s leased to bad"
4049- " mac %s vs %s") % (ethernet_card['mac_address'], mac))
4050-
4051- if not fixed_ip_ref['leased']:
4052- LOG.warn(_("IP %s released that was not leased"), address,
4053- context=context)
4054- self.db.fixed_ip_update(context,
4055- fixed_ip_ref['address'],
4056- {'leased': False})
4057- if not fixed_ip_ref['allocated']:
4058- self.db.fixed_ip_disassociate(context, fixed_ip_ref['id'])
4059- # NOTE(vish): dhcp server isn't updated until next setup, this
4060- # means there will stale entries in the conf file
4061- # the code below will update the file if necessary
4062- if FLAGS.ns_flat_dhcp_update_dhcp_on_disassociate:
4063- network_ref = fixed_ip['network']
4064- hosts = self._get_dhcp_hosts(context, network_ref['id'])
4065- self.dhcp_driver.update_dhcp(network_ref['bridge'],
4066- network_ref['gateway'],
4067- network_ref['dhcp_start'],
4068- hosts,
4069- dhcp_script=FLAGS.\
4070- ns_flat_dhcp_dhcpbridge)
4071-
4072- def disassociate_floating_ip(self, context, floating_address):
4073- """Disassociates a floating ip."""
4074- fixed_address = self.db.floating_ip_disassociate(context,
4075- floating_address)
4076- self.driver.unbind_floating_ip(floating_address)
4077- self.driver.remove_floating_forward(floating_address, fixed_address)
4078-
4079
4080=== modified file 'nova/network/flat_vlan/compute.py'
4081--- nova/network/flat_vlan/compute.py 2011-03-31 09:36:57 +0000
4082+++ nova/network/flat_vlan/compute.py 2011-04-04 00:58:27 +0000
4083@@ -125,8 +125,8 @@
4084 is_vpn: Boolean to check if the call is for VPN.
4085 """
4086 if FLAGS.net_flat_vlan_use_vlan or FLAGS.net_flat_vlan_use_dhcp:
4087- driver = utils.import_object(
4088- FLAGS.net_flat_vlan_network_agent_driver)
4089+ driver = utils.import_object(FLAGS.net_flat_vlan_network_driver)
4090+ filter_drv = utils.import_object(FLAGS.net_flat_vlan_filter_driver)
4091 for vnic_id in vnic_ids:
4092 network_ref = db_api.network_get_by_ethernet_card(context,
4093 vnic_id)
4094@@ -137,7 +137,8 @@
4095 else:
4096 driver.ensure_bridge(network_ref['bridge'],
4097 FLAGS.net_flat_vlan_dhcp_agent_interface)
4098-
4099+ filter_drv.ensure_bridge_forward(bridge)
4100+
4101 def teardown_compute_network(self, context, vnic_ids):
4102 """Clean up the compute node.
4103
4104
4105=== modified file 'nova/network/flat_vlan/db/api.py'
4106--- nova/network/flat_vlan/db/api.py 2011-03-31 06:18:29 +0000
4107+++ nova/network/flat_vlan/db/api.py 2011-04-04 00:58:27 +0000
4108@@ -24,7 +24,7 @@
4109
4110 FLAGS = flags.FlagAccessor()
4111
4112-IMPL = utils.LazyPluggable(FLAGS.net_flat_vlan_db_backend,
4113+IMPL = utils.LazyPluggable(FLAGS.get('net_flat_vlan_db_backend'),
4114 sqlalchemy='nova.network.flat_vlan.db.sqlalchemy.api')
4115
4116 ###################
4117@@ -246,3 +246,9 @@
4118 """Associates an IP to an ethernet card."""
4119 return IMPL.dao_factory.get_dao(context).\
4120 fixed_ip_associate_pool(network_id, ethernet_card_id)
4121+
4122+def fixed_ip_disassociate_all_by_timeout(context, host, time):
4123+ """Disassociates fixed IP by timeout."""
4124+ return IMPL.dao_factory.get_dao(context).\
4125+ fixed_ip_disassociate_all_by_timeout(host, time)
4126+
4127\ No newline at end of file
4128
4129=== modified file 'nova/network/flat_vlan/db/sqlalchemy/api.py'
4130--- nova/network/flat_vlan/db/sqlalchemy/api.py 2011-03-31 06:18:29 +0000
4131+++ nova/network/flat_vlan/db/sqlalchemy/api.py 2011-04-04 00:58:27 +0000
4132@@ -26,7 +26,6 @@
4133 from nova import exception
4134 from nova.db import api as nova_db
4135 from nova.db.sqlalchemy import api as nova_api
4136-from nova.network.flat_vlan.db.sqlalchemy import api
4137 from nova.network.flat_vlan.db.sqlalchemy import models
4138 from nova.network.flat_vlan.db.sqlalchemy.session import get_session
4139
4140@@ -74,8 +73,7 @@
4141 """
4142
4143 def __init__(self):
4144- self._dao_cache = api.DataAccessCache(
4145- models.FlatVlanNetworkDataAccess)
4146+ self._dao_cache = DataAccessCache(models.FlatVlanNetworkDataAccess)
4147 self._session = None
4148
4149 def get_session(self):
4150
4151=== modified file 'nova/network/flat_vlan/db/sqlalchemy/models.py'
4152--- nova/network/flat_vlan/db/sqlalchemy/models.py 2011-03-31 06:18:29 +0000
4153+++ nova/network/flat_vlan/db/sqlalchemy/models.py 2011-04-04 00:58:27 +0000
4154@@ -19,7 +19,7 @@
4155 """
4156 from sqlalchemy import or_
4157 from sqlalchemy.orm import relationship, backref
4158-from sqlalchemy.orm import joinedload
4159+from sqlalchemy.orm import joinedload, joinedload_all
4160 from sqlalchemy import Column, Boolean, Integer, String
4161 from sqlalchemy import ForeignKey
4162 from sqlalchemy.ext.declarative import declarative_base
4163@@ -309,6 +309,20 @@
4164 first()
4165 return result
4166
4167+ def fixed_ip_disassociate_all_by_timeout(self, host, time):
4168+ if not self._is_admin:
4169+ raise exception.NotAuthorized()
4170+ inner_q = self._session.query(Network.id).\
4171+ filter_by(host=host).\
4172+ subquery()
4173+ result = self._session.query(self.fixed_ip_dto_class).\
4174+ filter(self.fixed_ip_dto_class.network_id.in_(inner_q)).\
4175+ filter(self.fixed_ip_dto_class.updated_at < time).\
4176+ filter(self.fixed_ip_dto_class.ethernet_card_id != None).\
4177+ filter_by(allocated=0).\
4178+ update({'ethernet_card_id': None,
4179+ 'leased': 0}, synchronize_session='fetch')
4180+ return result
4181
4182 class FloatingIpDataAccess(DataAccess):
4183 """A Data Access Object to access floating IPs.
4184
4185=== added directory 'nova/network/flat_vlan/driver'
4186=== added file 'nova/network/flat_vlan/driver/__init__.py'
4187--- nova/network/flat_vlan/driver/__init__.py 1970-01-01 00:00:00 +0000
4188+++ nova/network/flat_vlan/driver/__init__.py 2011-04-04 00:58:27 +0000
4189@@ -0,0 +1,16 @@
4190+# vim: tabstop=4 shiftwidth=4 softtabstop=4
4191+
4192+# Copyright 2011 Midokura KK
4193+# All Rights Reserved.
4194+#
4195+# Licensed under the Apache License, Version 2.0 (the "License"); you may
4196+# not use this file except in compliance with the License. You may obtain
4197+# a copy of the License at
4198+#
4199+# http://www.apache.org/licenses/LICENSE-2.0
4200+#
4201+# Unless required by applicable law or agreed to in writing, software
4202+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
4203+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
4204+# License for the specific language governing permissions and limitations
4205+# under the License.
4206\ No newline at end of file
4207
4208=== added directory 'nova/network/flat_vlan/driver/linux'
4209=== added file 'nova/network/flat_vlan/driver/linux/__init__.py'
4210--- nova/network/flat_vlan/driver/linux/__init__.py 1970-01-01 00:00:00 +0000
4211+++ nova/network/flat_vlan/driver/linux/__init__.py 2011-04-04 00:58:27 +0000
4212@@ -0,0 +1,16 @@
4213+# vim: tabstop=4 shiftwidth=4 softtabstop=4
4214+
4215+# Copyright 2011 Midokura KK
4216+# All Rights Reserved.
4217+#
4218+# Licensed under the Apache License, Version 2.0 (the "License"); you may
4219+# not use this file except in compliance with the License. You may obtain
4220+# a copy of the License at
4221+#
4222+# http://www.apache.org/licenses/LICENSE-2.0
4223+#
4224+# Unless required by applicable law or agreed to in writing, software
4225+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
4226+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
4227+# License for the specific language governing permissions and limitations
4228+# under the License.
4229\ No newline at end of file
4230
4231=== added file 'nova/network/flat_vlan/driver/linux/dhcp.py'
4232--- nova/network/flat_vlan/driver/linux/dhcp.py 1970-01-01 00:00:00 +0000
4233+++ nova/network/flat_vlan/driver/linux/dhcp.py 2011-04-04 00:58:27 +0000
4234@@ -0,0 +1,151 @@
4235+# vim: tabstop=4 shiftwidth=4 softtabstop=4
4236+
4237+# Copyright (c) 2011 NTT.
4238+# All Rights Reserved.
4239+#
4240+# Licensed under the Apache License, Version 2.0 (the "License"); you may
4241+# not use this file except in compliance with the License. You may obtain
4242+# a copy of the License at
4243+#
4244+# http://www.apache.org/licenses/LICENSE-2.0
4245+#
4246+# Unless required by applicable law or agreed to in writing, software
4247+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
4248+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
4249+# License for the specific language governing permissions and limitations
4250+# under the License.
4251+import calendar
4252+import os
4253+
4254+from nova import log as logging
4255+from nova import utils
4256+
4257+from nova.network.flat_vlan import flags
4258+
4259+LOG = logging.getLogger("nova.flat_vlan_linux_dhcp")
4260+FLAGS = flags.FlagAccessor()
4261+
4262+def _dhcp_file(bridge, kind):
4263+ """Return path to a pid, leases or conf file for a bridge"""
4264+ if not os.path.exists(FLAGS.net_flat_vlan_networks_path):
4265+ os.makedirs(FLAGS.net_flat_vlan_networks_path)
4266+ return os.path.abspath("%s/nova-%s.%s" % (FLAGS.net_flat_vlan_networks_path,
4267+ bridge,
4268+ kind))
4269+
4270+def _dnsmasq_cmd(bridge, gateway, dhcp_start, dhcp_script):
4271+ """Builds dnsmasq command"""
4272+ cmd = ['sudo', '-E', 'dnsmasq',
4273+ '--strict-order',
4274+ '--bind-interfaces',
4275+ '--conf-file=',
4276+ '--domain=%s' % FLAGS.net_flat_vlan_dhcp_domain,
4277+ '--pid-file=%s' % _dhcp_file(bridge, 'pid'),
4278+ '--listen-address=%s' % gateway,
4279+ '--except-interface=lo',
4280+ '--dhcp-range=%s,static,120s' % dhcp_start,
4281+ '--dhcp-hostsfile=%s' % _dhcp_file(bridge, 'conf'),
4282+ '--dhcp-script=%s' % dhcp_script,
4283+ '--leasefile-ro']
4284+ if FLAGS.net_flat_vlan_dns_server:
4285+ cmd += ['-h', '-R', '--server=%s' % FLAGS.net_flat_vlan_dns_server]
4286+ return cmd
4287+
4288+def _dnsmasq_pid_for(bridge):
4289+ """Returns the pid for prior dnsmasq instance for a bridge
4290+
4291+ Returns None if no pid file exists
4292+
4293+ If machine has rebooted pid might be incorrect (caller should check)
4294+ """
4295+
4296+ pid_file = _dhcp_file(bridge, 'pid')
4297+
4298+ if os.path.exists(pid_file):
4299+ with open(pid_file, 'r') as f:
4300+ return int(f.read())
4301+
4302+def _stop_dnsmasq(bridge):
4303+ """Stops the dnsmasq instance for a given bridge"""
4304+ pid = _dnsmasq_pid_for(bridge)
4305+
4306+ if pid:
4307+ try:
4308+ _execute('sudo', 'kill', '-TERM', pid)
4309+ except Exception as exc: # pylint: disable=W0703
4310+ LOG.debug(_("Killing dnsmasq threw %s"), exc)
4311+
4312+def _execute(*cmd, **kwargs):
4313+ """Wrapper around utils._execute for fake_network"""
4314+ if FLAGS.fake_network:
4315+ LOG.debug("FAKE NET: %s", " ".join(map(str, cmd)))
4316+ return "fake", 0
4317+ else:
4318+ return utils.execute(*cmd, **kwargs)
4319+
4320+def _host_dhcp(dhcp_host):
4321+ """Return a host string for an address"""
4322+ return "%s,%s.%s,%s" % (dhcp_host.mac_address,
4323+ dhcp_host.hostname,
4324+ FLAGS.net_flat_vlan_dhcp_domain,
4325+ dhcp_host.ip_address)
4326+
4327+def _host_lease(dhcp_host):
4328+ """Return a host string for an address in leasefile format"""
4329+ seconds_since_epoch = calendar.timegm(dhcp_host.timestamp.utctimetuple())
4330+ lease_time = FLAGS.net_flat_vlan_dhcp_lease_time
4331+ return "%d %s %s %s *" % (seconds_since_epoch + lease_time,
4332+ dhcp_host.mac_address,
4333+ dhcp_host.address,
4334+ dhcp_host.hostname or '*')
4335+
4336+def get_dhcp_hosts(dhcp_hosts):
4337+ """Get a string containing a network's hosts config in dnsmasq format"""
4338+ hosts = []
4339+ for dhcp_host in dhcp_hosts:
4340+ hosts.append(_host_dhcp(dhcp_host))
4341+ return '\n'.join(hosts)
4342+
4343+def get_dhcp_leases(dhcp_hosts):
4344+ """Return a network's hosts config in dnsmasq leasefile format"""
4345+ hosts = []
4346+ for dhcp_host in dhcp_hosts:
4347+ hosts.append(_host_lease(dhcp_host))
4348+ return '\n'.join(hosts)
4349+
4350+@utils.synchronized('dnsmasq_start')
4351+def update_dhcp(bridge, gateway, dhcp_start, dhcp_hosts,
4352+ dhcp_script=FLAGS.net_flat_vlan_dhcpbridge):
4353+ """(Re)starts a dnsmasq server for a given network
4354+
4355+ if a dnsmasq instance is already running then send a HUP
4356+ signal causing it to reload, otherwise spawn a new instance
4357+ """
4358+ conffile = _dhcp_file(bridge, 'conf')
4359+ with open(conffile, 'w') as f:
4360+ f.write(get_dhcp_hosts(dhcp_hosts))
4361+
4362+ # Make sure dnsmasq can actually read it (it setuid()s to "nobody")
4363+ os.chmod(conffile, 0644)
4364+
4365+ pid = _dnsmasq_pid_for(bridge)
4366+
4367+ # if dnsmasq is already running, then tell it to reload
4368+ if pid:
4369+ out, _err = _execute('cat', "/proc/%d/cmdline" % pid,
4370+ check_exit_code=False)
4371+ if conffile in out:
4372+ try:
4373+ _execute('sudo', 'kill', '-HUP', pid)
4374+ return
4375+ except Exception as exc: # pylint: disable-msg=W0703
4376+ LOG.debug(_("Hupping dnsmasq threw %s"), exc)
4377+ else:
4378+ LOG.debug(_("Pid %d is stale, relaunching dnsmasq"), pid)
4379+
4380+ # FLAGFILE and DNSMASQ_INTERFACE in env
4381+ env = {'FLAGFILE': FLAGS.net_flat_vlan_dhcpbridge_flagfile,
4382+ 'DNSMASQ_INTERFACE': bridge}
4383+ command = _dnsmasq_cmd(bridge, gateway, dhcp_start, dhcp_script)
4384+ _execute(*command, addl_env=env)
4385+
4386
4387=== added file 'nova/network/flat_vlan/driver/linux/filter.py'
4388--- nova/network/flat_vlan/driver/linux/filter.py 1970-01-01 00:00:00 +0000
4389+++ nova/network/flat_vlan/driver/linux/filter.py 2011-04-04 00:58:27 +0000
4390@@ -0,0 +1,391 @@
4391+# vim: tabstop=4 shiftwidth=4 softtabstop=4
4392+
4393+# Copyright 2011 Midokura KK
4394+# All Rights Reserved.
4395+#
4396+# Licensed under the Apache License, Version 2.0 (the "License"); you may
4397+# not use this file except in compliance with the License. You may obtain
4398+# a copy of the License at
4399+#
4400+# http://www.apache.org/licenses/LICENSE-2.0
4401+#
4402+# Unless required by applicable law or agreed to in writing, software
4403+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
4404+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
4405+# License for the specific language governing permissions and limitations
4406+# under the License.
4407+import inspect
4408+import os
4409+
4410+from nova import log as logging
4411+from nova import utils
4412+
4413+from nova.network.flat_vlan import flags
4414+
4415+LOG = logging.getLogger("nova.flat_vlan_linux_filter")
4416+FLAGS = flags.FlagAccessor()
4417+
4418+binary_name = os.path.basename(inspect.stack()[-1][1])
4419+
4420+def _execute(*cmd, **kwargs):
4421+ """Wrapper around utils._execute for fake_network"""
4422+ if FLAGS.fake_network:
4423+ LOG.debug("FAKE NET: %s", " ".join(map(str, cmd)))
4424+ return "fake", 0
4425+ else:
4426+ return utils.execute(*cmd, **kwargs)
4427+
4428+class IptablesRule(object):
4429+ """An iptables rule
4430+
4431+ You shouldn't need to use this class directly, it's only used by
4432+ IptablesManager
4433+ """
4434+ def __init__(self, chain, rule, wrap=True, top=False):
4435+ self.chain = chain
4436+ self.rule = rule
4437+ self.wrap = wrap
4438+ self.top = top
4439+
4440+ def __eq__(self, other):
4441+ return ((self.chain == other.chain) and
4442+ (self.rule == other.rule) and
4443+ (self.top == other.top) and
4444+ (self.wrap == other.wrap))
4445+
4446+ def __ne__(self, other):
4447+ return not self == other
4448+
4449+ def __str__(self):
4450+ if self.wrap:
4451+ chain = '%s-%s' % (binary_name, self.chain)
4452+ else:
4453+ chain = self.chain
4454+ return '-A %s %s' % (chain, self.rule)
4455+
4456+
4457+class IptablesTable(object):
4458+ """An iptables table"""
4459+
4460+ def __init__(self):
4461+ self.rules = []
4462+ self.chains = set()
4463+ self.unwrapped_chains = set()
4464+
4465+ def add_chain(self, name, wrap=True):
4466+ """Adds a named chain to the table
4467+
4468+ The chain name is wrapped to be unique for the component creating
4469+ it, so different components of Nova can safely create identically
4470+ named chains without interfering with one another.
4471+
4472+ At the moment, its wrapped name is <binary name>-<chain name>,
4473+ so if nova-compute creates a chain named "OUTPUT", it'll actually
4474+ end up named "nova-compute-OUTPUT".
4475+ """
4476+ if wrap:
4477+ self.chains.add(name)
4478+ else:
4479+ self.unwrapped_chains.add(name)
4480+
4481+ def remove_chain(self, name, wrap=True):
4482+ """Remove named chain
4483+
4484+ This removal "cascades". All rule in the chain are removed, as are
4485+ all rules in other chains that jump to it.
4486+
4487+ If the chain is not found, this is merely logged.
4488+ """
4489+ if wrap:
4490+ chain_set = self.chains
4491+ else:
4492+ chain_set = self.unwrapped_chains
4493+
4494+ if name not in chain_set:
4495+ LOG.debug(_("Attempted to remove chain %s which doesn't exist"),
4496+ name)
4497+ return
4498+
4499+ chain_set.remove(name)
4500+ self.rules = filter(lambda r: r.chain != name, self.rules)
4501+
4502+ if wrap:
4503+ jump_snippet = '-j %s-%s' % (binary_name, name)
4504+ else:
4505+ jump_snippet = '-j %s' % (name,)
4506+
4507+ self.rules = filter(lambda r: jump_snippet not in r.rule, self.rules)
4508+
4509+ def add_rule(self, chain, rule, wrap=True, top=False):
4510+ """Add a rule to the table
4511+
4512+ This is just like what you'd feed to iptables, just without
4513+ the "-A <chain name>" bit at the start.
4514+
4515+ However, if you need to jump to one of your wrapped chains,
4516+ prepend its name with a '$' which will ensure the wrapping
4517+ is applied correctly.
4518+ """
4519+ if wrap and chain not in self.chains:
4520+ raise ValueError(_("Unknown chain: %r") % chain)
4521+
4522+ if '$' in rule:
4523+ rule = ' '.join(map(self._wrap_target_chain, rule.split(' ')))
4524+
4525+ self.rules.append(IptablesRule(chain, rule, wrap, top))
4526+
4527+ def _wrap_target_chain(self, s):
4528+ if s.startswith('$'):
4529+ return '%s-%s' % (binary_name, s[1:])
4530+ return s
4531+
4532+ def remove_rule(self, chain, rule, wrap=True, top=False):
4533+ """Remove a rule from a chain
4534+
4535+ Note: The rule must be exactly identical to the one that was added.
4536+ You cannot switch arguments around like you can with the iptables
4537+ CLI tool.
4538+ """
4539+ try:
4540+ self.rules.remove(IptablesRule(chain, rule, wrap, top))
4541+ except ValueError:
4542+ LOG.debug(_("Tried to remove rule that wasn't there:"
4543+ " %(chain)r %(rule)r %(wrap)r %(top)r"),
4544+ {'chain': chain, 'rule': rule,
4545+ 'top': top, 'wrap': wrap})
4546+
4547+
4548+class IptablesManager(object):
4549+ """Wrapper for iptables
4550+
4551+ See IptablesTable for some usage docs
4552+
4553+ A number of chains are set up to begin with.
4554+
4555+ First, nova-filter-top. It's added at the top of FORWARD and OUTPUT. Its
4556+ name is not wrapped, so it's shared between the various nova workers. It's
4557+ intended for rules that need to live at the top of the FORWARD and OUTPUT
4558+ chains. It's in both the ipv4 and ipv6 set of tables.
4559+
4560+ For ipv4 and ipv6, the builtin INPUT, OUTPUT, and FORWARD filter chains are
4561+ wrapped, meaning that the "real" INPUT chain has a rule that jumps to the
4562+ wrapped INPUT chain, etc. Additionally, there's a wrapped chain named
4563+ "local" which is jumped to from nova-filter-top.
4564+
4565+ For ipv4, the builtin PREROUTING, OUTPUT, and POSTROUTING nat chains are
4566+ wrapped in the same was as the builtin filter chains. Additionally, there's
4567+ a snat chain that is applied after the POSTROUTING chain.
4568+ """
4569+ def __init__(self, execute=None):
4570+ if not execute:
4571+ self.execute = _execute
4572+ else:
4573+ self.execute = execute
4574+
4575+ self.ipv4 = {'filter': IptablesTable(),
4576+ 'nat': IptablesTable()}
4577+ self.ipv6 = {'filter': IptablesTable()}
4578+
4579+ # Add a nova-filter-top chain. It's intended to be shared
4580+ # among the various nova components. It sits at the very top
4581+ # of FORWARD and OUTPUT.
4582+ for tables in [self.ipv4, self.ipv6]:
4583+ tables['filter'].add_chain('nova-filter-top', wrap=False)
4584+ tables['filter'].add_rule('FORWARD', '-j nova-filter-top',
4585+ wrap=False, top=True)
4586+ tables['filter'].add_rule('OUTPUT', '-j nova-filter-top',
4587+ wrap=False, top=True)
4588+
4589+ tables['filter'].add_chain('local')
4590+ tables['filter'].add_rule('nova-filter-top', '-j $local',
4591+ wrap=False)
4592+
4593+ # Wrap the builtin chains
4594+ builtin_chains = {4: {'filter': ['INPUT', 'OUTPUT', 'FORWARD'],
4595+ 'nat': ['PREROUTING', 'OUTPUT', 'POSTROUTING']},
4596+ 6: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}}
4597+
4598+ for ip_version in builtin_chains:
4599+ if ip_version == 4:
4600+ tables = self.ipv4
4601+ elif ip_version == 6:
4602+ tables = self.ipv6
4603+
4604+ for table, chains in builtin_chains[ip_version].iteritems():
4605+ for chain in chains:
4606+ tables[table].add_chain(chain)
4607+ tables[table].add_rule(chain, '-j $%s' % (chain,),
4608+ wrap=False)
4609+
4610+ # Add a nova-postrouting-bottom chain. It's intended to be shared
4611+ # among the various nova components. We set it as the last chain
4612+ # of POSTROUTING chain.
4613+ self.ipv4['nat'].add_chain('nova-postrouting-bottom', wrap=False)
4614+ self.ipv4['nat'].add_rule('POSTROUTING', '-j nova-postrouting-bottom',
4615+ wrap=False)
4616+
4617+ # We add a snat chain to the shared nova-postrouting-bottom chain
4618+ # so that it's applied last.
4619+ self.ipv4['nat'].add_chain('snat')
4620+ self.ipv4['nat'].add_rule('nova-postrouting-bottom', '-j $snat',
4621+ wrap=False)
4622+
4623+ # And then we add a floating-snat chain and jump to first thing in
4624+ # the snat chain.
4625+ self.ipv4['nat'].add_chain('floating-snat')
4626+ self.ipv4['nat'].add_rule('snat', '-j $floating-snat')
4627+
4628+ @utils.synchronized('iptables', external=True)
4629+ def apply(self):
4630+ """Apply the current in-memory set of iptables rules
4631+
4632+ This will blow away any rules left over from previous runs of the
4633+ same component of Nova, and replace them with our current set of
4634+ rules. This happens atomically, thanks to iptables-restore.
4635+ """
4636+ s = [('iptables', self.ipv4)]
4637+ if FLAGS.net_flat_vlan_use_ipv6:
4638+ s += [('ip6tables', self.ipv6)]
4639+
4640+ for cmd, tables in s:
4641+ for table in tables:
4642+ current_table, _ = self.execute('sudo',
4643+ '%s-save' % (cmd,),
4644+ '-t', '%s' % (table,),
4645+ attempts=5)
4646+ current_lines = current_table.split('\n')
4647+ new_filter = self._modify_rules(current_lines,
4648+ tables[table])
4649+ self.execute('sudo', '%s-restore' % (cmd,),
4650+ process_input='\n'.join(new_filter),
4651+ attempts=5)
4652+
4653+ def _modify_rules(self, current_lines, table, binary=None):
4654+ unwrapped_chains = table.unwrapped_chains
4655+ chains = table.chains
4656+ rules = table.rules
4657+
4658+ # Remove any trace of our rules
4659+ new_filter = filter(lambda line: binary_name not in line,
4660+ current_lines)
4661+
4662+ seen_chains = False
4663+ rules_index = 0
4664+ for rules_index, rule in enumerate(new_filter):
4665+ if not seen_chains:
4666+ if rule.startswith(':'):
4667+ seen_chains = True
4668+ else:
4669+ if not rule.startswith(':'):
4670+ break
4671+
4672+ our_rules = []
4673+ for rule in rules:
4674+ rule_str = str(rule)
4675+ if rule.top:
4676+ # rule.top == True means we want this rule to be at the top.
4677+ # Further down, we weed out duplicates from the bottom of the
4678+ # list, so here we remove the dupes ahead of time.
4679+ new_filter = filter(lambda s: s.strip() != rule_str.strip(),
4680+ new_filter)
4681+ our_rules += [rule_str]
4682+
4683+ new_filter[rules_index:rules_index] = our_rules
4684+
4685+ new_filter[rules_index:rules_index] = [':%s - [0:0]' % \
4686+ (name,) \
4687+ for name in unwrapped_chains]
4688+ new_filter[rules_index:rules_index] = [':%s-%s - [0:0]' % \
4689+ (binary_name, name,) \
4690+ for name in chains]
4691+
4692+ seen_lines = set()
4693+
4694+ def _weed_out_duplicates(line):
4695+ line = line.strip()
4696+ if line in seen_lines:
4697+ return False
4698+ else:
4699+ seen_lines.add(line)
4700+ return True
4701+
4702+ # We filter duplicates, letting the *last* occurrence take
4703+ # precendence.
4704+ new_filter.reverse()
4705+ new_filter = filter(_weed_out_duplicates, new_filter)
4706+ new_filter.reverse()
4707+ return new_filter
4708+
4709+
4710+def metadata_forward():
4711+ """Create forwarding rule for metadata"""
4712+ iptables_manager.ipv4['nat'].add_rule("PREROUTING",
4713+ "-s 0.0.0.0/0 -d 169.254.169.254/32 "
4714+ "-p tcp -m tcp --dport 80 -j DNAT "
4715+ "--to-destination %s:%s" % \
4716+ (FLAGS.ec2_dmz_host,
4717+ FLAGS.ec2_port))
4718+ iptables_manager.apply()
4719+
4720+def init_host():
4721+ """Basic networking setup goes here"""
4722+ # NOTE(devcamcar): Cloud public SNAT entries and the default
4723+ # SNAT rule for outbound traffic.
4724+ iptables_manager.ipv4['nat'].add_rule("snat",
4725+ "-s %s -j SNAT --to-source %s" % \
4726+ (FLAGS.net_flat_vlan_fixed_range,
4727+ FLAGS.net_flat_vlan_routing_source_ip))
4728+
4729+ iptables_manager.ipv4['nat'].add_rule("POSTROUTING",
4730+ "-s %s -d %s -j ACCEPT" % \
4731+ (FLAGS.net_flat_vlan_fixed_range,
4732+ FLAGS.net_flat_vlan_dmz_cidr))
4733+
4734+ iptables_manager.ipv4['nat'].add_rule("POSTROUTING",
4735+ "-s %(range)s -d %(range)s "
4736+ "-j ACCEPT" % \
4737+ {'range': FLAGS.net_flat_vlan_fixed_range})
4738+ iptables_manager.apply()
4739+
4740+def ensure_vlan_forward(public_ip, port, private_ip):
4741+ """Sets up forwarding rules for vlan"""
4742+ iptables_manager.ipv4['filter'].add_rule("FORWARD",
4743+ "-d %s -p udp "
4744+ "--dport 1194 "
4745+ "-j ACCEPT" % private_ip)
4746+ iptables_manager.ipv4['nat'].add_rule("PREROUTING",
4747+ "-d %s -p udp "
4748+ "--dport %s -j DNAT --to %s:1194" %
4749+ (public_ip, port, private_ip))
4750+ iptables_manager.apply()
4751+
4752+
4753+def ensure_floating_forward(floating_ip, fixed_ip):
4754+ """Ensure floating ip forwarding rule"""
4755+ for chain, rule in floating_forward_rules(floating_ip, fixed_ip):
4756+ iptables_manager.ipv4['nat'].add_rule(chain, rule)
4757+ iptables_manager.apply()
4758+
4759+
4760+def remove_floating_forward(floating_ip, fixed_ip):
4761+ """Remove forwarding for floating ip"""
4762+ for chain, rule in floating_forward_rules(floating_ip, fixed_ip):
4763+ iptables_manager.ipv4['nat'].remove_rule(chain, rule)
4764+ iptables_manager.apply()
4765+
4766+
4767+def floating_forward_rules(floating_ip, fixed_ip):
4768+ return [("PREROUTING", "-d %s -j DNAT --to %s" % (floating_ip, fixed_ip)),
4769+ ("OUTPUT", "-d %s -j DNAT --to %s" % (floating_ip, fixed_ip)),
4770+ ("floating-snat",
4771+ "-s %s -j SNAT --to %s" % (fixed_ip, floating_ip))]
4772+
4773+def ensure_bridge_forward(bridge):
4774+ iptables_manager.ipv4['filter'].add_rule("FORWARD",
4775+ "--in-interface %s -j ACCEPT" % \
4776+ bridge)
4777+ iptables_manager.ipv4['filter'].add_rule("FORWARD",
4778+ "--out-interface %s -j ACCEPT" % \
4779+ bridge)
4780+
4781+iptables_manager = IptablesManager()
4782\ No newline at end of file
4783
4784=== added file 'nova/network/flat_vlan/driver/linux/network.py'
4785--- nova/network/flat_vlan/driver/linux/network.py 1970-01-01 00:00:00 +0000
4786+++ nova/network/flat_vlan/driver/linux/network.py 2011-04-04 00:58:27 +0000
4787@@ -0,0 +1,149 @@
4788+# vim: tabstop=4 shiftwidth=4 softtabstop=4
4789+
4790+# Copyright 2011 Midokura KK
4791+# All Rights Reserved.
4792+#
4793+# Licensed under the Apache License, Version 2.0 (the "License"); you may
4794+# not use this file except in compliance with the License. You may obtain
4795+# a copy of the License at
4796+#
4797+# http://www.apache.org/licenses/LICENSE-2.0
4798+#
4799+# Unless required by applicable law or agreed to in writing, software
4800+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
4801+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
4802+# License for the specific language governing permissions and limitations
4803+# under the License.
4804+"""
4805+Implements vlans, bridges, and iptables rules using linux utilities.
4806+"""
4807+import os
4808+
4809+from nova import exception
4810+from nova import log as logging
4811+from nova import utils
4812+
4813+from nova.network.flat_vlan import flags
4814+
4815+LOG = logging.getLogger("nova.flat_vlan_linux_net")
4816+FLAGS = flags.FlagAccessor()
4817+
4818+def bind_floating_ip(floating_ip, check_exit_code=True):
4819+ """Bind ip to public interface"""
4820+ _execute('sudo', 'ip', 'addr', 'add', floating_ip,
4821+ 'dev', FLAGS.net_flat_vlan_public_interface,
4822+ check_exit_code=check_exit_code)
4823+
4824+def unbind_floating_ip(floating_ip):
4825+ """Unbind a public ip from public interface"""
4826+ _execute('sudo', 'ip', 'addr', 'del', floating_ip,
4827+ 'dev', FLAGS.net_flat_vlan_public_interface)
4828+
4829+def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None):
4830+ """Create a vlan and bridge unless they already exist"""
4831+ interface = ensure_vlan(vlan_num)
4832+ ensure_bridge(bridge, interface, net_attrs)
4833+
4834+def ensure_vlan(vlan_num):
4835+ """Create a vlan unless it already exists"""
4836+ interface = "vlan%s" % vlan_num
4837+ if not _device_exists(interface):
4838+ LOG.debug(_("Starting VLAN inteface %s"), interface)
4839+ _execute('sudo', 'vconfig', 'set_name_type', 'VLAN_PLUS_VID_NO_PAD')
4840+ _execute('sudo', 'vconfig', 'add', FLAGS.net_flat_vlan_vlan_interface,
4841+ vlan_num)
4842+ _execute('sudo', 'ip', 'link', 'set', interface, 'up')
4843+ return interface
4844+
4845+def ensure_bridge(bridge, interface, net_attrs=None):
4846+ """Create a bridge unless it already exists.
4847+
4848+ :param interface: the interface to create the bridge on.
4849+ :param net_attrs: dictionary with attributes used to create the bridge.
4850+
4851+ If net_attrs is set, it will add the net_attrs['gateway'] to the bridge
4852+ using net_attrs['broadcast'] and net_attrs['cidr']. It will also add
4853+ the ip_v6 address specified in net_attrs['cidr_v6'] if
4854+ net_flat_vlan_use_ipv6 is set.
4855+
4856+ The code will attempt to move any ips that already exist on the interface
4857+ onto the bridge and reset the default gateway if necessary.
4858+ """
4859+ if not _device_exists(bridge):
4860+ LOG.debug(_("Starting Bridge interface for %s"), interface)
4861+ _execute('sudo', 'brctl', 'addbr', bridge)
4862+ _execute('sudo', 'brctl', 'setfd', bridge, 0)
4863+ # _execute("sudo brctl setageing %s 10" % bridge)
4864+ _execute('sudo', 'brctl', 'stp', bridge, 'off')
4865+ _execute('sudo', 'ip', 'link', 'set', bridge, 'up')
4866+ if net_attrs:
4867+ # NOTE(vish): The ip for dnsmasq has to be the first address on the
4868+ # bridge for it to respond to reqests properly
4869+ suffix = net_attrs['cidr'].rpartition('/')[2]
4870+ out, err = _execute('sudo', 'ip', 'addr', 'add',
4871+ "%s/%s" %
4872+ (net_attrs['gateway'], suffix),
4873+ 'brd',
4874+ net_attrs['broadcast'],
4875+ 'dev',
4876+ bridge,
4877+ check_exit_code=False)
4878+ if err and err != "RTNETLINK answers: File exists\n":
4879+ raise exception.Error("Failed to add ip: %s" % err)
4880+ if(FLAGS.net_flat_vlan_use_ipv6):
4881+ _execute('sudo', 'ip', '-f', 'inet6', 'addr',
4882+ 'change', net_attrs['cidr_v6'],
4883+ 'dev', bridge)
4884+ # NOTE(vish): If the public interface is the same as the
4885+ # bridge, then the bridge has to be in promiscuous
4886+ # to forward packets properly.
4887+ if(FLAGS.net_flat_vlan_public_interface == bridge):
4888+ _execute('sudo', 'ip', 'link', 'set',
4889+ 'dev', bridge, 'promisc', 'on')
4890+ if interface:
4891+ # NOTE(vish): This will break if there is already an ip on the
4892+ # interface, so we move any ips to the bridge
4893+ gateway = None
4894+ out, err = _execute('sudo', 'route', '-n')
4895+ for line in out.split("\n"):
4896+ fields = line.split()
4897+ if fields and fields[0] == "0.0.0.0" and fields[-1] == interface:
4898+ gateway = fields[1]
4899+ out, err = _execute('sudo', 'ip', 'addr', 'show', 'dev', interface,
4900+ 'scope', 'global')
4901+ for line in out.split("\n"):
4902+ fields = line.split()
4903+ if fields and fields[0] == "inet":
4904+ params = fields[1:-1]
4905+ _execute(*_ip_bridge_cmd('del', params, fields[-1]))
4906+ _execute(*_ip_bridge_cmd('add', params, bridge))
4907+ if gateway:
4908+ _execute('sudo', 'route', 'add', '0.0.0.0', 'gw', gateway)
4909+ out, err = _execute('sudo', 'brctl', 'addif', bridge, interface,
4910+ check_exit_code=False)
4911+
4912+ if (err and err != "device %s is already a member of a bridge; can't "
4913+ "enslave it to bridge %s.\n" % (interface, bridge)):
4914+ raise exception.Error("Failed to add interface: %s" % err)
4915+
4916+def _execute(*cmd, **kwargs):
4917+ """Wrapper around utils._execute for fake_network"""
4918+ if FLAGS.fake_network:
4919+ LOG.debug("FAKE NET: %s", " ".join(map(str, cmd)))
4920+ return "fake", 0
4921+ else:
4922+ return utils.execute(*cmd, **kwargs)
4923+
4924+def _device_exists(device):
4925+ """Check if ethernet device exists"""
4926+ (_out, err) = _execute('ip', 'link', 'show', 'dev', device,
4927+ check_exit_code=False)
4928+ return not err
4929+
4930+def _ip_bridge_cmd(action, params, device):
4931+ """Build commands to add/del ips to bridges/devices"""
4932+
4933+ cmd = ['sudo', 'ip', 'addr', action]
4934+ cmd.extend(params)
4935+ cmd.extend(['dev', device])
4936+ return cmd
4937
4938=== added file 'nova/network/flat_vlan/driver/linux/ra.py'
4939--- nova/network/flat_vlan/driver/linux/ra.py 1970-01-01 00:00:00 +0000
4940+++ nova/network/flat_vlan/driver/linux/ra.py 2011-04-04 00:58:27 +0000
4941@@ -0,0 +1,107 @@
4942+# vim: tabstop=4 shiftwidth=4 softtabstop=4
4943+
4944+# Copyright (c) 2011 NTT.
4945+# All Rights Reserved.
4946+#
4947+# Licensed under the Apache License, Version 2.0 (the "License"); you may
4948+# not use this file except in compliance with the License. You may obtain
4949+# a copy of the License at
4950+#
4951+# http://www.apache.org/licenses/LICENSE-2.0
4952+#
4953+# Unless required by applicable law or agreed to in writing, software
4954+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
4955+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
4956+# License for the specific language governing permissions and limitations
4957+# under the License.
4958+
4959+import os
4960+
4961+from nova import log as logging
4962+from nova import utils
4963+
4964+from nova.network.flat_vlan import flags
4965+
4966+LOG = logging.getLogger("nova.flat_vlan_linux_ra")
4967+
4968+FLAGS = flags.FlagAccessor()
4969+
4970+def _ra_file(bridge, kind):
4971+ """Return path to a pid or conf file for a bridge"""
4972+
4973+ if not os.path.exists(FLAGS.net_flat_vlan_networks_path):
4974+ os.makedirs(FLAGS.net_flat_vlan_networks_path)
4975+ return os.path.abspath("%s/nova-ra-%s.%s" % (
4976+ FLAGS.net_flat_vlan_networks_path,
4977+ bridge,
4978+ kind))
4979+
4980+def _ra_pid_for(bridge):
4981+ """Returns the pid for prior radvd instance for a bridge
4982+
4983+ Returns None if no pid file exists
4984+
4985+ If machine has rebooted pid might be incorrect (caller should check)
4986+ """
4987+
4988+ pid_file = _ra_file(bridge, 'pid')
4989+
4990+ if os.path.exists(pid_file):
4991+ with open(pid_file, 'r') as f:
4992+ return int(f.read())
4993+
4994+def _execute(*cmd, **kwargs):
4995+ """Wrapper around utils._execute for fake_network"""
4996+ if FLAGS.fake_network:
4997+ LOG.debug("FAKE NET: %s", " ".join(map(str, cmd)))
4998+ return "fake", 0
4999+ else:
5000+ return utils.execute(*cmd, **kwargs)
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: