Skip to content

Commit

Permalink
refactor: use the new Lexicon-based plugin API (#52)
Browse files Browse the repository at this point in the history
* Use new Lexicon-based plugin API

* chore: bump version to 2.7.4 to match minimum certbot required.

---------

Co-authored-by: Adrien Ferrand <[email protected]>
Co-authored-by: miigotu <[email protected]>
  • Loading branch information
3 people authored Nov 4, 2023
1 parent 48bea07 commit 6ed4b23
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 164 deletions.
120 changes: 24 additions & 96 deletions certbot_dns_godaddy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,113 +5,41 @@
"""

import logging
from typing import Any, Callable

import zope.interface
from certbot import errors, interfaces
from certbot.plugins import dns_common, dns_common_lexicon
from lexicon.providers import godaddy
from requests.exceptions import RequestException
import tldextract
from certbot.plugins import dns_common_lexicon

logger = logging.getLogger(__name__)


@zope.interface.implementer(interfaces.IAuthenticator)
@zope.interface.provider(interfaces.IPluginFactory)
class Authenticator(dns_common.DNSAuthenticator):
"""DNS Authenticator for godaddy
class Authenticator(dns_common_lexicon.LexiconDNSAuthenticator):
"""DNS Authenticator for GoDaddy
This Authenticator uses the godaddy API to fulfill a dns-01 challenge.
This Authenticator uses the GoDaddy API to fulfill a dns-01 challenge.
"""

description = ('Obtain certificates using a DNS TXT record (if you are '
'using godaddy for DNS).')

def __init__(self, *args, **kwargs):
super(Authenticator, self).__init__(*args, **kwargs)
self.credentials = None
'using GoDaddy for DNS).')

def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self._add_provider_option('key',
'Key to access the Godaddy API',
'auth_key')
self._add_provider_option('secret',
'Secret to access the Godaddy API',
'auth_secret')

@classmethod
def add_parser_arguments(cls, add):
super(Authenticator, cls).add_parser_arguments(add,default_propagation_seconds=30)
add('credentials', help='godaddy credentials INI file.')

def more_info(self):
def add_parser_arguments(cls, add: Callable[..., None],
default_propagation_seconds: int = 30) -> None:
super().add_parser_arguments(add, default_propagation_seconds)
add('credentials', help='GoDaddy credentials INI file.')

def more_info(self) -> str:
return ('This plugin configures a DNS TXT record to respond to a '
'dns-01 challenge using the godaddy API.')

def _setup_credentials(self):
self.credentials = self._configure_credentials(
'credentials',
'godaddy credentials INI file',
{
'key': 'Key to access the Godaddy API',
'secret': 'Secret to access the Godaddy API',
}
)

def _perform(self, domain, validation_name, validation):
return self.godaddy_client.add_txt_record(domain, validation_name, validation)

def _cleanup(self, domain, validation_name, validation):
return self.godaddy_client.del_txt_record(domain, validation_name, validation)


@property
def godaddy_client(self):
return _GodaddyLexiconClient(credentials=self.credentials.conf)


class _GodaddyLexiconClient(dns_common_lexicon.LexiconClient):
"""Encapsulates all communication with godaddy via Lexicon."""

def __init__(self, credentials):
super(_GodaddyLexiconClient, self).__init__()
config = dns_common_lexicon.build_lexicon_config('godaddy', {}, {
'auth_key': credentials('key'),
'auth_secret': credentials('secret')
})

self.provider = godaddy.Provider(config)

def add_txt_record(self, domain, record_name, record_content):
"""
Add a TXT record using the supplied information.
:param str domain: The domain to use to look up the managed zone.
:param str record_name: The record name (typically beginning with '_acme-challenge.').
:param str record_content: The record content (typically the challenge validation).
:raises errors.PluginError: if an error occurs communicating with the DNS Provider API
"""
ex = tldextract.extract(domain)
try:
self._find_domain_id(ex.registered_domain)
except errors.PluginError as e:
logger.debug('Encountered error finding domain_id during add: %s', e, exc_info=True)
return

try:
self.provider.create_record(rtype='TXT', name=record_name, content=record_content)
except RequestException as e:
logger.debug('Encountered error adding TXT record: %s', e, exc_info=True)
raise errors.PluginError('Error adding TXT record: {0}'.format(e))

def del_txt_record(self, domain, record_name, record_content):
"""
Delete a TXT record using the supplied information.
:param str domain: The domain to use to look up the managed zone.
:param str record_name: The record name (typically beginning with '_acme-challenge.').
:param str record_content: The record content (typically the challenge validation).
:raises errors.PluginError: if an error occurs communicating with the DNS Provider API
"""
ex = tldextract.extract(domain)
try:
self._find_domain_id(ex.registered_domain)
except errors.PluginError as e:
logger.debug('Encountered error finding domain_id during deletion: %s', e, exc_info=True)
return

try:
self.provider.delete_record(rtype='TXT', name=record_name, content=record_content)
except RequestException as e:
logger.debug('Encountered error deleting TXT record: %s', e, exc_info=True)
def _provider_name(self) -> str:
return 'godaddy'
93 changes: 30 additions & 63 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 3 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "certbot-dns-godaddy"
version = "2.6.0"
version = "2.7.4"
description = "A certbot plugin that implements letsencrypt dns wildcard support for godaddy using lexicon"
authors = ["Dustyn Gibson <[email protected]>"]
license = "Apache-2.0"
Expand Down Expand Up @@ -31,10 +31,8 @@ classifiers = [

[tool.poetry.dependencies]
python = ">=3.7,<4.0"
acme = "2.6.0"
certbot = "2.6.0"
dns-lexicon = ">=3.2.3"
"zope.interface" = ">=5.4.0"
certbot = ">=2.7.4"
dns-lexicon = ">=3.14.0"

[tool.poetry.dev-dependencies]
isort = "^5.8.0"
Expand Down

0 comments on commit 6ed4b23

Please sign in to comment.