Merge lp:~openstack-gd/nova/libvirt-multinic-nova into lp:~hudson-openstack/nova/trunk
- libvirt-multinic-nova
- Merge into trunk
Proposed by
Ilya Alekseyev
Status: | Superseded |
---|---|
Proposed branch: | lp:~openstack-gd/nova/libvirt-multinic-nova |
Merge into: | lp:~hudson-openstack/nova/trunk |
Diff against target: |
499 lines (+206/-100) 3 files modified
nova/virt/interfaces.template (+13/-12) nova/virt/libvirt.xml.template (+12/-9) nova/virt/libvirt_conn.py (+181/-79) |
To merge this branch: | bzr merge lp:~openstack-gd/nova/libvirt-multinic-nova |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sandy Walsh (community) | Needs Fixing | ||
Joshua McKenty | Pending | ||
Trey Morris | Pending | ||
Review via email: mp+53871@code.launchpad.net |
This proposal has been superseded by a proposal from 2011-03-23.
Commit message
Description of the change
libvirt driver multi_nic support. In this phase libvirt can work with and without multi_nic support, as in multi_nic support for xenapi: https:/
To post a comment you must log in.
- 813. By Eldar Nugaev
-
merge with trunk
- 814. By Eldar Nugaev
-
merge with trunk
- 815. By Eldar Nugaev
-
merge with trunk
- 816. By Ilya Alekseyev
-
review comments fixed
- 817. By Ilya Alekseyev
-
trunk merged
- 818. By Ilya Alekseyev
-
pep8 fixed
- 819. By Ilya Alekseyev
-
xml template fixed
- 820. By Ilya Alekseyev
-
one more minor fix
Revision history for this message
Ilya Alekseyev (ilyaalekseyev) wrote : | # |
Sandy, thank you very much for good review. Please look at my only comment below.
> The 'eth##' will be incremented each time ... even if injected, is that what
> you wanted?
>
yes
- 821. By Eldar Nugaev
-
migration gateway_v6 to network_info
- 822. By Eldar Nugaev
-
small fix
- 823. By Ilya Alekseyev
-
couple of bugs fixed
- 824. By Eldar Nugaev
-
pep8 clearing
- 825. By Ilya Alekseyev
-
trunk merged. conflicts resolved
- 826. By Ilya Alekseyev
-
style and spacing fixed
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'nova/virt/interfaces.template' | |||
2 | --- nova/virt/interfaces.template 2011-03-02 01:12:47 +0000 | |||
3 | +++ nova/virt/interfaces.template 2011-03-23 19:11:11 +0000 | |||
4 | @@ -5,19 +5,20 @@ | |||
5 | 5 | auto lo | 5 | auto lo |
6 | 6 | iface lo inet loopback | 6 | iface lo inet loopback |
7 | 7 | 7 | ||
16 | 8 | # The primary network interface | 8 | #for $ifc in $interfaces |
17 | 9 | auto eth0 | 9 | auto ${ifc.name} |
18 | 10 | iface eth0 inet static | 10 | iface ${ifc.name} inet static |
19 | 11 | address ${address} | 11 | address ${ifc.address} |
20 | 12 | netmask ${netmask} | 12 | netmask ${ifc.netmask} |
21 | 13 | broadcast ${broadcast} | 13 | broadcast ${ifc.broadcast} |
22 | 14 | gateway ${gateway} | 14 | gateway ${ifc.gateway} |
23 | 15 | dns-nameservers ${dns} | 15 | dns-nameservers ${ifc.dns} |
24 | 16 | 16 | ||
25 | 17 | #if $use_ipv6 | 17 | #if $use_ipv6 |
30 | 18 | iface eth0 inet6 static | 18 | iface ${ifc.name} inet6 static |
31 | 19 | address ${address_v6} | 19 | address ${ifc.address_v6} |
32 | 20 | netmask ${netmask_v6} | 20 | netmask ${ifc.netmask_v6} |
33 | 21 | gateway ${gateway_v6} | 21 | gateway ${ifc.gateway_v6} |
34 | 22 | #end if | 22 | #end if |
35 | 23 | 23 | ||
36 | 24 | #end for | ||
37 | 24 | 25 | ||
38 | === modified file 'nova/virt/libvirt.xml.template' | |||
39 | --- nova/virt/libvirt.xml.template 2011-03-02 01:12:47 +0000 | |||
40 | +++ nova/virt/libvirt.xml.template 2011-03-23 19:11:11 +0000 | |||
41 | @@ -69,21 +69,24 @@ | |||
42 | 69 | </disk> | 69 | </disk> |
43 | 70 | #end if | 70 | #end if |
44 | 71 | #end if | 71 | #end if |
45 | 72 | |||
46 | 73 | #for $nic in $nics | ||
47 | 72 | <interface type='bridge'> | 74 | <interface type='bridge'> |
50 | 73 | <source bridge='${bridge_name}'/> | 75 | <source bridge='${nic.bridge_name}'/> |
51 | 74 | <mac address='${mac_address}'/> | 76 | <mac address='${nic.mac_address}'/> |
52 | 75 | <!-- <model type='virtio'/> CANT RUN virtio network right now --> | 77 | <!-- <model type='virtio'/> CANT RUN virtio network right now --> |
58 | 76 | <filterref filter="nova-instance-${name}"> | 78 | <filterref filter="nova-instance-${name}-${nic.id}"> |
59 | 77 | <parameter name="IP" value="${ip_address}" /> | 79 | <parameter name="IP" value="${nic.ip_address}" /> |
60 | 78 | <parameter name="DHCPSERVER" value="${dhcp_server}" /> | 80 | <parameter name="DHCPSERVER" value="${nic.dhcp_server}" /> |
61 | 79 | #if $getVar('extra_params', False) | 81 | #if $getVar('nic.extra_params', False) |
62 | 80 | ${extra_params} | 82 | ${nic.extra_params} |
63 | 81 | #end if | 83 | #end if |
66 | 82 | #if $getVar('gateway_v6', False) | 84 | #if $getVar('nic.gateway_v6', False) |
67 | 83 | <parameter name="RASERVER" value="${gateway_v6}" /> | 85 | <parameter name="RASERVER" value="${nic.gateway_v6}" /> |
68 | 84 | #end if | 86 | #end if |
69 | 85 | </filterref> | 87 | </filterref> |
70 | 86 | </interface> | 88 | </interface> |
71 | 89 | #end for | ||
72 | 87 | 90 | ||
73 | 88 | <!-- The order is significant here. File must be defined first --> | 91 | <!-- The order is significant here. File must be defined first --> |
74 | 89 | <serial type="file"> | 92 | <serial type="file"> |
75 | 90 | 93 | ||
76 | === modified file 'nova/virt/libvirt_conn.py' | |||
77 | --- nova/virt/libvirt_conn.py 2011-03-23 05:29:32 +0000 | |||
78 | +++ nova/virt/libvirt_conn.py 2011-03-23 19:11:11 +0000 | |||
79 | @@ -153,6 +153,49 @@ | |||
80 | 153 | return int(net.version()) | 153 | return int(net.version()) |
81 | 154 | 154 | ||
82 | 155 | 155 | ||
83 | 156 | def _get_network_info(instance): | ||
84 | 157 | #TODO(ilyaalekseyev) If we will keep this function | ||
85 | 158 | # we should cache network_info | ||
86 | 159 | admin_context = context.get_admin_context() | ||
87 | 160 | |||
88 | 161 | ip_addresses = db.fixed_ip_get_all_by_instance(admin_context, | ||
89 | 162 | instance['id']) | ||
90 | 163 | |||
91 | 164 | networks = db.network_get_all_by_instance(admin_context, | ||
92 | 165 | instance['id']) | ||
93 | 166 | network_info = [] | ||
94 | 167 | |||
95 | 168 | def ip_dict(ip): | ||
96 | 169 | return { | ||
97 | 170 | "ip": ip.address, | ||
98 | 171 | "netmask": network["netmask"], | ||
99 | 172 | "enabled": "1"} | ||
100 | 173 | |||
101 | 174 | def ip6_dict(ip6): | ||
102 | 175 | prefix = ip6.network.cidr_v6 | ||
103 | 176 | mac = instance.mac_address | ||
104 | 177 | return { | ||
105 | 178 | "ip": utils.to_global_ipv6(prefix, mac), | ||
106 | 179 | "netmask": ip6.network.netmask_v6, | ||
107 | 180 | "gateway": ip6.network.gateway_v6, | ||
108 | 181 | "enabled": "1"} | ||
109 | 182 | |||
110 | 183 | for network in networks: | ||
111 | 184 | network_ips = [ip for ip in ip_addresses | ||
112 | 185 | if ip.network_id == network.id] | ||
113 | 186 | |||
114 | 187 | mapping = { | ||
115 | 188 | 'label': network['label'], | ||
116 | 189 | 'gateway': network['gateway'], | ||
117 | 190 | 'mac': instance.mac_address, | ||
118 | 191 | 'dns': [network['dns']], | ||
119 | 192 | 'ips': [ip_dict(ip) for ip in network_ips], | ||
120 | 193 | 'ip6s': [ip6_dict(ip) for ip in network_ips]} | ||
121 | 194 | |||
122 | 195 | network_info.append((network, mapping)) | ||
123 | 196 | return network_info | ||
124 | 197 | |||
125 | 198 | |||
126 | 156 | class LibvirtConnection(object): | 199 | class LibvirtConnection(object): |
127 | 157 | 200 | ||
128 | 158 | def __init__(self, read_only): | 201 | def __init__(self, read_only): |
129 | @@ -416,16 +459,18 @@ | |||
130 | 416 | # the normal xml file, we can just call reboot here | 459 | # the normal xml file, we can just call reboot here |
131 | 417 | self.reboot(instance) | 460 | self.reboot(instance) |
132 | 418 | 461 | ||
133 | 462 | # NOTE(ilyaalekseyev): Implementation like in multinics | ||
134 | 463 | # for xenapi(tr3buchet) | ||
135 | 419 | @exception.wrap_exception | 464 | @exception.wrap_exception |
138 | 420 | def spawn(self, instance): | 465 | def spawn(self, instance, network_info=None): |
139 | 421 | xml = self.to_xml(instance) | 466 | xml = self.to_xml(instance, network_info) |
140 | 422 | db.instance_set_state(context.get_admin_context(), | 467 | db.instance_set_state(context.get_admin_context(), |
141 | 423 | instance['id'], | 468 | instance['id'], |
142 | 424 | power_state.NOSTATE, | 469 | power_state.NOSTATE, |
143 | 425 | 'launching') | 470 | 'launching') |
147 | 426 | self.firewall_driver.setup_basic_filtering(instance) | 471 | self.firewall_driver.setup_basic_filtering(instance, network_info) |
148 | 427 | self.firewall_driver.prepare_instance_filter(instance) | 472 | self.firewall_driver.prepare_instance_filter(instance, network_info) |
149 | 428 | self._create_image(instance, xml) | 473 | self._create_image(instance, xml, network_info) |
150 | 429 | self._conn.createXML(xml, 0) | 474 | self._conn.createXML(xml, 0) |
151 | 430 | LOG.debug(_("instance %s: is running"), instance['name']) | 475 | LOG.debug(_("instance %s: is running"), instance['name']) |
152 | 431 | self.firewall_driver.apply_instance_filter(instance) | 476 | self.firewall_driver.apply_instance_filter(instance) |
153 | @@ -582,7 +627,11 @@ | |||
154 | 582 | utils.execute('truncate', target, '-s', "%dG" % local_gb) | 627 | utils.execute('truncate', target, '-s', "%dG" % local_gb) |
155 | 583 | # TODO(vish): should we format disk by default? | 628 | # TODO(vish): should we format disk by default? |
156 | 584 | 629 | ||
158 | 585 | def _create_image(self, inst, libvirt_xml, suffix='', disk_images=None): | 630 | def _create_image(self, inst, libvirt_xml, suffix='', disk_images=None, |
159 | 631 | network_info=None): | ||
160 | 632 | if not network_info: | ||
161 | 633 | network_info = _get_network_info(inst) | ||
162 | 634 | |||
163 | 586 | # syntactic nicety | 635 | # syntactic nicety |
164 | 587 | def basepath(fname='', suffix=suffix): | 636 | def basepath(fname='', suffix=suffix): |
165 | 588 | return os.path.join(FLAGS.instances_path, | 637 | return os.path.join(FLAGS.instances_path, |
166 | @@ -658,28 +707,35 @@ | |||
167 | 658 | 707 | ||
168 | 659 | key = str(inst['key_data']) | 708 | key = str(inst['key_data']) |
169 | 660 | net = None | 709 | net = None |
175 | 661 | network_ref = db.network_get_by_instance(context.get_admin_context(), | 710 | |
176 | 662 | inst['id']) | 711 | nets = [] |
177 | 663 | if network_ref['injected']: | 712 | ifc_template = open(FLAGS.injected_network_template).read() |
178 | 664 | admin_context = context.get_admin_context() | 713 | ifc_num = -1 |
179 | 665 | address = db.instance_get_fixed_address(admin_context, inst['id']) | 714 | admin_context = context.get_admin_context() |
180 | 715 | for (network_ref, mapping) in network_info: | ||
181 | 716 | ifc_num += 1 | ||
182 | 717 | |||
183 | 718 | if not 'injected' in network_ref: | ||
184 | 719 | continue | ||
185 | 720 | |||
186 | 721 | address = mapping['ips'][0]['ip'] | ||
187 | 666 | address_v6 = None | 722 | address_v6 = None |
188 | 667 | if FLAGS.use_ipv6: | 723 | if FLAGS.use_ipv6: |
204 | 668 | address_v6 = db.instance_get_fixed_address_v6(admin_context, | 724 | address_v6 = mapping['ip6s'][0]['ip'] |
205 | 669 | inst['id']) | 725 | net_info = {'name': 'eth%d' % ifc_num, |
206 | 670 | 726 | 'address': address, | |
207 | 671 | interfaces_info = {'address': address, | 727 | 'netmask': network_ref['netmask'], |
208 | 672 | 'netmask': network_ref['netmask'], | 728 | 'gateway': network_ref['gateway'], |
209 | 673 | 'gateway': network_ref['gateway'], | 729 | 'broadcast': network_ref['broadcast'], |
210 | 674 | 'broadcast': network_ref['broadcast'], | 730 | 'dns': network_ref['dns'], |
211 | 675 | 'dns': network_ref['dns'], | 731 | 'address_v6': address_v6, |
212 | 676 | 'address_v6': address_v6, | 732 | 'gateway_v6': network_ref['gateway_v6'], |
213 | 677 | 'gateway_v6': network_ref['gateway_v6'], | 733 | 'netmask_v6': network_ref['netmask_v6'], |
214 | 678 | 'netmask_v6': network_ref['netmask_v6'], | 734 | 'use_ipv6': FLAGS.use_ipv6} |
215 | 679 | 'use_ipv6': FLAGS.use_ipv6} | 735 | nets.append(net_info) |
216 | 680 | 736 | ||
217 | 681 | net = str(Template(self.interfaces_xml, | 737 | net = str(Template(ifc_template, searchList=[{'interfaces': nets}])) |
218 | 682 | searchList=[interfaces_info])) | 738 | |
219 | 683 | if key or net: | 739 | if key or net: |
220 | 684 | inst_name = inst['name'] | 740 | inst_name = inst['name'] |
221 | 685 | img_id = inst.image_id | 741 | img_id = inst.image_id |
222 | @@ -701,20 +757,11 @@ | |||
223 | 701 | if FLAGS.libvirt_type == 'uml': | 757 | if FLAGS.libvirt_type == 'uml': |
224 | 702 | utils.execute('sudo', 'chown', 'root', basepath('disk')) | 758 | utils.execute('sudo', 'chown', 'root', basepath('disk')) |
225 | 703 | 759 | ||
237 | 704 | def to_xml(self, instance, rescue=False): | 760 | def _get_nic_for_xml(self, instance_id, network, mapping): |
227 | 705 | # TODO(termie): cache? | ||
228 | 706 | LOG.debug(_('instance %s: starting toXML method'), instance['name']) | ||
229 | 707 | network = db.network_get_by_instance(context.get_admin_context(), | ||
230 | 708 | instance['id']) | ||
231 | 709 | # FIXME(vish): stick this in db | ||
232 | 710 | instance_type = instance['instance_type'] | ||
233 | 711 | # instance_type = test.INSTANCE_TYPES[instance_type] | ||
234 | 712 | instance_type = instance_types.get_instance_type(instance_type) | ||
235 | 713 | ip_address = db.instance_get_fixed_address(context.get_admin_context(), | ||
236 | 714 | instance['id']) | ||
238 | 715 | # Assume that the gateway also acts as the dhcp server. | 761 | # Assume that the gateway also acts as the dhcp server. |
239 | 716 | dhcp_server = network['gateway'] | 762 | dhcp_server = network['gateway'] |
240 | 717 | gateway_v6 = network['gateway_v6'] | 763 | gateway_v6 = network['gateway_v6'] |
241 | 764 | mac_id = mapping['mac'].replace(':', '') | ||
242 | 718 | 765 | ||
243 | 719 | if FLAGS.allow_project_net_traffic: | 766 | if FLAGS.allow_project_net_traffic: |
244 | 720 | if FLAGS.use_ipv6: | 767 | if FLAGS.use_ipv6: |
245 | @@ -739,6 +786,41 @@ | |||
246 | 739 | (net, mask) | 786 | (net, mask) |
247 | 740 | else: | 787 | else: |
248 | 741 | extra_params = "\n" | 788 | extra_params = "\n" |
249 | 789 | |||
250 | 790 | result = { | ||
251 | 791 | 'id': mac_id, | ||
252 | 792 | 'bridge_name': network['bridge'], | ||
253 | 793 | 'mac_address': mapping['mac'], | ||
254 | 794 | 'ip_address': mapping['ips'][0]['ip'], | ||
255 | 795 | 'dhcp_server': dhcp_server, | ||
256 | 796 | 'extra_params': extra_params, | ||
257 | 797 | } | ||
258 | 798 | |||
259 | 799 | if gateway_v6: | ||
260 | 800 | result['gateway_v6'] = gateway_v6 + "/128" | ||
261 | 801 | |||
262 | 802 | return result | ||
263 | 803 | |||
264 | 804 | def to_xml(self, instance, rescue=False, network_info=None): | ||
265 | 805 | admin_context = context.get_admin_context() | ||
266 | 806 | |||
267 | 807 | # TODO(termie): cache? | ||
268 | 808 | LOG.debug(_('instance %s: starting toXML method'), instance['name']) | ||
269 | 809 | |||
270 | 810 | #TODO(ilyaalekseyev) remove network_info creation code | ||
271 | 811 | # when multinics will be completed | ||
272 | 812 | if not network_info: | ||
273 | 813 | network_info = _get_network_info(instance) | ||
274 | 814 | |||
275 | 815 | nics = [] | ||
276 | 816 | for (network, mapping) in network_info: | ||
277 | 817 | nics.append(self._get_nic_for_xml(instance['id'], | ||
278 | 818 | network, | ||
279 | 819 | mapping)) | ||
280 | 820 | # FIXME(vish): stick this in db | ||
281 | 821 | instance_type_name = instance['instance_type'] | ||
282 | 822 | instance_type = instance_types.get_instance_type(instance_type_name) | ||
283 | 823 | |||
284 | 742 | if FLAGS.use_cow_images: | 824 | if FLAGS.use_cow_images: |
285 | 743 | driver_type = 'qcow2' | 825 | driver_type = 'qcow2' |
286 | 744 | else: | 826 | else: |
287 | @@ -750,17 +832,11 @@ | |||
288 | 750 | instance['name']), | 832 | instance['name']), |
289 | 751 | 'memory_kb': instance_type['memory_mb'] * 1024, | 833 | 'memory_kb': instance_type['memory_mb'] * 1024, |
290 | 752 | 'vcpus': instance_type['vcpus'], | 834 | 'vcpus': instance_type['vcpus'], |
291 | 753 | 'bridge_name': network['bridge'], | ||
292 | 754 | 'mac_address': instance['mac_address'], | ||
293 | 755 | 'ip_address': ip_address, | ||
294 | 756 | 'dhcp_server': dhcp_server, | ||
295 | 757 | 'extra_params': extra_params, | ||
296 | 758 | 'rescue': rescue, | 835 | 'rescue': rescue, |
297 | 759 | 'local': instance_type['local_gb'], | 836 | 'local': instance_type['local_gb'], |
299 | 760 | 'driver_type': driver_type} | 837 | 'driver_type': driver_type, |
300 | 838 | 'nics': nics} | ||
301 | 761 | 839 | ||
302 | 762 | if gateway_v6: | ||
303 | 763 | xml_info['gateway_v6'] = gateway_v6 + "/128" | ||
304 | 764 | if not rescue: | 840 | if not rescue: |
305 | 765 | if instance['kernel_id']: | 841 | if instance['kernel_id']: |
306 | 766 | xml_info['kernel'] = xml_info['basepath'] + "/kernel" | 842 | xml_info['kernel'] = xml_info['basepath'] + "/kernel" |
307 | @@ -773,7 +849,6 @@ | |||
308 | 773 | xml = str(Template(self.libvirt_xml, searchList=[xml_info])) | 849 | xml = str(Template(self.libvirt_xml, searchList=[xml_info])) |
309 | 774 | LOG.debug(_('instance %s: finished toXML method'), | 850 | LOG.debug(_('instance %s: finished toXML method'), |
310 | 775 | instance['name']) | 851 | instance['name']) |
311 | 776 | |||
312 | 777 | return xml | 852 | return xml |
313 | 778 | 853 | ||
314 | 779 | def get_info(self, instance_name): | 854 | def get_info(self, instance_name): |
315 | @@ -1274,7 +1349,7 @@ | |||
316 | 1274 | 1349 | ||
317 | 1275 | 1350 | ||
318 | 1276 | class FirewallDriver(object): | 1351 | class FirewallDriver(object): |
320 | 1277 | def prepare_instance_filter(self, instance): | 1352 | def prepare_instance_filter(self, instance, network_info=None): |
321 | 1278 | """Prepare filters for the instance. | 1353 | """Prepare filters for the instance. |
322 | 1279 | 1354 | ||
323 | 1280 | At this point, the instance isn't running yet.""" | 1355 | At this point, the instance isn't running yet.""" |
324 | @@ -1308,7 +1383,7 @@ | |||
325 | 1308 | the security group.""" | 1383 | the security group.""" |
326 | 1309 | raise NotImplementedError() | 1384 | raise NotImplementedError() |
327 | 1310 | 1385 | ||
329 | 1311 | def setup_basic_filtering(self, instance): | 1386 | def setup_basic_filtering(self, instance, network_info=None): |
330 | 1312 | """Create rules to block spoofing and allow dhcp. | 1387 | """Create rules to block spoofing and allow dhcp. |
331 | 1313 | 1388 | ||
332 | 1314 | This gets called when spawning an instance, before | 1389 | This gets called when spawning an instance, before |
333 | @@ -1322,6 +1397,11 @@ | |||
334 | 1322 | instance['id']) | 1397 | instance['id']) |
335 | 1323 | return network['gateway_v6'] | 1398 | return network['gateway_v6'] |
336 | 1324 | 1399 | ||
337 | 1400 | def _all_gateway_v6_for_instance(self, instance): | ||
338 | 1401 | networks = db.network_get_all_by_instance(context.get_admin_context(), | ||
339 | 1402 | instance['id']) | ||
340 | 1403 | return [network['gateway_v6'] for network in networks] | ||
341 | 1404 | |||
342 | 1325 | 1405 | ||
343 | 1326 | class NWFilterFirewall(FirewallDriver): | 1406 | class NWFilterFirewall(FirewallDriver): |
344 | 1327 | """ | 1407 | """ |
345 | @@ -1413,7 +1493,7 @@ | |||
346 | 1413 | </rule> | 1493 | </rule> |
347 | 1414 | </filter>''' | 1494 | </filter>''' |
348 | 1415 | 1495 | ||
350 | 1416 | def setup_basic_filtering(self, instance): | 1496 | def setup_basic_filtering(self, instance, network_info=None): |
351 | 1417 | """Set up basic filtering (MAC, IP, and ARP spoofing protection)""" | 1497 | """Set up basic filtering (MAC, IP, and ARP spoofing protection)""" |
352 | 1418 | logging.info('called setup_basic_filtering in nwfilter') | 1498 | logging.info('called setup_basic_filtering in nwfilter') |
353 | 1419 | 1499 | ||
354 | @@ -1518,7 +1598,7 @@ | |||
355 | 1518 | # Nothing to do | 1598 | # Nothing to do |
356 | 1519 | pass | 1599 | pass |
357 | 1520 | 1600 | ||
359 | 1521 | def prepare_instance_filter(self, instance): | 1601 | def prepare_instance_filter(self, instance, network_info=None): |
360 | 1522 | """ | 1602 | """ |
361 | 1523 | Creates an NWFilter for the given instance. In the process, | 1603 | Creates an NWFilter for the given instance. In the process, |
362 | 1524 | it makes sure the filters for the security groups as well as | 1604 | it makes sure the filters for the security groups as well as |
363 | @@ -1536,8 +1616,8 @@ | |||
364 | 1536 | 'nova-base-ipv6', | 1616 | 'nova-base-ipv6', |
365 | 1537 | 'nova-allow-dhcp-server'] | 1617 | 'nova-allow-dhcp-server'] |
366 | 1538 | if FLAGS.use_ipv6: | 1618 | if FLAGS.use_ipv6: |
369 | 1539 | gateway_v6 = self._gateway_v6_for_instance(instance) | 1619 | gateways_v6 = self._all_gateway_v6_for_instance(instance) |
370 | 1540 | if gateway_v6: | 1620 | if gateways_v6: |
371 | 1541 | instance_secgroup_filter_children += ['nova-allow-ra-server'] | 1621 | instance_secgroup_filter_children += ['nova-allow-ra-server'] |
372 | 1542 | 1622 | ||
373 | 1543 | ctxt = context.get_admin_context() | 1623 | ctxt = context.get_admin_context() |
374 | @@ -1623,9 +1703,11 @@ | |||
375 | 1623 | self.iptables.ipv6['filter'].add_chain('sg-fallback') | 1703 | self.iptables.ipv6['filter'].add_chain('sg-fallback') |
376 | 1624 | self.iptables.ipv6['filter'].add_rule('sg-fallback', '-j DROP') | 1704 | self.iptables.ipv6['filter'].add_rule('sg-fallback', '-j DROP') |
377 | 1625 | 1705 | ||
379 | 1626 | def setup_basic_filtering(self, instance): | 1706 | def setup_basic_filtering(self, instance, network_info=None): |
380 | 1627 | """Use NWFilter from libvirt for this.""" | 1707 | """Use NWFilter from libvirt for this.""" |
382 | 1628 | return self.nwfilter.setup_basic_filtering(instance) | 1708 | if not network_info: |
383 | 1709 | network_info = _get_network_info(instance) | ||
384 | 1710 | return self.nwfilter.setup_basic_filtering(instance, network_info) | ||
385 | 1629 | 1711 | ||
386 | 1630 | def apply_instance_filter(self, instance): | 1712 | def apply_instance_filter(self, instance): |
387 | 1631 | """No-op. Everything is done in prepare_instance_filter""" | 1713 | """No-op. Everything is done in prepare_instance_filter""" |
388 | @@ -1639,29 +1721,40 @@ | |||
389 | 1639 | LOG.info(_('Attempted to unfilter instance %s which is not ' | 1721 | LOG.info(_('Attempted to unfilter instance %s which is not ' |
390 | 1640 | 'filtered'), instance['id']) | 1722 | 'filtered'), instance['id']) |
391 | 1641 | 1723 | ||
393 | 1642 | def prepare_instance_filter(self, instance): | 1724 | def prepare_instance_filter(self, instance, network_info=None): |
394 | 1725 | if not network_info: | ||
395 | 1726 | network_info = _get_network_info(instance) | ||
396 | 1643 | self.instances[instance['id']] = instance | 1727 | self.instances[instance['id']] = instance |
398 | 1644 | self.add_filters_for_instance(instance) | 1728 | self.add_filters_for_instance(instance, network_info) |
399 | 1645 | self.iptables.apply() | 1729 | self.iptables.apply() |
400 | 1646 | 1730 | ||
402 | 1647 | def add_filters_for_instance(self, instance): | 1731 | def add_filters_for_instance(self, instance, network_info=None): |
403 | 1732 | if not network_info: | ||
404 | 1733 | network_info = _get_network_info(instance) | ||
405 | 1648 | chain_name = self._instance_chain_name(instance) | 1734 | chain_name = self._instance_chain_name(instance) |
406 | 1649 | 1735 | ||
407 | 1650 | self.iptables.ipv4['filter'].add_chain(chain_name) | 1736 | self.iptables.ipv4['filter'].add_chain(chain_name) |
412 | 1651 | ipv4_address = self._ip_for_instance(instance) | 1737 | |
413 | 1652 | self.iptables.ipv4['filter'].add_rule('local', | 1738 | ips_v4 = [ip['ip'] for (_, mapping) in network_info |
414 | 1653 | '-d %s -j $%s' % | 1739 | for ip in mapping['ips']] |
415 | 1654 | (ipv4_address, chain_name)) | 1740 | |
416 | 1741 | for ipv4_address in ips_v4: | ||
417 | 1742 | self.iptables.ipv4['filter'].add_rule('local', | ||
418 | 1743 | '-d %s -j $%s' % | ||
419 | 1744 | (ipv4_address, chain_name)) | ||
420 | 1655 | 1745 | ||
421 | 1656 | if FLAGS.use_ipv6: | 1746 | if FLAGS.use_ipv6: |
422 | 1657 | self.iptables.ipv6['filter'].add_chain(chain_name) | 1747 | self.iptables.ipv6['filter'].add_chain(chain_name) |
430 | 1658 | ipv6_address = self._ip_for_instance_v6(instance) | 1748 | ips_v6 = [ip['ip'] for (_, mapping) in network_info |
431 | 1659 | self.iptables.ipv6['filter'].add_rule('local', | 1749 | for ip in mapping['ip6s']] |
432 | 1660 | '-d %s -j $%s' % | 1750 | |
433 | 1661 | (ipv6_address, | 1751 | for ipv6_address in ips_v6: |
434 | 1662 | chain_name)) | 1752 | self.iptables.ipv6['filter'].add_rule('local', |
435 | 1663 | 1753 | '-d %s -j $%s' % | |
436 | 1664 | ipv4_rules, ipv6_rules = self.instance_rules(instance) | 1754 | (ipv6_address, |
437 | 1755 | chain_name)) | ||
438 | 1756 | |||
439 | 1757 | ipv4_rules, ipv6_rules = self.instance_rules(instance, network_info) | ||
440 | 1665 | 1758 | ||
441 | 1666 | for rule in ipv4_rules: | 1759 | for rule in ipv4_rules: |
442 | 1667 | self.iptables.ipv4['filter'].add_rule(chain_name, rule) | 1760 | self.iptables.ipv4['filter'].add_rule(chain_name, rule) |
443 | @@ -1677,7 +1770,9 @@ | |||
444 | 1677 | if FLAGS.use_ipv6: | 1770 | if FLAGS.use_ipv6: |
445 | 1678 | self.iptables.ipv6['filter'].remove_chain(chain_name) | 1771 | self.iptables.ipv6['filter'].remove_chain(chain_name) |
446 | 1679 | 1772 | ||
448 | 1680 | def instance_rules(self, instance): | 1773 | def instance_rules(self, instance, network_info=None): |
449 | 1774 | if not network_info: | ||
450 | 1775 | network_info = _get_network_info(instance) | ||
451 | 1681 | ctxt = context.get_admin_context() | 1776 | ctxt = context.get_admin_context() |
452 | 1682 | 1777 | ||
453 | 1683 | ipv4_rules = [] | 1778 | ipv4_rules = [] |
454 | @@ -1691,28 +1786,35 @@ | |||
455 | 1691 | ipv4_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] | 1786 | ipv4_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] |
456 | 1692 | ipv6_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] | 1787 | ipv6_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] |
457 | 1693 | 1788 | ||
461 | 1694 | dhcp_server = self._dhcp_server_for_instance(instance) | 1789 | dhcp_servers = [network['gateway'] for (network, _m) in network_info] |
462 | 1695 | ipv4_rules += ['-s %s -p udp --sport 67 --dport 68 ' | 1790 | |
463 | 1696 | '-j ACCEPT' % (dhcp_server,)] | 1791 | for dhcp_server in dhcp_servers: |
464 | 1792 | ipv4_rules.append('-s %s -p udp --sport 67 --dport 68 ' | ||
465 | 1793 | '-j ACCEPT' % (dhcp_server,)) | ||
466 | 1697 | 1794 | ||
467 | 1698 | #Allow project network traffic | 1795 | #Allow project network traffic |
468 | 1699 | if FLAGS.allow_project_net_traffic: | 1796 | if FLAGS.allow_project_net_traffic: |
471 | 1700 | cidr = self._project_cidr_for_instance(instance) | 1797 | cidrs = [network['cidr'] for (network, _m) in network_info] |
472 | 1701 | ipv4_rules += ['-s %s -j ACCEPT' % (cidr,)] | 1798 | for cidr in cidrs: |
473 | 1799 | ipv4_rules.append('-s %s -j ACCEPT' % (cidr,)) | ||
474 | 1702 | 1800 | ||
475 | 1703 | # We wrap these in FLAGS.use_ipv6 because they might cause | 1801 | # We wrap these in FLAGS.use_ipv6 because they might cause |
476 | 1704 | # a DB lookup. The other ones are just list operations, so | 1802 | # a DB lookup. The other ones are just list operations, so |
477 | 1705 | # they're not worth the clutter. | 1803 | # they're not worth the clutter. |
478 | 1706 | if FLAGS.use_ipv6: | 1804 | if FLAGS.use_ipv6: |
479 | 1707 | # Allow RA responses | 1805 | # Allow RA responses |
483 | 1708 | gateway_v6 = self._gateway_v6_for_instance(instance) | 1806 | gateways_v6 = self._all_gateway_v6_for_instance(instance) |
484 | 1709 | if gateway_v6: | 1807 | for gateway_v6 in gateways_v6: |
485 | 1710 | ipv6_rules += ['-s %s/128 -p icmpv6 -j ACCEPT' % (gateway_v6,)] | 1808 | ipv6_rules.append( |
486 | 1809 | '-s %s/128 -p icmpv6 -j ACCEPT' % (gateway_v6,)) | ||
487 | 1711 | 1810 | ||
488 | 1712 | #Allow project network traffic | 1811 | #Allow project network traffic |
489 | 1713 | if FLAGS.allow_project_net_traffic: | 1812 | if FLAGS.allow_project_net_traffic: |
492 | 1714 | cidrv6 = self._project_cidrv6_for_instance(instance) | 1813 | cidrv6s = [network['cidr_v6'] for (network, _m) |
493 | 1715 | ipv6_rules += ['-s %s -j ACCEPT' % (cidrv6,)] | 1814 | in network_info] |
494 | 1815 | |||
495 | 1816 | for cidrv6 in cidrv6s: | ||
496 | 1817 | ipv6_rules.append('-s %s -j ACCEPT' % (cidrv6,)) | ||
497 | 1716 | 1818 | ||
498 | 1717 | security_groups = db.security_group_get_by_instance(ctxt, | 1819 | security_groups = db.security_group_get_by_instance(ctxt, |
499 | 1718 | instance['id']) | 1820 | instance['id']) |
149 if not network_info:
180 if _m is unused, you can just use _
182 if network_ ref['injected' ]:
if 'injected' in network_ref: might be safer (no KeyError if missing)
or better
if not 'injected' in network_ref:
continue
and pull the indent in the for rest
183 do we need to make the context inside the loop? can this be done outside?
186-188 can be replaced with ra_server = network_ ref.get( 'ra_server' , "fd00::"
The 'eth##' will be incremented each time ... even if injected, is that what you wanted?
253 if not ...
263 commented out code?
264 seems to overwrite 262?
351 353 commented out code?
354 if ra_servers:
398 should be like 416
450, 459, 482 use append()?