Merge ~ltrager/maas:network_testing_models into maas:master

Proposed by Lee Trager
Status: Merged
Approved by: Lee Trager
Approved revision: e8075505cb458a525fe871f4ff7e5f93780f1b15
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ltrager/maas:network_testing_models
Merge into: maas:master
Diff against target: 487 lines (+172/-26)
12 files modified
src/maasserver/forms/tests/test_pods.py (+2/-2)
src/maasserver/migrations/maasserver/0188_network_testing.py (+33/-0)
src/maasserver/models/interface.py (+19/-1)
src/maasserver/models/tests/test_interface.py (+27/-6)
src/maasserver/testing/factory.py (+17/-4)
src/maasserver/tests/test_routablepairs.py (+9/-9)
src/maasserver/websockets/handlers/tests/test_script.py (+2/-1)
src/metadataserver/enum.py (+3/-1)
src/metadataserver/migrations/0020_network_testing.py (+35/-0)
src/metadataserver/models/script.py (+7/-1)
src/metadataserver/models/scriptresult.py (+5/-0)
src/metadataserver/models/tests/test_script.py (+13/-1)
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Newell Jensen (community) Approve
Review via email: mp+368567@code.launchpad.net

Commit message

Add database columns for network testing

To post a comment you must log in.
Revision history for this message
Newell Jensen (newell-jensen) wrote :

Follows the spec. Looks good.

review: Approve
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Looks good to me.

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :
~ltrager/maas:network_testing_models updated
e807550... by Lee Trager

Fix failing test

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/maasserver/forms/tests/test_pods.py b/src/maasserver/forms/tests/test_pods.py
index 948d4ce..03d332a 100644
--- a/src/maasserver/forms/tests/test_pods.py
+++ b/src/maasserver/forms/tests/test_pods.py
@@ -1869,9 +1869,9 @@ class TestGetKnownHostInterfaces(MAASServerTestCase):
1869 node = factory.make_Machine_with_Interface_on_Subnet()1869 node = factory.make_Machine_with_Interface_on_Subnet()
1870 node.interface_set.all().delete()1870 node.interface_set.all().delete()
1871 bridge = factory.make_Interface(1871 bridge = factory.make_Interface(
1872 iftype=INTERFACE_TYPE.BRIDGE, node=node, disconnected=True)1872 iftype=INTERFACE_TYPE.BRIDGE, node=node, link_connected=False)
1873 physical = factory.make_Interface(1873 physical = factory.make_Interface(
1874 iftype=INTERFACE_TYPE.PHYSICAL, node=node, disconnected=True)1874 iftype=INTERFACE_TYPE.PHYSICAL, node=node, link_connected=False)
1875 interfaces = get_known_host_interfaces(node)1875 interfaces = get_known_host_interfaces(node)
1876 self.assertItemsEqual(1876 self.assertItemsEqual(
1877 interfaces, [1877 interfaces, [
diff --git a/src/maasserver/migrations/maasserver/0188_network_testing.py b/src/maasserver/migrations/maasserver/0188_network_testing.py
1878new file mode 1006441878new file mode 100644
index 0000000..bb9e267
--- /dev/null
+++ b/src/maasserver/migrations/maasserver/0188_network_testing.py
@@ -0,0 +1,33 @@
1# -*- coding: utf-8 -*-
2# Generated by Django 1.11.11 on 2019-06-07 19:40
3from __future__ import unicode_literals
4
5from django.db import (
6 migrations,
7 models,
8)
9
10
11class Migration(migrations.Migration):
12
13 dependencies = [
14 ('maasserver', '0187_status_messages_change_event_logging_levels'),
15 ]
16
17 operations = [
18 migrations.AddField(
19 model_name='interface',
20 name='interface_speed',
21 field=models.PositiveIntegerField(default=0),
22 ),
23 migrations.AddField(
24 model_name='interface',
25 name='link_connected',
26 field=models.BooleanField(default=True),
27 ),
28 migrations.AddField(
29 model_name='interface',
30 name='link_speed',
31 field=models.PositiveIntegerField(default=0),
32 ),
33 ]
diff --git a/src/maasserver/models/interface.py b/src/maasserver/models/interface.py
index 842e0e8..6b5932e 100644
--- a/src/maasserver/models/interface.py
+++ b/src/maasserver/models/interface.py
@@ -1,4 +1,4 @@
1# Copyright 2015-2018 Canonical Ltd. This software is licensed under the1# Copyright 2015-2019 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""Model for interfaces."""4"""Model for interfaces."""
@@ -28,6 +28,7 @@ from django.db.models import (
28 ForeignKey,28 ForeignKey,
29 Manager,29 Manager,
30 ManyToManyField,30 ManyToManyField,
31 PositiveIntegerField,
31 PROTECT,32 PROTECT,
32 Q,33 Q,
33 TextField,34 TextField,
@@ -571,6 +572,15 @@ class Interface(CleanSave, TimestampedModel):
571 max_length=255, blank=True, null=True,572 max_length=255, blank=True, null=True,
572 help_text="Firmware version of the interface.")573 help_text="Firmware version of the interface.")
573574
575 # Whether or not the Interface is physically connected to an uplink.
576 link_connected = BooleanField(default=True)
577
578 # The speed of the interface in Mbit/s
579 interface_speed = PositiveIntegerField(default=0)
580
581 # The speed of the link in Mbit/s
582 link_speed = PositiveIntegerField(default=0)
583
574 def __init__(self, *args, **kwargs):584 def __init__(self, *args, **kwargs):
575 type = kwargs.get('type', self.get_type())585 type = kwargs.get('type', self.get_type())
576 kwargs['type'] = type586 kwargs['type'] = type
@@ -1475,6 +1485,14 @@ class Interface(CleanSave, TimestampedModel):
1475 'mdns': self.mdns_discovery_state,1485 'mdns': self.mdns_discovery_state,
1476 }1486 }
14771487
1488 def save(self, *args, **kwargs):
1489 if (self.link_speed > self.interface_speed and
1490 self.interface_speed != 0):
1491 raise ValidationError('link_speed may not exceed interface_speed')
1492 if not self.link_connected:
1493 self.link_speed = 0
1494 return super().save(*args, **kwargs)
1495
14781496
1479class InterfaceRelationship(CleanSave, TimestampedModel):1497class InterfaceRelationship(CleanSave, TimestampedModel):
1480 child = ForeignKey(1498 child = ForeignKey(
diff --git a/src/maasserver/models/tests/test_interface.py b/src/maasserver/models/tests/test_interface.py
index 36cd455..934705d 100644
--- a/src/maasserver/models/tests/test_interface.py
+++ b/src/maasserver/models/tests/test_interface.py
@@ -1,4 +1,4 @@
1# Copyright 2015-2016 Canonical Ltd. This software is licensed under the1# Copyright 2015-2019 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""Tests for the Interface model."""4"""Tests for the Interface model."""
@@ -873,7 +873,7 @@ class InterfaceTest(MAASServerTestCase):
873 mac = factory.make_MAC()873 mac = factory.make_MAC()
874 interface = factory.make_Interface(874 interface = factory.make_Interface(
875 INTERFACE_TYPE.PHYSICAL,875 INTERFACE_TYPE.PHYSICAL,
876 name=name, node=node, mac_address=mac, disconnected=True)876 name=name, node=node, mac_address=mac, link_connected=False)
877 self.assertThat(interface, MatchesStructure.byEquality(877 self.assertThat(interface, MatchesStructure.byEquality(
878 name=name, node=node, mac_address=mac,878 name=name, node=node, mac_address=mac,
879 type=INTERFACE_TYPE.PHYSICAL, vlan=None))879 type=INTERFACE_TYPE.PHYSICAL, vlan=None))
@@ -884,7 +884,7 @@ class InterfaceTest(MAASServerTestCase):
884 mac = factory.make_MAC()884 mac = factory.make_MAC()
885 interface = factory.make_Interface(885 interface = factory.make_Interface(
886 INTERFACE_TYPE.PHYSICAL,886 INTERFACE_TYPE.PHYSICAL,
887 name=name, node=node, mac_address=mac, disconnected=True)887 name=name, node=node, mac_address=mac, link_connected=False)
888 interface.acquired = True888 interface.acquired = True
889 self.assertRaises(ValueError, interface.save)889 self.assertRaises(ValueError, interface.save)
890890
@@ -1103,6 +1103,27 @@ class InterfaceTest(MAASServerTestCase):
1103 #: Test is this doesn't raise an exception1103 #: Test is this doesn't raise an exception
1104 interface.remove_tag(tag)1104 interface.remove_tag(tag)
11051105
1106 def test_save_link_speed_may_not_exceed_interface_speed(self):
1107 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1108 interface.interface_speed = 100
1109 interface.link_speed = 1000
1110 self.assertRaises(ValidationError, interface.save)
1111
1112 def test_save_link_speed_may_exceed_unknown_interface_speed(self):
1113 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1114 interface.interface_speed = 0
1115 interface.link_speed = 1000
1116 interface.save()
1117 interface = reload_object(interface)
1118 self.assertEquals(0, interface.interface_speed)
1119 self.assertEquals(1000, interface.link_speed)
1120
1121 def test_save_if_link_disconnected_set_link_speed_to_zero(self):
1122 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
1123 interface.link_connected = False
1124 interface.save()
1125 self.assertEquals(0, interface.link_speed)
1126
11061127
1107class InterfaceUpdateNeighbourTest(MAASServerTestCase):1128class InterfaceUpdateNeighbourTest(MAASServerTestCase):
1108 """Tests for `Interface.update_neighbour`."""1129 """Tests for `Interface.update_neighbour`."""
@@ -1378,7 +1399,7 @@ class InterfaceMTUTest(MAASServerTestCase):
13781399
1379 def test_get_effective_mtu_returns_default_mtu(self):1400 def test_get_effective_mtu_returns_default_mtu(self):
1380 nic1 = factory.make_Interface(1401 nic1 = factory.make_Interface(
1381 INTERFACE_TYPE.PHYSICAL, disconnected=True)1402 INTERFACE_TYPE.PHYSICAL, link_connected=False)
1382 self.assertEqual(DEFAULT_MTU, nic1.get_effective_mtu())1403 self.assertEqual(DEFAULT_MTU, nic1.get_effective_mtu())
13831404
1384 def test_get_effective_mtu_returns_interface_mtu(self):1405 def test_get_effective_mtu_returns_interface_mtu(self):
@@ -2380,7 +2401,7 @@ class TestForceAutoOrDHCPLink(MAASServerTestCase):
23802401
2381 def test__does_nothing_when_disconnected(self):2402 def test__does_nothing_when_disconnected(self):
2382 interface = factory.make_Interface(2403 interface = factory.make_Interface(
2383 INTERFACE_TYPE.PHYSICAL, disconnected=True)2404 INTERFACE_TYPE.PHYSICAL, link_connected=False)
2384 self.assertIsNone(interface.force_auto_or_dhcp_link())2405 self.assertIsNone(interface.force_auto_or_dhcp_link())
23852406
2386 def test__sets_to_AUTO_on_subnet(self):2407 def test__sets_to_AUTO_on_subnet(self):
@@ -2412,7 +2433,7 @@ class TestEnsureLinkUp(MAASServerTestCase):
24122433
2413 def test__does_nothing_if_no_vlan(self):2434 def test__does_nothing_if_no_vlan(self):
2414 interface = factory.make_Interface(2435 interface = factory.make_Interface(
2415 INTERFACE_TYPE.PHYSICAL, disconnected=True)2436 INTERFACE_TYPE.PHYSICAL, link_connected=False)
2416 interface.ensure_link_up()2437 interface.ensure_link_up()
2417 interface = reload_object(interface)2438 interface = reload_object(interface)
2418 self.assertEqual(2439 self.assertEqual(
diff --git a/src/maasserver/testing/factory.py b/src/maasserver/testing/factory.py
index ec327a4..7ce4b7a 100644
--- a/src/maasserver/testing/factory.py
+++ b/src/maasserver/testing/factory.py
@@ -1,4 +1,4 @@
1# Copyright 2012-2018 Canonical Ltd. This software is licensed under the1# Copyright 2012-2019 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""Test object factories."""4"""Test object factories."""
@@ -1323,7 +1323,8 @@ class Factory(maastesting.factory.Factory):
1323 self, iftype=INTERFACE_TYPE.PHYSICAL, node=None, mac_address=None,1323 self, iftype=INTERFACE_TYPE.PHYSICAL, node=None, mac_address=None,
1324 vlan=None, parents=None, name=None, cluster_interface=None,1324 vlan=None, parents=None, name=None, cluster_interface=None,
1325 ip=None, subnet=None, enabled=True, fabric=None, tags=None,1325 ip=None, subnet=None, enabled=True, fabric=None, tags=None,
1326 disconnected=False, params=""):1326 link_connected=True, interface_speed=None, link_speed=None,
1327 params=""):
1327 if subnet is None and cluster_interface is not None:1328 if subnet is None and cluster_interface is not None:
1328 subnet = cluster_interface.subnet1329 subnet = cluster_interface.subnet
1329 if subnet is not None and vlan is None:1330 if subnet is not None and vlan is None:
@@ -1344,7 +1345,7 @@ class Factory(maastesting.factory.Factory):
1344 elif iftype == INTERFACE_TYPE.VLAN:1345 elif iftype == INTERFACE_TYPE.VLAN:
1345 # Need to calculate this later based on the VID.1346 # Need to calculate this later based on the VID.
1346 name = None1347 name = None
1347 if not disconnected:1348 if link_connected:
1348 if vlan is None:1349 if vlan is None:
1349 if fabric is not None:1350 if fabric is not None:
1350 if iftype == INTERFACE_TYPE.VLAN:1351 if iftype == INTERFACE_TYPE.VLAN:
@@ -1375,9 +1376,21 @@ class Factory(maastesting.factory.Factory):
1375 node = parents[0].get_node()1376 node = parents[0].get_node()
1376 if tags is None:1377 if tags is None:
1377 tags = [self.make_name('tag') for _ in range(3)]1378 tags = [self.make_name('tag') for _ in range(3)]
1379 link_speeds = [10, 100, 1000, 10000, 20000, 40000, 50000, 100000]
1380 if interface_speed is None:
1381 interface_speed = random.choice(link_speeds)
1382 if link_speed is None:
1383 if not link_connected:
1384 link_speed = 0
1385 else:
1386 link_speed = random.choice([
1387 speed for speed in link_speeds
1388 if speed <= interface_speed])
1378 interface = Interface(1389 interface = Interface(
1379 node=node, mac_address=mac_address, type=iftype,1390 node=node, mac_address=mac_address, type=iftype,
1380 name=name, vlan=vlan, enabled=enabled, tags=tags, params=params)1391 name=name, vlan=vlan, enabled=enabled, tags=tags,
1392 link_connected=link_connected, interface_speed=interface_speed,
1393 link_speed=link_speed, params=params)
1381 interface.save()1394 interface.save()
1382 if subnet is None and ip is not None:1395 if subnet is None and ip is not None:
1383 subnet = Subnet.objects.get_best_subnet_for_ip(ip)1396 subnet = Subnet.objects.get_best_subnet_for_ip(ip)
diff --git a/src/maasserver/tests/test_routablepairs.py b/src/maasserver/tests/test_routablepairs.py
index 7ba6fe8..45ca34c 100644
--- a/src/maasserver/tests/test_routablepairs.py
+++ b/src/maasserver/tests/test_routablepairs.py
@@ -1,4 +1,4 @@
1# Copyright 2016 Canonical Ltd. This software is licensed under the1# Copyright 2016-2019 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""Tests for `maasserver.routablepairs`."""4"""Tests for `maasserver.routablepairs`."""
@@ -136,7 +136,7 @@ class TestFindAddressesBetweenNodes(MAASServerTestCase):
136 # null space, one in a non-null space.136 # null space, one in a non-null space.
137 origin = factory.make_Node(hostname="origin")137 origin = factory.make_Node(hostname="origin")
138 origin_iface = factory.make_Interface(138 origin_iface = factory.make_Interface(
139 node=origin, disconnected=True)139 node=origin, link_connected=False)
140 origin_subnet = factory.make_Subnet(140 origin_subnet = factory.make_Subnet(
141 space=space, cidr=next(networks))141 space=space, cidr=next(networks))
142 origin_subnet_null_space = factory.make_Subnet(142 origin_subnet_null_space = factory.make_Subnet(
@@ -150,14 +150,14 @@ class TestFindAddressesBetweenNodes(MAASServerTestCase):
150 node_same_subnet = factory.make_Node(hostname="same-subnet")150 node_same_subnet = factory.make_Node(hostname="same-subnet")
151 sip_same_subnet = factory.make_StaticIPAddress(151 sip_same_subnet = factory.make_StaticIPAddress(
152 interface=factory.make_Interface(152 interface=factory.make_Interface(
153 node=node_same_subnet, disconnected=True),153 node=node_same_subnet, link_connected=False),
154 subnet=origin_subnet)154 subnet=origin_subnet)
155155
156 # Same VLAN, different subnet, different node.156 # Same VLAN, different subnet, different node.
157 node_same_vlan = factory.make_Node(hostname="same-vlan")157 node_same_vlan = factory.make_Node(hostname="same-vlan")
158 sip_same_vlan = factory.make_StaticIPAddress(158 sip_same_vlan = factory.make_StaticIPAddress(
159 interface=factory.make_Interface(159 interface=factory.make_Interface(
160 node=node_same_vlan, disconnected=True),160 node=node_same_vlan, link_connected=False),
161 subnet=factory.make_Subnet(161 subnet=factory.make_Subnet(
162 space=space, vlan=origin_subnet.vlan,162 space=space, vlan=origin_subnet.vlan,
163 cidr=next(networks)))163 cidr=next(networks)))
@@ -166,7 +166,7 @@ class TestFindAddressesBetweenNodes(MAASServerTestCase):
166 node_same_space = factory.make_Node(hostname="same-space")166 node_same_space = factory.make_Node(hostname="same-space")
167 sip_same_space = factory.make_StaticIPAddress(167 sip_same_space = factory.make_StaticIPAddress(
168 interface=factory.make_Interface(168 interface=factory.make_Interface(
169 node=node_same_space, disconnected=True),169 node=node_same_space, link_connected=False),
170 subnet=factory.make_Subnet(170 subnet=factory.make_Subnet(
171 space=space, cidr=next(networks)))171 space=space, cidr=next(networks)))
172172
@@ -174,7 +174,7 @@ class TestFindAddressesBetweenNodes(MAASServerTestCase):
174 node_null_space = factory.make_Node(hostname="null-space")174 node_null_space = factory.make_Node(hostname="null-space")
175 factory.make_StaticIPAddress(175 factory.make_StaticIPAddress(
176 interface=factory.make_Interface(176 interface=factory.make_Interface(
177 node=node_null_space, disconnected=True),177 node=node_null_space, link_connected=False),
178 subnet=factory.make_Subnet(178 subnet=factory.make_Subnet(
179 space=None, cidr=next(networks)))179 space=None, cidr=next(networks)))
180180
@@ -208,7 +208,7 @@ class TestFindAddressesBetweenNodes(MAASServerTestCase):
208 # would have obscured the test.208 # would have obscured the test.
209 origin_sip_2 = factory.make_StaticIPAddress(209 origin_sip_2 = factory.make_StaticIPAddress(
210 interface=factory.make_Interface(210 interface=factory.make_Interface(
211 node=origin, disconnected=True),211 node=origin, link_connected=False),
212 subnet=factory.make_Subnet(212 subnet=factory.make_Subnet(
213 space=space, cidr=next(networks)))213 space=space, cidr=next(networks)))
214214
@@ -239,7 +239,7 @@ class TestFindAddressesBetweenNodes(MAASServerTestCase):
239 # null space, one in a non-null space.239 # null space, one in a non-null space.
240 origin = factory.make_Node(hostname="origin")240 origin = factory.make_Node(hostname="origin")
241 origin_iface = factory.make_Interface(241 origin_iface = factory.make_Interface(
242 node=origin, disconnected=True)242 node=origin, link_connected=False)
243 origin_subnet_null_space = factory.make_Subnet(243 origin_subnet_null_space = factory.make_Subnet(
244 space=None, cidr=network1)244 space=None, cidr=network1)
245 factory.make_StaticIPAddress(245 factory.make_StaticIPAddress(
@@ -248,7 +248,7 @@ class TestFindAddressesBetweenNodes(MAASServerTestCase):
248 # Same subnet, different node.248 # Same subnet, different node.
249 node_no_match = factory.make_Node(hostname="no-match")249 node_no_match = factory.make_Node(hostname="no-match")
250 no_match_iface = factory.make_Interface(250 no_match_iface = factory.make_Interface(
251 node=node_no_match, disconnected=True)251 node=node_no_match, link_connected=False)
252 no_match_subnet_null_space = factory.make_Subnet(252 no_match_subnet_null_space = factory.make_Subnet(
253 space=None, cidr=network2)253 space=None, cidr=network2)
254 factory.make_StaticIPAddress(254 factory.make_StaticIPAddress(
diff --git a/src/maasserver/websockets/handlers/tests/test_script.py b/src/maasserver/websockets/handlers/tests/test_script.py
index 7d498d2..1108d6d 100644
--- a/src/maasserver/websockets/handlers/tests/test_script.py
+++ b/src/maasserver/websockets/handlers/tests/test_script.py
@@ -1,4 +1,4 @@
1# Copyright 2017-2018 Canonical Ltd. This software is licensed under the1# Copyright 2017-2019 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""Tests for `maasserver.websockets.handlers.script`"""4"""Tests for `maasserver.websockets.handlers.script`"""
@@ -35,6 +35,7 @@ class TestScriptHandler(MAASServerTestCase):
35 'for_hardware': script.for_hardware,35 'for_hardware': script.for_hardware,
36 'may_reboot': script.may_reboot,36 'may_reboot': script.may_reboot,
37 'recommission': script.recommission,37 'recommission': script.recommission,
38 'apply_configured_networking': script.apply_configured_networking,
38 'created': dehydrate_datetime(script.created),39 'created': dehydrate_datetime(script.created),
39 'updated': dehydrate_datetime(script.updated),40 'updated': dehydrate_datetime(script.updated),
40 }41 }
diff --git a/src/metadataserver/enum.py b/src/metadataserver/enum.py
index 25222bc..983a5b3 100644
--- a/src/metadataserver/enum.py
+++ b/src/metadataserver/enum.py
@@ -1,4 +1,4 @@
1# Copyright 2012-2018 Canonical Ltd. This software is licensed under the1# Copyright 2012-2019 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""Enumerations meaningful to the metadataserver application."""4"""Enumerations meaningful to the metadataserver application."""
@@ -101,6 +101,7 @@ class HARDWARE_TYPE:
101 CPU = 1101 CPU = 1
102 MEMORY = 2102 MEMORY = 2
103 STORAGE = 3103 STORAGE = 3
104 NETWORK = 4
104105
105106
106# Labels are also used for autotagging scripts.107# Labels are also used for autotagging scripts.
@@ -109,6 +110,7 @@ HARDWARE_TYPE_CHOICES = (
109 (HARDWARE_TYPE.CPU, "CPU"),110 (HARDWARE_TYPE.CPU, "CPU"),
110 (HARDWARE_TYPE.MEMORY, "Memory"),111 (HARDWARE_TYPE.MEMORY, "Memory"),
111 (HARDWARE_TYPE.STORAGE, "Storage"),112 (HARDWARE_TYPE.STORAGE, "Storage"),
113 (HARDWARE_TYPE.NETWORK, "Network"),
112)114)
113115
114116
diff --git a/src/metadataserver/migrations/0020_network_testing.py b/src/metadataserver/migrations/0020_network_testing.py
115new file mode 100644117new file mode 100644
index 0000000..2ea2ecb
--- /dev/null
+++ b/src/metadataserver/migrations/0020_network_testing.py
@@ -0,0 +1,35 @@
1# -*- coding: utf-8 -*-
2# Generated by Django 1.11.11 on 2019-06-07 19:40
3from __future__ import unicode_literals
4
5from django.db import (
6 migrations,
7 models,
8)
9import django.db.models.deletion
10
11
12class Migration(migrations.Migration):
13
14 dependencies = [
15 ('maasserver', '0188_network_testing'),
16 ('metadataserver', '0019_add_script_result_suppressed'),
17 ]
18
19 operations = [
20 migrations.AddField(
21 model_name='script',
22 name='apply_configured_networking',
23 field=models.BooleanField(default=False),
24 ),
25 migrations.AddField(
26 model_name='scriptresult',
27 name='interface',
28 field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='maasserver.Interface'),
29 ),
30 migrations.AlterField(
31 model_name='script',
32 name='hardware_type',
33 field=models.IntegerField(choices=[(0, 'Node'), (1, 'CPU'), (2, 'Memory'), (3, 'Storage'), (4, 'Network')], default=0),
34 ),
35 ]
diff --git a/src/metadataserver/models/script.py b/src/metadataserver/models/script.py
index ffa4e69..3bfda14 100644
--- a/src/metadataserver/models/script.py
+++ b/src/metadataserver/models/script.py
@@ -1,4 +1,4 @@
1# Copyright 2017 Canonical Ltd. This software is licensed under the1# Copyright 2017-2019 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4__all__ = [4__all__ = [
@@ -75,6 +75,8 @@ def translate_hardware_type(hardware_type):
75 return HARDWARE_TYPE.MEMORY75 return HARDWARE_TYPE.MEMORY
76 elif hardware_type in ['storage', 'disk', 'ssd']:76 elif hardware_type in ['storage', 'disk', 'ssd']:
77 return HARDWARE_TYPE.STORAGE77 return HARDWARE_TYPE.STORAGE
78 elif hardware_type in ['network', 'net', 'interface']:
79 return HARDWARE_TYPE.NETWORK
78 else:80 else:
79 raise ValidationError(81 raise ValidationError(
80 'Hardware type must be node, cpu, memory, or storage')82 'Hardware type must be node, cpu, memory, or storage')
@@ -182,6 +184,10 @@ class Script(CleanSave, TimestampedModel):
182 # scripts after receiving the result.184 # scripts after receiving the result.
183 recommission = BooleanField(default=False)185 recommission = BooleanField(default=False)
184186
187 # Whether or not maas-run-remote-scripts should apply user configured
188 # network settings before running the Script.
189 apply_configured_networking = BooleanField(default=False)
190
185 @property191 @property
186 def ForHardware(self):192 def ForHardware(self):
187 """Parses the for_hardware field and returns a ForHardware tuple."""193 """Parses the for_hardware field and returns a ForHardware tuple."""
diff --git a/src/metadataserver/models/scriptresult.py b/src/metadataserver/models/scriptresult.py
index e3b80ff..5ec3c98 100644
--- a/src/metadataserver/models/scriptresult.py
+++ b/src/metadataserver/models/scriptresult.py
@@ -24,6 +24,7 @@ from django.db.models import (
24from maasserver.fields import JSONObjectField24from maasserver.fields import JSONObjectField
25from maasserver.models.cleansave import CleanSave25from maasserver.models.cleansave import CleanSave
26from maasserver.models.event import Event26from maasserver.models.event import Event
27from maasserver.models.interface import Interface
27from maasserver.models.physicalblockdevice import PhysicalBlockDevice28from maasserver.models.physicalblockdevice import PhysicalBlockDevice
28from maasserver.models.timestampedmodel import (29from maasserver.models.timestampedmodel import (
29 now,30 now,
@@ -73,6 +74,10 @@ class ScriptResult(CleanSave, TimestampedModel):
73 PhysicalBlockDevice, editable=False, blank=True, null=True,74 PhysicalBlockDevice, editable=False, blank=True, null=True,
74 on_delete=CASCADE)75 on_delete=CASCADE)
7576
77 # If the result is in reference to a particular Interface link it.
78 interface = ForeignKey(
79 Interface, editable=False, blank=True, null=True, on_delete=CASCADE)
80
76 script_version = ForeignKey(81 script_version = ForeignKey(
77 VersionedTextFile, blank=True, null=True, editable=False,82 VersionedTextFile, blank=True, null=True, editable=False,
78 on_delete=SET_NULL)83 on_delete=SET_NULL)
diff --git a/src/metadataserver/models/tests/test_script.py b/src/metadataserver/models/tests/test_script.py
index ebf12d9..9c10e16 100644
--- a/src/metadataserver/models/tests/test_script.py
+++ b/src/metadataserver/models/tests/test_script.py
@@ -1,4 +1,4 @@
1# Copyright 2017 Canonical Ltd. This software is licensed under the1# Copyright 2017-2019 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4__all__ = []4__all__ = []
@@ -162,6 +162,18 @@ class TestTranslateHardwareType(MAASServerTestCase):
162 'value': 'ssd',162 'value': 'ssd',
163 'return_value': HARDWARE_TYPE.STORAGE,163 'return_value': HARDWARE_TYPE.STORAGE,
164 }),164 }),
165 ('network', {
166 'value': 'network',
167 'return_value': HARDWARE_TYPE.NETWORK,
168 }),
169 ('net', {
170 'value': 'net',
171 'return_value': HARDWARE_TYPE.NETWORK,
172 }),
173 ('interface', {
174 'value': 'interface',
175 'return_value': HARDWARE_TYPE.NETWORK,
176 }),
165 ('invalid value', {177 ('invalid value', {
166 'value': factory.make_name('value'),178 'value': factory.make_name('value'),
167 'exception': 'Hardware type must be node, cpu, memory, or storage',179 'exception': 'Hardware type must be node, cpu, memory, or storage',

Subscribers

People subscribed via source and target branches