Conversation
|
Not tested, but feature-wise I agree this is a better solution than #4610. |
|
This appears to be working well now and I tested it quite a bit. I had a red herring because when I renewed with Anyway, issuing with The only remaining problem that I know about is that I don't have test coverage for all four combinations of |
Per discussion with @ohemorange, I'm going to add one more unit test related to this. |
|
This is ready for review! |
|
@ohemorange, can you add this to your review queue? |
|
already on it! |
|
awesome work thank you - i'm using this branch |
ohemorange
left a comment
There was a problem hiding this comment.
Added some suggestions to increase pythonicness and such
certbot/client.py
Outdated
| return cert.encode(), chain.encode() | ||
|
|
||
| def obtain_certificate(self, domains): | ||
| def obtain_certificate(self, domains, oldkeypath=None): |
There was a problem hiding this comment.
old_key_path or old_keypath for pythonicness?
certbot/client.py
Outdated
| if self.config.dry_run: | ||
| key = util.Key(file=None, | ||
| pem=crypto_util.make_key(self.config.rsa_key_size)) | ||
| if oldkeypath is None: |
certbot/client.py
Outdated
| else: | ||
| key = crypto_util.init_save_key( | ||
| self.config.rsa_key_size, self.config.key_dir) | ||
| if oldkeypath is None: |
certbot/client.py
Outdated
| keypath = oldkeypath | ||
| keypem = f.read() | ||
| key = util.Key(file=keypath, pem=keypem) | ||
| logger.info("New key obtained by reusing existing private key " |
There was a problem hiding this comment.
Perhaps clearer to drop the "new key obtained by"
There was a problem hiding this comment.
I didn't think so because it does create a new file, but maybe users will be able to figure it out!
| key = util.Key(file=keypath, pem=keypem) | ||
| logger.info("New key obtained by reusing existing private key " | ||
| "from %s.", oldkeypath) | ||
|
|
There was a problem hiding this comment.
if you stick an else: key = None here, the rest gets a little cleaner
certbot/cli.py
Outdated
| "certificate.") | ||
| helpful.add( | ||
| "automation", "--no-reuse-key", dest="reuse_key", | ||
| action="store_false", default=flag_default("reuse_key"), |
There was a problem hiding this comment.
did we ever figure out why this works? as in where the magic code lives. just out of curiosity
There was a problem hiding this comment.
Nope, I'm not really sure!
There was a problem hiding this comment.
I'm not sure if this exactly answers your question, but we have a number of flags like --foo and --no-foo. For example, take a look at --redirect.
--redirect sets redirect on the config object to True while --no-redirect sets it to False. Both --redirect and --no-redirect share the same default which isn't True or False, but None. This allows us to differentiate between the user saying yes or no to a redirect and not answering the question.
Do we want to do anything special in the case where the user doesn't provide either --reuse-key or --no-reuse-key? If not, I think we can probably get rid of --no-reuse-key and keep the default reuse_key value to False. If we do want this for some reason, we should probably change the default value from False to None.
There was a problem hiding this comment.
faaascinating.
the only reason I could think of to have --no-reuse-key would be to override the saved setting in the renewal config file, but users can just delete that line.
otherwise, I'm for just having --reuse-key and having the default be False.
There was a problem hiding this comment.
After talking to @bmw, I more clearly understand the point that for options that don't relate to prompts, we don't need a separate --no version because simply leaving the option out when reissuing with certonly is already sufficient to set it to False.
certbot/renewal.py
Outdated
| if not domains: | ||
| domains = lineage.names() | ||
| new_cert, new_chain, new_key, _ = le_client.obtain_certificate(domains) | ||
| if config.reuse_key: |
There was a problem hiding this comment.
old_key = lineage.privkey if config.reuse_key else None
new_cert, new_chain, new_key, _ = le_client.obtain_certificate(domains, old_key)
| # pylint: disable=too-many-locals,too-many-arguments | ||
| quiet_mode=False, expiry_date=datetime.datetime.now(), | ||
| reuse_key=False): | ||
| # pylint: disable=too-many-locals,too-many-arguments,too-many-branches |
There was a problem hiding this comment.
Is there a way to add the tests that doesn't stick the checks into _test_renewal_common? We already overload this with too much stuff.
There was a problem hiding this comment.
I agree, but I think it might look even more complex by defining a whole new set of ways to test renewals!
tests/boulder-integration.sh
Outdated
| ls -l "${root}/conf/archive/reusekey.le.wtf/privkey"* | ||
| # The final awk command here exits successfully if its input consists of | ||
| # exactly two lines with identical first fields, and unsuccessfully otherwise. | ||
| sha256sum "${root}/conf/archive/reusekey.le.wtf/privkey"* | awk '{a[$1] = 1}; END {exit(NR !=2 || length(a)!=1)}' |
There was a problem hiding this comment.
let's stick this awk command into a named parametrized function
|
Maybe I’m missing something, but I don’t understand when/how old_keypath is set. |
|
It's passed in as an argument to |
|
No, I’m trying to understand how to get certbot to reuse the same key for each request on my server. |
|
(For existing lineage as well as new ones) |
|
Seth, This just came in extremely handy to test a system we've been working on. Thank you. |
Intended to supersede #4610 (with a different syntax per discussion with @ohemorange ).
Fixes #3788; fixes #3709.