added nameserver error class to be used in domain

This commit is contained in:
Alysia Broddrick 2023-10-04 17:58:33 -07:00
parent 6944b31ba0
commit f7e168de19
No known key found for this signature in database
GPG key ID: 03917052CD0F06B7
4 changed files with 64 additions and 65 deletions

View file

@ -15,7 +15,10 @@ from epplibwrapper import (
RegistryError, RegistryError,
ErrorCode, ErrorCode,
) )
from registrar.models.utility.nameserver_error import (
NameserverError,
NameserverErrorCodes as nsErrorCodes,
)
from .utility.domain_field import DomainField from .utility.domain_field import DomainField
from .utility.domain_helper import DomainHelper from .utility.domain_helper import DomainHelper
from .utility.time_stamped_model import TimeStampedModel from .utility.time_stamped_model import TimeStampedModel
@ -231,8 +234,9 @@ class Domain(TimeStampedModel, DomainHelper):
try: try:
hosts = self._get_property("hosts") hosts = self._get_property("hosts")
except Exception as err: except Exception as err:
# TODO-848: Check/add to error handling ticket if it's not addressed # Do not raise error when missing nameservers
# (Don't throw error as this is normal for a new domain?) # this is a standard occurence when a domain
# is first created
logger.info("Domain is missing nameservers %s" % err) logger.info("Domain is missing nameservers %s" % err)
return [] return []
@ -279,20 +283,17 @@ class Domain(TimeStampedModel, DomainHelper):
def checkHostIPCombo(self, nameserver: str, ip: list): def checkHostIPCombo(self, nameserver: str, ip: list):
if self.isSubdomain(nameserver) and (ip is None or ip == []): if self.isSubdomain(nameserver) and (ip is None or ip == []):
raise ValueError( raise NameserverError(code=nsErrorCodes.MISSING_IP, nameserver=nameserver)
"Nameserver %s needs to have an "
"IP address because it is a subdomain" % nameserver
)
elif not self.isSubdomain(nameserver) and (ip is not None and ip != []): elif not self.isSubdomain(nameserver) and (ip is not None and ip != []):
raise ValueError( raise NameserverError(
"Nameserver %s cannot be linked " code=nsErrorCodes.GLUE_RECORD_NOT_ALLOWED, nameserver=nameserver, ip=ip
"because %s is not a subdomain" % (nameserver, ip)
) )
elif ip is not None and ip != []: elif ip is not None and ip != []:
for addr in ip: for addr in ip:
if not self._valid_ip_addr(addr): if not self._valid_ip_addr(addr):
raise ValueError( raise NameserverError(
"Nameserver %s has an invalid IP address: %s" % (nameserver, ip) code=nsErrorCodes.INVALID_IP, nameserver=nameserver, ip=ip
) )
return None return None
@ -428,9 +429,7 @@ class Domain(TimeStampedModel, DomainHelper):
example: [(ns1.okay.gov, [127.0.0.1, others ips])]""" example: [(ns1.okay.gov, [127.0.0.1, others ips])]"""
if len(hosts) > 13: if len(hosts) > 13:
raise ValueError( raise NameserverError(code=nsErrorCodes.TOO_MANY_HOSTS)
"Too many hosts provided, you may not have more than 13 nameservers."
)
logger.info("Setting nameservers") logger.info("Setting nameservers")
logger.info(hosts) logger.info(hosts)
@ -452,7 +451,6 @@ class Domain(TimeStampedModel, DomainHelper):
len(oldNameservers) - successDeletedCount + successCreatedCount len(oldNameservers) - successDeletedCount + successCreatedCount
) )
if successTotalNameservers < 2: if successTotalNameservers < 2:
try: try:
self.dns_needed() self.dns_needed()

View file

@ -11,8 +11,7 @@ class NameserverErrorCodes(IntEnum):
MISSING_IP = 1 MISSING_IP = 1
GLUE_RECORD_NOT_ALLOWED = 2 GLUE_RECORD_NOT_ALLOWED = 2
INVALID_IP = 3 INVALID_IP = 3
TOO_MANY_HOSTS=4 TOO_MANY_HOSTS = 4
class NameserverError(Exception): class NameserverError(Exception):
@ -25,25 +24,24 @@ class NameserverError(Exception):
_error_mapping = { _error_mapping = {
NameserverErrorCodes.MISSING_IP: "Nameserver {} needs to have an " NameserverErrorCodes.MISSING_IP: "Nameserver {} needs to have an "
"IP address because it is a subdomain", "IP address because it is a subdomain",
NameserverErrorCodes.GLUE_RECORD_NOT_ALLOWED: "Nameserver {} cannot be linked " NameserverErrorCodes.GLUE_RECORD_NOT_ALLOWED: "Nameserver {} cannot be linked "
"because it is not a subdomain", "because it is not a subdomain",
NameserverErrorCodes.INVALID_IP: "Nameserver {} has an invalid IP address: {}", NameserverErrorCodes.INVALID_IP: "Nameserver {} has an invalid IP address: {}",
NameserverErrorCodes.TOO_MANY_HOSTS: "Too many hosts provided, you may not have more than 13 nameservers.", NameserverErrorCodes.TOO_MANY_HOSTS: "Too many hosts provided, you may not have more than 13 nameservers.",
} }
def __init__(self, *args, code=None,nameserver=None,ip=None, **kwargs): def __init__(self, *args, code=None, nameserver=None, ip=None, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.code = code self.code = code
if self.code in self._error_mapping: if self.code in self._error_mapping:
self.message = self._error_mapping.get(self.code) self.message = self._error_mapping.get(self.code)
if nameserver is not None and ip is not None: if nameserver is not None and ip is not None:
self.message=self.message.format(str(nameserver),str(ip)) self.message = self.message.format(str(nameserver), str(ip))
elif nameserver is not None: elif nameserver is not None:
self.message=self.message.format(str(nameserver)) self.message = self.message.format(str(nameserver))
elif ip is not None: elif ip is not None:
self.message=self.message.format(str(ip)) self.message = self.message.format(str(ip))
def __str__(self): def __str__(self):
return f"{self.message}" return f"{self.message}"

View file

@ -16,6 +16,7 @@ from registrar.models.domain_information import DomainInformation
from registrar.models.draft_domain import DraftDomain from registrar.models.draft_domain import DraftDomain
from registrar.models.public_contact import PublicContact from registrar.models.public_contact import PublicContact
from registrar.models.user import User from registrar.models.user import User
from registrar.models.utility.nameserver_error import NameserverError
from .common import MockEppLib from .common import MockEppLib
from django_fsm import TransitionNotAllowed # type: ignore from django_fsm import TransitionNotAllowed # type: ignore
from epplibwrapper import ( from epplibwrapper import (
@ -1141,7 +1142,7 @@ class TestRegistrantNameservers(MockEppLib):
name="nameserversubdomain.gov", state=Domain.State.READY name="nameserversubdomain.gov", state=Domain.State.READY
) )
with self.assertRaises(ValueError): with self.assertRaises(NameserverError):
domain.nameservers = [ domain.nameservers = [
("ns1.nameserversubdomain.gov",), ("ns1.nameserversubdomain.gov",),
("ns2.nameserversubdomain.gov",), ("ns2.nameserversubdomain.gov",),
@ -1152,7 +1153,7 @@ class TestRegistrantNameservers(MockEppLib):
name="nameserversubdomain.gov", state=Domain.State.READY name="nameserversubdomain.gov", state=Domain.State.READY
) )
with self.assertRaises(ValueError): with self.assertRaises(NameserverError):
domain.nameservers = [ domain.nameservers = [
("ns1.cats-da-best.gov", ["1.2.3.4"]), ("ns1.cats-da-best.gov", ["1.2.3.4"]),
("ns2.cats-da-best.gov", ["2.3.4.5"]), ("ns2.cats-da-best.gov", ["2.3.4.5"]),
@ -1163,16 +1164,12 @@ class TestRegistrantNameservers(MockEppLib):
name="nameserversubdomain.gov", state=Domain.State.READY name="nameserversubdomain.gov", state=Domain.State.READY
) )
with self.assertRaises(ValueError): with self.assertRaises(NameserverError):
domain.nameservers = [ domain.nameservers = [
("ns1.nameserversubdomain.gov", ["1.2.3"]), ("ns1.nameserversubdomain.gov", ["1.2.3"]),
("ns2.nameserversubdomain.gov", ["2.3.4"]), ("ns2.nameserversubdomain.gov", ["2.3.4"]),
] ]
@skip("not implemented yet")
def test_caching_issue(self):
raise
@skip("not implemented yet") @skip("not implemented yet")
def test_update_is_unsuccessful(self): def test_update_is_unsuccessful(self):
""" """
@ -1192,11 +1189,9 @@ class TestRegistrantNameservers(MockEppLib):
with self.assertRaises(RegistryError): with self.assertRaises(RegistryError):
domain.nameservers = [("ns1.failednameserver.gov", ["4.5.6"])] domain.nameservers = [("ns1.failednameserver.gov", ["4.5.6"])]
# print("self.mockedSendFunction.call_args_list is ")
# print(self.mockedSendFunction.call_args_list)
def tearDown(self): def tearDown(self):
self.threeNS = False self.threeNS = False
Domain.objects.all().delete()
return super().tearDown() return super().tearDown()

View file

@ -2,36 +2,44 @@ from django.test import TestCase
from registrar.models.utility.nameserver_error import ( from registrar.models.utility.nameserver_error import (
NameserverError, NameserverError,
NameserverErrorCodes as nsErrorCodes) NameserverErrorCodes as nsErrorCodes,
)
class TestNameserverError(TestCase): class TestNameserverError(TestCase):
def test_with_no_ip(self): def test_with_no_ip(self):
"""Test NameserverError when no ip address is passed""" """Test NameserverError when no ip address is passed"""
nameserver="nameserver val" nameserver = "nameserver val"
expected=f"Nameserver {nameserver} needs to have an "\ expected = (
"IP address because it is a subdomain" f"Nameserver {nameserver} needs to have an "
"IP address because it is a subdomain"
)
nsException=NameserverError(code=nsErrorCodes.MISSING_IP,nameserver=nameserver) nsException = NameserverError(
self.assertEqual(nsException.message,expected) code=nsErrorCodes.MISSING_IP, nameserver=nameserver
self.assertEqual(nsException.code,nsErrorCodes.MISSING_IP) )
self.assertEqual(nsException.message, expected)
self.assertEqual(nsException.code, nsErrorCodes.MISSING_IP)
def test_with_only_code(self): def test_with_only_code(self):
"""Test NameserverError when no ip address or nameserver is passed, only the code value""" """Test NameserverError when no ip address or nameserver is passed, only the code value"""
nameserver="nameserver val" nameserver = "nameserver val"
expected="Too many hosts provided, you may not have more than 13 nameservers." expected = "Too many hosts provided, you may not have more than 13 nameservers."
nsException=NameserverError(code=nsErrorCodes.TOO_MANY_HOSTS,nameserver=nameserver) nsException = NameserverError(
self.assertEqual(nsException.message,expected) code=nsErrorCodes.TOO_MANY_HOSTS, nameserver=nameserver
self.assertEqual(nsException.code,nsErrorCodes.TOO_MANY_HOSTS) )
self.assertEqual(nsException.message, expected)
self.assertEqual(nsException.code, nsErrorCodes.TOO_MANY_HOSTS)
def test_with_ip_nameserver(self): def test_with_ip_nameserver(self):
"""Test NameserverError when ip and nameserver are passed""" """Test NameserverError when ip and nameserver are passed"""
ip="ip val" ip = "ip val"
nameserver="nameserver val" nameserver = "nameserver val"
expected=f"Nameserver {nameserver} has an invalid IP address: {ip}" expected = f"Nameserver {nameserver} has an invalid IP address: {ip}"
nsException=NameserverError(code=nsErrorCodes.INVALID_IP,nameserver=nameserver, ip=ip) nsException = NameserverError(
self.assertEqual(nsException.message,expected) code=nsErrorCodes.INVALID_IP, nameserver=nameserver, ip=ip
self.assertEqual(nsException.code,nsErrorCodes.INVALID_IP) )
self.assertEqual(nsException.message, expected)
self.assertEqual(nsException.code, nsErrorCodes.INVALID_IP)