sts-sponsors team mailing list archive
-
sts-sponsors team
-
Mailing list archive
-
Message #04889
[Merge] ~ack/maas:drop-mac-wrapper into maas:master
Alberto Donato has proposed merging ~ack/maas:drop-mac-wrapper into maas:master.
Commit message:
drop MAC wrapper object and related logic
Requested reviews:
MAAS Maintainers (maas-maintainers)
For more details, see:
https://code.launchpad.net/~ack/maas/+git/maas/+merge/436442
--
Your team MAAS Committers is subscribed to branch maas:master.
diff --git a/src/maasserver/api/machines.py b/src/maasserver/api/machines.py
index 3f9b55e..7ba6143 100644
--- a/src/maasserver/api/machines.py
+++ b/src/maasserver/api/machines.py
@@ -62,7 +62,7 @@ from maasserver.exceptions import (
NodeStateViolation,
Unauthorized,
)
-from maasserver.fields import validate_mac
+from maasserver.fields import mac_validator
from maasserver.forms import (
AdminMachineForm,
get_machine_create_form,
@@ -1915,7 +1915,7 @@ class AnonMachinesHandler(AnonNodesHandler):
macs_valid = True
for mac_address in mac_addresses:
try:
- validate_mac(mac_address)
+ mac_validator(mac_address)
except ValidationError:
macs_valid = False
break
diff --git a/src/maasserver/api/networks.py b/src/maasserver/api/networks.py
index bbe0eb8..8635109 100644
--- a/src/maasserver/api/networks.py
+++ b/src/maasserver/api/networks.py
@@ -137,7 +137,7 @@ class NetworkHandler(OperationsHandler):
unique_interfaces_by_mac,
key=lambda x: (
x.node_config.node.hostname.lower(),
- x.mac_address.get_raw(),
+ x.mac_address,
),
)
return [
diff --git a/src/maasserver/api/tests/test_enlistment.py b/src/maasserver/api/tests/test_enlistment.py
index fe5f429..9384922 100644
--- a/src/maasserver/api/tests/test_enlistment.py
+++ b/src/maasserver/api/tests/test_enlistment.py
@@ -489,7 +489,7 @@ class TestAnonymousEnlistmentAPI(APITestCase.ForAnonymous):
random.choice(macs),
# A MAC address unknown to MAAS shouldn't effect finding
# the machine.
- factory.make_MAC(),
+ factory.make_mac_address(),
],
},
)
diff --git a/src/maasserver/api/tests/test_events.py b/src/maasserver/api/tests/test_events.py
index 64fb3a3..dfe5acd 100644
--- a/src/maasserver/api/tests/test_events.py
+++ b/src/maasserver/api/tests/test_events.py
@@ -815,7 +815,7 @@ class TestEventsURIs(APITestCase.ForUser):
"domain": machine.domain.name,
"hostname": machine.hostname,
"id": machine.system_id,
- "mac_address": interface.mac_address.raw,
+ "mac_address": interface.mac_address,
"zone": machine.zone.name,
}
event = factory.make_Event(node=machine)
diff --git a/src/maasserver/api/tests/test_machine.py b/src/maasserver/api/tests/test_machine.py
index a2bd82c..0477be6 100644
--- a/src/maasserver/api/tests/test_machine.py
+++ b/src/maasserver/api/tests/test_machine.py
@@ -247,7 +247,7 @@ class TestMachineAPI(APITestCase.ForUser):
self.assertEqual(http.client.OK, response.status_code)
parsed_result = json_load_bytes(response.content)
self.assertEqual(
- machine.boot_interface.mac_address.get_raw(),
+ machine.boot_interface.mac_address,
parsed_result["boot_interface"]["mac_address"],
)
diff --git a/src/maasserver/api/tests/test_network.py b/src/maasserver/api/tests/test_network.py
index d81c4c2..843e360 100644
--- a/src/maasserver/api/tests/test_network.py
+++ b/src/maasserver/api/tests/test_network.py
@@ -202,10 +202,10 @@ class TestListConnectedMACs(APITestCase.ForUser):
interfaces,
key=lambda x: (
x.node_config.node.hostname.lower(),
- x.mac_address.get_raw(),
+ x.mac_address,
),
)
self.assertEqual(
- [nic.mac_address.get_raw() for nic in sorted_interfaces],
+ [nic.mac_address for nic in sorted_interfaces],
self.extract_macs(self.request_connected_macs(subnet)),
)
diff --git a/src/maasserver/djangosettings/settings.py b/src/maasserver/djangosettings/settings.py
index 9cf2d4d..1e7ccea 100644
--- a/src/maasserver/djangosettings/settings.py
+++ b/src/maasserver/djangosettings/settings.py
@@ -334,10 +334,6 @@ ALLOWED_HOSTS = ["*"]
# Consider the request secure if the header is set
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
-# Extend Django's JSON serialization. Without this, JSON serialization of
-# MAC addresses in model fields will break.
-SERIALIZATION_MODULES = {"maasjson": "maasserver.json"}
-
# MAAS has no upload limit to allow for big image files.
# (Django 1.10 introduced this limit with a default of 2.5MB.)
DATA_UPLOAD_MAX_MEMORY_SIZE = None
diff --git a/src/maasserver/fields.py b/src/maasserver/fields.py
index 1034765..94d64cf 100644
--- a/src/maasserver/fields.py
+++ b/src/maasserver/fields.py
@@ -10,15 +10,12 @@ __all__ = [
"HostListFormField",
"IPListFormField",
"IPv4CIDRField",
- "MAC",
"MACAddressField",
"MACAddressFormField",
"MODEL_NAME_VALIDATOR",
"NodeChoiceField",
- "register_mac_type",
"VerboseRegexValidator",
"VersionedTextFileField",
- "validate_mac",
]
import re
@@ -39,7 +36,6 @@ from django.db.models import (
from django.utils.deconstruct import deconstructible
from django.utils.encoding import force_str
from netaddr import AddrFormatError, IPAddress, IPNetwork
-import psycopg2.extensions
from maasserver.models.versionedtextfile import VersionedTextFile
from maasserver.utils.converters import parse_systemd_interval
@@ -84,13 +80,6 @@ class VerboseRegexValidator(RegexValidator):
mac_validator = VerboseRegexValidator(regex=MAC_RE, message=MAC_ERROR_MSG)
-def validate_mac(value):
- """Django validator for a MAC."""
- if isinstance(value, MAC):
- value = value.get_raw()
- mac_validator(value)
-
-
class StrippedCharField(forms.CharField):
"""A CharField that will strip surrounding whitespace before validation."""
@@ -144,145 +133,14 @@ class MACAddressField(Field):
description = "MAC address"
- default_validators = [validate_mac]
+ default_validators = [mac_validator]
def db_type(self, *args, **kwargs):
return "macaddr"
- def to_python(self, value):
- return MAC(value)
-
- def from_db_value(self, value, expression, connection):
- return MAC(value)
-
def get_prep_value(self, value):
- value = super().get_prep_value(value)
# Convert empty string to None.
- if not value:
- return None
- return value
-
-
-class MAC:
- """A MAC address represented as a database value.
-
- PostgreSQL supports MAC addresses as a native type. They show up
- client-side as this class. It is essentially a wrapper for a string.
-
- This NEVER represents a null or empty MAC address.
- """
-
- def __new__(cls, value):
- """Return `None` if `value` is `None` or the empty string."""
- if value is None:
- return None
- elif isinstance(value, (bytes, str)):
- return None if len(value) == 0 else super().__new__(cls)
- else:
- return super().__new__(cls)
-
- def __init__(self, value):
- """Wrap a MAC address, or None, into a `MAC`.
-
- :param value: A MAC address, in the form of a string or a `MAC`;
- or None.
- """
- # The wrapped attribute is stored as self._wrapped, following
- # ISQLQuote's example.
- if isinstance(value, MAC):
- self._wrapped = value._wrapped
- elif isinstance(value, bytes):
- self._wrapped = value.decode("ascii")
- elif isinstance(value, str):
- self._wrapped = value
- else:
- raise TypeError(f"expected MAC or string, got: {value!r}")
-
- def __conform__(self, protocol):
- """Tell psycopg2 that this type implements the adapter protocol."""
- # The psychopg2 docs say to check that the protocol is ISQLQuote,
- # but not what to do if it isn't.
- assert protocol == psycopg2.extensions.ISQLQuote, (
- "Unsupported psycopg2 adapter protocol: %s" % protocol
- )
- return self
-
- def getquoted(self):
- """Render this object in SQL.
-
- This is part of psycopg2's adapter protocol.
- """
- return "'%s'::macaddr" % self._wrapped
-
- def get_raw(self):
- """Return the wrapped value."""
- return self._wrapped
-
- @property
- def raw(self):
- """The MAC address as a string."""
- return self._wrapped
-
- @classmethod
- def parse(cls, value, cur):
- """Turn a value as received from the database into a MAC."""
- return cls(value)
-
- def __repr__(self):
- """Represent the MAC as a string."""
- return "<MAC %s>" % self._wrapped
-
- def __str__(self):
- """Represent the MAC as a Unicode string."""
- return self._wrapped
-
- def __bytes__(self):
- return self._wrapped.encode("ascii")
-
- def __len__(self):
- """Defer to len of the wrapped value."""
- return len(self._wrapped)
-
- def __eq__(self, other):
- """Two `MAC`s are equal if they wrap the same value.
-
- A MAC is is also equal to the value it wraps. This is non-commutative,
- but it supports Django code that compares input values to various
- kinds of "null" or "empty."
- """
- if isinstance(other, MAC):
- return self._wrapped == other._wrapped
- else:
- return self._wrapped == other
-
- def __ne__(self, other):
- return not (self == other)
-
- def __hash__(self):
- return hash(self._wrapped)
-
-
-def register_mac_type(cursor):
- """Register our `MAC` type with psycopg2 and Django."""
-
- # This is standard, but not built-in, magic to register a type in
- # psycopg2: execute a query that returns a field of the corresponding
- # database type, then get its oid out of the cursor, use that to create
- # a "typecaster" in psycopg (by calling new_type(), confusingly!), then
- # register that type in psycopg.
- cursor.execute("SELECT NULL::macaddr")
- oid = cursor.description[0][1]
- mac_caster = psycopg2.extensions.new_type((oid,), "macaddr", MAC.parse)
- psycopg2.extensions.register_type(mac_caster)
-
- # Now do the same for the type array-of-MACs. The "typecaster" created
- # for MAC is passed in; it gets used for parsing an individual element
- # of an array's text representation as received from the database.
- cursor.execute("SELECT '{}'::macaddr[]")
- oid = cursor.description[0][1]
- psycopg2.extensions.register_type(
- psycopg2.extensions.new_array_type((oid,), "macaddr", mac_caster)
- )
+ return super().get_prep_value(value) or None
class XMLField(Field):
diff --git a/src/maasserver/forms/interface.py b/src/maasserver/forms/interface.py
index 6967f8e..46b6229 100644
--- a/src/maasserver/forms/interface.py
+++ b/src/maasserver/forms/interface.py
@@ -461,7 +461,7 @@ class ChildInterfaceForm(InterfaceForm):
"""
if self.instance.id is not None:
parent_macs = {
- parent.mac_address.get_raw(): parent
+ parent.mac_address: parent
for parent in self.instance.parents.all()
}
else:
diff --git a/src/maasserver/json.py b/src/maasserver/json.py
deleted file mode 100644
index a560b37..0000000
--- a/src/maasserver/json.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2013-2016 Canonical Ltd. This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Extension of Django's JSON serializer to support MAAS custom data types.
-
-We register this as a replacement for Django's own JSON serialization by
-setting it in the SERIALIZATION_MODULES setting.
-"""
-
-
-import json
-
-import django.core.serializers.json
-
-from maasserver.fields import MAC
-
-
-class MAASJSONEncoder(django.core.serializers.json.DjangoJSONEncoder):
- """MAAS-specific JSON encoder.
-
- Compared to Django's encoder, it adds support for representing a
- `MAC` in JSON.
- """
-
- def default(self, value):
- if isinstance(value, MAC):
- return value.get_raw()
- else:
- return super().default(value)
-
-
-class Serializer(django.core.serializers.json.Serializer):
- """A copy of Django's serializer for JSON, but using our own encoder."""
-
- def end_serialization(self):
- json.dump(
- self.objects, self.stream, cls=MAASJSONEncoder, **self.options
- )
-
-
-# Keep using Django's deserializer. Loading a MAC from JSON will produce a
-# string.
-Deserializer = django.core.serializers.json.Deserializer
diff --git a/src/maasserver/models/interface.py b/src/maasserver/models/interface.py
index 6c8368b..5b765e4 100644
--- a/src/maasserver/models/interface.py
+++ b/src/maasserver/models/interface.py
@@ -49,8 +49,8 @@ from maasserver.exceptions import (
StaticIPAddressUnavailable,
)
from maasserver.fields import (
+ mac_validator,
MACAddressField,
- validate_mac,
VerboseRegexValidator,
)
from maasserver.models.cleansave import CleanSave
@@ -979,7 +979,7 @@ class Interface(CleanSave, TimestampedModel):
network = IPNetwork(net_cidr)
if network.prefixlen != 64:
return None
- return EUI(self.mac_address.raw).ipv6(network.first)
+ return EUI(self.mac_address).ipv6(network.first)
def remove_link_dhcp(self, subnet_family=None):
"""Removes the DHCP links if they have no subnet or if the linked
@@ -1490,7 +1490,7 @@ class Interface(CleanSave, TimestampedModel):
# Verify that the MAC address is legal if it is not empty.
if self.mac_address:
- validate_mac(self.mac_address)
+ mac_validator(self.mac_address)
def delete(self, remove_ip_address=True):
# We set the _skip_ip_address_removal so the signal can use it to
diff --git a/src/maasserver/models/node.py b/src/maasserver/models/node.py
index e9766d6..00202dd 100644
--- a/src/maasserver/models/node.py
+++ b/src/maasserver/models/node.py
@@ -112,7 +112,6 @@ from maasserver.exceptions import (
StaticIPAddressExhaustion,
StorageClearProblem,
)
-from maasserver.fields import MAC
from maasserver.models.blockdevice import BlockDevice
from maasserver.models.bootresource import BootResource
from maasserver.models.cacheset import CacheSet
@@ -2150,11 +2149,10 @@ class Node(CleanSave, TimestampedModel):
if name is None:
name = self.get_next_ifname()
- mac = MAC(mac_address)
- UnknownInterface.objects.filter(mac_address=mac).delete()
+ UnknownInterface.objects.filter(mac_address=mac_address).delete()
numa_node = self.default_numanode if self.is_machine else None
iface, created = PhysicalInterface.objects.get_or_create(
- mac_address=mac,
+ mac_address=mac_address,
defaults={
"node_config": self.current_config,
"name": name,
@@ -3159,8 +3157,7 @@ class Node(CleanSave, TimestampedModel):
boot_interface is not None
and boot_interface.mac_address is not None
):
- mac = boot_interface.mac_address.get_raw()
- power_params["mac_address"] = mac
+ power_params["mac_address"] = boot_interface.mac_address
# boot_mode is something that tells the template whether this is
# a PXE boot or a local HD boot.
diff --git a/src/maasserver/models/tests/test_interface.py b/src/maasserver/models/tests/test_interface.py
index b9c2e9b..82c70ce 100644
--- a/src/maasserver/models/tests/test_interface.py
+++ b/src/maasserver/models/tests/test_interface.py
@@ -1008,7 +1008,7 @@ class TestInterface(MAASServerTestCase):
# twice: once as part of Interface.clean() resulting in the __all__
# error, and once as part of field validation that happens after a
# few queries are done, so we cannot easily get rid of
- # validate_mac() in clean().
+ # mac_validator() in clean().
self.assertThat(
exception.message_dict,
MatchesDict(
@@ -1035,7 +1035,7 @@ class TestInterface(MAASServerTestCase):
def test_creates_interface(self):
name = factory.make_name("name")
node_config = factory.make_NodeConfig()
- mac = factory.make_MAC()
+ mac = factory.make_mac_address()
interface = factory.make_Interface(
INTERFACE_TYPE.PHYSICAL,
name=name,
@@ -1055,7 +1055,7 @@ class TestInterface(MAASServerTestCase):
def test_allows_null_vlan(self):
name = factory.make_name("name")
node_config = factory.make_NodeConfig()
- mac = factory.make_MAC()
+ mac = factory.make_mac_address()
interface = factory.make_Interface(
INTERFACE_TYPE.PHYSICAL,
name=name,
@@ -1077,11 +1077,11 @@ class TestInterface(MAASServerTestCase):
def test_string_representation_contains_essential_data(self):
name = factory.make_name("name")
node = factory.make_Node()
- mac = factory.make_MAC()
+ mac = factory.make_mac_address()
interface = factory.make_Interface(
INTERFACE_TYPE.PHYSICAL, name=name, node=node, mac_address=mac
)
- self.assertIn(mac.get_raw(), str(interface))
+ self.assertIn(mac, str(interface))
self.assertIn(name, str(interface))
def test_deletes_related_children(self):
@@ -1802,7 +1802,7 @@ class TestPhysicalInterfaceTransactional(MAASTransactionServerTestCase):
with transaction.atomic():
_create_physical(mac)
- mac = factory.make_MAC()
+ mac = factory.make_mac_address()
t = threading.Thread(target=create_physical, args=(mac,))
with transaction.atomic():
@@ -2482,7 +2482,7 @@ class TestUpdateIpAddresses(MAASServerTestCase):
def test_does_not_add_eui_64_address(self):
# See also LP#1639090.
- mac_address = factory.make_MAC()
+ mac_address = factory.make_mac_address()
iface = factory.make_Interface(
INTERFACE_TYPE.PHYSICAL, mac_address=mac_address
)
@@ -2494,7 +2494,7 @@ class TestUpdateIpAddresses(MAASServerTestCase):
def test_does_not_add_addresses_from_duplicate_subnet(self):
# See also LP#1803188.
- mac_address = factory.make_MAC()
+ mac_address = factory.make_mac_address()
vlan = factory.make_VLAN()
factory.make_Subnet(cidr="10.0.0.0/8", vlan=vlan)
factory.make_Subnet(cidr="2001::/64", vlan=vlan)
diff --git a/src/maasserver/models/tests/test_node.py b/src/maasserver/models/tests/test_node.py
index 4cf6669..25fc5e1 100644
--- a/src/maasserver/models/tests/test_node.py
+++ b/src/maasserver/models/tests/test_node.py
@@ -771,8 +771,7 @@ class TestRegionControllerManagerGetOrCreateRunningController(
def set_mac_address_to_match(self, node):
raw_macs = [
- nic.mac_address.raw
- for nic in node.current_config.interface_set.all()
+ nic.mac_address for nic in node.current_config.interface_set.all()
]
node_module.get_mac_addresses.return_value = [random.choice(raw_macs)]
diff --git a/src/maasserver/rpc/tests/test_nodes.py b/src/maasserver/rpc/tests/test_nodes.py
index dee97b7..80c49a3 100644
--- a/src/maasserver/rpc/tests/test_nodes.py
+++ b/src/maasserver/rpc/tests/test_nodes.py
@@ -339,7 +339,7 @@ class TestRequestNodeInfoByMACAddress(MAASServerTestCase):
def test_request_node_info_by_mac_address_returns_node_for_mac(self):
interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
node, boot_purpose = request_node_info_by_mac_address(
- interface.mac_address.get_raw()
+ interface.mac_address
)
self.assertEqual(node, interface.node_config.node)
diff --git a/src/maasserver/rpc/tests/test_rackcontrollers.py b/src/maasserver/rpc/tests/test_rackcontrollers.py
index 8e9c1a7..88b0591 100644
--- a/src/maasserver/rpc/tests/test_rackcontrollers.py
+++ b/src/maasserver/rpc/tests/test_rackcontrollers.py
@@ -112,11 +112,10 @@ class TestRegisterRackController(MAASServerTestCase):
def test_finds_existing_node_by_mac(self):
node = factory.make_Node()
nic = factory.make_Interface(node=node)
- mac = nic.mac_address.raw
interfaces = {
nic.name: {
"type": "physical",
- "mac_address": mac,
+ "mac_address": nic.mac_address,
"parents": [],
"links": [],
"enabled": True,
diff --git a/src/maasserver/rpc/tests/test_regionservice_calls.py b/src/maasserver/rpc/tests/test_regionservice_calls.py
index ddda99c..dbc756a 100644
--- a/src/maasserver/rpc/tests/test_regionservice_calls.py
+++ b/src/maasserver/rpc/tests/test_regionservice_calls.py
@@ -958,7 +958,7 @@ class TestRegionProtocol_SendEventMACAddress(MAASTransactionServerTestCase):
Region(),
SendEventMACAddress,
{
- "mac_address": mac_address.get_raw(),
+ "mac_address": mac_address,
"type_name": name,
"description": event_description,
},
@@ -985,7 +985,7 @@ class TestRegionProtocol_SendEventMACAddress(MAASTransactionServerTestCase):
event_type = factory.make_name("type_name")
yield deferToDatabase(self.create_event_type, event_type, "", 0)
interface = yield deferToDatabase(self.make_interface)
- mac_address = interface.mac_address.get_raw()
+ mac_address = interface.mac_address
yield eventloop.start()
try:
@@ -1289,7 +1289,7 @@ class TestRegionProtocol_RequestNodeInforByMACAddress(
node_info_function.return_value = (node, purpose)
interface = yield deferToDatabase(self.make_interface, node)
- params = {"mac_address": interface.mac_address.get_raw()}
+ params = {"mac_address": interface.mac_address}
response = yield call_responder(
Region(), RequestNodeInfoByMACAddress, params
diff --git a/src/maasserver/start_up.py b/src/maasserver/start_up.py
index c572b1f..824eca2 100644
--- a/src/maasserver/start_up.py
+++ b/src/maasserver/start_up.py
@@ -6,7 +6,6 @@
import logging
-from django.db import connection
from django.db.utils import DatabaseError
from twisted.internet.defer import inlineCallbacks
@@ -16,7 +15,6 @@ from maasserver.deprecations import (
log_deprecations,
sync_deprecation_notifications,
)
-from maasserver.fields import register_mac_type
from maasserver.models import (
Config,
ControllerInfo,
@@ -169,9 +167,6 @@ def start_up(master=False):
@transactional
def inner_start_up(master=False):
"""Startup jobs that must run serialized w.r.t. other starting servers."""
- # Register our MAC data type with psycopg.
- register_mac_type(connection.cursor())
-
# All commissioning and testing scripts are stored in the database. For
# a commissioning ScriptSet to be created Scripts must exist first. Call
# this early, only on the master process, to ensure they exist and are
diff --git a/src/maasserver/testing/factory.py b/src/maasserver/testing/factory.py
index 65414ca..521f706 100644
--- a/src/maasserver/testing/factory.py
+++ b/src/maasserver/testing/factory.py
@@ -42,7 +42,7 @@ from maasserver.enum import (
POWER_STATE,
RDNS_MODE,
)
-from maasserver.fields import LargeObjectFile, MAC
+from maasserver.fields import LargeObjectFile
from maasserver.models import (
BlockDevice,
BootResource,
@@ -1058,10 +1058,6 @@ class Factory(maastesting.factory.Factory):
**kwargs,
)
- def make_MAC(self):
- """Generate a random MAC address, in the form of a MAC object."""
- return MAC(self.make_mac_address())
-
def make_Node_with_Interface_on_Subnet(
self,
interface_count=1,
@@ -1783,7 +1779,7 @@ class Factory(maastesting.factory.Factory):
INTERFACE_TYPE.BRIDGE,
INTERFACE_TYPE.UNKNOWN,
]:
- mac_address = self.make_MAC()
+ mac_address = self.make_mac_address()
if tags is None:
tags = [self.make_name("tag") for _ in range(3)]
link_speeds = [10, 100, 1000, 10000, 20000, 40000, 50000, 100000]
diff --git a/src/maasserver/testing/testcase.py b/src/maasserver/testing/testcase.py
index 4ea0dfb..143a288 100644
--- a/src/maasserver/testing/testcase.py
+++ b/src/maasserver/testing/testcase.py
@@ -25,7 +25,6 @@ from django.db import (
)
from django.db.utils import IntegrityError, OperationalError
-from maasserver.fields import register_mac_type
from maasserver.models import signals
from maasserver.testing.fixtures import (
IntroCompletedFixture,
@@ -78,11 +77,6 @@ class MAASRegionTestCaseBase(PostCommitHooksTestMixin):
"""Set the current client."""
self.__client = client
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- register_mac_type(connection.cursor())
-
def setUp(self):
reset_queries() # Formerly this was handled by... Django?
super().setUp()
diff --git a/src/maasserver/tests/test_fields.py b/src/maasserver/tests/test_fields.py
index 0769d8d..dee3717 100644
--- a/src/maasserver/tests/test_fields.py
+++ b/src/maasserver/tests/test_fields.py
@@ -1,16 +1,13 @@
# Copyright 2012-2017 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
-import json
from random import choice, randint
import re
-from django.core import serializers
from django.core.exceptions import ValidationError
from django.db import connection, DatabaseError
from django.db.models import BinaryField
from psycopg2 import OperationalError
-from psycopg2.extensions import ISQLQuote
from testtools import ExpectedException
from maasserver.enum import INTERFACE_TYPE
@@ -20,15 +17,12 @@ from maasserver.fields import (
IPListFormField,
LargeObjectField,
LargeObjectFile,
- MAC,
MODEL_NAME_VALIDATOR,
NodeChoiceField,
- register_mac_type,
SubnetListFormField,
SystemdIntervalField,
URLOrPPAFormField,
URLOrPPAValidator,
- validate_mac,
VerboseRegexField,
VerboseRegexValidator,
VersionedTextFileField,
@@ -50,134 +44,6 @@ from maastesting.matchers import MockCalledOnceWith
from maastesting.testcase import MAASTestCase
-class TestMAC(MAASServerTestCase):
- def test_conform_accepts_ISQLQuote(self):
- mac = MAC(factory.make_mac_address())
- self.assertEqual(mac, mac.__conform__(ISQLQuote))
-
- def test_new_MAC_with_None_is_None(self):
- self.assertIsNone(MAC(None))
-
- def test_new_MAC_with_empty_unicode_string_is_None(self):
- self.assertIsNone(MAC(""))
-
- def test_new_MAC_with_empty_byte_string_is_None(self):
- self.assertIsNone(MAC(b""))
-
- def test_new_MAC_with_other_value_types_are_rejected(self):
- self.assertRaises(TypeError, MAC, 1234)
- self.assertRaises(TypeError, MAC, object())
- self.assertRaises(TypeError, MAC, self)
-
- def test_as_representation(self):
- addr = factory.make_mac_address()
- mac = MAC(addr)
- self.assertEqual("<MAC " + addr + ">", repr(mac))
-
- def test_as_unicode_string(self):
- addr = factory.make_mac_address()
- mac = MAC(addr)
- self.assertEqual(addr, str(mac))
-
- def test_as_byte_string(self):
- addr = factory.make_mac_address()
- mac = MAC(addr)
- self.assertEqual(addr.encode("ascii"), bytes(mac))
-
- def test_get_raw_returns_wrapped_address(self):
- addr = factory.make_mac_address()
- self.assertEqual(addr, MAC(addr).get_raw())
-
- def test_get_raw_punches_through_double_wrapping(self):
- addr = factory.make_mac_address()
- self.assertEqual(addr, MAC(MAC(addr)).get_raw())
-
- def test_raw_property_is_the_address(self):
- addr = factory.make_mac_address()
- self.assertEqual(addr, MAC(addr).raw)
-
- def test_getquoted_returns_SQL_for_MAC(self):
- addr = factory.make_mac_address()
- self.assertEqual("'%s'::macaddr" % addr, MAC(addr).getquoted())
-
- def test_getquoted_punches_through_double_wrapping(self):
- addr = factory.make_mac_address()
- self.assertEqual("'%s'::macaddr" % addr, MAC(MAC(addr)).getquoted())
-
- def test_mac_is_len_able(self):
- mac = factory.make_MAC()
- self.assertEqual(len(mac), len(mac.raw))
-
- def test_mac_equals_self(self):
- mac = factory.make_MAC()
- self.assertTrue(mac == mac)
-
- def test_mac_equals_identical_mac(self):
- addr = factory.make_mac_address()
- self.assertTrue(MAC(addr) == MAC(addr))
-
- def test_eq_punches_through_double_wrapping_on_self(self):
- mac = factory.make_MAC()
- self.assertTrue(MAC(mac) == mac)
-
- def test_eq_punches_through_double_wrapping_on_other(self):
- mac = factory.make_MAC()
- self.assertTrue(mac == MAC(mac))
-
- def test_eq_punches_through_double_double_wrappings(self):
- mac = factory.make_MAC()
- self.assertTrue(MAC(mac) == MAC(mac))
-
- def test_mac_does_not_equal_other(self):
- self.assertFalse(factory.make_MAC() == factory.make_MAC())
-
- def test_mac_differs_from_other(self):
- self.assertTrue(factory.make_MAC() != factory.make_MAC())
-
- def test_mac_does_not_differ_from_self(self):
- mac = factory.make_MAC()
- self.assertFalse(mac != mac)
-
- def test_mac_address_does_not_equal_none(self):
- self.assertIsNotNone(factory.make_MAC())
-
- def test_ne_punches_through_double_wrapping_on_self(self):
- mac = factory.make_MAC()
- self.assertFalse(MAC(mac) != mac)
-
- def test_ne_punches_through_double_wrapping_on_other(self):
- mac = factory.make_MAC()
- self.assertFalse(mac != MAC(mac))
-
- def test_ne_punches_through_double_double_wrapping(self):
- mac = factory.make_MAC()
- self.assertFalse(MAC(mac) != MAC(mac))
-
- def test_different_macs_hash_differently(self):
- mac1 = factory.make_MAC()
- mac2 = factory.make_MAC()
- self.assertCountEqual({mac1, mac2}, [mac1, mac2])
-
- def test_identical_macs_hash_identically(self):
- addr = factory.make_mac_address()
- self.assertCountEqual(
- {MAC(addr), MAC(addr), MAC(MAC(addr)), addr}, [addr]
- )
-
- def test_django_serializes_MAC_to_JSON(self):
- interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
- query = Interface.objects.filter(id=interface.id)
- output = serializers.serialize("json", query)
- self.assertIn(json.dumps(interface.mac_address.get_raw()), output)
- self.assertIn('"%s"' % interface.mac_address.get_raw(), output)
-
- def test_register_mac_type_is_idempotent(self):
- register_mac_type(connection.cursor())
- register_mac_type(connection.cursor())
- # The test is that we get here without crashing.
- pass
-
-
class TestModelNameValidator(MAASServerTestCase):
def test_valid_name(self):
self.assertIsNone(MODEL_NAME_VALIDATOR("a-valid-name"))
@@ -235,49 +101,6 @@ class TestMACAddressField(MAASServerTestCase):
loaded_mac = Interface.objects.get(id=interface.id)
self.assertEqual("aa:bb:cc:dd:ee:ff", loaded_mac.mac_address)
- def test_accepts_colon_separated_octets(self):
- validate_mac("00:aa:22:cc:44:dd")
- # No error.
- pass
-
- def test_accepts_dash_separated_octets(self):
- validate_mac("00-aa-22-cc-44-dd")
- # No error.
- pass
-
- def test_accepts_upper_and_lower_case(self):
- validate_mac("AA:BB:CC:dd:ee:ff")
- # No error.
- pass
-
- def test_accepts_cisco_format(self):
- validate_mac("0000.0200.3fff")
- # No error.
- pass
-
- def test_accepts_leading_and_trailing_whitespace(self):
- validate_mac(" AA:BB:CC:DD:EE:FF ")
- # No error.
- pass
-
- def test_rejects_short_mac(self):
- self.assertRaises(ValidationError, validate_mac, "00:11:22:33:44")
-
- def test_rejects_long_mac(self):
- self.assertRaises(
- ValidationError, validate_mac, "00:11:22:33:44:55:66"
- )
-
- def test_accepts_short_octet(self):
- # Hit both parts of the regex.
- validate_mac("00:1:22:33:44:55")
- validate_mac("00:11:22:33:44:5")
- # No error.
- pass
-
- def test_rejects_long_octet(self):
- self.assertRaises(ValidationError, validate_mac, "00:11:222:33:44:55")
-
class TestXMLField(MAASLegacyServerTestCase):
diff --git a/src/maasserver/tests/test_preseed_network.py b/src/maasserver/tests/test_preseed_network.py
index 91ffd76..a1d5a72 100644
--- a/src/maasserver/tests/test_preseed_network.py
+++ b/src/maasserver/tests/test_preseed_network.py
@@ -503,7 +503,7 @@ class TestDHCPNetworkLayout(MAASServerTestCase, AssertNetworkConfigMixin):
"config": [
{
"id": iface.name,
- "mac_address": iface.mac_address.raw,
+ "mac_address": iface.mac_address,
"mtu": iface.get_effective_mtu(),
"name": iface.name,
"type": "physical",
diff --git a/src/maasserver/tests/test_start_up.py b/src/maasserver/tests/test_start_up.py
index 13e806f..95f85e0 100644
--- a/src/maasserver/tests/test_start_up.py
+++ b/src/maasserver/tests/test_start_up.py
@@ -77,8 +77,8 @@ class TestStartUp(MAASTransactionServerTestCase):
def check_lock(_):
raise locked if locks.startup.is_locked() else unlocked
- self.patch(start_up, "register_mac_type").side_effect = check_lock
- self.assertRaises(type(locked), start_up.inner_start_up, master=False)
+ self.patch(start_up, "load_builtin_scripts").side_effect = check_lock
+ self.assertRaises(type(locked), start_up.inner_start_up, master=True)
def test_start_up_retries_with_wait_on_exception(self):
inner_start_up = self.patch(start_up, "inner_start_up")
diff --git a/src/maasserver/triggers/tests/test_websocket_listener.py b/src/maasserver/triggers/tests/test_websocket_listener.py
index 1506d30..277fce2 100644
--- a/src/maasserver/triggers/tests/test_websocket_listener.py
+++ b/src/maasserver/triggers/tests/test_websocket_listener.py
@@ -1847,7 +1847,7 @@ class TestNodeInterfaceListener(
yield deferToDatabase(
self.update_interface,
interface.id,
- {"mac_address": factory.make_MAC()},
+ {"mac_address": factory.make_mac_address()},
)
yield dv.get(timeout=2)
self.assertEqual(("update", node.system_id), dv.value)
@@ -1949,7 +1949,7 @@ class TestDeviceWithParentInterfaceListener(
yield deferToDatabase(
self.update_interface,
interface.id,
- {"mac_address": factory.make_MAC()},
+ {"mac_address": factory.make_mac_address()},
)
yield dv.get(timeout=2)
self.assertEqual(("update", parent.system_id), dv.value)
diff --git a/src/maasserver/websockets/handlers/device.py b/src/maasserver/websockets/handlers/device.py
index 4d98b8c..4d3a696 100644
--- a/src/maasserver/websockets/handlers/device.py
+++ b/src/maasserver/websockets/handlers/device.py
@@ -35,7 +35,7 @@ def get_Interface_from_list(interfaces, mac):
mac = EUI(mac)
for interface in interfaces:
ifmac = interface.mac_address
- if ifmac is not None and EUI(ifmac.raw) == mac:
+ if ifmac is not None and EUI(ifmac) == mac:
return interface
else:
return None
diff --git a/src/maasserver/websockets/handlers/tests/test_device.py b/src/maasserver/websockets/handlers/tests/test_device.py
index eb595d7..c792209 100644
--- a/src/maasserver/websockets/handlers/tests/test_device.py
+++ b/src/maasserver/websockets/handlers/tests/test_device.py
@@ -18,7 +18,6 @@ from maasserver.enum import (
NODE_TYPE,
)
from maasserver.exceptions import NodeActionError
-from maasserver.fields import MAC
from maasserver.forms import DeviceForm, DeviceWithMACsForm
from maasserver.models import Interface, StaticIPAddress
from maasserver.node_action import compile_node_actions
@@ -577,7 +576,7 @@ class TestDeviceHandler(MAASTransactionServerTestCase):
created_device["ip_assignment"],
Equals(DEVICE_IP_ASSIGNMENT_TYPE.STATIC),
)
- static_interface = Interface.objects.get(mac_address=MAC(mac))
+ static_interface = Interface.objects.get(mac_address=mac)
observed_subnet = static_interface.ip_addresses.first().subnet
self.expectThat(
observed_subnet,
@@ -620,7 +619,7 @@ class TestDeviceHandler(MAASTransactionServerTestCase):
Equals(DEVICE_IP_ASSIGNMENT_TYPE.STATIC),
)
self.expectThat(created_device["ip_address"], Equals(ip_address))
- static_interface = Interface.objects.get(mac_address=MAC(mac))
+ static_interface = Interface.objects.get(mac_address=mac)
observed_subnet = static_interface.ip_addresses.first().subnet
self.expectThat(
observed_subnet,
@@ -674,7 +673,7 @@ class TestDeviceHandler(MAASTransactionServerTestCase):
self.expectThat(
created_device["ip_address"], Equals(static_ip_address)
)
- static_interface = Interface.objects.get(mac_address=MAC(mac_static))
+ static_interface = Interface.objects.get(mac_address=mac_static)
observed_subnet = static_interface.ip_addresses.first().subnet
self.expectThat(
observed_subnet,
@@ -824,7 +823,7 @@ class TestDeviceHandler(MAASTransactionServerTestCase):
updated_device["ip_assignment"],
Equals(DEVICE_IP_ASSIGNMENT_TYPE.STATIC),
)
- static_interface = Interface.objects.get(mac_address=MAC(mac))
+ static_interface = Interface.objects.get(mac_address=mac)
observed_subnet = static_interface.ip_addresses.first().subnet
self.expectThat(
observed_subnet,
@@ -857,7 +856,7 @@ class TestDeviceHandler(MAASTransactionServerTestCase):
Equals(DEVICE_IP_ASSIGNMENT_TYPE.STATIC),
)
self.expectThat(updated_device["ip_address"], Equals(ip_address))
- static_interface = Interface.objects.get(mac_address=MAC(mac))
+ static_interface = Interface.objects.get(mac_address=mac)
observed_subnet = static_interface.ip_addresses.first().subnet
self.expectThat(
observed_subnet,
diff --git a/src/metadataserver/builtin_scripts/tests/test_hooks.py b/src/metadataserver/builtin_scripts/tests/test_hooks.py
index 8ee17cc..182ed48 100644
--- a/src/metadataserver/builtin_scripts/tests/test_hooks.py
+++ b/src/metadataserver/builtin_scripts/tests/test_hooks.py
@@ -21,7 +21,6 @@ from maasserver.enum import (
NODE_STATUS,
PARTITION_TABLE_TYPE,
)
-from maasserver.fields import MAC
from maasserver.models import (
NodeMetadata,
NUMANode,
@@ -3892,9 +3891,9 @@ class TestUpdateNodeNetworkInformation(MAASServerTestCase):
"""
EXPECTED_INTERFACES = {
- "eth0": MAC("00:00:00:00:00:01"),
- "eth1": MAC("00:00:00:00:00:02"),
- "eth2": MAC("00:00:00:00:00:03"),
+ "eth0": "00:00:00:00:00:01",
+ "eth1": "00:00:00:00:00:02",
+ "eth2": "00:00:00:00:00:03",
}
def assert_expected_interfaces_and_macs_exist_for_node(
@@ -4160,7 +4159,7 @@ class TestUpdateNodeNetworkInformation(MAASServerTestCase):
iface.mac_address
for iface in node.current_config.interface_set.all()
]
- self.assertNotIn(MAC("01:23:45:67:89:ab"), db_macaddresses)
+ self.assertNotIn("01:23:45:67:89:ab", db_macaddresses)
def test_reassign_mac(self):
"""Test whether we can assign a MAC address previously connected to a
@@ -4169,7 +4168,7 @@ class TestUpdateNodeNetworkInformation(MAASServerTestCase):
# Create a MAC address that we know IS in the test dataset.
interface_to_be_reassigned = factory.make_Interface(node=node1)
- interface_to_be_reassigned.mac_address = MAC("00:00:00:00:00:01")
+ interface_to_be_reassigned.mac_address = "00:00:00:00:00:01"
interface_to_be_reassigned.save()
node2 = factory.make_Node()
@@ -4223,27 +4222,27 @@ class TestUpdateNodeNetworkInformation(MAASServerTestCase):
# Note: since this VLANInterface will be linked to the default VLAN
# ("vid 0", which is actually invalid) the VLANInterface will
# automatically get the name "vlan0".
- ETH0_MAC = self.EXPECTED_INTERFACES["eth0"].get_raw()
- ETH1_MAC = self.EXPECTED_INTERFACES["eth1"].get_raw()
+ eth0_mac = self.EXPECTED_INTERFACES["eth0"]
+ eth1_mac = self.EXPECTED_INTERFACES["eth1"]
BOND_NAME = "bond0"
node = factory.make_Node()
eth0 = factory.make_Interface(
- name="eth0", mac_address=ETH0_MAC, node=node
+ name="eth0", mac_address=eth0_mac, node=node
)
eth1 = factory.make_Interface(
- name="eth1", mac_address=ETH1_MAC, node=node
+ name="eth1", mac_address=eth1_mac, node=node
)
factory.make_Interface(
INTERFACE_TYPE.VLAN,
- mac_address=ETH0_MAC,
+ mac_address=eth0_mac,
parents=[eth0],
node=node,
)
factory.make_Interface(
INTERFACE_TYPE.BOND,
- mac_address=ETH1_MAC,
+ mac_address=eth1_mac,
parents=[eth1],
node=node,
name=BOND_NAME,
@@ -4255,12 +4254,12 @@ class TestUpdateNodeNetworkInformation(MAASServerTestCase):
self.assert_expected_interfaces_and_macs_exist_for_node(node)
def test_interface_name_changed(self):
- ETH0_MAC = self.EXPECTED_INTERFACES["eth1"].get_raw()
+ eth0_mac = self.EXPECTED_INTERFACES["eth1"]
node = factory.make_Node()
factory.make_Interface(
INTERFACE_TYPE.PHYSICAL,
name="eth0",
- mac_address=ETH0_MAC,
+ mac_address=eth0_mac,
node=node,
)
update_node_network_information(
@@ -4272,10 +4271,10 @@ class TestUpdateNodeNetworkInformation(MAASServerTestCase):
def test_mac_id_is_preserved(self):
"""Test whether MAC address entities are preserved and not recreated"""
- ETH0_MAC = self.EXPECTED_INTERFACES["eth0"].get_raw()
+ eth0_mac = self.EXPECTED_INTERFACES["eth0"]
node = factory.make_Node()
iface_to_be_preserved = factory.make_Interface(
- mac_address=ETH0_MAC, node=node
+ mac_address=eth0_mac, node=node
)
update_node_network_information(
@@ -4285,11 +4284,11 @@ class TestUpdateNodeNetworkInformation(MAASServerTestCase):
self.assertIsNotNone(reload_object(iface_to_be_preserved))
def test_legacy_model_upgrade_preserves_interfaces(self):
- ETH0_MAC = self.EXPECTED_INTERFACES["eth0"].get_raw()
- ETH1_MAC = self.EXPECTED_INTERFACES["eth1"].get_raw()
+ eth0_mac = self.EXPECTED_INTERFACES["eth0"]
+ eth1_mac = self.EXPECTED_INTERFACES["eth1"]
node = factory.make_Node()
- eth0 = factory.make_Interface(mac_address=ETH0_MAC, node=node)
- eth1 = factory.make_Interface(mac_address=ETH1_MAC, node=node)
+ eth0 = factory.make_Interface(mac_address=eth0_mac, node=node)
+ eth1 = factory.make_Interface(mac_address=eth1_mac, node=node)
update_node_network_information(
node, make_lxd_output(), create_numa_nodes(node)
)
@@ -4300,15 +4299,15 @@ class TestUpdateNodeNetworkInformation(MAASServerTestCase):
self.assert_expected_interfaces_and_macs_exist_for_node(node)
def test_legacy_model_with_extra_mac(self):
- ETH0_MAC = self.EXPECTED_INTERFACES["eth0"].get_raw()
- ETH1_MAC = self.EXPECTED_INTERFACES["eth1"].get_raw()
- ETH2_MAC = self.EXPECTED_INTERFACES["eth2"].get_raw()
- ETH3_MAC = "00:00:00:00:01:04"
+ eth0_mac = self.EXPECTED_INTERFACES["eth0"]
+ eth1_mac = self.EXPECTED_INTERFACES["eth1"]
+ eth2_mac = self.EXPECTED_INTERFACES["eth2"]
+ eth3_mac = "00:00:00:00:01:04"
node = factory.make_Node()
- eth0 = factory.make_Interface(mac_address=ETH0_MAC, node=node)
- eth1 = factory.make_Interface(mac_address=ETH1_MAC, node=node)
- eth2 = factory.make_Interface(mac_address=ETH2_MAC, node=node)
- eth3 = factory.make_Interface(mac_address=ETH3_MAC, node=node)
+ eth0 = factory.make_Interface(mac_address=eth0_mac, node=node)
+ eth1 = factory.make_Interface(mac_address=eth1_mac, node=node)
+ eth2 = factory.make_Interface(mac_address=eth2_mac, node=node)
+ eth3 = factory.make_Interface(mac_address=eth3_mac, node=node)
update_node_network_information(
node, make_lxd_output(), create_numa_nodes(node)
@@ -4325,12 +4324,12 @@ class TestUpdateNodeNetworkInformation(MAASServerTestCase):
self.assertIsNone(reload_object(eth3))
def test_deletes_virtual_interfaces_with_unique_mac(self):
- ETH0_MAC = self.EXPECTED_INTERFACES["eth0"].get_raw()
- ETH1_MAC = self.EXPECTED_INTERFACES["eth1"].get_raw()
+ eth0_mac = self.EXPECTED_INTERFACES["eth0"]
+ eth1_mac = self.EXPECTED_INTERFACES["eth1"]
BOND_MAC = "00:00:00:00:01:02"
node = factory.make_Node()
- eth0 = factory.make_Interface(mac_address=ETH0_MAC, node=node)
- eth1 = factory.make_Interface(mac_address=ETH1_MAC, node=node)
+ eth0 = factory.make_Interface(mac_address=eth0_mac, node=node)
+ eth1 = factory.make_Interface(mac_address=eth1_mac, node=node)
factory.make_Interface(INTERFACE_TYPE.VLAN, node=node, parents=[eth0])
factory.make_Interface(
INTERFACE_TYPE.BOND,
@@ -4715,7 +4714,7 @@ class TestUpdateBootInterface(MAASServerTestCase):
)
def test_boot_interface_bootif_bonded_interfaces(self):
- mac_address = factory.make_MAC()
+ mac_address = factory.make_mac_address()
parent = factory.make_Interface(
INTERFACE_TYPE.PHYSICAL, node=self.node, mac_address=mac_address
)
Follow ups