Revision 8764d304
b/snf-cyclades-app/synnefo/db/models.py | ||
---|---|---|
555 | 555 |
pool.put(address) |
556 | 556 |
pool.save() |
557 | 557 |
|
558 |
@property |
|
559 |
def subnet4(self): |
|
560 |
return self.get_subnet(version=4) |
|
561 |
|
|
562 |
@property |
|
563 |
def subnet6(self): |
|
564 |
return self.get_subnet(version=6) |
|
565 |
|
|
566 |
def get_subnet(self, version=4): |
|
567 |
for subnet in self.subnets.all(): |
|
568 |
if subnet.ipversion == version: |
|
569 |
return subnet.cidr |
|
570 |
|
|
558 | 571 |
class InvalidBackendIdError(Exception): |
559 | 572 |
def __init__(self, value): |
560 | 573 |
self.value = value |
... | ... | |
596 | 609 |
dns_nameservers = fields.SeparatedValuesField('DNS Nameservers', null=True) |
597 | 610 |
|
598 | 611 |
def __unicode__(self): |
599 |
return "<Subnet %s, Network: %s>" % (self.id, self.network_id) |
|
612 |
msg = u"<Subnet %s, Network: %s, CIDR: %s>" |
|
613 |
return msg % (self.id, self.network_id, self.cidr) |
|
600 | 614 |
|
601 | 615 |
def get_pool(self, locked=True): |
602 | 616 |
if self.ipversion == 6: |
... | ... | |
769 | 783 |
|
770 | 784 |
@property |
771 | 785 |
def ipv4_address(self): |
772 |
try: |
|
773 |
return self.ips.get(subnet__ipversion=4).address |
|
774 |
except IPAddress.DoesNotExist: |
|
775 |
return None |
|
786 |
return self.get_ip_address(version=4) |
|
787 |
|
|
788 |
@property |
|
789 |
def ipv6_address(self): |
|
790 |
return self.get_ip_address(version=6) |
|
791 |
|
|
792 |
def get_ip_address(self, version=4): |
|
793 |
for ip in self.ips.all(): |
|
794 |
if ip.subnet.ipversion == version: |
|
795 |
return ip.address |
|
796 |
return None |
|
776 | 797 |
|
777 | 798 |
|
778 | 799 |
class SecurityGroup(models.Model): |
b/snf-cyclades-app/synnefo/db/models_factory.py | ||
---|---|---|
157 | 157 |
models.Network.FLAVORS[a.flavor]['tags']) |
158 | 158 |
public = False |
159 | 159 |
deleted = False |
160 |
state = factory.Sequence(round_seq_first(models.Network.OPER_STATES))
|
|
160 |
state = "ACTIVE"
|
|
161 | 161 |
|
162 | 162 |
|
163 | 163 |
class DeletedNetwork(NetworkFactory): |
... | ... | |
191 | 191 |
size = 0 |
192 | 192 |
|
193 | 193 |
|
194 |
class IPv4SubnetFactory(factory.DjangoModelFactory):
|
|
194 |
class SubnetFactory(factory.DjangoModelFactory): |
|
195 | 195 |
FACTORY_FOR = models.Subnet |
196 |
|
|
197 | 196 |
network = factory.SubFactory(NetworkFactory, state="ACTIVE") |
198 | 197 |
name = factory.LazyAttribute(lambda self: random_string(30)) |
199 |
ipversion = 4 |
|
200 |
cidr = factory.Sequence(lambda n: '192.168.{0}.0/24'.format(n)) |
|
201 | 198 |
dhcp = True |
202 |
gateway = factory.Sequence(lambda n: '192.168.{0}.1'.format(n)) |
|
203 | 199 |
dns_nameservers = [] |
204 | 200 |
host_routes = [] |
201 |
|
|
202 |
|
|
203 |
class IPv4SubnetFactory(SubnetFactory): |
|
204 |
ipversion = 4 |
|
205 |
cidr = factory.Sequence(lambda n: '192.168.{0}.0/24'.format(n)) |
|
206 |
gateway = factory.Sequence(lambda n: '192.168.{0}.1'.format(n)) |
|
205 | 207 |
pool = factory.RelatedFactory(IPPoolTableFactory, 'subnet') |
206 | 208 |
|
207 | 209 |
|
208 |
class IPv6SubnetFactory(IPv4SubnetFactory):
|
|
210 |
class IPv6SubnetFactory(SubnetFactory): |
|
209 | 211 |
ipversion = 6 |
210 | 212 |
cidr = "2001:648:2ffc:1112::/64" |
211 | 213 |
gateway = None |
212 | 214 |
|
213 | 215 |
|
216 |
class NetworkWithSubnetFactory(NetworkFactory): |
|
217 |
subnet = factory.RelatedFactory(IPv4SubnetFactory, 'network') |
|
218 |
subnet6 = factory.RelatedFactory(IPv6SubnetFactory, 'network') |
|
219 |
|
|
220 |
|
|
214 | 221 |
class IPv4AddressFactory(factory.DjangoModelFactory): |
215 | 222 |
FACTORY_FOR = models.IPAddress |
216 | 223 |
|
217 |
subnet = factory.SubFactory(IPv4SubnetFactory) |
|
218 | 224 |
network = factory.SubFactory(NetworkFactory) |
225 |
subnet = factory.SubFactory(IPv4SubnetFactory, |
|
226 |
network=factory.SelfAttribute('..network')) |
|
219 | 227 |
address =\ |
220 | 228 |
factory.LazyAttributeSequence(lambda self, n: self.subnet.cidr[:-4] + |
221 | 229 |
'{0}'.format(int(n) + 2)) |
b/snf-cyclades-app/synnefo/logic/backend.py | ||
---|---|---|
35 | 35 |
from datetime import datetime, timedelta |
36 | 36 |
|
37 | 37 |
from synnefo.db.models import (Backend, VirtualMachine, Network, |
38 |
IPAddress, |
|
39 | 38 |
BackendNetwork, BACKEND_STATUSES, |
40 | 39 |
pooled_rapi_client, VirtualMachineDiagnostic, |
41 |
Flavor) |
|
40 |
Flavor, IPAddress)
|
|
42 | 41 |
from synnefo.logic import utils |
43 | 42 |
from synnefo import quotas |
44 | 43 |
from synnefo.api.util import release_resource |
... | ... | |
60 | 59 |
# stale and removed from DB. |
61 | 60 |
BUILDING_NIC_TIMEOUT = timedelta(seconds=180) |
62 | 61 |
|
63 |
NIC_FIELDS = ["state", "mac", "ipv4", "ipv6", "network", "firewall_profile",
|
|
64 |
"index"] |
|
62 |
NIC_FIELDS = ["state", "mac", "ipv4_address", "ipv6_address", "network",
|
|
63 |
"firewall_profile", "index"]
|
|
65 | 64 |
UNKNOWN_NIC_PREFIX = "unknown-" |
66 | 65 |
|
67 | 66 |
|
... | ... | |
260 | 259 |
" valid name." % ganeti_nic |
261 | 260 |
log.error(msg) |
262 | 261 |
continue |
263 |
if ganeti_nic["ipv4"]: |
|
264 |
network = ganeti_nic["network"] |
|
265 |
network.reserve_address(ganeti_nic["ipv4"]) |
|
266 |
vm.nics.create(id=nic_name, **ganeti_nic) |
|
262 |
ipaddress = None |
|
263 |
network = ganeti_nic["network"] |
|
264 |
ipv4_address = ganeti_nic["ipv4_address"] |
|
265 |
if ipv4_address: |
|
266 |
network.reserve_address(ipv4_address) |
|
267 |
subnet = network.subnets.get(ipversion=4) |
|
268 |
ipaddress = IPAddress.objects.create(address=ipv4_address, |
|
269 |
network=network, |
|
270 |
subnet=subnet, |
|
271 |
userid=vm.userid) |
|
272 |
# TODO |
|
273 |
ganeti_nic.pop("ipv4_address") |
|
274 |
ganeti_nic.pop("ip", None) |
|
275 |
ganeti_nic.pop("ipv6_address") |
|
276 |
nic = vm.nics.create(id=nic_name, **ganeti_nic) |
|
277 |
if ipaddress is not None: |
|
278 |
ipaddress.nic = nic |
|
279 |
ipaddress.save() |
|
267 | 280 |
elif not nics_are_equal(db_nic, ganeti_nic): |
268 | 281 |
# Special case where the IPv4 address has changed, because you |
269 | 282 |
# need to release the old IPv4 address and reserve the new one |
270 |
if db_nic.ipv4 != ganeti_nic["ipv4"]: |
|
283 |
ipv4_address = ganeti_nic["ipv4_address"] |
|
284 |
if db_nic.ipv4_address != ipv4_address: |
|
271 | 285 |
release_nic_address(db_nic) |
272 |
if ganeti_nic["ipv4"]: |
|
273 |
ganeti_nic["network"].reserve_address(ganeti_nic["ipv4"]) |
|
274 |
|
|
275 |
# Update the NIC in DB with the values from Ganeti NIC |
|
276 |
[setattr(db_nic, f, ganeti_nic[f]) for f in NIC_FIELDS] |
|
277 |
db_nic.save() |
|
286 |
if ipv4_address: |
|
287 |
network = ganeti_nic["network"] |
|
288 |
network.reserve_address(ipv4_address) |
|
289 |
subnet = network.subnets.get(ipversion=4) |
|
290 |
ipaddress, _ =\ |
|
291 |
IPAddress.objects.get_or_create(network=network, |
|
292 |
subnet=subnet, |
|
293 |
userid=vm.userid, |
|
294 |
address=ipv4_address) |
|
295 |
ipaddress.nic = nic |
|
296 |
ipaddress.save() |
|
297 |
|
|
298 |
for f in ["state", "mac", "network", "firewall_profile", "index"]: |
|
299 |
# Update the NIC in DB with the values from Ganeti NIC |
|
300 |
setattr(db_nic, f, ganeti_nic[f]) |
|
301 |
db_nic.save() |
|
278 | 302 |
|
279 | 303 |
# Dummy update the network, to work with 'changed-since' |
280 | 304 |
db_nic.network.save() |
... | ... | |
308 | 332 |
# Get the new nic info |
309 | 333 |
mac = gnic.get('mac') |
310 | 334 |
ipv4 = gnic.get('ip') |
311 |
ipv6 = mac2eui64(mac, network.subnet6)\
|
|
312 |
if network.subnet6 is not None else None
|
|
335 |
subnet6 = network.subnet6
|
|
336 |
ipv6 = mac2eui64(mac, subnet6) if subnet6 else None
|
|
313 | 337 |
|
314 | 338 |
firewall = gnic.get('firewall') |
315 | 339 |
firewall_profile = _reverse_tags.get(firewall) |
... | ... | |
320 | 344 |
'index': index, |
321 | 345 |
'network': network, |
322 | 346 |
'mac': mac, |
323 |
'ipv4': ipv4, |
|
324 |
'ipv6': ipv6, |
|
347 |
'ipv4_address': ipv4,
|
|
348 |
'ipv6_address': ipv6,
|
|
325 | 349 |
'firewall_profile': firewall_profile, |
326 | 350 |
'state': 'ACTIVE'} |
327 | 351 |
|
... | ... | |
338 | 362 |
|
339 | 363 |
""" |
340 | 364 |
|
341 |
if nic.ipv4: |
|
342 |
if nic.ip_type == "FLOATING": |
|
343 |
IPAddress.objects.filter(machine=nic.machine_id, |
|
344 |
network=nic.network_id, |
|
345 |
ipv4=nic.ipv4).update(machine=None) |
|
365 |
for ip in nic.ips.all(): |
|
366 |
if ip.subnet.ipversion == 4: |
|
367 |
if ip.floating_ip: |
|
368 |
ip.nic = None |
|
369 |
ip.save() |
|
370 |
else: |
|
371 |
ip.network.release_address(ip.address) |
|
372 |
ip.delete() |
|
346 | 373 |
else: |
347 |
nic.network.release_address(nic.ipv4)
|
|
374 |
ip.delete()
|
|
348 | 375 |
|
349 | 376 |
|
350 | 377 |
@transaction.commit_on_success |
... | ... | |
718 | 745 |
subnet6 = None |
719 | 746 |
gateway = None |
720 | 747 |
gateway6 = None |
721 |
for subnet in network.subnets.all(): |
|
722 |
if subnet.ipversion == 4: |
|
723 |
if subnet.dhcp: |
|
748 |
for dbsubnet in network.subnets.all():
|
|
749 |
if dbsubnet.ipversion == 4:
|
|
750 |
if dbsubnet.dhcp:
|
|
724 | 751 |
tags.append('nfdhcpd') |
725 |
subnet = subnet.cidr |
|
726 |
gateway = subnet.gateway |
|
727 |
elif subnet.ipversion == 6: |
|
728 |
subnet6 = subnet.cidr |
|
729 |
gateway6 = subnet.gateway |
|
752 |
subnet = dbsubnet.cidr
|
|
753 |
gateway = dbsubnet.gateway
|
|
754 |
elif dbsubnet.ipversion == 6:
|
|
755 |
subnet6 = dbsubnet.cidr
|
|
756 |
gateway6 = dbsubnet.gateway
|
|
730 | 757 |
|
731 | 758 |
if network.public: |
732 | 759 |
conflicts_check = True |
... | ... | |
823 | 850 |
|
824 | 851 |
nic = {'name': nic.backend_uuid, |
825 | 852 |
'network': network.backend_id, |
826 |
'ip': nic.ipv4} |
|
853 |
'ip': nic.ipv4_address}
|
|
827 | 854 |
|
828 | 855 |
log.debug("Adding NIC %s to VM %s", nic, vm) |
829 | 856 |
|
b/snf-cyclades-app/synnefo/logic/networks.py | ||
---|---|---|
39 | 39 |
from snf_django.lib.api import faults |
40 | 40 |
from synnefo.api import util |
41 | 41 |
from synnefo import quotas |
42 |
from synnefo.db.models import Network, Backend |
|
42 |
from synnefo.db.models import Network, Backend, Subnet
|
|
43 | 43 |
from synnefo.db.utils import validate_mac |
44 | 44 |
from synnefo.db.pools import EmptyPool |
45 | 45 |
from synnefo.logic import backend as backend_mod |
... | ... | |
108 | 108 |
network = Network.objects.create( |
109 | 109 |
name=name, |
110 | 110 |
userid=user_id, |
111 |
subnet=subnet, |
|
112 |
subnet6=subnet6, |
|
113 |
gateway=gateway, |
|
114 |
gateway6=gateway6, |
|
115 |
dhcp=dhcp, |
|
116 | 111 |
flavor=flavor, |
117 | 112 |
mode=mode, |
118 | 113 |
link=link, |
... | ... | |
123 | 118 |
action='CREATE', |
124 | 119 |
state='ACTIVE') |
125 | 120 |
|
121 |
if subnet: |
|
122 |
Subnet.objects.create(network=network, |
|
123 |
ipversion=4, |
|
124 |
cidr=subnet, |
|
125 |
gateway=gateway, |
|
126 |
dhcp=dhcp) |
|
127 |
if subnet6: |
|
128 |
Subnet.objects.create(network=network, |
|
129 |
ipversion=6, |
|
130 |
cidr=subnet6, |
|
131 |
gateway=gateway6, |
|
132 |
dhcp=dhcp) |
|
133 |
|
|
126 | 134 |
# Issue commission to Quotaholder and accept it since at the end of |
127 | 135 |
# this transaction the Network object will be created in the DB. |
128 | 136 |
# Note: the following call does a commit! |
b/snf-cyclades-app/synnefo/logic/reconciliation.py | ||
---|---|---|
341 | 341 |
|
342 | 342 |
|
343 | 343 |
def format_db_nic(nic): |
344 |
return NIC_MSG % (nic.id, nic.state, nic.ipv4, nic.network_id, nic.mac,
|
|
345 |
nic.index, nic.firewall_profile) |
|
344 |
return NIC_MSG % (nic.id, nic.state, nic.ipv4_address, nic.network_id,
|
|
345 |
nic.mac, nic.index, nic.firewall_profile)
|
|
346 | 346 |
|
347 | 347 |
|
348 | 348 |
def format_gnt_nic(nic): |
349 | 349 |
nic_name, nic = nic |
350 |
return NIC_MSG % (nic_name, nic["state"], nic["ipv4"], nic["network"].id, |
|
351 |
nic["mac"], nic["index"], nic["firewall_profile"]) |
|
350 |
return NIC_MSG % (nic_name, nic["state"], nic["ipv4_address"], |
|
351 |
nic["network"].id, nic["mac"], nic["index"], |
|
352 |
nic["firewall_profile"]) |
|
352 | 353 |
|
353 | 354 |
|
354 | 355 |
# |
b/snf-cyclades-app/synnefo/logic/servers.py | ||
---|---|---|
357 | 357 |
raise faults.BuildInProgress('Network not active yet') |
358 | 358 |
|
359 | 359 |
address = None |
360 |
if network.subnet is not None and network.dhcp: |
|
361 |
# Get a free IP from the address pool. |
|
362 |
address = util.get_network_free_address(network) |
|
360 |
try: |
|
361 |
subnet = network.subnets.get(ipversion=4, dhcp=True) |
|
362 |
address = util.get_network_free_address(subnet, userid=vm.userid) |
|
363 |
except Subnet.DoesNotExist: |
|
364 |
subnet = None |
|
365 |
|
|
363 | 366 |
nic = NetworkInterface.objects.create(machine=vm, network=network, |
364 |
ip_type="STATIC", ipv4=address, |
|
365 | 367 |
state="BUILDING") |
368 |
if address is not None: |
|
369 |
address.nic = nic |
|
370 |
address.save() |
|
366 | 371 |
log.info("Connecting VM %s to Network %s. NIC: %s", vm, network, nic) |
367 | 372 |
|
368 | 373 |
return backend.connect_to_network(vm, nic) |
b/snf-cyclades-app/synnefo/logic/tests/__init__.py | ||
---|---|---|
3 | 3 |
from .utils_tests import * |
4 | 4 |
from .rapi_pool_tests import * |
5 | 5 |
from .reconciliation import * |
6 |
from .callbacks import * |
b/snf-cyclades-app/synnefo/logic/tests/callbacks.py | ||
---|---|---|
136 | 136 |
def test_remove(self, client): |
137 | 137 |
vm = mfactory.VirtualMachineFactory() |
138 | 138 |
# Also create a NIC |
139 |
nic = mfactory.NetworkInterfaceFactory(machine=vm) |
|
140 |
nic.network.get_pool().reserve(nic.ipv4) |
|
139 |
ip = mfactory.IPv4AddressFactory(nic__machine=vm) |
|
140 |
nic = ip.nic |
|
141 |
nic.network.get_pool().reserve(nic.ipv4_address) |
|
141 | 142 |
msg = self.create_msg(operation='OP_INSTANCE_REMOVE', |
142 | 143 |
instance=vm.backend_vm_id) |
143 | 144 |
with mocked_quotaholder(): |
... | ... | |
148 | 149 |
self.assertTrue(db_vm.deleted) |
149 | 150 |
# Check that nics are deleted |
150 | 151 |
self.assertFalse(db_vm.nics.all()) |
151 |
self.assertTrue(nic.network.get_pool().is_available(nic.ipv4))
|
|
152 |
self.assertTrue(nic.network.get_pool().is_available(ip.address))
|
|
152 | 153 |
vm2 = mfactory.VirtualMachineFactory() |
153 |
network = mfactory.NetworkFactory(floating_ip_pool=True) |
|
154 |
fp1 = mfactory.IPAddressFactory(machine=vm2, network=network) |
|
155 |
fp2 = mfactory.IPAddressFactory(machine=vm2, network=network) |
|
156 |
mfactory.NetworkInterfaceFactory(machine=vm2, network=network, |
|
157 |
ipv4=fp1.ipv4) |
|
158 |
mfactory.NetworkInterfaceFactory(machine=vm2, network=network, |
|
159 |
ipv4=fp2.ipv4) |
|
154 |
fp1 = mfactory.IPv4AddressFactory(nic__machine=vm2, floating_ip=True, |
|
155 |
network__floating_ip_pool=True) |
|
156 |
network = fp1.network |
|
157 |
nic1 = mfactory.NetworkInterfaceFactory(machine=vm2) |
|
158 |
fp1.nic = nic1 |
|
159 |
fp1.save() |
|
160 | 160 |
pool = network.get_pool() |
161 |
pool.reserve(fp1.ipv4) |
|
162 |
pool.reserve(fp2.ipv4) |
|
161 |
pool.reserve(fp1.address) |
|
163 | 162 |
pool.save() |
164 | 163 |
msg = self.create_msg(operation='OP_INSTANCE_REMOVE', |
165 | 164 |
instance=vm2.backend_vm_id) |
... | ... | |
169 | 168 |
db_vm = VirtualMachine.objects.get(id=vm.id) |
170 | 169 |
self.assertEqual(db_vm.operstate, 'DESTROYED') |
171 | 170 |
self.assertTrue(db_vm.deleted) |
172 |
self.assertEqual(IPAddress.objects.get(id=fp1.id).machine, None) |
|
173 |
self.assertEqual(IPAddress.objects.get(id=fp2.id).machine, None) |
|
171 |
self.assertEqual(IPAddress.objects.get(id=fp1.id).nic, None) |
|
174 | 172 |
pool = network.get_pool() |
175 | 173 |
# Test that floating ips are not released |
176 |
self.assertFalse(pool.is_available(fp1.ipv4)) |
|
177 |
self.assertFalse(pool.is_available(fp2.ipv4)) |
|
174 |
self.assertFalse(pool.is_available(fp1.address)) |
|
178 | 175 |
|
179 | 176 |
@patch("synnefo.logic.rapi_pool.GanetiRapiClient") |
180 | 177 |
def test_remove_error(self, rapi, client): |
... | ... | |
255 | 252 |
for status in ["success", "error"]: |
256 | 253 |
msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS', |
257 | 254 |
instance=vm.backend_vm_id, |
258 |
beparams={},
|
|
255 |
job_fields={"beparams": {}},
|
|
259 | 256 |
status=status) |
260 | 257 |
client.reset_mock() |
261 | 258 |
with mocked_quotaholder(): |
... | ... | |
267 | 264 |
vm.operstate = "STOPPED" |
268 | 265 |
vm.save() |
269 | 266 |
for status in ["queued", "waiting", "running"]: |
267 |
beparams = {"vcpus": 4, "minmem": 2048, "maxmem": 2048} |
|
270 | 268 |
msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS', |
271 | 269 |
instance=vm.backend_vm_id, |
272 |
beparams={"vcpus": 4, "minmem": 2048, |
|
273 |
"maxmem": 2048}, |
|
270 |
job_fields={"beparams": beparams}, |
|
274 | 271 |
status=status) |
275 | 272 |
client.reset_mock() |
276 | 273 |
update_db(client, msg) |
... | ... | |
295 | 292 |
vm.save() |
296 | 293 |
f2 = mfactory.FlavorFactory(cpu=8, ram=2048, disk_template="drbd", |
297 | 294 |
disk=1024) |
295 |
beparams = {"vcpus": 8, "minmem": 2048, "maxmem": 2048} |
|
298 | 296 |
msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS', |
299 | 297 |
instance=vm.backend_vm_id, |
300 |
beparams={"vcpus": 8, "minmem": 2048, |
|
301 |
"maxmem": 2048}, |
|
298 |
job_fields={"beparams": beparams}, |
|
302 | 299 |
status="success") |
303 | 300 |
client.reset_mock() |
304 | 301 |
with mocked_quotaholder(): |
... | ... | |
307 | 304 |
db_vm = VirtualMachine.objects.get(id=vm.id) |
308 | 305 |
self.assertEqual(db_vm.operstate, "STOPPED") |
309 | 306 |
self.assertEqual(db_vm.flavor, f2) |
307 |
beparams = {"vcpus": 100, "minmem": 2048, "maxmem": 2048} |
|
310 | 308 |
msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS', |
311 | 309 |
instance=vm.backend_vm_id, |
312 |
beparams={"vcpus": 100, "minmem": 2048, |
|
313 |
"maxmem": 2048}, |
|
310 |
job_fields={"beparams": beparams}, |
|
314 | 311 |
status="success") |
315 | 312 |
client.reset_mock() |
316 | 313 |
with mocked_quotaholder(): |
... | ... | |
354 | 351 |
|
355 | 352 |
def test_no_nics(self, client): |
356 | 353 |
vm = mfactory.VirtualMachineFactory(operstate='ERROR') |
357 |
mfactory.NetworkInterfaceFactory(machine=vm) |
|
358 |
mfactory.NetworkInterfaceFactory(machine=vm) |
|
359 |
mfactory.NetworkInterfaceFactory(machine=vm) |
|
354 |
mfactory.NetworkInterfaceFactory(machine=vm, state="ACTIVE")
|
|
355 |
mfactory.NetworkInterfaceFactory(machine=vm, state="ACTIVE")
|
|
356 |
mfactory.NetworkInterfaceFactory(machine=vm, state="ACTIVE")
|
|
360 | 357 |
self.assertEqual(len(vm.nics.all()), 3) |
361 |
msg = self.create_msg(nics=[], |
|
358 |
msg = self.create_msg(instance_nics=[],
|
|
362 | 359 |
instance=vm.backend_vm_id) |
363 | 360 |
update_db(client, msg) |
364 | 361 |
self.assertTrue(client.basic_ack.called) |
... | ... | |
368 | 365 |
def test_empty_nic(self, client): |
369 | 366 |
vm = mfactory.VirtualMachineFactory(operstate='ERROR') |
370 | 367 |
for public in [True, False]: |
371 |
net = mfactory.NetworkFactory(public=public, subnet6=None) |
|
372 |
msg = self.create_msg(nics=[{'network': net.backend_id}], |
|
368 |
net = mfactory.NetworkFactory(public=public) |
|
369 |
msg = self.create_msg(instance_nics=[{'network': net.backend_id, |
|
370 |
'name': 'snf-nic-100'}], |
|
373 | 371 |
instance=vm.backend_vm_id) |
374 | 372 |
update_db(client, msg) |
375 | 373 |
self.assertTrue(client.basic_ack.called) |
... | ... | |
377 | 375 |
nics = db_vm.nics.all() |
378 | 376 |
self.assertEqual(len(nics), 1) |
379 | 377 |
self.assertEqual(nics[0].index, 0) |
380 |
self.assertEqual(nics[0].ipv4, None) |
|
381 |
self.assertEqual(nics[0].ipv6, None) |
|
378 |
self.assertEqual(nics[0].ipv4_address, None)
|
|
379 |
self.assertEqual(nics[0].ipv6_address, None)
|
|
382 | 380 |
self.assertEqual(nics[0].mac, None) |
383 | 381 |
if public: |
384 | 382 |
self.assertEqual(nics[0].firewall_profile, |
... | ... | |
388 | 386 |
|
389 | 387 |
def test_full_nic(self, client): |
390 | 388 |
vm = mfactory.VirtualMachineFactory(operstate='ERROR') |
391 |
net = mfactory.NetworkFactory(subnet='10.0.0.0/24', subnet6=None) |
|
389 |
net = mfactory.NetworkWithSubnetFactory(subnet__cidr='10.0.0.0/24', |
|
390 |
subnet__gateway="10.0.0.1", |
|
391 |
subnet6=None) |
|
392 | 392 |
pool = net.get_pool() |
393 | 393 |
self.assertTrue(pool.is_available('10.0.0.22')) |
394 | 394 |
pool.save() |
395 |
msg = self.create_msg(nics=[{'network': net.backend_id, |
|
396 |
'ip': '10.0.0.22', |
|
397 |
'mac': 'aa:bb:cc:00:11:22'}], |
|
395 |
msg = self.create_msg(instance_nics=[{'network': net.backend_id, |
|
396 |
'ip': '10.0.0.22', |
|
397 |
'mac': 'aa:bb:cc:00:11:22', |
|
398 |
'name': 'snf-nic-200'}], |
|
398 | 399 |
instance=vm.backend_vm_id) |
399 | 400 |
update_db(client, msg) |
400 | 401 |
self.assertTrue(client.basic_ack.called) |
... | ... | |
402 | 403 |
nics = db_vm.nics.all() |
403 | 404 |
self.assertEqual(len(nics), 1) |
404 | 405 |
self.assertEqual(nics[0].index, 0) |
405 |
self.assertEqual(nics[0].ipv4, '10.0.0.22') |
|
406 |
self.assertEqual(nics[0].ipv6, None) |
|
406 |
self.assertEqual(nics[0].ipv4_address, '10.0.0.22')
|
|
407 |
self.assertEqual(nics[0].ipv6_address, None)
|
|
407 | 408 |
self.assertEqual(nics[0].mac, 'aa:bb:cc:00:11:22') |
408 | 409 |
pool = net.get_pool() |
409 | 410 |
self.assertFalse(pool.is_available('10.0.0.22')) |
... | ... | |
609 | 610 |
self.assertEqual(bn.network.state, db_bnet.network.state) |
610 | 611 |
|
611 | 612 |
def test_ips(self, client): |
612 |
network = mfactory.NetworkFactory(subnet='10.0.0.0/24') |
|
613 |
network = mfactory.NetworkWithSubnetFactory(subnet__cidr='10.0.0.0/24', |
|
614 |
subnet__gateway="10.0.0.1") |
|
613 | 615 |
bn = mfactory.BackendNetworkFactory(network=network) |
614 | 616 |
msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS', |
615 | 617 |
network=network.backend_id, |
616 | 618 |
cluster=bn.backend.clustername, |
617 | 619 |
status='success', |
618 |
add_reserved_ips=['10.0.0.10', '10.0.0.20'],
|
|
619 |
remove_reserved_ips=[])
|
|
620 |
job_fields={"add_reserved_ips": ["10.0.0.10",
|
|
621 |
"10.0.0.20"]})
|
|
620 | 622 |
update_network(client, msg) |
621 | 623 |
self.assertTrue(client.basic_ack.called) |
622 | 624 |
pool = network.get_pool() |
623 | 625 |
self.assertTrue(pool.is_reserved('10.0.0.10')) |
624 | 626 |
self.assertTrue(pool.is_reserved('10.0.0.20')) |
625 | 627 |
pool.save() |
626 |
# Release them
|
|
628 |
# Check that they are not released
|
|
627 | 629 |
msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS', |
628 | 630 |
network=network.backend_id, |
629 | 631 |
cluster=bn.backend.clustername, |
630 |
add_reserved_ips=[], |
|
631 |
remove_reserved_ips=['10.0.0.10', '10.0.0.20']) |
|
632 |
job_fields={ |
|
633 |
"remove_reserved_ips": ["10.0.0.10", |
|
634 |
"10.0.0.20"]}) |
|
632 | 635 |
update_network(client, msg) |
633 |
self.assertTrue(client.basic_ack.called) |
|
636 |
#self.assertTrue(client.basic_ack.called)
|
|
634 | 637 |
pool = network.get_pool() |
635 |
self.assertFalse(pool.is_reserved('10.0.0.10'))
|
|
636 |
self.assertFalse(pool.is_reserved('10.0.0.20'))
|
|
638 |
self.assertTrue(pool.is_reserved('10.0.0.10'))
|
|
639 |
self.assertTrue(pool.is_reserved('10.0.0.20'))
|
|
637 | 640 |
|
638 | 641 |
|
639 | 642 |
@patch('synnefo.lib.amqp.AMQPClient') |
b/snf-cyclades-app/synnefo/logic/tests/networks.py | ||
---|---|---|
70 | 70 |
kwargs["dhcp"] = False |
71 | 71 |
with mocked_quotaholder(): |
72 | 72 |
net = networks.create(**kwargs) |
73 |
self.assertEqual(net.subnet, "192.168.20.0/24") |
|
74 |
self.assertEqual(net.gateway, "192.168.20.1") |
|
73 |
self.assertEqual(net.subnet4, "192.168.20.0/24")
|
|
74 |
self.assertEqual(net.subnets.get(ipversion=4).gateway, "192.168.20.1")
|
|
75 | 75 |
self.assertEqual(net.public, True) |
76 | 76 |
self.assertEqual(net.flavor, "CUSTOM") |
77 |
self.assertEqual(net.dhcp, False) |
|
77 |
self.assertEqual(net.subnets.get(ipversion=4).dhcp, False)
|
|
78 | 78 |
self.assertEqual(net.action, "CREATE") |
79 | 79 |
self.assertEqual(net.state, "ACTIVE") |
80 | 80 |
self.assertEqual(net.name, "test") |
... | ... | |
149 | 149 |
kwargs["gateway6"] = "2001:648:2ffc:1112::1" |
150 | 150 |
with mocked_quotaholder(): |
151 | 151 |
net = networks.create(**kwargs) |
152 |
self.assertEqual(net.subnet6, "2001:648:2ffc:1112::/64") |
|
153 |
self.assertEqual(net.gateway6, "2001:648:2ffc:1112::1") |
|
152 |
subnet6 = net.subnets.get(ipversion=6) |
|
153 |
self.assertEqual(subnet6.cidr, "2001:648:2ffc:1112::/64") |
|
154 |
self.assertEqual(subnet6.gateway, "2001:648:2ffc:1112::1") |
|
154 | 155 |
self.assertRaises(Exception, net.get_pool) |
b/snf-cyclades-app/synnefo/logic/tests/reconciliation.py | ||
---|---|---|
181 | 181 |
self.assertEqual(vm1.operstate, "STARTED") |
182 | 182 |
|
183 | 183 |
def test_unsynced_nics(self, mrapi): |
184 |
network1 = mfactory.NetworkFactory(subnet="10.0.0.0/24") |
|
185 |
network2 = mfactory.NetworkFactory(subnet="192.168.2.0/24") |
|
184 |
network1 = mfactory.NetworkWithSubnetFactory( |
|
185 |
subnet__cidr="10.0.0.0/24", subnet__gateway="10.0.0.2") |
|
186 |
network2 = mfactory.NetworkWithSubnetFactory( |
|
187 |
subnet__cidr="192.168.2.0/24", subnet__gateway="192.168.2.2") |
|
186 | 188 |
vm1 = mfactory.VirtualMachineFactory(backend=self.backend, |
187 | 189 |
deleted=False, |
188 | 190 |
operstate="STOPPED") |
189 |
nic = mfactory.NetworkInterfaceFactory(machine=vm1, network=network1, |
|
190 |
ipv4="10.0.0.0") |
|
191 |
subnet = network1.subnets.get(ipversion=4) |
|
192 |
ip = mfactory.IPv4AddressFactory(nic__machine=vm1, network=network1, |
|
193 |
subnet=subnet, |
|
194 |
address="10.0.0.3") |
|
195 |
nic = ip.nic |
|
191 | 196 |
mrapi().GetInstances.return_value =\ |
192 | 197 |
[{"name": vm1.backend_vm_id, |
193 | 198 |
"beparams": {"maxmem": 2048, |
... | ... | |
207 | 212 |
self.assertEqual(vm1.operstate, "STARTED") |
208 | 213 |
nic = vm1.nics.all()[0] |
209 | 214 |
self.assertEqual(nic.network, network2) |
210 |
self.assertEqual(nic.ipv4, "192.168.2.1") |
|
215 |
self.assertEqual(nic.ipv4_address, "192.168.2.1")
|
|
211 | 216 |
self.assertEqual(nic.mac, "aa:00:bb:cc:dd:ee") |
212 | 217 |
|
213 | 218 |
|
... | ... | |
221 | 226 |
fix=True) |
222 | 227 |
|
223 | 228 |
def test_parted_network(self, mrapi): |
224 |
net1 = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False)
|
|
229 |
net1 = mfactory.NetworkWithSubnetFactory(public=False)
|
|
225 | 230 |
mrapi().GetNetworks.return_value = [] |
226 | 231 |
# Test nothing if Ganeti returns nothing |
227 | 232 |
self.assertEqual(net1.backend_networks.count(), 0) |
... | ... | |
234 | 239 |
"group_list": [["default", |
235 | 240 |
"bridged", |
236 | 241 |
"prv0"]], |
237 |
"network": net1.subnet, |
|
242 |
"network": net1.subnet4,
|
|
238 | 243 |
"map": "....", |
239 | 244 |
"external_reservations": ""}] |
240 | 245 |
self.reconciler.reconcile_networks() |
... | ... | |
255 | 260 |
self.assertFalse(net1.backend_networks |
256 | 261 |
.filter(backend=self.backend).exists()) |
257 | 262 |
# Test creation if network is a floating IP pool |
258 |
net2 = mfactory.NetworkFactory(subnet="192.168.0.0/30", |
|
259 |
floating_ip_pool=True) |
|
263 |
net2 = mfactory.NetworkWithSubnetFactory(floating_ip_pool=True) |
|
260 | 264 |
mrapi().GetNetworks.return_value = [] |
261 | 265 |
self.assertEqual(net2.backend_networks.count(), 0) |
262 | 266 |
self.reconciler.reconcile_networks() |
... | ... | |
266 | 270 |
def test_stale_network(self, mrapi): |
267 | 271 |
# Test that stale network will be deleted from DB, if network action is |
268 | 272 |
# destroy |
269 |
net1 = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False, |
|
270 |
flavor="IP_LESS_ROUTED", |
|
271 |
action="DESTROY", deleted=False) |
|
273 |
net1 = mfactory.NetworkWithSubnetFactory(public=False, |
|
274 |
flavor="IP_LESS_ROUTED", |
|
275 |
action="DESTROY", |
|
276 |
deleted=False) |
|
272 | 277 |
bn1 = mfactory.BackendNetworkFactory(network=net1, |
273 | 278 |
backend=self.backend, |
274 | 279 |
operstate="ACTIVE") |
... | ... | |
281 | 286 |
self.assertEqual(bn1.operstate, "DELETED") |
282 | 287 |
self.assertTrue(net1.deleted) |
283 | 288 |
# But not if action is not DESTROY |
284 |
net2 = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False, |
|
285 |
action="CREATE") |
|
289 |
net2 = mfactory.NetworkWithSubnetFactory(public=False, action="CREATE") |
|
286 | 290 |
mfactory.BackendNetworkFactory(network=net2, backend=self.backend) |
287 | 291 |
self.assertFalse(net2.deleted) |
288 | 292 |
self.reconciler.reconcile_networks() |
289 | 293 |
self.assertFalse(net2.deleted) |
290 | 294 |
|
291 | 295 |
def test_missing_network(self, mrapi): |
292 |
net2 = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False, |
|
293 |
action="CREATE") |
|
296 |
net2 = mfactory.NetworkWithSubnetFactory(public=False, action="CREATE") |
|
294 | 297 |
mfactory.BackendNetworkFactory(network=net2, backend=self.backend) |
295 | 298 |
mrapi().GetNetworks.return_value = [] |
296 | 299 |
self.reconciler.reconcile_networks() |
... | ... | |
300 | 303 |
# pass |
301 | 304 |
|
302 | 305 |
def test_unsynced_networks(self, mrapi): |
303 |
net = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False, |
|
304 |
state="PENDING", |
|
305 |
action="CREATE", deleted=False) |
|
306 |
net = mfactory.NetworkWithSubnetFactory(public=False, state="PENDING", |
|
307 |
action="CREATE", deleted=False) |
|
306 | 308 |
bn = mfactory.BackendNetworkFactory(network=net, backend=self.backend, |
307 | 309 |
operstate="PENDING") |
308 | 310 |
mrapi().GetNetworks.return_value = [{"name": net.backend_id, |
309 | 311 |
"group_list": [], |
310 |
"network": net.subnet, |
|
312 |
"network": net.subnet4,
|
|
311 | 313 |
"map": "....", |
312 | 314 |
"external_reservations": ""}] |
313 | 315 |
self.assertEqual(bn.operstate, "PENDING") |
... | ... | |
316 | 318 |
self.assertEqual(bn.operstate, "ACTIVE") |
317 | 319 |
|
318 | 320 |
def test_orphan_networks(self, mrapi): |
319 |
net = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False,
|
|
320 |
action="CREATE", deleted=True)
|
|
321 |
net = mfactory.NetworkWithSubnetFactory(public=False, action="CREATE",
|
|
322 |
deleted=True)
|
|
321 | 323 |
mrapi().GetNetworks.return_value = [{"name": net.backend_id, |
322 | 324 |
"group_list": [], |
323 |
"network": net.subnet, |
|
325 |
"network": net.subnet4,
|
|
324 | 326 |
"map": "....", |
325 | 327 |
"external_reservations": ""}] |
326 | 328 |
self.reconciler.reconcile_networks() |
b/snf-cyclades-app/synnefo/logic/tests/servers.py | ||
---|---|---|
60 | 60 |
self.assertRaises(faults.ServiceUnavailable, servers.create, **kwargs) |
61 | 61 |
self.assertEqual(models.VirtualMachine.objects.count(), 0) |
62 | 62 |
|
63 |
mfactory.BackendFactory(drained=False)
|
|
64 |
mfactory.BackendNetworkFactory(network__public=True)
|
|
63 |
subnet = mfactory.IPv4SubnetFactory(network__public=True)
|
|
64 |
mfactory.BackendNetworkFactory(network=subnet.network)
|
|
65 | 65 |
|
66 | 66 |
# error in nics |
67 | 67 |
req = deepcopy(kwargs) |
... | ... | |
94 | 94 |
self.assertEqual(vm.task, "BUILD") |
95 | 95 |
|
96 | 96 |
# test connect in IPv6 only network |
97 |
net = mfactory.IPv6NetworkFactory(state="ACTIVE") |
|
97 |
subnet = mfactory.IPv6SubnetFactory() |
|
98 |
net = subnet.network |
|
98 | 99 |
mfactory.BackendNetworkFactory(network=net) |
99 | 100 |
with override_settings(settings, |
100 | 101 |
DEFAULT_INSTANCE_NETWORKS=[str(net.id)]): |
... | ... | |
102 | 103 |
vm = servers.create(**kwargs) |
103 | 104 |
nics = vm.nics.all() |
104 | 105 |
self.assertEqual(len(nics), 1) |
105 |
self.assertEqual(nics[0].ipv4, None)
|
|
106 |
self.assertFalse(nics[0].ips.filter(subnet__ipversion=4).exists())
|
|
106 | 107 |
args, kwargs = mrapi().CreateInstance.call_args |
107 | 108 |
ganeti_nic = kwargs["nics"][0] |
108 | 109 |
self.assertEqual(ganeti_nic["ip"], None) |
... | ... | |
113 | 114 |
class ServerTest(TransactionTestCase): |
114 | 115 |
def test_connect_network(self, mrapi): |
115 | 116 |
# Common connect |
116 |
net = mfactory.NetworkFactory(subnet="192.168.2.0/24",
|
|
117 |
gateway="192.168.2.1",
|
|
118 |
state="ACTIVE",
|
|
119 |
dhcp=True,
|
|
120 |
flavor="CUSTOM")
|
|
117 |
subnet = mfactory.IPv4SubnetFactory(network__flavor="CUSTOM",
|
|
118 |
cidr="192.168.2.0/24",
|
|
119 |
gateway="192.168.2.1",
|
|
120 |
dhcp=True)
|
|
121 |
net = subnet.network
|
|
121 | 122 |
vm = mfactory.VirtualMachineFactory(operstate="STARTED") |
122 | 123 |
mfactory.BackendNetworkFactory(network=net, backend=vm.backend) |
123 | 124 |
mrapi().ModifyInstance.return_value = 42 |
... | ... | |
132 | 133 |
self.assertEqual(nics[2]["ip"], "192.168.2.2") |
133 | 134 |
self.assertEqual(nics[2]["network"], net.backend_id) |
134 | 135 |
|
135 |
# No dhcp
|
|
136 |
# no dhcp
|
|
136 | 137 |
vm = mfactory.VirtualMachineFactory(operstate="STARTED") |
137 |
net = mfactory.NetworkFactory(subnet="192.168.2.0/24",
|
|
138 |
gateway="192.168.2.1", |
|
139 |
state="ACTIVE",
|
|
140 |
dhcp=False)
|
|
138 |
subnet = mfactory.IPv4SubnetFactory(cidr="192.168.2.0/24",
|
|
139 |
gateway="192.168.2.1",
|
|
140 |
dhcp=False)
|
|
141 |
net = subnet.network
|
|
141 | 142 |
mfactory.BackendNetworkFactory(network=net, backend=vm.backend) |
142 | 143 |
servers.connect(vm, net) |
143 | 144 |
pool = net.get_pool(locked=False) |
... | ... | |
152 | 153 |
|
153 | 154 |
# Test connect to IPv6 only network |
154 | 155 |
vm = mfactory.VirtualMachineFactory(operstate="STARTED") |
155 |
net = mfactory.NetworkFactory(subnet6="2000::/64",
|
|
156 |
state="ACTIVE",
|
|
157 |
gateway="2000::1")
|
|
156 |
subnet = mfactory.IPv6SubnetFactory(cidr="2000::/64",
|
|
157 |
gateway="2000::1")
|
|
158 |
net = subnet.network
|
|
158 | 159 |
mfactory.BackendNetworkFactory(network=net, backend=vm.backend) |
159 | 160 |
servers.connect(vm, net) |
160 | 161 |
args, kwargs = mrapi().ModifyInstance.call_args |
Also available in: Unified diff