change to debugable

This commit is contained in:
Helge 2020-12-21 13:19:45 +01:00
parent f6bc5bc9e9
commit d6b0bf9f05
5 changed files with 58 additions and 40 deletions

2
.gitignore vendored
View file

@ -3,6 +3,8 @@
# Created by https://www.toptal.com/developers/gitignore/api/windows,visualstudiocode,python
# Edit at https://www.toptal.com/developers/gitignore?templates=windows,visualstudiocode,python
my_debug/
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/

16
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "/home/pi/dev/certbot/venv3/bin/certbot",
"console": "integratedTerminal",
"args": ["certonly", "-a", "dns-ionos", "-d", "example.com", "--config-dir", "my_debug/config", "--work-dir", "my_debug/work", "--logs-dir", "my_debug/logs"]
}
]
}

View file

@ -1,4 +1,4 @@
"""DNS Authenticator for ISPConfig."""
"""DNS Authenticator for IONOS."""
import json
import logging
import time
@ -16,12 +16,12 @@ logger = logging.getLogger(__name__)
@zope.interface.implementer(interfaces.IAuthenticator)
@zope.interface.provider(interfaces.IPluginFactory)
class Authenticator(dns_common.DNSAuthenticator):
"""DNS Authenticator for ISPConfig
"""DNS Authenticator for IONOS
This Authenticator uses the ISPConfig Remote REST API to fulfill a dns-01 challenge.
This Authenticator uses the IONOS Remote REST API to fulfill a dns-01 challenge.
"""
description = "Obtain certificates using a DNS TXT record (if you are using ISPConfig for DNS)."
description = "Obtain certificates using a DNS TXT record (if you are using IONOS for DNS)."
ttl = 60
def __init__(self, *args, **kwargs):
@ -33,53 +33,53 @@ class Authenticator(dns_common.DNSAuthenticator):
super(Authenticator, cls).add_parser_arguments(
add, default_propagation_seconds=120
)
add("credentials", help="ISPConfig credentials INI file.")
add("credentials", help="IONOS credentials INI file.")
def more_info(self): # pylint: disable=missing-docstring,no-self-use
return (
"This plugin configures a DNS TXT record to respond to a dns-01 challenge using "
+ "the ISPConfig Remote REST API."
+ "the IONOS Remote REST API."
)
def _setup_credentials(self):
self.credentials = self._configure_credentials(
"credentials",
"ISPConfig credentials INI file",
"IONOS credentials INI file",
{
"endpoint": "URL of the ISPConfig Remote API.",
"username": "Username for ISPConfig Remote API.",
"password": "Password for ISPConfig Remote API.",
"endpoint": "URL of the IONOS Remote API.",
"prefix": "Prefix for IONOS Remote API.",
"secret": "Secret for IONOS Remote API.",
},
)
def _perform(self, domain, validation_name, validation):
self._get_ispconfig_client().add_txt_record(
self._get_ionos_client().add_txt_record(
domain, validation_name, validation, self.ttl
)
def _cleanup(self, domain, validation_name, validation):
self._get_ispconfig_client().del_txt_record(
self._get_ionos_client().del_txt_record(
domain, validation_name, validation, self.ttl
)
def _get_ispconfig_client(self):
return _ISPConfigClient(
def _get_ionos_client(self):
return _ionosClient(
self.credentials.conf("endpoint"),
self.credentials.conf("username"),
self.credentials.conf("password"),
self.credentials.conf("prefix"),
self.credentials.conf("secret"),
)
class _ISPConfigClient(object):
class _ionosClient(object):
"""
Encapsulates all communication with the ISPConfig Remote REST API.
Encapsulates all communication with the IONOS Remote REST API.
"""
def __init__(self, endpoint, username, password):
logger.debug("creating ispconfigclient")
def __init__(self, endpoint, prefix, secret):
logger.debug("creating ionosclient")
self.endpoint = endpoint
self.username = username
self.password = password
self.prefix = prefix
self.secret = secret
self.session = requests.Session()
self.session_id = None
@ -87,7 +87,7 @@ class _ISPConfigClient(object):
if self.session_id is not None:
return
logger.debug("logging in")
logindata = {"username": self.username, "password": self.password}
logindata = {"prefix": self.prefix, "secret": self.secret}
self.session_id = self._api_request("login", logindata)
logger.debug("session id is %s", self.session_id)
@ -131,7 +131,7 @@ class _ISPConfigClient(object):
:param str record_name: The record name (typically beginning with '_acme-challenge.').
:param str record_content: The record content (typically the challenge validation).
:param int record_ttl: The record TTL (number of seconds that the record may be cached).
:raises certbot.errors.PluginError: if an error occurs communicating with the ISPConfig API
:raises certbot.errors.PluginError: if an error occurs communicating with the IONOS API
"""
self._login()
zone_id, zone_name = self._find_managed_zone_id(domain, record_name)
@ -165,7 +165,7 @@ class _ISPConfigClient(object):
:param str record_name: The record name (typically beginning with '_acme-challenge.').
:param str record_content: The record content (typically the challenge validation).
:param int record_ttl: The record TTL (number of seconds that the record may be cached).
:raises certbot.errors.PluginError: if an error occurs communicating with the ISPConfig API
:raises certbot.errors.PluginError: if an error occurs communicating with the IONOS API
"""
self._login()
zone_id, zone_name = self._find_managed_zone_id(domain, record_name)

View file

@ -1,4 +1,4 @@
"""Tests for certbot_dns_ispconfig.dns_ispconfig."""
"""Tests for certbot_dns_ionos.dns_ionos."""
import unittest
@ -24,28 +24,28 @@ class AuthenticatorTest(
def setUp(self):
super(AuthenticatorTest, self).setUp()
from certbot_dns_ispconfig.dns_ispconfig import Authenticator
from certbot_dns_ionos.dns_ionos import Authenticator
path = os.path.join(self.tempdir, "file.ini")
dns_test_common.write(
{
"ispconfig_prefix": FAKE_PREFIX,
"ispconfig_secret": FAKE_SECRET,
"ispconfig_endpoint": FAKE_ENDPOINT,
"ionos_prefix": FAKE_PREFIX,
"ionos_secret": FAKE_SECRET,
"ionos_endpoint": FAKE_ENDPOINT,
},
path,
)
super(AuthenticatorTest, self).setUp()
self.config = mock.MagicMock(
ispconfig_credentials=path, ispconfig_propagation_seconds=0
ionos_credentials=path, ionos_propagation_seconds=0
) # don't wait during tests
self.auth = Authenticator(self.config, "ispconfig")
self.auth = Authenticator(self.config, "ionos")
self.mock_client = mock.MagicMock()
# _get_ispconfig_client | pylint: disable=protected-access
self.auth._get_ispconfig_client = mock.MagicMock(return_value=self.mock_client)
# _get_ionos_client | pylint: disable=protected-access
self.auth._get_ionos_client = mock.MagicMock(return_value=self.mock_client)
def test_perform(self):
self.auth.perform([self.achall])
@ -70,17 +70,17 @@ class AuthenticatorTest(
self.assertEqual(expected, self.mock_client.mock_calls)
class ISPConfigClientTest(unittest.TestCase):
class ionosClientTest(unittest.TestCase):
record_name = "foo"
record_content = "bar"
record_ttl = 42
def setUp(self):
from certbot_dns_ispconfig.dns_ispconfig import _ISPConfigClient
from certbot_dns_ionos.dns_ionos import _ionosClient
self.adapter = requests_mock.Adapter()
self.client = _ISPConfigClient(FAKE_ENDPOINT, FAKE_PREFIX, FAKE_SECRET)
self.client = _ionosClient(FAKE_ENDPOINT, FAKE_PREFIX, FAKE_SECRET)
self.client.session.mount("mock", self.adapter)
def _register_response(

View file

@ -1,7 +1,7 @@
from setuptools import setup
from setuptools import find_packages
version = "0.0.1"
version = "0.0.2"
install_requires = [
"acme>=0.29.0",
@ -56,8 +56,8 @@ setup(
install_requires=install_requires,
entry_points={
"certbot.plugins": [
"dns-ispconfig = certbot_dns_ispconfig.dns_ispconfig:Authenticator"
"dns-ionos = certbot_dns_ionos.dns_ionos:Authenticator"
]
},
test_suite="certbot_dns_ispconfig",
test_suite="certbot_dns_ionos",
)