mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
Improvements to SSH known_hosts module and state.
This commit is contained in:
parent
054f7c9551
commit
ad80801d0f
@ -795,6 +795,22 @@ def set_auth_key(
|
||||
return 'new'
|
||||
|
||||
|
||||
def _get_matched_host_line_numbers(lines, enc):
|
||||
'''
|
||||
Helper function which parses ssh-keygen -F function output and yield line
|
||||
number of known_hosts entries with encryption key type matching enc,
|
||||
one by one.
|
||||
'''
|
||||
enc = enc if enc else "rsa"
|
||||
for i, line in enumerate(lines):
|
||||
if i % 2 == 0:
|
||||
line_no = int(line.strip().split()[-1])
|
||||
line_enc = lines[i + 1].strip().split()[-2]
|
||||
if line_enc != enc:
|
||||
continue
|
||||
yield line_no
|
||||
|
||||
|
||||
def _parse_openssh_output(lines, fingerprint_hash_type=None):
|
||||
'''
|
||||
Helper function which parses ssh-keygen -F and ssh-keyscan function output
|
||||
@ -837,6 +853,33 @@ def get_known_host(user,
|
||||
|
||||
salt '*' ssh.get_known_host <user> <hostname>
|
||||
'''
|
||||
salt.utils.warn_until(
|
||||
'Neon',
|
||||
'get_known_host has been deprecated in favour of '
|
||||
'get_known_host_entries.'
|
||||
)
|
||||
known_hosts = get_known_host_entries(user, hostname, config, port, fingerprint_hash_type)
|
||||
return known_hosts[0] if known_hosts else None
|
||||
|
||||
|
||||
@salt.utils.decorators.path.which('ssh-keygen')
|
||||
def get_known_host_entries(user,
|
||||
hostname,
|
||||
config=None,
|
||||
port=None,
|
||||
fingerprint_hash_type=None):
|
||||
'''
|
||||
.. versionadded:: Oxygen
|
||||
|
||||
Return information about known host entries from the configfile, if any.
|
||||
If there are no entries for a matching hostname, return None.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' ssh.get_known_host_entries <user> <hostname>
|
||||
'''
|
||||
full = _get_known_hosts_file(config=config, user=user)
|
||||
|
||||
if isinstance(full, dict):
|
||||
@ -847,11 +890,11 @@ def get_known_host(user,
|
||||
lines = __salt__['cmd.run'](cmd,
|
||||
ignore_retcode=True,
|
||||
python_shell=False).splitlines()
|
||||
known_hosts = list(
|
||||
known_host_entries = list(
|
||||
_parse_openssh_output(lines,
|
||||
fingerprint_hash_type=fingerprint_hash_type)
|
||||
)
|
||||
return known_hosts[0] if known_hosts else None
|
||||
return known_host_entries if known_host_entries else None
|
||||
|
||||
|
||||
@salt.utils.decorators.path.which('ssh-keyscan')
|
||||
@ -872,9 +915,8 @@ def recv_known_host(hostname,
|
||||
or ssh-dss
|
||||
|
||||
port
|
||||
optional parameter, denoting the port of the remote host, which will be
|
||||
used in case, if the public key will be requested from it. By default
|
||||
the port 22 is used.
|
||||
Optional parameter, denoting the port of the remote host on which an
|
||||
SSH daemon is running. By default the port 22 is used.
|
||||
|
||||
hash_known_hosts : True
|
||||
Hash all hostnames and addresses in the known hosts file.
|
||||
@ -888,8 +930,8 @@ def recv_known_host(hostname,
|
||||
.. versionadded:: 2016.3.0
|
||||
|
||||
fingerprint_hash_type
|
||||
The public key fingerprint hash type that the public key fingerprint
|
||||
was originally hashed with. This defaults to ``sha256`` if not specified.
|
||||
The fingerprint hash type that the public key fingerprints were
|
||||
originally hashed with. This defaults to ``sha256`` if not specified.
|
||||
|
||||
.. versionadded:: 2016.11.4
|
||||
.. versionchanged:: 2017.7.0: default changed from ``md5`` to ``sha256``
|
||||
@ -900,6 +942,60 @@ def recv_known_host(hostname,
|
||||
|
||||
salt '*' ssh.recv_known_host <hostname> enc=<enc> port=<port>
|
||||
'''
|
||||
salt.utils.warn_until(
|
||||
'Neon',
|
||||
'recv_known_host has been deprecated in favour of '
|
||||
'recv_known_host_entries.'
|
||||
)
|
||||
known_hosts = recv_known_host_entries(hostname, enc, port, hash_known_hosts, timeout, fingerprint_hash_type)
|
||||
return known_hosts[0] if known_hosts else None
|
||||
|
||||
|
||||
@salt.utils.decorators.path.which('ssh-keyscan')
|
||||
def recv_known_host_entries(hostname,
|
||||
enc=None,
|
||||
port=None,
|
||||
hash_known_hosts=True,
|
||||
timeout=5,
|
||||
fingerprint_hash_type=None):
|
||||
'''
|
||||
.. versionadded:: Oxygen
|
||||
|
||||
Retrieve information about host public keys from remote server
|
||||
|
||||
hostname
|
||||
The name of the remote host (e.g. "github.com")
|
||||
|
||||
enc
|
||||
Defines what type of key is being used, can be ed25519, ecdsa ssh-rsa
|
||||
or ssh-dss
|
||||
|
||||
port
|
||||
Optional parameter, denoting the port of the remote host on which an
|
||||
SSH daemon is running. By default the port 22 is used.
|
||||
|
||||
hash_known_hosts : True
|
||||
Hash all hostnames and addresses in the known hosts file.
|
||||
|
||||
timeout : int
|
||||
Set the timeout for connection attempts. If ``timeout`` seconds have
|
||||
elapsed since a connection was initiated to a host or since the last
|
||||
time anything was read from that host, then the connection is closed
|
||||
and the host in question considered unavailable. Default is 5 seconds.
|
||||
|
||||
fingerprint_hash_type
|
||||
The fingerprint hash type that the public key fingerprints were
|
||||
originally hashed with. This defaults to ``sha256`` if not specified.
|
||||
|
||||
.. versionadded:: 2016.11.4
|
||||
.. versionchanged:: 2017.7.0: default changed from ``md5`` to ``sha256``
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' ssh.recv_known_host_entries <hostname> enc=<enc> port=<port>
|
||||
'''
|
||||
# The following list of OSes have an old version of openssh-clients
|
||||
# and thus require the '-t' option for ssh-keyscan
|
||||
need_dash_t = ('CentOS-5',)
|
||||
@ -920,9 +1016,9 @@ def recv_known_host(hostname,
|
||||
while not lines and attempts > 0:
|
||||
attempts = attempts - 1
|
||||
lines = __salt__['cmd.run'](cmd, python_shell=False).splitlines()
|
||||
known_hosts = list(_parse_openssh_output(lines,
|
||||
known_host_entries = list(_parse_openssh_output(lines,
|
||||
fingerprint_hash_type=fingerprint_hash_type))
|
||||
return known_hosts[0] if known_hosts else None
|
||||
return known_host_entries if known_host_entries else None
|
||||
|
||||
|
||||
def check_known_host(user=None, hostname=None, key=None, fingerprint=None,
|
||||
@ -953,18 +1049,20 @@ def check_known_host(user=None, hostname=None, key=None, fingerprint=None,
|
||||
else:
|
||||
config = config or '.ssh/known_hosts'
|
||||
|
||||
known_host = get_known_host(user,
|
||||
known_host_entries = get_known_host_entries(user,
|
||||
hostname,
|
||||
config=config,
|
||||
port=port,
|
||||
fingerprint_hash_type=fingerprint_hash_type)
|
||||
known_keys = [h['key'] for h in known_host_entries] if known_host_entries else []
|
||||
known_fingerprints = [h['fingerprint'] for h in known_host_entries] if known_host_entries else []
|
||||
|
||||
if not known_host or 'fingerprint' not in known_host:
|
||||
if not known_host_entries:
|
||||
return 'add'
|
||||
if key:
|
||||
return 'exists' if key == known_host['key'] else 'update'
|
||||
return 'exists' if key in known_keys else 'update'
|
||||
elif fingerprint:
|
||||
return ('exists' if fingerprint == known_host['fingerprint']
|
||||
return ('exists' if fingerprint in known_fingerprints
|
||||
else 'update')
|
||||
else:
|
||||
return 'exists'
|
||||
@ -1084,70 +1182,99 @@ def set_known_host(user=None,
|
||||
|
||||
update_required = False
|
||||
check_required = False
|
||||
stored_host = get_known_host(user,
|
||||
stored_host_entries = get_known_host_entries(user,
|
||||
hostname,
|
||||
config=config,
|
||||
port=port,
|
||||
fingerprint_hash_type=fingerprint_hash_type)
|
||||
stored_keys = [h['key'] for h in stored_host_entries] if stored_host_entries else []
|
||||
stored_fingerprints = [h['fingerprint'] for h in stored_host_entries] if stored_host_entries else []
|
||||
|
||||
if not stored_host:
|
||||
if not stored_host_entries:
|
||||
update_required = True
|
||||
elif fingerprint and fingerprint != stored_host['fingerprint']:
|
||||
elif fingerprint and fingerprint not in stored_fingerprints:
|
||||
update_required = True
|
||||
elif key and key != stored_host['key']:
|
||||
elif key and key not in stored_keys:
|
||||
update_required = True
|
||||
elif key != stored_host['key']:
|
||||
elif key is None and fingerprint is None:
|
||||
check_required = True
|
||||
|
||||
if not update_required and not check_required:
|
||||
return {'status': 'exists', 'key': stored_host['key']}
|
||||
return {'status': 'exists', 'keys': stored_keys}
|
||||
|
||||
if not key:
|
||||
remote_host = recv_known_host(hostname,
|
||||
remote_host_entries = recv_known_host_entries(hostname,
|
||||
enc=enc,
|
||||
port=port,
|
||||
hash_known_hosts=hash_known_hosts,
|
||||
timeout=timeout,
|
||||
fingerprint_hash_type=fingerprint_hash_type)
|
||||
if not remote_host:
|
||||
known_keys = [h['key'] for h in remote_host_entries] if remote_host_entries else []
|
||||
known_fingerprints = [h['fingerprint'] for h in remote_host_entries] if remote_host_entries else []
|
||||
if not remote_host_entries:
|
||||
return {'status': 'error',
|
||||
'error': 'Unable to receive remote host key'}
|
||||
'error': 'Unable to receive remote host keys'}
|
||||
|
||||
if fingerprint and fingerprint != remote_host['fingerprint']:
|
||||
if fingerprint and fingerprint not in known_fingerprints:
|
||||
return {'status': 'error',
|
||||
'error': ('Remote host public key found but its fingerprint '
|
||||
'does not match one you have provided')}
|
||||
'error': ('Remote host public keys found but none of their'
|
||||
'fingerprints match the one you have provided')}
|
||||
|
||||
if check_required:
|
||||
if remote_host['key'] == stored_host['key']:
|
||||
return {'status': 'exists', 'key': stored_host['key']}
|
||||
for key in known_keys:
|
||||
if key in stored_keys:
|
||||
return {'status': 'exists', 'keys': stored_keys}
|
||||
|
||||
full = _get_known_hosts_file(config=config, user=user)
|
||||
|
||||
if isinstance(full, dict):
|
||||
return full
|
||||
|
||||
# Get information about the known_hosts file before rm_known_host()
|
||||
# because it will create a new file with mode 0600
|
||||
orig_known_hosts_st = None
|
||||
try:
|
||||
orig_known_hosts_st = os.stat(full)
|
||||
except OSError as exc:
|
||||
if exc.args[1] == 'No such file or directory':
|
||||
log.debug('{0} doesnt exist. Nothing to preserve.'.format(full))
|
||||
if os.path.isfile(full):
|
||||
origmode = os.stat(full).st_mode
|
||||
|
||||
# remove everything we had in the config so far
|
||||
rm_known_host(user, hostname, config=config)
|
||||
# remove existing known_host entry with matching hostname and encryption key type
|
||||
# use ssh-keygen -F to find the specific line(s) for this host + enc combo
|
||||
ssh_hostname = _hostname_and_port_to_ssh_hostname(hostname, port)
|
||||
cmd = ['ssh-keygen', '-F', ssh_hostname, '-f', full]
|
||||
lines = __salt__['cmd.run'](cmd,
|
||||
ignore_retcode=True,
|
||||
python_shell=False).splitlines()
|
||||
remove_lines = list(
|
||||
_get_matched_host_line_numbers(lines, enc)
|
||||
)
|
||||
|
||||
if remove_lines:
|
||||
try:
|
||||
with salt.utils.files.fopen(full, 'r+') as ofile:
|
||||
known_hosts_lines = list(ofile)
|
||||
# Delete from last line to first to avoid invalidating earlier indexes
|
||||
for line_no in sorted(remove_lines, reverse=True):
|
||||
del known_hosts_lines[line_no - 1]
|
||||
# Write out changed known_hosts file
|
||||
ofile.seek(0)
|
||||
ofile.truncate()
|
||||
for line in known_hosts_lines:
|
||||
ofile.write(line)
|
||||
except (IOError, OSError) as exception:
|
||||
raise CommandExecutionError(
|
||||
"Couldn't remove old entry(ies) from known hosts file: '{0}'".format(exception)
|
||||
)
|
||||
else:
|
||||
origmode = None
|
||||
|
||||
# set up new value
|
||||
if key:
|
||||
remote_host = {'hostname': hostname, 'enc': enc, 'key': key}
|
||||
remote_host_entries = [{'hostname': hostname, 'enc': enc, 'key': key}]
|
||||
|
||||
if hash_known_hosts or port in [DEFAULT_SSH_PORT, None] or ':' in remote_host['hostname']:
|
||||
line = '{hostname} {enc} {key}\n'.format(**remote_host)
|
||||
else:
|
||||
remote_host['port'] = port
|
||||
line = '[{hostname}]:{port} {enc} {key}\n'.format(**remote_host)
|
||||
lines = []
|
||||
for entry in remote_host_entries:
|
||||
if hash_known_hosts or port in [DEFAULT_SSH_PORT, None] or ':' in entry['hostname']:
|
||||
line = '{hostname} {enc} {key}\n'.format(**entry)
|
||||
else:
|
||||
entry['port'] = port
|
||||
line = '[{hostname}]:{port} {enc} {key}\n'.format(**entry)
|
||||
lines.append(line)
|
||||
|
||||
# ensure ~/.ssh exists
|
||||
ssh_dir = os.path.dirname(full)
|
||||
@ -1173,27 +1300,25 @@ def set_known_host(user=None,
|
||||
# write line to known_hosts file
|
||||
try:
|
||||
with salt.utils.files.fopen(full, 'a') as ofile:
|
||||
ofile.write(line)
|
||||
for line in lines:
|
||||
ofile.write(line)
|
||||
except (IOError, OSError) as exception:
|
||||
raise CommandExecutionError(
|
||||
"Couldn't append to known hosts file: '{0}'".format(exception)
|
||||
)
|
||||
|
||||
if os.geteuid() == 0:
|
||||
if user:
|
||||
os.chown(full, uinfo['uid'], uinfo['gid'])
|
||||
elif orig_known_hosts_st:
|
||||
os.chown(full, orig_known_hosts_st.st_uid, orig_known_hosts_st.st_gid)
|
||||
|
||||
if orig_known_hosts_st:
|
||||
os.chmod(full, orig_known_hosts_st.st_mode)
|
||||
if os.geteuid() == 0 and user:
|
||||
os.chown(full, uinfo['uid'], uinfo['gid'])
|
||||
if origmode:
|
||||
os.chmod(full, origmode)
|
||||
else:
|
||||
os.chmod(full, 0o600)
|
||||
|
||||
if key and hash_known_hosts:
|
||||
cmd_result = __salt__['ssh.hash_known_hosts'](user=user, config=full)
|
||||
|
||||
return {'status': 'updated', 'old': stored_host, 'new': remote_host}
|
||||
rval = {'status': 'updated', 'old': stored_host_entries, 'new': remote_host_entries}
|
||||
return rval
|
||||
|
||||
|
||||
def user_keys(user=None, pubfile=None, prvfile=None):
|
||||
|
@ -178,13 +178,13 @@ def present(
|
||||
return dict(ret, result=False, comment=result['error'])
|
||||
else: # 'updated'
|
||||
if key:
|
||||
new_key = result['new']['key']
|
||||
new_key = result['new'][0]['key']
|
||||
return dict(ret,
|
||||
changes={'old': result['old'], 'new': result['new']},
|
||||
comment='{0}\'s key saved to {1} (key: {2})'.format(
|
||||
name, config, new_key))
|
||||
else:
|
||||
fingerprint = result['new']['fingerprint']
|
||||
fingerprint = result['new'][0]['fingerprint']
|
||||
return dict(ret,
|
||||
changes={'old': result['old'], 'new': result['new']},
|
||||
comment='{0}\'s key saved to {1} (fingerprint: {2})'.format(
|
||||
@ -225,7 +225,7 @@ def absent(name, user=None, config=None):
|
||||
ret['result'] = False
|
||||
return dict(ret, comment=comment)
|
||||
|
||||
known_host = __salt__['ssh.get_known_host'](user=user, hostname=name, config=config)
|
||||
known_host = __salt__['ssh.get_known_host_entries'](user=user, hostname=name, config=config)
|
||||
if not known_host:
|
||||
return dict(ret, comment='Host is already absent')
|
||||
|
||||
|
@ -104,7 +104,7 @@ class SSHModuleTest(ModuleCase):
|
||||
# user will get an indicator of what went wrong.
|
||||
self.assertEqual(len(list(ret.items())), 0) # Zero keys found
|
||||
|
||||
def test_get_known_host(self):
|
||||
def test_get_known_host_entries(self):
|
||||
'''
|
||||
Check that known host information is returned from ~/.ssh/config
|
||||
'''
|
||||
@ -113,7 +113,7 @@ class SSHModuleTest(ModuleCase):
|
||||
KNOWN_HOSTS)
|
||||
arg = ['root', 'github.com']
|
||||
kwargs = {'config': KNOWN_HOSTS}
|
||||
ret = self.run_function('ssh.get_known_host', arg, **kwargs)
|
||||
ret = self.run_function('ssh.get_known_host_entries', arg, **kwargs)[0]
|
||||
try:
|
||||
self.assertEqual(ret['enc'], 'ssh-rsa')
|
||||
self.assertEqual(ret['key'], self.key)
|
||||
@ -125,16 +125,16 @@ class SSHModuleTest(ModuleCase):
|
||||
)
|
||||
)
|
||||
|
||||
def test_recv_known_host(self):
|
||||
def test_recv_known_host_entries(self):
|
||||
'''
|
||||
Check that known host information is returned from remote host
|
||||
'''
|
||||
ret = self.run_function('ssh.recv_known_host', ['github.com'])
|
||||
ret = self.run_function('ssh.recv_known_host_entries', ['github.com'])
|
||||
try:
|
||||
self.assertNotEqual(ret, None)
|
||||
self.assertEqual(ret['enc'], 'ssh-rsa')
|
||||
self.assertEqual(ret['key'], self.key)
|
||||
self.assertEqual(ret['fingerprint'], GITHUB_FINGERPRINT)
|
||||
self.assertEqual(ret[0]['enc'], 'ssh-rsa')
|
||||
self.assertEqual(ret[0]['key'], self.key)
|
||||
self.assertEqual(ret[0]['fingerprint'], GITHUB_FINGERPRINT)
|
||||
except AssertionError as exc:
|
||||
raise AssertionError(
|
||||
'AssertionError: {0}. Function returned: {1}'.format(
|
||||
@ -215,7 +215,7 @@ class SSHModuleTest(ModuleCase):
|
||||
try:
|
||||
self.assertEqual(ret['status'], 'updated')
|
||||
self.assertEqual(ret['old'], None)
|
||||
self.assertEqual(ret['new']['fingerprint'], GITHUB_FINGERPRINT)
|
||||
self.assertEqual(ret['new'][0]['fingerprint'], GITHUB_FINGERPRINT)
|
||||
except AssertionError as exc:
|
||||
raise AssertionError(
|
||||
'AssertionError: {0}. Function returned: {1}'.format(
|
||||
@ -223,8 +223,8 @@ class SSHModuleTest(ModuleCase):
|
||||
)
|
||||
)
|
||||
# check that item does exist
|
||||
ret = self.run_function('ssh.get_known_host', ['root', 'github.com'],
|
||||
config=KNOWN_HOSTS)
|
||||
ret = self.run_function('ssh.get_known_host_entries', ['root', 'github.com'],
|
||||
config=KNOWN_HOSTS)[0]
|
||||
try:
|
||||
self.assertEqual(ret['fingerprint'], GITHUB_FINGERPRINT)
|
||||
except AssertionError as exc:
|
||||
|
@ -66,7 +66,7 @@ class SSHKnownHostsStateTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
raise err
|
||||
|
||||
self.assertSaltStateChangesEqual(
|
||||
ret, GITHUB_FINGERPRINT, keys=('new', 'fingerprint')
|
||||
ret, GITHUB_FINGERPRINT, keys=('new', 0, 'fingerprint')
|
||||
)
|
||||
|
||||
# save twice, no changes
|
||||
@ -81,7 +81,7 @@ class SSHKnownHostsStateTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
**dict(kwargs, name=GITHUB_IP))
|
||||
try:
|
||||
self.assertSaltStateChangesEqual(
|
||||
ret, GITHUB_FINGERPRINT, keys=('new', 'fingerprint')
|
||||
ret, GITHUB_FINGERPRINT, keys=('new', 0, 'fingerprint')
|
||||
)
|
||||
except AssertionError as err:
|
||||
try:
|
||||
@ -94,8 +94,8 @@ class SSHKnownHostsStateTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
|
||||
# record for every host must be available
|
||||
ret = self.run_function(
|
||||
'ssh.get_known_host', ['root', 'github.com'], config=KNOWN_HOSTS
|
||||
)
|
||||
'ssh.get_known_host_entries', ['root', 'github.com'], config=KNOWN_HOSTS
|
||||
)[0]
|
||||
try:
|
||||
self.assertNotIn(ret, ('', None))
|
||||
except AssertionError:
|
||||
@ -103,8 +103,8 @@ class SSHKnownHostsStateTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
'Salt return \'{0}\' is in (\'\', None).'.format(ret)
|
||||
)
|
||||
ret = self.run_function(
|
||||
'ssh.get_known_host', ['root', GITHUB_IP], config=KNOWN_HOSTS
|
||||
)
|
||||
'ssh.get_known_host_entries', ['root', GITHUB_IP], config=KNOWN_HOSTS
|
||||
)[0]
|
||||
try:
|
||||
self.assertNotIn(ret, ('', None, {}))
|
||||
except AssertionError:
|
||||
@ -144,7 +144,7 @@ class SSHKnownHostsStateTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
# remove once, the key is gone
|
||||
ret = self.run_state('ssh_known_hosts.absent', **kwargs)
|
||||
self.assertSaltStateChangesEqual(
|
||||
ret, GITHUB_FINGERPRINT, keys=('old', 'fingerprint')
|
||||
ret, GITHUB_FINGERPRINT, keys=('old', 0, 'fingerprint')
|
||||
)
|
||||
|
||||
# remove twice, nothing has changed
|
||||
|
@ -572,7 +572,7 @@ class ModuleCase(TestCase, SaltClientTestCaseMixin):
|
||||
behavior of the raw function call
|
||||
'''
|
||||
know_to_return_none = (
|
||||
'file.chown', 'file.chgrp', 'ssh.recv_known_host'
|
||||
'file.chown', 'file.chgrp', 'ssh.recv_known_host_entries'
|
||||
)
|
||||
if 'f_arg' in kwargs:
|
||||
kwargs['arg'] = kwargs.pop('f_arg')
|
||||
|
@ -96,7 +96,7 @@ class SshKnownHostsTestCase(TestCase, LoaderModuleMockMixin):
|
||||
self.assertDictEqual(ssh_known_hosts.present(name, user), ret)
|
||||
|
||||
result = {'status': 'updated', 'error': '',
|
||||
'new': {'fingerprint': fingerprint, 'key': key},
|
||||
'new': [{'fingerprint': fingerprint, 'key': key}],
|
||||
'old': ''}
|
||||
mock = MagicMock(return_value=result)
|
||||
with patch.dict(ssh_known_hosts.__salt__,
|
||||
@ -104,8 +104,8 @@ class SshKnownHostsTestCase(TestCase, LoaderModuleMockMixin):
|
||||
comt = ("{0}'s key saved to .ssh/known_hosts (key: {1})"
|
||||
.format(name, key))
|
||||
ret.update({'comment': comt, 'result': True,
|
||||
'changes': {'new': {'fingerprint': fingerprint,
|
||||
'key': key}, 'old': ''}})
|
||||
'changes': {'new': [{'fingerprint': fingerprint,
|
||||
'key': key}], 'old': ''}})
|
||||
self.assertDictEqual(ssh_known_hosts.present(name, user,
|
||||
key=key), ret)
|
||||
|
||||
@ -136,14 +136,14 @@ class SshKnownHostsTestCase(TestCase, LoaderModuleMockMixin):
|
||||
|
||||
mock = MagicMock(return_value=False)
|
||||
with patch.dict(ssh_known_hosts.__salt__,
|
||||
{'ssh.get_known_host': mock}):
|
||||
{'ssh.get_known_host_entries': mock}):
|
||||
comt = ('Host is already absent')
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(ssh_known_hosts.absent(name, user), ret)
|
||||
|
||||
mock = MagicMock(return_value=True)
|
||||
with patch.dict(ssh_known_hosts.__salt__,
|
||||
{'ssh.get_known_host': mock}):
|
||||
{'ssh.get_known_host_entries': mock}):
|
||||
with patch.dict(ssh_known_hosts.__opts__, {'test': True}):
|
||||
comt = ('Key for github.com is set to be'
|
||||
' removed from .ssh/known_hosts')
|
||||
|
Loading…
Reference in New Issue
Block a user