integration: add test for early renewal from ARI (#10311)

This depends on a pending Pebble pull request and so will fail
integration tests until/unless that lands:
https://github.com/letsencrypt/pebble/pull/501

However, I'd appreciate some eyes on this PR in this regard: is the
interface we're using in Pebble useful and appropriate? If not, we can
adjust the Pebble PR.

Inspired based on conversation on
https://github.com/certbot/certbot/pull/10307, but note that this just
tests the general case; it does not test the "default server differs
from lineage server" case yet; when I try adding that I get some bugs
that may reflect a problem in #10307 I need to fix (or may reflect that
I need to inhibit the `--server` flag rather than trying to override it
late in the command line).
This commit is contained in:
Jacob Hoffman-Andrews 2025-06-06 14:39:10 -07:00 committed by GitHub
parent 95a70e98c2
commit a75057042f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 45 additions and 1 deletions

View file

@ -1,4 +1,5 @@
"""Module executing integration tests against certbot core."""
import json
import os
from os.path import exists
from os.path import join
@ -310,6 +311,31 @@ def test_graceful_renew_it_is_time(context: IntegrationTestsContext) -> None:
assert_hook_execution(context.hook_probe, 'deploy')
def test_renew_when_ari_says_its_time(context: IntegrationTestsContext) -> None:
"""Test graceful renew is done when it is due time."""
certname = context.get_domain('renew')
context.certbot(['-d', certname])
assert_cert_count_for_lineage(context.config_dir, certname, 1)
# Tell Pebble to make ARI look urgent
with open(join(context.config_dir, 'live', certname, 'cert.pem'), 'r') as c:
certificate_pem = c.read()
misc.set_ari_response(certificate_pem, json.dumps({
'suggestedWindow': {
'start': '2020-01-01T00:00:00Z',
'end': '2020-01-01T00:00:00Z'
}
}))
context.certbot(['renew', '--deploy-hook', misc.echo('deploy', context.hook_probe)],
force_renew=False)
assert_cert_count_for_lineage(context.config_dir, certname, 2)
assert_hook_execution(context.hook_probe, 'deploy')
def test_renew_with_changed_private_key_complexity(context: IntegrationTestsContext) -> None:
"""Test proper renew with updated private key complexity."""
certname = context.get_domain('renew')

View file

@ -8,6 +8,7 @@ import errno
import functools
import http.server as SimpleHTTPServer
import importlib.resources
import json
import os
import re
import shutil
@ -318,3 +319,20 @@ def get_acme_issuers() -> List[Certificate]:
issuers.append(load_pem_x509_certificate(request.content, default_backend()))
return issuers
def set_ari_response(certificate_pem: str, response_json: str) -> None:
"""POST to an endpoint on the Pebble server setting the ARI response
for the given certificate."""
set_renewal_info_body = json.dumps(
{
'certificate': certificate_pem,
'ariResponse': response_json,
})
_suppress_x509_verification_warnings()
url = PEBBLE_MANAGEMENT_URL + '/set-renewal-info/'
print(f'sending to {url}: {set_renewal_info_body}')
resp = requests.post(url, verify=False, timeout=10, data=set_renewal_info_body)
if resp.status_code != 200:
print(f'setting renewal info: {resp.status_code} {resp.text}')
assert resp.status_code == 200

View file

@ -15,7 +15,7 @@ import requests
from certbot_integration_tests.utils.constants import DEFAULT_HTTP_01_PORT
from certbot_integration_tests.utils.constants import MOCK_OCSP_SERVER_PORT
PEBBLE_VERSION = 'v2.7.0'
PEBBLE_VERSION = 'v2.8.0'
def fetch(workspace: str, http_01_port: int = DEFAULT_HTTP_01_PORT) -> Tuple[str, str, str]: