Correctly error when private key files exist, but are invalid.
Also adds an additional message if Paramiko<2.7 is installed which
may be causing the invalid load due to incompatibility with the
file format.
@@ -112,10 +112,14 @@ def _get_private_key(state, key_filename, key_password):
path.join(state.deploy_dir, key_filename),
)
+ key_file_exists = False
+
for filename in ssh_key_filenames:
if not path.isfile(filename):
continue
+ key_file_exists = True
+
try:
key = _load_private_key_file(filename, key_filename, key_password)
break
@@ -124,7 +128,20 @@ def _get_private_key(state, key_filename, key_password):
# No break, so no key found
else:
- raise IOError('No such private key file: {0}'.format(key_filename))
+ if not key_file_exists:
+ raise PyinfraError('No such private key file: {0}'.format(key_filename))
+
+ # TODO: upgrade min paramiko version to 2.7 and remove this (pyinfra v2)
+ extra_info = ''
+ from pkg_resources import get_distribution, parse_version
+ if get_distribution('paramiko').parsed_version < parse_version('2.7'):
+ extra_info = (
+ '\n Paramiko versions under 2.7 do not support the latest OpenSSH key formats,'
+ ' upgrading may fix this error.'
+ '\n For more information, see this issue: '
+ 'https://github.com/Fizzadar/pyinfra/issues/548'
+ )
+ raise PyinfraError('Invalid private key file: {0}{1}'.format(key_filename, extra_info))
# Load any certificate, names from OpenSSH:
# https://github.com/openssh/openssh-portable/blob/049297de975b92adcc2db77e3fb7046c0e3c695d/ssh-keygen.c#L2453 # noqa: E501
