Skip to content

Commit

Permalink
Updates to Certbot 3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
chaptergy committed Nov 27, 2024
1 parent dbab60b commit 6b653ed
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 99 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Do the basic setup described in the [certbot snap readme](https://github.com/cer
Run the following command in the repository root (so you are in the folder containing the `setup.py`):

```sh
sh generate-snap.sh
sh generate_dnsplugins_snapcraft.sh
snapcraft clean --use-lxd
snapcraft --debug --use-lxd
```
Expand Down
62 changes: 8 additions & 54 deletions certbot_dns_njalla/dns_njalla.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
"""DNS Authenticator for Njalla."""
import logging

from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon

from lexicon.providers import njalla

logger = logging.getLogger(__name__)


class Authenticator(dns_common.DNSAuthenticator):
class Authenticator(dns_common_lexicon.LexiconDNSAuthenticator):
"""DNS Authenticator for Njalla
This Authenticator uses the Njalla REST API to fulfill a dns-01 challenge.
Expand All @@ -20,7 +17,9 @@ class Authenticator(dns_common.DNSAuthenticator):

def __init__(self, *args, **kwargs):
super(Authenticator, self).__init__(*args, **kwargs)
self.credentials = None
self._add_provider_option('token',
f'Token for the Njalla API',
'auth_token')

@classmethod
def add_parser_arguments(cls, add):
Expand All @@ -35,54 +34,9 @@ def more_info(self): # pylint: disable=missing-docstring,no-self-use
+ "the Njalla REST API."
)

def _setup_credentials(self):
self._configure_file('credentials',
'Absolute path to Njalla credentials INI file')
dns_common.validate_file_permissions(self.conf('credentials'))
self.credentials = self._configure_credentials(
"credentials",
"Njalla credentials INI file",
{
"token": "Token for the Njalla API.",
},
)

def _remove_subdomains(self, domain):
split_domain = domain.split('.')
return f'{split_domain[-2]}.{split_domain[-1]}'

def _perform(self, domain, validation_name, validation):
self._get_njalla_client().add_txt_record(
self._remove_subdomains(domain), validation_name, validation
)

def _cleanup(self, domain, validation_name, validation):
self._get_njalla_client().del_txt_record(
self._remove_subdomains(domain), validation_name, validation
)

def _get_njalla_client(self):
return _NjallaLexiconClient(
self.credentials.conf("token"),
self.ttl
)


class _NjallaLexiconClient(dns_common_lexicon.LexiconClient):
"""
Encapsulates all communication with the Njalla API via Lexicon.
"""

def __init__(self, api_token, ttl):
super(_NjallaLexiconClient, self).__init__()

config = dns_common_lexicon.build_lexicon_config('njalla', {
'ttl': ttl,
}, {
'auth_token': api_token,
})

self.provider = njalla.Provider(config)
@property
def _provider_name(self) -> str:
return 'njalla'

def _handle_http_error(self, e, domain_name):
if domain_name in str(e) and (
Expand All @@ -92,4 +46,4 @@ def _handle_http_error(self, e, domain_name):
str(e).startswith('404 Client Error: Not Found for url:')
):
return # Expected errors when zone name guess is wrong
return super(_NjallaLexiconClient, self)._handle_http_error(e, domain_name)
return super()._handle_http_error(e, domain_name)
29 changes: 5 additions & 24 deletions certbot_dns_njalla/dns_njalla_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@


class AuthenticatorTest(test_util.TempDirTestCase,
dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
dns_test_common_lexicon.BaseLexiconDNSAuthenticatorTest):

DOMAIN_NOT_FOUND = HTTPError('422 Client Error: Unprocessable Entity for url: {0}.'.format(DOMAIN))
LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized')

def setUp(self):
super(AuthenticatorTest, self).setUp()
super().setUp()

from certbot_dns_njalla.dns_njalla import Authenticator

Expand All @@ -38,27 +41,5 @@ def setUp(self):

self.auth = Authenticator(self.config, "njalla")

self.mock_client = mock.MagicMock()
# _get_njalla_client | pylint: disable=protected-access
self.auth._get_njalla_client = mock.MagicMock(
return_value=self.mock_client)


class NjallaLexiconClientTest(unittest.TestCase,
dns_test_common_lexicon.BaseLexiconClientTest):
DOMAIN_NOT_FOUND = HTTPError(
'422 Client Error: Unprocessable Entity for url: {0}.'.format(DOMAIN))
LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized')

def setUp(self):
from certbot_dns_njalla.dns_njalla import _NjallaLexiconClient

self.client = _NjallaLexiconClient(
api_token=API_TOKEN, ttl=0)

self.provider_mock = mock.MagicMock()
self.client.provider = self.provider_mock


if __name__ == "__main__":
unittest.main() # pragma: no cover
28 changes: 17 additions & 11 deletions generate-snapcraft-yml.sh → generate_dnsplugins_snapcraft.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,38 +1,43 @@
#!/bin/bash
# Taken from https://github.com/certbot/certbot/blob/main/tools/snap/generate_dnsplugins_snapcraft.sh
# Generate the snapcraft.yaml file for a DNS plugins
# Usage: bash generate_dnsplugins_snapcraft.sh path/to/dns/plugin
# For example, from the certbot home directory:
# tools/snap/generate_dnsplugins_snapcraft.sh certbot-dns-dnsimple
set -e

PLUGIN_PATH=./
PLUGIN_PATH=$1
PLUGIN=$(grep "[^_a-zA-Z]name" "${PLUGIN_PATH}/setup.py" | sed -E 's|\s+name="(.*)",|\1|g')
SUMMARY=$(grep "[^_a-zA-Z]description" "${PLUGIN_PATH}/setup.py" | sed -E 's|\s+description="(.*)",|\1|g')
DESCRIPTION=$(sed -E -n "/[[:space:]]+description=/ s/[[:space:]]+description=['\"](.*)['\"],/\1/ p" "${PLUGIN_PATH}/setup.py")
mkdir -p "${PLUGIN_PATH}/snap"
cat <<EOF > "${PLUGIN_PATH}/snap/snapcraft.yaml"
# This file is generated automatically and should not be edited manually.
name: ${PLUGIN}
summary: ${SUMMARY}
description: ${SUMMARY}
summary: ${DESCRIPTION}
description: ${DESCRIPTION}
confinement: strict
grade: stable
base: core20
base: core24
adopt-info: ${PLUGIN}
parts:
${PLUGIN}:
plugin: python
source: .
override-pull: |
snapcraftctl pull
snapcraftctl set-version \`grep ^version \$SNAPCRAFT_PART_SRC/setup.py | cut -f2 -d= | tr -d "'[:space:]" | tr -d '"'\`
craftctl default
craftctl set version=\$(grep ^version \$SNAPCRAFT_PART_SRC/setup.py | cut -f2 -d= | tr -d "'[:space:]")
build-environment:
# We set this environment variable while building to try and increase the
# stability of fetching the rust crates needed to build the cryptography
# library.
- CARGO_NET_GIT_FETCH_WITH_CLI: "true"
# Constraints are passed through the environment variable PIP_CONSTRAINTS instead of using the
# parts.[part_name].constraints option available in snapcraft.yaml when the Python plugin is
# used. This is done to let these constraints be applied not only on the certbot package
# build, but also on any isolated build that pip could trigger when building wheels for
# dependencies. See https://github.com/certbot/certbot/pull/8443 for more info.
# - PIP_CONSTRAINT: \$SNAPCRAFT_PART_SRC/snap-constraints.txt
- PIP_CONSTRAINT: \$SNAPCRAFT_PART_SRC/snap-constraints.txt
- SNAP_BUILD: "True"
# To build cryptography and cffi if needed
build-packages:
Expand All @@ -43,24 +48,25 @@ parts:
- libffi-dev
- python3-dev
- cargo
- pkg-config
certbot-metadata:
plugin: dump
source: .
stage: [setup.py, certbot-shared]
override-pull: |
snapcraftctl pull
craftctl default
mkdir -p \$SNAPCRAFT_PART_SRC/certbot-shared
slots:
certbot:
interface: content
content: certbot-1
read:
- \$SNAP/lib/python3.8/site-packages
- \$SNAP/lib/python3.12/site-packages
plugs:
certbot-metadata:
interface: content
content: metadata-1
target: \$SNAP/certbot-shared
EOF
EOF
9 changes: 6 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
from setuptools import setup
from setuptools import find_packages

version = "1.0.2"
version = "2.0.0"

install_requires = [
'certbot>=0.31.0',
'dns-lexicon>=3.4.1',
'certbot>=3.0.0',
'dns-lexicon>=3.14.1',
]
test_requirements = [
'mock',
Expand Down Expand Up @@ -51,6 +51,9 @@
packages=find_packages(),
install_requires=install_requires,
tests_require=test_requirements,
extras_require={
'test': test_requirements,
},
entry_points={
"certbot.plugins": [
"dns-njalla = certbot_dns_njalla.dns_njalla:Authenticator"
Expand Down
17 changes: 11 additions & 6 deletions snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,27 @@ summary: Njalla DNS Authenticator plugin for Certbot
description: Njalla DNS Authenticator plugin for Certbot
confinement: strict
grade: stable
base: core20
base: core24
adopt-info: certbot-dns-njalla

parts:
certbot-dns-njalla:
plugin: python
source: .
override-pull: |
snapcraftctl pull
snapcraftctl set-version `grep ^version $SNAPCRAFT_PART_SRC/setup.py | cut -f2 -d= | tr -d "'[:space:]" | tr -d '"'`
craftctl default
craftctl set version=$(grep ^version $SNAPCRAFT_PART_SRC/setup.py | cut -f2 -d= | tr -d "'[:space:]")
build-environment:
# We set this environment variable while building to try and increase the
# stability of fetching the rust crates needed to build the cryptography
# library.
- CARGO_NET_GIT_FETCH_WITH_CLI: "true"
# Constraints are passed through the environment variable PIP_CONSTRAINTS instead of using the
# parts.[part_name].constraints option available in snapcraft.yaml when the Python plugin is
# used. This is done to let these constraints be applied not only on the certbot package
# build, but also on any isolated build that pip could trigger when building wheels for
# dependencies. See https://github.com/certbot/certbot/pull/8443 for more info.
# - PIP_CONSTRAINT: $SNAPCRAFT_PART_SRC/snap-constraints.txt
- PIP_CONSTRAINT: $SNAPCRAFT_PART_SRC/snap-constraints.txt
- SNAP_BUILD: "True"
# To build cryptography and cffi if needed
build-packages:
Expand All @@ -31,20 +35,21 @@ parts:
- libffi-dev
- python3-dev
- cargo
- pkg-config
certbot-metadata:
plugin: dump
source: .
stage: [setup.py, certbot-shared]
override-pull: |
snapcraftctl pull
craftctl default
mkdir -p $SNAPCRAFT_PART_SRC/certbot-shared
slots:
certbot:
interface: content
content: certbot-1
read:
- $SNAP/lib/python3.8/site-packages
- $SNAP/lib/python3.12/site-packages

plugs:
certbot-metadata:
Expand Down

0 comments on commit 6b653ed

Please sign in to comment.