mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-16 07:55:12 +02:00
Check if registry connection can be made
This commit is contained in:
parent
c4d2950ac9
commit
dfec8c200e
2 changed files with 54 additions and 11 deletions
|
@ -15,6 +15,7 @@ from django.conf import settings
|
||||||
|
|
||||||
from .cert import Cert, Key
|
from .cert import Cert, Key
|
||||||
from .errors import LoginError, RegistryError
|
from .errors import LoginError, RegistryError
|
||||||
|
from .socket import Socket
|
||||||
from .utility.pool import EppConnectionPool
|
from .utility.pool import EppConnectionPool
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -41,7 +42,6 @@ class EPPLibWrapper:
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""Initialize settings which will be used for all connections."""
|
"""Initialize settings which will be used for all connections."""
|
||||||
|
|
||||||
# prepare (but do not send) a Login command
|
# prepare (but do not send) a Login command
|
||||||
self._login = commands.Login(
|
self._login = commands.Login(
|
||||||
cl_id=settings.SECRET_REGISTRY_CL_ID,
|
cl_id=settings.SECRET_REGISTRY_CL_ID,
|
||||||
|
@ -51,6 +51,7 @@ class EPPLibWrapper:
|
||||||
"urn:ietf:params:xml:ns:contact-1.0",
|
"urn:ietf:params:xml:ns:contact-1.0",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
# establish a client object with a TCP socket transport
|
# establish a client object with a TCP socket transport
|
||||||
self._client = Client(
|
self._client = Client(
|
||||||
SocketTransport(
|
SocketTransport(
|
||||||
|
@ -71,19 +72,23 @@ class EPPLibWrapper:
|
||||||
# Occasionally pings the registry to keep the connection alive
|
# Occasionally pings the registry to keep the connection alive
|
||||||
"keepalive": settings.POOL_KEEP_ALIVE,
|
"keepalive": settings.POOL_KEEP_ALIVE,
|
||||||
}
|
}
|
||||||
self._pool = EppConnectionPool(
|
|
||||||
client=self._client, login=self._login, options=options
|
self._pool = None
|
||||||
)
|
if not settings.DEBUG or self._test_registry_connection_success():
|
||||||
|
self._pool = EppConnectionPool(
|
||||||
|
client=self._client, login=self._login, options=options
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.warning("Cannot contact the Registry")
|
||||||
|
# TODO - signal that the app may need to restart?
|
||||||
|
|
||||||
def _send(self, command):
|
def _send(self, command):
|
||||||
"""Helper function used by `send`."""
|
"""Helper function used by `send`."""
|
||||||
cmd_type = command.__class__.__name__
|
cmd_type = command.__class__.__name__
|
||||||
try:
|
try:
|
||||||
# We won't have an EPP connection locally,
|
if self._pool is None:
|
||||||
# shortcut this and raise an err
|
|
||||||
# TODO - implement a timeout in _pool.get()
|
|
||||||
if settings.DEBUG:
|
|
||||||
raise LoginError
|
raise LoginError
|
||||||
|
# TODO - add a timeout
|
||||||
with self._pool.get() as connection:
|
with self._pool.get() as connection:
|
||||||
response = connection.send(command)
|
response = connection.send(command)
|
||||||
except (ValueError, ParsingError) as err:
|
except (ValueError, ParsingError) as err:
|
||||||
|
@ -127,6 +132,18 @@ class EPPLibWrapper:
|
||||||
else: # don't try again
|
else: # don't try again
|
||||||
raise err
|
raise err
|
||||||
|
|
||||||
|
def _test_registry_connection_success(self):
|
||||||
|
"""Check that determines if our login
|
||||||
|
credentials are valid, and/or if the Registrar
|
||||||
|
can be contacted
|
||||||
|
"""
|
||||||
|
socket = Socket(self._login, self._client)
|
||||||
|
can_login = False
|
||||||
|
# Something went wrong if this doesn't exist
|
||||||
|
if hasattr(socket, "test_connection_success"):
|
||||||
|
can_login = socket.test_connection_success()
|
||||||
|
return can_login
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Initialize epplib
|
# Initialize epplib
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import logging
|
import logging
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from epplib import commands
|
from epplib import commands
|
||||||
|
from epplib.client import Client
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -14,7 +16,7 @@ logger = logging.getLogger(__name__)
|
||||||
class Socket:
|
class Socket:
|
||||||
"""Context manager which establishes a TCP connection with registry."""
|
"""Context manager which establishes a TCP connection with registry."""
|
||||||
|
|
||||||
def __init__(self, client, login) -> None:
|
def __init__(self, client: commands.Login, login: Client) -> None:
|
||||||
"""Save the epplib client and login details."""
|
"""Save the epplib client and login details."""
|
||||||
self.client = client
|
self.client = client
|
||||||
self.login = login
|
self.login = login
|
||||||
|
@ -27,15 +29,39 @@ class Socket:
|
||||||
"""Runs disconnect(), which closes a connection with EPPLib."""
|
"""Runs disconnect(), which closes a connection with EPPLib."""
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
|
|
||||||
def connect(self):
|
def connect(self, pass_response_only=False):
|
||||||
"""Use epplib to connect."""
|
"""Use epplib to connect."""
|
||||||
self.client.connect()
|
self.client.connect()
|
||||||
response = self.client.send(self.login)
|
response = self.client.send(self.login)
|
||||||
if response.code >= 2000:
|
if self.is_login_error(response.code):
|
||||||
self.client.close()
|
self.client.close()
|
||||||
raise LoginError(response.msg)
|
raise LoginError(response.msg)
|
||||||
return self.client
|
return self.client
|
||||||
|
|
||||||
|
def is_login_error(self, code):
|
||||||
|
return code >= 2000
|
||||||
|
|
||||||
|
def test_connection_success(self):
|
||||||
|
"""Tests if a successful connection can be made with the registry"""
|
||||||
|
# Something went wrong if this doesn't exist
|
||||||
|
if not hasattr(self.client, "connect"):
|
||||||
|
return False
|
||||||
|
|
||||||
|
counter = 0 # we'll try 3 times
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
self.client.connect()
|
||||||
|
response = self.client.send(self.login)
|
||||||
|
except LoginError as err:
|
||||||
|
if err.should_retry() and counter < 3:
|
||||||
|
counter += 1
|
||||||
|
sleep((counter * 50) / 1000) # sleep 50 ms to 150 ms
|
||||||
|
else: # don't try again
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
self.disconnect()
|
||||||
|
return not self.is_login_error(response.code)
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
"""Close the connection."""
|
"""Close the connection."""
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue