Merge lp:~openstack-gd/nova/libvirt-multinic-nova into lp:~hudson-openstack/nova/trunk
- libvirt-multinic-nova
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Paul Voccio |
Approved revision: | 826 |
Merged at revision: | 876 |
Proposed branch: | lp:~openstack-gd/nova/libvirt-multinic-nova |
Merge into: | lp:~hudson-openstack/nova/trunk |
Diff against target: |
692 lines (+260/-164) 6 files modified
nova/tests/test_virt.py (+4/-2) nova/utils.py (+9/-5) nova/virt/driver.py (+1/-1) nova/virt/interfaces.template (+13/-12) nova/virt/libvirt.xml.template (+12/-9) nova/virt/libvirt_conn.py (+221/-135) |
To merge this branch: | bzr merge lp:~openstack-gd/nova/libvirt-multinic-nova |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Trey Morris (community) | Needs Fixing | ||
Paul Voccio (community) | Approve | ||
Matt Dietz (community) | Approve | ||
Nachi Ueno (community) | Needs Fixing | ||
Vish Ishaya | Pending | ||
Joshua McKenty | Pending | ||
Sandy Walsh | Pending | ||
Review via email: mp+54589@code.launchpad.net |
This proposal supersedes a proposal from 2011-03-17.
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:/
Sandy Walsh (sandy-walsh) wrote : Posted in a previous version of this proposal | # |
Ilya Alekseyev (ilyaalekseyev) wrote : Posted in a previous version of this proposal | # |
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
Nachi Ueno (nati-ueno) wrote : | # |
Unit test fails, would you please check?
Failure
runTest ERROR
=======
ERROR: test_403 (nova.tests.
-------
Traceback (most recent call last):
File "/home/
delay, error = self.proxy.
File "/home/
conn.
File "/home/
resp = str(req.
File "/usr/lib/
application, catch_exc_
File "/usr/lib/
app_iter = application(
File "/usr/lib/
return resp(environ, start_response)
File "/usr/lib/
return self.generate_
File "/usr/lib/
content_
File "/usr/lib/
"You cannot set the body to a unicode value without a charset")
TypeError: You cannot set the body to a unicode value without a charset
=======
ERROR: test_response_
-------
Traceback (most recent call last):
File "/home/
delay = self._request(
File "/home/
response = request.
File "/usr/lib/
application, catch_exc_
File "/usr/lib/
app_iter = application(
File "/usr/lib/
return resp(environ, start_response)
File "/usr/lib/
return self.generate_
File "/usr/lib/
content_
File "/usr/lib/
"You cannot set the body to a unicode value without a charset")
TypeError: You cannot set the body to a unicode value without a charset
=======
ERROR: test_response_
Nachi Ueno (nati-ueno) wrote : | # |
I found the versions of some libraries causes the unit test fails.
Please ignore above comment.
Andrey Brindeyev (abrindeyev) wrote : | # |
> I found the versions of some libraries causes the unit test fails.
Nachi,
Thanks for letting us know!
Could you please document here which libraries (and their versions) caused problems on your side?
Thanks in advance, Andrey.
Nachi Ueno (nati-ueno) wrote : | # |
Hi Andrey,
We need following package when we use nova.sh.
sudo apt-get install python-webob
sudo apt-get install python-novaclient
# Sorry again,this is not by your branch.
Unit test was OK.
But I can not run instances.
When I run instance, I got a error message.
2011-03-24 07:01:07,634 ERROR nova.exception [-] Uncaught exception
(nova.exception): TRACE: Traceback (most recent call last):
(nova.exception): TRACE: File "/home/
(nova.exception): TRACE: return f(*args, **kw)
(nova.exception): TRACE: File "/home/
(nova.exception): TRACE: xml = self.to_
(nova.exception): TRACE: File "/home/
(nova.exception): TRACE: network_info = _get_network_
(nova.exception): TRACE: File "/home/
(nova.exception): TRACE: 'ip6s': [ip6_dict(ip) for ip in network_ips]}
(nova.exception): TRACE: File "/home/
(nova.exception): TRACE: "ip": utils.to_
(nova.exception): TRACE: File "/home/
(nova.exception): TRACE: maskIP = netaddr.
(nova.exception): TRACE: File "/usr/lib/
(nova.exception): TRACE: prefix, suffix = addr.split('/')
(nova.exception): TRACE: AttributeError: 'NoneType' object has no attribute 'split'
(nova.exception): TRACE:
2011-03-24 07:01:07,645 ERROR nova.compute.
(nova.compute.
(nova.compute.
(nova.compute.
(nova.compute.
(nova.compute.
(nova.compute.
(nova.compute.
libvir: QEMU error : Domain not found: no domain with matching name 'instance-00000001'
I found that _get_network_info should check FLAGS.use_ipv6.
156 def _get_network_
157 #TODO(ilyaaleks
158 # we should cache network_info
159 admin_context = context.
160 ip_addresses = db.fixed_
161 instance['id'])
162
163 networks = db.network_
164 instance['id'])
165 network_info = []
166
167 def i...
Ilya Alekseyev (ilyaalekseyev) wrote : | # |
Nachi, thank you much for review.
Fixing.
- 823. By Ilya Alekseyev
-
couple of bugs fixed
- 824. By Eldar Nugaev
-
pep8 clearing
- 825. By Ilya Alekseyev
-
trunk merged. conflicts resolved
Matt Dietz (cerberus) wrote : | # |
Nachi: could you use http://
Ilya Alekseyev (ilyaalekseyev) wrote : | # |
Hi Nachi!
We checked that VMs is starting and available via ipv4.
Thank you very much for you help.
Matt Dietz (cerberus) wrote : | # |
I'd like to see a lot more unit tests covering this functionality. The only addition I see is you updated one test to check for a mac address. Considering the substantial change this represents, going forward untested is pretty scary. Do you think you could throw a few tests in there?
Nit-picks / Style junk:
42 + return (mac64_addr ^ netaddr.
43 + format()
I'd like to see format() indented at least 8 spaces for readability's sake.
146 + #TODO(ilyaaleks
147 + # we should cache network_info
You should be consistent with your spacing. I'd move TODO over one space
- 826. By Ilya Alekseyev
-
style and spacing fixed
Eldar Nugaev (reldan) wrote : | # |
Hi Matt.
Thank you too much for your review.
We're synchronizing our changes with Trey Morris, he's working on add multi-nic support for xen https:/
Next blueprint https:/
> I'd like to see a lot more unit tests covering this functionality. The only
> addition I see is you updated one test to check for a mac address. Considering
> the substantial change this represents, going forward untested is pretty
> scary. Do you think you could throw a few tests in there?
>
> Nit-picks / Style junk:
>
> 42 + return (mac64_addr ^ netaddr.
> maskIP).\
> 43 + format()
>
> I'd like to see format() indented at least 8 spaces for readability's sake.
>
> 146 + #TODO(ilyaaleks
> 147 + # we should cache network_info
>
> You should be consistent with your spacing. I'd move TODO over one space
Eldar Nugaev (reldan) wrote : | # |
Bug for additional tests - https:/
Matt Dietz (cerberus) wrote : | # |
Alright Eldar, that works for me.
Trey Morris (tr3buchet) wrote : | # |
looks good to me. You'll want to add 'rxtx_cap' and 'broadcast' to network info in _get_network_info() as in vmops.
Trey Morris (tr3buchet) wrote : | # |
or it's already merged.. holy hell.
Ilya Alekseyev (ilyaalekseyev) wrote : | # |
Thank you Trey.
I've created new bug, we will fix it.
https:/
Salvatore Orlando (salvatore-orlando) wrote : | # |
Hi Ilya,
I have updated xenapi code for doing network injection, using interfaces.
I've seen that you populate the template in the following way:
net = str(Template(
I tried to do the same thing, but Cheetah was complaining that it could not find 'use_ipv6'. I looked at the template and found out that use_ipv6 is a first-level variable:
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
#for $ifc in $interfaces
auto ${ifc.name}
iface ${ifc.name} inet static
address ${ifc.address}
netmask ${ifc.netmask}
broadcast ${ifc.broadcast}
gateway ${ifc.gateway}
--> #if $use_ipv6 <--
iface ${ifc.name} inet6 static
address ${ifc.address_v6}
netmask ${ifc.netmask_v6}
gateway ${ifc.gateway_v6}
#end if
#end for
I therefore updated my code in the following way (and it worked):
net = str(template(
What am I missing? Do you have any hint about why I neeeded to pass use_ipv6 in this way?
Thanks,
Salvatore
Ilya Alekseyev (ilyaalekseyev) wrote : | # |
Hi Salvatore!
I think you did it in right way.
I kept use_ipv6 as first level variable bacause it depends on global flag.
I'll fix my code, asap. Thank you.
Preview Diff
1 | === modified file 'nova/tests/test_virt.py' | |||
2 | --- nova/tests/test_virt.py 2011-03-24 09:52:41 +0000 | |||
3 | +++ nova/tests/test_virt.py 2011-03-24 20:02:31 +0000 | |||
4 | @@ -796,7 +796,8 @@ | |||
5 | 796 | 796 | ||
6 | 797 | instance_ref = db.instance_create(self.context, | 797 | instance_ref = db.instance_create(self.context, |
7 | 798 | {'user_id': 'fake', | 798 | {'user_id': 'fake', |
9 | 799 | 'project_id': 'fake'}) | 799 | 'project_id': 'fake', |
10 | 800 | 'mac_address': '00:A0:C9:14:C8:29'}) | ||
11 | 800 | inst_id = instance_ref['id'] | 801 | inst_id = instance_ref['id'] |
12 | 801 | 802 | ||
13 | 802 | ip = '10.11.12.13' | 803 | ip = '10.11.12.13' |
14 | @@ -813,7 +814,8 @@ | |||
15 | 813 | 'instance_id': instance_ref['id']}) | 814 | 'instance_id': instance_ref['id']}) |
16 | 814 | 815 | ||
17 | 815 | def _ensure_all_called(): | 816 | def _ensure_all_called(): |
19 | 816 | instance_filter = 'nova-instance-%s' % instance_ref['name'] | 817 | instance_filter = 'nova-instance-%s-%s' % (instance_ref['name'], |
20 | 818 | '00A0C914C829') | ||
21 | 817 | secgroup_filter = 'nova-secgroup-%s' % self.security_group['id'] | 819 | secgroup_filter = 'nova-secgroup-%s' % self.security_group['id'] |
22 | 818 | for required in [secgroup_filter, 'allow-dhcp-server', | 820 | for required in [secgroup_filter, 'allow-dhcp-server', |
23 | 819 | 'no-arp-spoofing', 'no-ip-spoofing', | 821 | 'no-arp-spoofing', 'no-ip-spoofing', |
24 | 820 | 822 | ||
25 | === modified file 'nova/utils.py' | |||
26 | --- nova/utils.py 2011-03-24 18:51:38 +0000 | |||
27 | +++ nova/utils.py 2011-03-24 20:02:31 +0000 | |||
28 | @@ -311,11 +311,15 @@ | |||
29 | 311 | 311 | ||
30 | 312 | 312 | ||
31 | 313 | def to_global_ipv6(prefix, mac): | 313 | def to_global_ipv6(prefix, mac): |
37 | 314 | mac64 = netaddr.EUI(mac).eui64().words | 314 | try: |
38 | 315 | int_addr = int(''.join(['%02x' % i for i in mac64]), 16) | 315 | mac64 = netaddr.EUI(mac).eui64().words |
39 | 316 | mac64_addr = netaddr.IPAddress(int_addr) | 316 | int_addr = int(''.join(['%02x' % i for i in mac64]), 16) |
40 | 317 | maskIP = netaddr.IPNetwork(prefix).ip | 317 | mac64_addr = netaddr.IPAddress(int_addr) |
41 | 318 | return (mac64_addr ^ netaddr.IPAddress('::0200:0:0:0') | maskIP).format() | 318 | maskIP = netaddr.IPNetwork(prefix).ip |
42 | 319 | return (mac64_addr ^ netaddr.IPAddress('::0200:0:0:0') | maskIP).\ | ||
43 | 320 | format() | ||
44 | 321 | except TypeError: | ||
45 | 322 | raise TypeError(_("Bad mac for to_global_ipv6: %s") % mac) | ||
46 | 319 | 323 | ||
47 | 320 | 324 | ||
48 | 321 | def to_mac(ipv6_address): | 325 | def to_mac(ipv6_address): |
49 | 322 | 326 | ||
50 | === modified file 'nova/virt/driver.py' | |||
51 | --- nova/virt/driver.py 2011-03-24 02:15:41 +0000 | |||
52 | +++ nova/virt/driver.py 2011-03-24 20:02:31 +0000 | |||
53 | @@ -61,7 +61,7 @@ | |||
54 | 61 | """Return a list of InstanceInfo for all registered VMs""" | 61 | """Return a list of InstanceInfo for all registered VMs""" |
55 | 62 | raise NotImplementedError() | 62 | raise NotImplementedError() |
56 | 63 | 63 | ||
58 | 64 | def spawn(self, instance): | 64 | def spawn(self, instance, network_info=None): |
59 | 65 | """Launch a VM for the specified instance""" | 65 | """Launch a VM for the specified instance""" |
60 | 66 | raise NotImplementedError() | 66 | raise NotImplementedError() |
61 | 67 | 67 | ||
62 | 68 | 68 | ||
63 | === modified file 'nova/virt/interfaces.template' | |||
64 | --- nova/virt/interfaces.template 2011-03-02 01:12:47 +0000 | |||
65 | +++ nova/virt/interfaces.template 2011-03-24 20:02:31 +0000 | |||
66 | @@ -5,19 +5,20 @@ | |||
67 | 5 | auto lo | 5 | auto lo |
68 | 6 | iface lo inet loopback | 6 | iface lo inet loopback |
69 | 7 | 7 | ||
78 | 8 | # The primary network interface | 8 | #for $ifc in $interfaces |
79 | 9 | auto eth0 | 9 | auto ${ifc.name} |
80 | 10 | iface eth0 inet static | 10 | iface ${ifc.name} inet static |
81 | 11 | address ${address} | 11 | address ${ifc.address} |
82 | 12 | netmask ${netmask} | 12 | netmask ${ifc.netmask} |
83 | 13 | broadcast ${broadcast} | 13 | broadcast ${ifc.broadcast} |
84 | 14 | gateway ${gateway} | 14 | gateway ${ifc.gateway} |
85 | 15 | dns-nameservers ${dns} | 15 | dns-nameservers ${ifc.dns} |
86 | 16 | 16 | ||
87 | 17 | #if $use_ipv6 | 17 | #if $use_ipv6 |
92 | 18 | iface eth0 inet6 static | 18 | iface ${ifc.name} inet6 static |
93 | 19 | address ${address_v6} | 19 | address ${ifc.address_v6} |
94 | 20 | netmask ${netmask_v6} | 20 | netmask ${ifc.netmask_v6} |
95 | 21 | gateway ${gateway_v6} | 21 | gateway ${ifc.gateway_v6} |
96 | 22 | #end if | 22 | #end if |
97 | 23 | 23 | ||
98 | 24 | #end for | ||
99 | 24 | 25 | ||
100 | === modified file 'nova/virt/libvirt.xml.template' | |||
101 | --- nova/virt/libvirt.xml.template 2011-03-02 01:12:47 +0000 | |||
102 | +++ nova/virt/libvirt.xml.template 2011-03-24 20:02:31 +0000 | |||
103 | @@ -69,21 +69,24 @@ | |||
104 | 69 | </disk> | 69 | </disk> |
105 | 70 | #end if | 70 | #end if |
106 | 71 | #end if | 71 | #end if |
107 | 72 | |||
108 | 73 | #for $nic in $nics | ||
109 | 72 | <interface type='bridge'> | 74 | <interface type='bridge'> |
112 | 73 | <source bridge='${bridge_name}'/> | 75 | <source bridge='${nic.bridge_name}'/> |
113 | 74 | <mac address='${mac_address}'/> | 76 | <mac address='${nic.mac_address}'/> |
114 | 75 | <!-- <model type='virtio'/> CANT RUN virtio network right now --> | 77 | <!-- <model type='virtio'/> CANT RUN virtio network right now --> |
120 | 76 | <filterref filter="nova-instance-${name}"> | 78 | <filterref filter="nova-instance-${name}-${nic.id}"> |
121 | 77 | <parameter name="IP" value="${ip_address}" /> | 79 | <parameter name="IP" value="${nic.ip_address}" /> |
122 | 78 | <parameter name="DHCPSERVER" value="${dhcp_server}" /> | 80 | <parameter name="DHCPSERVER" value="${nic.dhcp_server}" /> |
123 | 79 | #if $getVar('extra_params', False) | 81 | #if $getVar('nic.extra_params', False) |
124 | 80 | ${extra_params} | 82 | ${nic.extra_params} |
125 | 81 | #end if | 83 | #end if |
128 | 82 | #if $getVar('gateway_v6', False) | 84 | #if $getVar('nic.gateway_v6', False) |
129 | 83 | <parameter name="RASERVER" value="${gateway_v6}" /> | 85 | <parameter name="RASERVER" value="${nic.gateway_v6}" /> |
130 | 84 | #end if | 86 | #end if |
131 | 85 | </filterref> | 87 | </filterref> |
132 | 86 | </interface> | 88 | </interface> |
133 | 89 | #end for | ||
134 | 87 | 90 | ||
135 | 88 | <!-- The order is significant here. File must be defined first --> | 91 | <!-- The order is significant here. File must be defined first --> |
136 | 89 | <serial type="file"> | 92 | <serial type="file"> |
137 | 90 | 93 | ||
138 | === modified file 'nova/virt/libvirt_conn.py' | |||
139 | --- nova/virt/libvirt_conn.py 2011-03-24 17:53:54 +0000 | |||
140 | +++ nova/virt/libvirt_conn.py 2011-03-24 20:02:31 +0000 | |||
141 | @@ -153,6 +153,51 @@ | |||
142 | 153 | return int(net.version()) | 153 | return int(net.version()) |
143 | 154 | 154 | ||
144 | 155 | 155 | ||
145 | 156 | def _get_network_info(instance): | ||
146 | 157 | # TODO(adiantum) If we will keep this function | ||
147 | 158 | # we should cache network_info | ||
148 | 159 | admin_context = context.get_admin_context() | ||
149 | 160 | |||
150 | 161 | ip_addresses = db.fixed_ip_get_all_by_instance(admin_context, | ||
151 | 162 | instance['id']) | ||
152 | 163 | |||
153 | 164 | networks = db.network_get_all_by_instance(admin_context, | ||
154 | 165 | instance['id']) | ||
155 | 166 | network_info = [] | ||
156 | 167 | |||
157 | 168 | def ip_dict(ip): | ||
158 | 169 | return { | ||
159 | 170 | "ip": ip.address, | ||
160 | 171 | "netmask": network["netmask"], | ||
161 | 172 | "enabled": "1"} | ||
162 | 173 | |||
163 | 174 | def ip6_dict(ip6): | ||
164 | 175 | prefix = ip6.network.cidr_v6 | ||
165 | 176 | mac = instance.mac_address | ||
166 | 177 | return { | ||
167 | 178 | "ip": utils.to_global_ipv6(prefix, mac), | ||
168 | 179 | "netmask": ip6.network.netmask_v6, | ||
169 | 180 | "gateway": ip6.network.gateway_v6, | ||
170 | 181 | "enabled": "1"} | ||
171 | 182 | |||
172 | 183 | for network in networks: | ||
173 | 184 | network_ips = [ip for ip in ip_addresses | ||
174 | 185 | if ip.network_id == network.id] | ||
175 | 186 | |||
176 | 187 | mapping = { | ||
177 | 188 | 'label': network['label'], | ||
178 | 189 | 'gateway': network['gateway'], | ||
179 | 190 | 'mac': instance.mac_address, | ||
180 | 191 | 'dns': [network['dns']], | ||
181 | 192 | 'ips': [ip_dict(ip) for ip in network_ips]} | ||
182 | 193 | |||
183 | 194 | if FLAGS.use_ipv6: | ||
184 | 195 | mapping['ip6s'] = [ip6_dict(ip) for ip in network_ips] | ||
185 | 196 | |||
186 | 197 | network_info.append((network, mapping)) | ||
187 | 198 | return network_info | ||
188 | 199 | |||
189 | 200 | |||
190 | 156 | class LibvirtConnection(driver.ComputeDriver): | 201 | class LibvirtConnection(driver.ComputeDriver): |
191 | 157 | 202 | ||
192 | 158 | def __init__(self, read_only): | 203 | def __init__(self, read_only): |
193 | @@ -444,16 +489,18 @@ | |||
194 | 444 | def poll_rescued_instances(self, timeout): | 489 | def poll_rescued_instances(self, timeout): |
195 | 445 | pass | 490 | pass |
196 | 446 | 491 | ||
197 | 492 | # NOTE(ilyaalekseyev): Implementation like in multinics | ||
198 | 493 | # for xenapi(tr3buchet) | ||
199 | 447 | @exception.wrap_exception | 494 | @exception.wrap_exception |
202 | 448 | def spawn(self, instance): | 495 | def spawn(self, instance, network_info=None): |
203 | 449 | xml = self.to_xml(instance) | 496 | xml = self.to_xml(instance, network_info) |
204 | 450 | db.instance_set_state(context.get_admin_context(), | 497 | db.instance_set_state(context.get_admin_context(), |
205 | 451 | instance['id'], | 498 | instance['id'], |
206 | 452 | power_state.NOSTATE, | 499 | power_state.NOSTATE, |
207 | 453 | 'launching') | 500 | 'launching') |
211 | 454 | self.firewall_driver.setup_basic_filtering(instance) | 501 | self.firewall_driver.setup_basic_filtering(instance, network_info) |
212 | 455 | self.firewall_driver.prepare_instance_filter(instance) | 502 | self.firewall_driver.prepare_instance_filter(instance, network_info) |
213 | 456 | self._create_image(instance, xml) | 503 | self._create_image(instance, xml, network_info) |
214 | 457 | self._conn.createXML(xml, 0) | 504 | self._conn.createXML(xml, 0) |
215 | 458 | LOG.debug(_("instance %s: is running"), instance['name']) | 505 | LOG.debug(_("instance %s: is running"), instance['name']) |
216 | 459 | self.firewall_driver.apply_instance_filter(instance) | 506 | self.firewall_driver.apply_instance_filter(instance) |
217 | @@ -609,7 +656,14 @@ | |||
218 | 609 | utils.execute('truncate', target, '-s', "%dG" % local_gb) | 656 | utils.execute('truncate', target, '-s', "%dG" % local_gb) |
219 | 610 | # TODO(vish): should we format disk by default? | 657 | # TODO(vish): should we format disk by default? |
220 | 611 | 658 | ||
222 | 612 | def _create_image(self, inst, libvirt_xml, suffix='', disk_images=None): | 659 | def _create_image(self, inst, libvirt_xml, suffix='', disk_images=None, |
223 | 660 | network_info=None): | ||
224 | 661 | if not network_info: | ||
225 | 662 | network_info = _get_network_info(inst) | ||
226 | 663 | |||
227 | 664 | if not suffix: | ||
228 | 665 | suffix = '' | ||
229 | 666 | |||
230 | 613 | # syntactic nicety | 667 | # syntactic nicety |
231 | 614 | def basepath(fname='', suffix=suffix): | 668 | def basepath(fname='', suffix=suffix): |
232 | 615 | return os.path.join(FLAGS.instances_path, | 669 | return os.path.join(FLAGS.instances_path, |
233 | @@ -685,28 +739,35 @@ | |||
234 | 685 | 739 | ||
235 | 686 | key = str(inst['key_data']) | 740 | key = str(inst['key_data']) |
236 | 687 | net = None | 741 | net = None |
242 | 688 | network_ref = db.network_get_by_instance(context.get_admin_context(), | 742 | |
243 | 689 | inst['id']) | 743 | nets = [] |
244 | 690 | if network_ref['injected']: | 744 | ifc_template = open(FLAGS.injected_network_template).read() |
245 | 691 | admin_context = context.get_admin_context() | 745 | ifc_num = -1 |
246 | 692 | address = db.instance_get_fixed_address(admin_context, inst['id']) | 746 | admin_context = context.get_admin_context() |
247 | 747 | for (network_ref, mapping) in network_info: | ||
248 | 748 | ifc_num += 1 | ||
249 | 749 | |||
250 | 750 | if not 'injected' in network_ref: | ||
251 | 751 | continue | ||
252 | 752 | |||
253 | 753 | address = mapping['ips'][0]['ip'] | ||
254 | 693 | address_v6 = None | 754 | address_v6 = None |
255 | 694 | if FLAGS.use_ipv6: | 755 | if FLAGS.use_ipv6: |
271 | 695 | address_v6 = db.instance_get_fixed_address_v6(admin_context, | 756 | address_v6 = mapping['ip6s'][0]['ip'] |
272 | 696 | inst['id']) | 757 | net_info = {'name': 'eth%d' % ifc_num, |
273 | 697 | 758 | 'address': address, | |
274 | 698 | interfaces_info = {'address': address, | 759 | 'netmask': network_ref['netmask'], |
275 | 699 | 'netmask': network_ref['netmask'], | 760 | 'gateway': network_ref['gateway'], |
276 | 700 | 'gateway': network_ref['gateway'], | 761 | 'broadcast': network_ref['broadcast'], |
277 | 701 | 'broadcast': network_ref['broadcast'], | 762 | 'dns': network_ref['dns'], |
278 | 702 | 'dns': network_ref['dns'], | 763 | 'address_v6': address_v6, |
279 | 703 | 'address_v6': address_v6, | 764 | 'gateway_v6': network_ref['gateway_v6'], |
280 | 704 | 'gateway_v6': network_ref['gateway_v6'], | 765 | 'netmask_v6': network_ref['netmask_v6'], |
281 | 705 | 'netmask_v6': network_ref['netmask_v6'], | 766 | 'use_ipv6': FLAGS.use_ipv6} |
282 | 706 | 'use_ipv6': FLAGS.use_ipv6} | 767 | nets.append(net_info) |
283 | 707 | 768 | ||
284 | 708 | net = str(Template(self.interfaces_xml, | 769 | net = str(Template(ifc_template, searchList=[{'interfaces': nets}])) |
285 | 709 | searchList=[interfaces_info])) | 770 | |
286 | 710 | if key or net: | 771 | if key or net: |
287 | 711 | inst_name = inst['name'] | 772 | inst_name = inst['name'] |
288 | 712 | img_id = inst.image_id | 773 | img_id = inst.image_id |
289 | @@ -728,20 +789,11 @@ | |||
290 | 728 | if FLAGS.libvirt_type == 'uml': | 789 | if FLAGS.libvirt_type == 'uml': |
291 | 729 | utils.execute('sudo', 'chown', 'root', basepath('disk')) | 790 | utils.execute('sudo', 'chown', 'root', basepath('disk')) |
292 | 730 | 791 | ||
304 | 731 | def to_xml(self, instance, rescue=False): | 792 | def _get_nic_for_xml(self, network, mapping): |
294 | 732 | # TODO(termie): cache? | ||
295 | 733 | LOG.debug(_('instance %s: starting toXML method'), instance['name']) | ||
296 | 734 | network = db.network_get_by_instance(context.get_admin_context(), | ||
297 | 735 | instance['id']) | ||
298 | 736 | # FIXME(vish): stick this in db | ||
299 | 737 | instance_type = instance['instance_type'] | ||
300 | 738 | # instance_type = test.INSTANCE_TYPES[instance_type] | ||
301 | 739 | instance_type = instance_types.get_instance_type(instance_type) | ||
302 | 740 | ip_address = db.instance_get_fixed_address(context.get_admin_context(), | ||
303 | 741 | instance['id']) | ||
305 | 742 | # Assume that the gateway also acts as the dhcp server. | 793 | # Assume that the gateway also acts as the dhcp server. |
306 | 743 | dhcp_server = network['gateway'] | 794 | dhcp_server = network['gateway'] |
307 | 744 | gateway_v6 = network['gateway_v6'] | 795 | gateway_v6 = network['gateway_v6'] |
308 | 796 | mac_id = mapping['mac'].replace(':', '') | ||
309 | 745 | 797 | ||
310 | 746 | if FLAGS.allow_project_net_traffic: | 798 | if FLAGS.allow_project_net_traffic: |
311 | 747 | if FLAGS.use_ipv6: | 799 | if FLAGS.use_ipv6: |
312 | @@ -766,6 +818,38 @@ | |||
313 | 766 | (net, mask) | 818 | (net, mask) |
314 | 767 | else: | 819 | else: |
315 | 768 | extra_params = "\n" | 820 | extra_params = "\n" |
316 | 821 | |||
317 | 822 | result = { | ||
318 | 823 | 'id': mac_id, | ||
319 | 824 | 'bridge_name': network['bridge'], | ||
320 | 825 | 'mac_address': mapping['mac'], | ||
321 | 826 | 'ip_address': mapping['ips'][0]['ip'], | ||
322 | 827 | 'dhcp_server': dhcp_server, | ||
323 | 828 | 'extra_params': extra_params, | ||
324 | 829 | } | ||
325 | 830 | |||
326 | 831 | if gateway_v6: | ||
327 | 832 | result['gateway_v6'] = gateway_v6 + "/128" | ||
328 | 833 | |||
329 | 834 | return result | ||
330 | 835 | |||
331 | 836 | def to_xml(self, instance, rescue=False, network_info=None): | ||
332 | 837 | # TODO(termie): cache? | ||
333 | 838 | LOG.debug(_('instance %s: starting toXML method'), instance['name']) | ||
334 | 839 | |||
335 | 840 | # TODO(adiantum) remove network_info creation code | ||
336 | 841 | # when multinics will be completed | ||
337 | 842 | if not network_info: | ||
338 | 843 | network_info = _get_network_info(instance) | ||
339 | 844 | |||
340 | 845 | nics = [] | ||
341 | 846 | for (network, mapping) in network_info: | ||
342 | 847 | nics.append(self._get_nic_for_xml(network, | ||
343 | 848 | mapping)) | ||
344 | 849 | # FIXME(vish): stick this in db | ||
345 | 850 | instance_type_name = instance['instance_type'] | ||
346 | 851 | instance_type = instance_types.get_instance_type(instance_type_name) | ||
347 | 852 | |||
348 | 769 | if FLAGS.use_cow_images: | 853 | if FLAGS.use_cow_images: |
349 | 770 | driver_type = 'qcow2' | 854 | driver_type = 'qcow2' |
350 | 771 | else: | 855 | else: |
351 | @@ -777,17 +861,11 @@ | |||
352 | 777 | instance['name']), | 861 | instance['name']), |
353 | 778 | 'memory_kb': instance_type['memory_mb'] * 1024, | 862 | 'memory_kb': instance_type['memory_mb'] * 1024, |
354 | 779 | 'vcpus': instance_type['vcpus'], | 863 | 'vcpus': instance_type['vcpus'], |
355 | 780 | 'bridge_name': network['bridge'], | ||
356 | 781 | 'mac_address': instance['mac_address'], | ||
357 | 782 | 'ip_address': ip_address, | ||
358 | 783 | 'dhcp_server': dhcp_server, | ||
359 | 784 | 'extra_params': extra_params, | ||
360 | 785 | 'rescue': rescue, | 864 | 'rescue': rescue, |
361 | 786 | 'local': instance_type['local_gb'], | 865 | 'local': instance_type['local_gb'], |
363 | 787 | 'driver_type': driver_type} | 866 | 'driver_type': driver_type, |
364 | 867 | 'nics': nics} | ||
365 | 788 | 868 | ||
366 | 789 | if gateway_v6: | ||
367 | 790 | xml_info['gateway_v6'] = gateway_v6 + "/128" | ||
368 | 791 | if not rescue: | 869 | if not rescue: |
369 | 792 | if instance['kernel_id']: | 870 | if instance['kernel_id']: |
370 | 793 | xml_info['kernel'] = xml_info['basepath'] + "/kernel" | 871 | xml_info['kernel'] = xml_info['basepath'] + "/kernel" |
371 | @@ -800,7 +878,6 @@ | |||
372 | 800 | xml = str(Template(self.libvirt_xml, searchList=[xml_info])) | 878 | xml = str(Template(self.libvirt_xml, searchList=[xml_info])) |
373 | 801 | LOG.debug(_('instance %s: finished toXML method'), | 879 | LOG.debug(_('instance %s: finished toXML method'), |
374 | 802 | instance['name']) | 880 | instance['name']) |
375 | 803 | |||
376 | 804 | return xml | 881 | return xml |
377 | 805 | 882 | ||
378 | 806 | def get_info(self, instance_name): | 883 | def get_info(self, instance_name): |
379 | @@ -1316,7 +1393,7 @@ | |||
380 | 1316 | 1393 | ||
381 | 1317 | 1394 | ||
382 | 1318 | class FirewallDriver(object): | 1395 | class FirewallDriver(object): |
384 | 1319 | def prepare_instance_filter(self, instance): | 1396 | def prepare_instance_filter(self, instance, network_info=None): |
385 | 1320 | """Prepare filters for the instance. | 1397 | """Prepare filters for the instance. |
386 | 1321 | 1398 | ||
387 | 1322 | At this point, the instance isn't running yet.""" | 1399 | At this point, the instance isn't running yet.""" |
388 | @@ -1350,7 +1427,7 @@ | |||
389 | 1350 | the security group.""" | 1427 | the security group.""" |
390 | 1351 | raise NotImplementedError() | 1428 | raise NotImplementedError() |
391 | 1352 | 1429 | ||
393 | 1353 | def setup_basic_filtering(self, instance): | 1430 | def setup_basic_filtering(self, instance, network_info=None): |
394 | 1354 | """Create rules to block spoofing and allow dhcp. | 1431 | """Create rules to block spoofing and allow dhcp. |
395 | 1355 | 1432 | ||
396 | 1356 | This gets called when spawning an instance, before | 1433 | This gets called when spawning an instance, before |
397 | @@ -1359,11 +1436,6 @@ | |||
398 | 1359 | """ | 1436 | """ |
399 | 1360 | raise NotImplementedError() | 1437 | raise NotImplementedError() |
400 | 1361 | 1438 | ||
401 | 1362 | def _gateway_v6_for_instance(self, instance): | ||
402 | 1363 | network = db.network_get_by_instance(context.get_admin_context(), | ||
403 | 1364 | instance['id']) | ||
404 | 1365 | return network['gateway_v6'] | ||
405 | 1366 | |||
406 | 1367 | 1439 | ||
407 | 1368 | class NWFilterFirewall(FirewallDriver): | 1440 | class NWFilterFirewall(FirewallDriver): |
408 | 1369 | """ | 1441 | """ |
409 | @@ -1455,10 +1527,13 @@ | |||
410 | 1455 | </rule> | 1527 | </rule> |
411 | 1456 | </filter>''' | 1528 | </filter>''' |
412 | 1457 | 1529 | ||
414 | 1458 | def setup_basic_filtering(self, instance): | 1530 | def setup_basic_filtering(self, instance, network_info=None): |
415 | 1459 | """Set up basic filtering (MAC, IP, and ARP spoofing protection)""" | 1531 | """Set up basic filtering (MAC, IP, and ARP spoofing protection)""" |
416 | 1460 | logging.info('called setup_basic_filtering in nwfilter') | 1532 | logging.info('called setup_basic_filtering in nwfilter') |
417 | 1461 | 1533 | ||
418 | 1534 | if not network_info: | ||
419 | 1535 | network_info = _get_network_info(instance) | ||
420 | 1536 | |||
421 | 1462 | if self.handle_security_groups: | 1537 | if self.handle_security_groups: |
422 | 1463 | # No point in setting up a filter set that we'll be overriding | 1538 | # No point in setting up a filter set that we'll be overriding |
423 | 1464 | # anyway. | 1539 | # anyway. |
424 | @@ -1467,9 +1542,11 @@ | |||
425 | 1467 | logging.info('ensuring static filters') | 1542 | logging.info('ensuring static filters') |
426 | 1468 | self._ensure_static_filters() | 1543 | self._ensure_static_filters() |
427 | 1469 | 1544 | ||
431 | 1470 | instance_filter_name = self._instance_filter_name(instance) | 1545 | for (network, mapping) in network_info: |
432 | 1471 | self._define_filter(self._filter_container(instance_filter_name, | 1546 | nic_id = mapping['mac'].replace(':', '') |
433 | 1472 | ['nova-base'])) | 1547 | instance_filter_name = self._instance_filter_name(instance, nic_id) |
434 | 1548 | self._define_filter(self._filter_container(instance_filter_name, | ||
435 | 1549 | ['nova-base'])) | ||
436 | 1473 | 1550 | ||
437 | 1474 | def _ensure_static_filters(self): | 1551 | def _ensure_static_filters(self): |
438 | 1475 | if self.static_filters_configured: | 1552 | if self.static_filters_configured: |
439 | @@ -1560,48 +1637,60 @@ | |||
440 | 1560 | # Nothing to do | 1637 | # Nothing to do |
441 | 1561 | pass | 1638 | pass |
442 | 1562 | 1639 | ||
444 | 1563 | def prepare_instance_filter(self, instance): | 1640 | def prepare_instance_filter(self, instance, network_info=None): |
445 | 1564 | """ | 1641 | """ |
446 | 1565 | Creates an NWFilter for the given instance. In the process, | 1642 | Creates an NWFilter for the given instance. In the process, |
447 | 1566 | it makes sure the filters for the security groups as well as | 1643 | it makes sure the filters for the security groups as well as |
448 | 1567 | the base filter are all in place. | 1644 | the base filter are all in place. |
449 | 1568 | """ | 1645 | """ |
450 | 1646 | if not network_info: | ||
451 | 1647 | network_info = _get_network_info(instance) | ||
452 | 1569 | if instance['image_id'] == FLAGS.vpn_image_id: | 1648 | if instance['image_id'] == FLAGS.vpn_image_id: |
453 | 1570 | base_filter = 'nova-vpn' | 1649 | base_filter = 'nova-vpn' |
454 | 1571 | else: | 1650 | else: |
455 | 1572 | base_filter = 'nova-base' | 1651 | base_filter = 'nova-base' |
456 | 1573 | 1652 | ||
460 | 1574 | instance_filter_name = self._instance_filter_name(instance) | 1653 | ctxt = context.get_admin_context() |
461 | 1575 | instance_secgroup_filter_name = '%s-secgroup' % (instance_filter_name,) | 1654 | |
462 | 1576 | instance_filter_children = [base_filter, instance_secgroup_filter_name] | 1655 | instance_secgroup_filter_name = \ |
463 | 1656 | '%s-secgroup' % (self._instance_filter_name(instance)) | ||
464 | 1657 | #% (instance_filter_name,) | ||
465 | 1658 | |||
466 | 1577 | instance_secgroup_filter_children = ['nova-base-ipv4', | 1659 | instance_secgroup_filter_children = ['nova-base-ipv4', |
467 | 1578 | 'nova-base-ipv6', | 1660 | 'nova-base-ipv6', |
468 | 1579 | 'nova-allow-dhcp-server'] | 1661 | 'nova-allow-dhcp-server'] |
483 | 1580 | if FLAGS.use_ipv6: | 1662 | |
484 | 1581 | gateway_v6 = self._gateway_v6_for_instance(instance) | 1663 | for security_group in \ |
485 | 1582 | if gateway_v6: | 1664 | db.security_group_get_by_instance(ctxt, instance['id']): |
472 | 1583 | instance_secgroup_filter_children += ['nova-allow-ra-server'] | ||
473 | 1584 | |||
474 | 1585 | ctxt = context.get_admin_context() | ||
475 | 1586 | |||
476 | 1587 | if FLAGS.allow_project_net_traffic: | ||
477 | 1588 | instance_filter_children += ['nova-project'] | ||
478 | 1589 | if FLAGS.use_ipv6: | ||
479 | 1590 | instance_filter_children += ['nova-project-v6'] | ||
480 | 1591 | |||
481 | 1592 | for security_group in db.security_group_get_by_instance(ctxt, | ||
482 | 1593 | instance['id']): | ||
486 | 1594 | 1665 | ||
487 | 1595 | self.refresh_security_group_rules(security_group['id']) | 1666 | self.refresh_security_group_rules(security_group['id']) |
488 | 1596 | 1667 | ||
489 | 1597 | instance_secgroup_filter_children += [('nova-secgroup-%s' % | 1668 | instance_secgroup_filter_children += [('nova-secgroup-%s' % |
491 | 1598 | security_group['id'])] | 1669 | security_group['id'])] |
492 | 1599 | 1670 | ||
494 | 1600 | self._define_filter( | 1671 | self._define_filter( |
495 | 1601 | self._filter_container(instance_secgroup_filter_name, | 1672 | self._filter_container(instance_secgroup_filter_name, |
496 | 1602 | instance_secgroup_filter_children)) | 1673 | instance_secgroup_filter_children)) |
497 | 1603 | 1674 | ||
499 | 1604 | self._define_filter( | 1675 | for (network, mapping) in network_info: |
500 | 1676 | nic_id = mapping['mac'].replace(':', '') | ||
501 | 1677 | instance_filter_name = self._instance_filter_name(instance, nic_id) | ||
502 | 1678 | instance_filter_children = \ | ||
503 | 1679 | [base_filter, instance_secgroup_filter_name] | ||
504 | 1680 | |||
505 | 1681 | if FLAGS.use_ipv6: | ||
506 | 1682 | gateway_v6 = network['gateway_v6'] | ||
507 | 1683 | |||
508 | 1684 | if gateway_v6: | ||
509 | 1685 | instance_secgroup_filter_children += \ | ||
510 | 1686 | ['nova-allow-ra-server'] | ||
511 | 1687 | |||
512 | 1688 | if FLAGS.allow_project_net_traffic: | ||
513 | 1689 | instance_filter_children += ['nova-project'] | ||
514 | 1690 | if FLAGS.use_ipv6: | ||
515 | 1691 | instance_filter_children += ['nova-project-v6'] | ||
516 | 1692 | |||
517 | 1693 | self._define_filter( | ||
518 | 1605 | self._filter_container(instance_filter_name, | 1694 | self._filter_container(instance_filter_name, |
519 | 1606 | instance_filter_children)) | 1695 | instance_filter_children)) |
520 | 1607 | 1696 | ||
521 | @@ -1649,8 +1738,10 @@ | |||
522 | 1649 | xml += "chain='ipv4'>%s</filter>" % rule_xml | 1738 | xml += "chain='ipv4'>%s</filter>" % rule_xml |
523 | 1650 | return xml | 1739 | return xml |
524 | 1651 | 1740 | ||
527 | 1652 | def _instance_filter_name(self, instance): | 1741 | def _instance_filter_name(self, instance, nic_id=None): |
528 | 1653 | return 'nova-instance-%s' % instance['name'] | 1742 | if not nic_id: |
529 | 1743 | return 'nova-instance-%s' % (instance['name']) | ||
530 | 1744 | return 'nova-instance-%s-%s' % (instance['name'], nic_id) | ||
531 | 1654 | 1745 | ||
532 | 1655 | 1746 | ||
533 | 1656 | class IptablesFirewallDriver(FirewallDriver): | 1747 | class IptablesFirewallDriver(FirewallDriver): |
534 | @@ -1665,9 +1756,11 @@ | |||
535 | 1665 | self.iptables.ipv6['filter'].add_chain('sg-fallback') | 1756 | self.iptables.ipv6['filter'].add_chain('sg-fallback') |
536 | 1666 | self.iptables.ipv6['filter'].add_rule('sg-fallback', '-j DROP') | 1757 | self.iptables.ipv6['filter'].add_rule('sg-fallback', '-j DROP') |
537 | 1667 | 1758 | ||
539 | 1668 | def setup_basic_filtering(self, instance): | 1759 | def setup_basic_filtering(self, instance, network_info=None): |
540 | 1669 | """Use NWFilter from libvirt for this.""" | 1760 | """Use NWFilter from libvirt for this.""" |
542 | 1670 | return self.nwfilter.setup_basic_filtering(instance) | 1761 | if not network_info: |
543 | 1762 | network_info = _get_network_info(instance) | ||
544 | 1763 | return self.nwfilter.setup_basic_filtering(instance, network_info) | ||
545 | 1671 | 1764 | ||
546 | 1672 | def apply_instance_filter(self, instance): | 1765 | def apply_instance_filter(self, instance): |
547 | 1673 | """No-op. Everything is done in prepare_instance_filter""" | 1766 | """No-op. Everything is done in prepare_instance_filter""" |
548 | @@ -1681,29 +1774,40 @@ | |||
549 | 1681 | LOG.info(_('Attempted to unfilter instance %s which is not ' | 1774 | LOG.info(_('Attempted to unfilter instance %s which is not ' |
550 | 1682 | 'filtered'), instance['id']) | 1775 | 'filtered'), instance['id']) |
551 | 1683 | 1776 | ||
553 | 1684 | def prepare_instance_filter(self, instance): | 1777 | def prepare_instance_filter(self, instance, network_info=None): |
554 | 1778 | if not network_info: | ||
555 | 1779 | network_info = _get_network_info(instance) | ||
556 | 1685 | self.instances[instance['id']] = instance | 1780 | self.instances[instance['id']] = instance |
558 | 1686 | self.add_filters_for_instance(instance) | 1781 | self.add_filters_for_instance(instance, network_info) |
559 | 1687 | self.iptables.apply() | 1782 | self.iptables.apply() |
560 | 1688 | 1783 | ||
562 | 1689 | def add_filters_for_instance(self, instance): | 1784 | def add_filters_for_instance(self, instance, network_info=None): |
563 | 1785 | if not network_info: | ||
564 | 1786 | network_info = _get_network_info(instance) | ||
565 | 1690 | chain_name = self._instance_chain_name(instance) | 1787 | chain_name = self._instance_chain_name(instance) |
566 | 1691 | 1788 | ||
567 | 1692 | self.iptables.ipv4['filter'].add_chain(chain_name) | 1789 | self.iptables.ipv4['filter'].add_chain(chain_name) |
572 | 1693 | ipv4_address = self._ip_for_instance(instance) | 1790 | |
573 | 1694 | self.iptables.ipv4['filter'].add_rule('local', | 1791 | ips_v4 = [ip['ip'] for (_, mapping) in network_info |
574 | 1695 | '-d %s -j $%s' % | 1792 | for ip in mapping['ips']] |
575 | 1696 | (ipv4_address, chain_name)) | 1793 | |
576 | 1794 | for ipv4_address in ips_v4: | ||
577 | 1795 | self.iptables.ipv4['filter'].add_rule('local', | ||
578 | 1796 | '-d %s -j $%s' % | ||
579 | 1797 | (ipv4_address, chain_name)) | ||
580 | 1697 | 1798 | ||
581 | 1698 | if FLAGS.use_ipv6: | 1799 | if FLAGS.use_ipv6: |
582 | 1699 | self.iptables.ipv6['filter'].add_chain(chain_name) | 1800 | self.iptables.ipv6['filter'].add_chain(chain_name) |
590 | 1700 | ipv6_address = self._ip_for_instance_v6(instance) | 1801 | ips_v6 = [ip['ip'] for (_, mapping) in network_info |
591 | 1701 | self.iptables.ipv6['filter'].add_rule('local', | 1802 | for ip in mapping['ip6s']] |
592 | 1702 | '-d %s -j $%s' % | 1803 | |
593 | 1703 | (ipv6_address, | 1804 | for ipv6_address in ips_v6: |
594 | 1704 | chain_name)) | 1805 | self.iptables.ipv6['filter'].add_rule('local', |
595 | 1705 | 1806 | '-d %s -j $%s' % | |
596 | 1706 | ipv4_rules, ipv6_rules = self.instance_rules(instance) | 1807 | (ipv6_address, |
597 | 1808 | chain_name)) | ||
598 | 1809 | |||
599 | 1810 | ipv4_rules, ipv6_rules = self.instance_rules(instance, network_info) | ||
600 | 1707 | 1811 | ||
601 | 1708 | for rule in ipv4_rules: | 1812 | for rule in ipv4_rules: |
602 | 1709 | self.iptables.ipv4['filter'].add_rule(chain_name, rule) | 1813 | self.iptables.ipv4['filter'].add_rule(chain_name, rule) |
603 | @@ -1719,7 +1823,9 @@ | |||
604 | 1719 | if FLAGS.use_ipv6: | 1823 | if FLAGS.use_ipv6: |
605 | 1720 | self.iptables.ipv6['filter'].remove_chain(chain_name) | 1824 | self.iptables.ipv6['filter'].remove_chain(chain_name) |
606 | 1721 | 1825 | ||
608 | 1722 | def instance_rules(self, instance): | 1826 | def instance_rules(self, instance, network_info=None): |
609 | 1827 | if not network_info: | ||
610 | 1828 | network_info = _get_network_info(instance) | ||
611 | 1723 | ctxt = context.get_admin_context() | 1829 | ctxt = context.get_admin_context() |
612 | 1724 | 1830 | ||
613 | 1725 | ipv4_rules = [] | 1831 | ipv4_rules = [] |
614 | @@ -1733,28 +1839,36 @@ | |||
615 | 1733 | ipv4_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] | 1839 | ipv4_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] |
616 | 1734 | ipv6_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] | 1840 | ipv6_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] |
617 | 1735 | 1841 | ||
621 | 1736 | dhcp_server = self._dhcp_server_for_instance(instance) | 1842 | dhcp_servers = [network['gateway'] for (network, _m) in network_info] |
622 | 1737 | ipv4_rules += ['-s %s -p udp --sport 67 --dport 68 ' | 1843 | |
623 | 1738 | '-j ACCEPT' % (dhcp_server,)] | 1844 | for dhcp_server in dhcp_servers: |
624 | 1845 | ipv4_rules.append('-s %s -p udp --sport 67 --dport 68 ' | ||
625 | 1846 | '-j ACCEPT' % (dhcp_server,)) | ||
626 | 1739 | 1847 | ||
627 | 1740 | #Allow project network traffic | 1848 | #Allow project network traffic |
628 | 1741 | if FLAGS.allow_project_net_traffic: | 1849 | if FLAGS.allow_project_net_traffic: |
631 | 1742 | cidr = self._project_cidr_for_instance(instance) | 1850 | cidrs = [network['cidr'] for (network, _m) in network_info] |
632 | 1743 | ipv4_rules += ['-s %s -j ACCEPT' % (cidr,)] | 1851 | for cidr in cidrs: |
633 | 1852 | ipv4_rules.append('-s %s -j ACCEPT' % (cidr,)) | ||
634 | 1744 | 1853 | ||
635 | 1745 | # We wrap these in FLAGS.use_ipv6 because they might cause | 1854 | # We wrap these in FLAGS.use_ipv6 because they might cause |
636 | 1746 | # a DB lookup. The other ones are just list operations, so | 1855 | # a DB lookup. The other ones are just list operations, so |
637 | 1747 | # they're not worth the clutter. | 1856 | # they're not worth the clutter. |
638 | 1748 | if FLAGS.use_ipv6: | 1857 | if FLAGS.use_ipv6: |
639 | 1749 | # Allow RA responses | 1858 | # Allow RA responses |
643 | 1750 | gateway_v6 = self._gateway_v6_for_instance(instance) | 1859 | gateways_v6 = [network['gateway_v6'] for (network, _) in |
644 | 1751 | if gateway_v6: | 1860 | network_info] |
645 | 1752 | ipv6_rules += ['-s %s/128 -p icmpv6 -j ACCEPT' % (gateway_v6,)] | 1861 | for gateway_v6 in gateways_v6: |
646 | 1862 | ipv6_rules.append( | ||
647 | 1863 | '-s %s/128 -p icmpv6 -j ACCEPT' % (gateway_v6,)) | ||
648 | 1753 | 1864 | ||
649 | 1754 | #Allow project network traffic | 1865 | #Allow project network traffic |
650 | 1755 | if FLAGS.allow_project_net_traffic: | 1866 | if FLAGS.allow_project_net_traffic: |
653 | 1756 | cidrv6 = self._project_cidrv6_for_instance(instance) | 1867 | cidrv6s = [network['cidr_v6'] for (network, _m) |
654 | 1757 | ipv6_rules += ['-s %s -j ACCEPT' % (cidrv6,)] | 1868 | in network_info] |
655 | 1869 | |||
656 | 1870 | for cidrv6 in cidrv6s: | ||
657 | 1871 | ipv6_rules.append('-s %s -j ACCEPT' % (cidrv6,)) | ||
658 | 1758 | 1872 | ||
659 | 1759 | security_groups = db.security_group_get_by_instance(ctxt, | 1873 | security_groups = db.security_group_get_by_instance(ctxt, |
660 | 1760 | instance['id']) | 1874 | instance['id']) |
661 | @@ -1836,31 +1950,3 @@ | |||
662 | 1836 | 1950 | ||
663 | 1837 | def _instance_chain_name(self, instance): | 1951 | def _instance_chain_name(self, instance): |
664 | 1838 | return 'inst-%s' % (instance['id'],) | 1952 | return 'inst-%s' % (instance['id'],) |
665 | 1839 | |||
666 | 1840 | def _ip_for_instance(self, instance): | ||
667 | 1841 | return db.instance_get_fixed_address(context.get_admin_context(), | ||
668 | 1842 | instance['id']) | ||
669 | 1843 | |||
670 | 1844 | def _ip_for_instance_v6(self, instance): | ||
671 | 1845 | return db.instance_get_fixed_address_v6(context.get_admin_context(), | ||
672 | 1846 | instance['id']) | ||
673 | 1847 | |||
674 | 1848 | def _dhcp_server_for_instance(self, instance): | ||
675 | 1849 | network = db.network_get_by_instance(context.get_admin_context(), | ||
676 | 1850 | instance['id']) | ||
677 | 1851 | return network['gateway'] | ||
678 | 1852 | |||
679 | 1853 | def _gateway_v6_for_instance(self, instance): | ||
680 | 1854 | network = db.network_get_by_instance(context.get_admin_context(), | ||
681 | 1855 | instance['id']) | ||
682 | 1856 | return network['gateway_v6'] | ||
683 | 1857 | |||
684 | 1858 | def _project_cidr_for_instance(self, instance): | ||
685 | 1859 | network = db.network_get_by_instance(context.get_admin_context(), | ||
686 | 1860 | instance['id']) | ||
687 | 1861 | return network['cidr'] | ||
688 | 1862 | |||
689 | 1863 | def _project_cidrv6_for_instance(self, instance): | ||
690 | 1864 | network = db.network_get_by_instance(context.get_admin_context(), | ||
691 | 1865 | instance['id']) | ||
692 | 1866 | return network['cidr_v6'] |
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()?