Skip to content

Commit

Permalink
Restore routes on challenge cleanup and add challenge *:80 listener i…
Browse files Browse the repository at this point in the history
…f needed
  • Loading branch information
kea committed Feb 11, 2024
1 parent 5525117 commit c082a03
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 20 deletions.
16 changes: 15 additions & 1 deletion certbot_nginx_unit/configurator.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Configurator(common.Installer, interfaces.Authenticator):

def __init__(self, *args: Any, **kwargs: Any):
super().__init__(*args, **kwargs)
self._prepared = False
self._configuration = None
self.unitc = Unitc()
self._entropy = datetime.now().strftime("%Y%m%d%H%M%S")
Expand All @@ -55,6 +56,8 @@ def __init__(self, *args: Any, **kwargs: Any):
self._full_root: str = ""
self._performed: DefaultDict[str, Set[AnnotatedChallenge]] = collections.defaultdict(set)
self._created_dirs: List[str] = []
self._to_remove: List[str] = []
self._backup_routes: List[str] = []

def get_all_names(self) -> Iterable[str]:
return []
Expand Down Expand Up @@ -140,11 +143,13 @@ def _ensure_challenge_listener(self):
if "listeners" not in self._configuration:
raise errors.PluginError("No listeners configured")
if "*:80" not in self._configuration["listeners"]:
raise errors.PluginError("No '*:80' default listeners configured")
self._configuration["listeners"]["*:80"] = {"pass": "routes"}
self._to_remove.append("/config/listeners/*:80")
if "pass" not in self._configuration["listeners"]["*:80"]:
raise errors.PluginError("Cannot configure the route for the *:80 listener")

actual_route = self._configuration["listeners"]["*:80"]["pass"]
self._backup_routes = self._configuration.get("routes", [])
default_route = self._ensure_acme_route(actual_route)
if actual_route == default_route:
return
Expand Down Expand Up @@ -237,7 +242,10 @@ def prepare(self) -> None:
"""Prepare the authenticator/installer."""
# @todo verify "unitc" executable
# @todo lock to prevent concurrent multi update
if self._prepared:
return
self._configuration = self._get_unit_configuration("/config")
self._prepared = True

def more_info(self) -> str: # pylint: disable=missing-function-docstring
return self.MORE_INFO.format(self.conf("path"))
Expand Down Expand Up @@ -339,6 +347,12 @@ def _perform_single(self, achall: AnnotatedChallenge) -> challenges.ChallengeRes
return response

def cleanup(self, achalls: List[AnnotatedChallenge]) -> None: # pylint: disable=missing-function-docstring
for config_path in self._to_remove:
self.unitc.delete(config_path, None, "Delete tmp configuration failed")

if self._configuration["routes"] != self._backup_routes:
self.unitc.put("/config/routes", json.dumps(self._backup_routes).encode())

for achall in achalls:
root_path = self._full_root
if root_path is not None:
Expand Down
25 changes: 6 additions & 19 deletions certbot_nginx_unit/tests/configurator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,6 @@ def only_80_listener_configuration_after_cert_list():
}


def only_80_listener_configuration_after_cert_dictionary():
return {
"listeners": {
"*:80": {"pass": "routes/acme"},
"*:443": {"pass": "routes/default"}
},
"routes": {
"acme": {
"match": {"uri": "/.well-known/acme-challenge/*"},
"action": {"share": "/srv/www/unit/$uri"},
},
"default": {
"action": {"share": "/srv/www/unit/index.html"}
}
}
}


def get_configuration_side_effect(*args):
if args[0] == "/config":
return json.dumps(empty_configuration())
Expand Down Expand Up @@ -183,7 +165,6 @@ def test_only_80_listener_configuration(self, unitc_mock):
'nginx unit copy to /certificates failed'
)

print(unitc_mock.put.mock_calls)
unitc_mock.put.assert_any_call(
'/config/listeners',
b'{"*:80": {"pass": "routes"}, "*:443": {"pass": "routes", "tls": {"certificate": ["domain_' +
Expand Down Expand Up @@ -221,4 +202,10 @@ def test_authenticate(self, unitc_mock, challenge_mock):
webroot + b'/$uri"}}, {"action": {"share": "/srv/www/unit/index.html"}}]'
)

configurator.cleanup(challenge_mock)
unitc_mock.put.assert_any_call(
'/config/routes',
json.dumps(only_80_listener_configuration()['routes']).encode()
)

notify.stop()

0 comments on commit c082a03

Please sign in to comment.