Always generate a new key pair if the private key doesn't exist (#598)

* Always generate a new key pair if the private key doesn't exist (#597)

This commit updates `KeypairBackend._should_generate()` to first check
if the original private key named by the `path` argument exists, and
return True if it does not. This brings the code in line with
the documentation, which says that a new key will always be generated if
the key file doesn't already exist.

As an alternative to the approach implemented here, I also considered
only modifying the condition in the `fail` branch of the if statement,
but I thought that would not map as cleanly to the behavior specified in
the documentation, so doing it the way I did should make it easier to
check that the code is doing the right thing just by looking at it.
I also considered doing something to make the logic more similar to
`PrivateKeyBackend.needs_regeneration()` (the openssl version of this
functionality), because the two are supposed to be acting the same way,
but I thought that'd be going beyond the scope of just fixing this bug.
If it'd be useful to make both methods work the same way, someone can
refactor the code in a future commit.

* Test different regenerate values with nonexistent keys

This commit changes the test task that generates new keys to use each of
the different values for the `regenerate` argument, which will ensure
that the module is capable of generating a key when no previous key
exists regardless of the value of `regenerate`. Previously, the task
would always run with the `partial_idempotence` value, and that obscured
a bug (#597) that would occur when it was set to `fail`. The bug was
fixed in the previous commit.
pull/601/head
David Zaslavsky 2023-05-01 12:16:42 -07:00 committed by GitHub
parent c568923478
commit ce3299f106
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 8 additions and 3 deletions

View File

@ -0,0 +1,2 @@
bugfixes:
- "openssh_keypair - always generate a new key pair if the private key does not exist. Previously, the module would fail when ``regenerate=fail`` without an existing key, contradicting the documentation (https://github.com/ansible-collections/community.crypto/pull/598)."

View File

@ -161,8 +161,10 @@ class KeypairBackend(OpensshModule):
pass pass
def _should_generate(self): def _should_generate(self):
if self.regenerate == 'never': if self.original_private_key is None:
return self.original_private_key is None return True
elif self.regenerate == 'never':
return False
elif self.regenerate == 'fail': elif self.regenerate == 'fail':
if not self._private_key_valid(): if not self._private_key_valid():
self.module.fail_json( self.module.fail_json(
@ -170,7 +172,7 @@ class KeypairBackend(OpensshModule):
"To force regeneration, call the module with `generate` set to " + "To force regeneration, call the module with `generate` set to " +
"`partial_idempotence`, `full_idempotence` or `always`, or with `force=true`." "`partial_idempotence`, `full_idempotence` or `always`, or with `force=true`."
) )
return self.original_private_key is None return False
elif self.regenerate in ('partial_idempotence', 'full_idempotence'): elif self.regenerate in ('partial_idempotence', 'full_idempotence'):
return not self._private_key_valid() return not self._private_key_valid()
else: else:

View File

@ -28,6 +28,7 @@
type: rsa type: rsa
size: 1024 size: 1024
backend: "{{ backend }}" backend: "{{ backend }}"
regenerate: "{{ item }}"
loop: "{{ regenerate_values }}" loop: "{{ regenerate_values }}"
- name: "({{ backend }}) Regenerate - setup password protected keys" - name: "({{ backend }}) Regenerate - setup password protected keys"
command: 'ssh-keygen -f {{ remote_tmp_dir }}/regenerate-b-{{ item }} -N {{ passphrase }}' command: 'ssh-keygen -f {{ remote_tmp_dir }}/regenerate-b-{{ item }} -N {{ passphrase }}'