mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-06-02 22:39:09 -07:00
known_hosts: support --diff (#20349)
* known_hosts: support --diff
* known_hosts: support --diff also without --check
* Add unit tests and fix incorrect diff in one corner case
Tests are good!
* Refactor for readability
* Python 3 compat
* More Python 3 compat
* Add an integration test for known_hosts
* Handle ssh-keygen -HF returning non-zero exit code
AFAICT this is a bug in ssh-keygen in some newer OpenSSH versions
(>= 6.4 probably; see commit dd9d5cc670
):
when you invoke ssh-keygen with -H and -F <host> options, it always
returns exit code 1. This is because in ssh-keygen.c there's a function
do_known_hosts() which calls
exit (find_host && !ctx.found_key);
at the end, and find_host is 1 (because we passed -F on the command line),
but ctx.found_key is always 0. Why is found_key always 0? Because the
callback passed to hostkeys_foreach(), which is known_hosts_hash(),
never bothers to set found_key to 1.
* This test does not need root
* Avoid ssh-ed25519 keys in sample known_hosts file
Older versions of OpenSSH do not like them and ssh-keygen -HF
aborts with an error when it sees such keys:
line 5 invalid key: example.net...
/root/ansible_testing/known_hosts is not a valid known_hosts file.
* Fix Python 3 errors
Specifically, the default mode of tempfile.NamedTemporaryFile is 'w+b',
which means Python 3 wants us to write bytes objects to it -- but the
keys we have are all unicode strings.
This commit is contained in:
parent
d0bc98bddb
commit
2efb692cc4
8 changed files with 324 additions and 4 deletions
112
test/units/modules/system/test_known_hosts.py
Normal file
112
test/units/modules/system/test_known_hosts.py
Normal file
|
@ -0,0 +1,112 @@
|
|||
import os
|
||||
import tempfile
|
||||
|
||||
from ansible.compat.tests import unittest
|
||||
from ansible.module_utils._text import to_bytes
|
||||
|
||||
from ansible.modules.system.known_hosts import compute_diff
|
||||
|
||||
|
||||
class KnownHostsDiffTestCase(unittest.TestCase):
|
||||
|
||||
def _create_file(self, content):
|
||||
tmp_file = tempfile.NamedTemporaryFile(prefix='ansible-test-', suffix='-known_hosts', delete=False)
|
||||
tmp_file.write(to_bytes(content))
|
||||
tmp_file.close()
|
||||
self.addCleanup(os.unlink, tmp_file.name)
|
||||
return tmp_file.name
|
||||
|
||||
def test_no_existing_file(self):
|
||||
path = tempfile.mktemp(prefix='ansible-test-', suffix='-known_hosts')
|
||||
key = 'example.com ssh-rsa AAAAetc\n'
|
||||
diff = compute_diff(path, found_line=None, replace_or_add=False, state='present', key=key)
|
||||
self.assertEqual(diff, {
|
||||
'before_header': '/dev/null',
|
||||
'after_header': path,
|
||||
'before': '',
|
||||
'after': 'example.com ssh-rsa AAAAetc\n',
|
||||
})
|
||||
|
||||
def test_key_addition(self):
|
||||
path = self._create_file(
|
||||
'two.example.com ssh-rsa BBBBetc\n'
|
||||
)
|
||||
key = 'one.example.com ssh-rsa AAAAetc\n'
|
||||
diff = compute_diff(path, found_line=None, replace_or_add=False, state='present', key=key)
|
||||
self.assertEqual(diff, {
|
||||
'before_header': path,
|
||||
'after_header': path,
|
||||
'before':
|
||||
'two.example.com ssh-rsa BBBBetc\n',
|
||||
'after':
|
||||
'two.example.com ssh-rsa BBBBetc\n'
|
||||
'one.example.com ssh-rsa AAAAetc\n',
|
||||
})
|
||||
|
||||
def test_no_change(self):
|
||||
path = self._create_file(
|
||||
'one.example.com ssh-rsa AAAAetc\n'
|
||||
'two.example.com ssh-rsa BBBBetc\n'
|
||||
)
|
||||
key = 'one.example.com ssh-rsa AAAAetc\n'
|
||||
diff = compute_diff(path, found_line=1, replace_or_add=False, state='present', key=key)
|
||||
self.assertEqual(diff, {
|
||||
'before_header': path,
|
||||
'after_header': path,
|
||||
'before':
|
||||
'one.example.com ssh-rsa AAAAetc\n'
|
||||
'two.example.com ssh-rsa BBBBetc\n',
|
||||
'after':
|
||||
'one.example.com ssh-rsa AAAAetc\n'
|
||||
'two.example.com ssh-rsa BBBBetc\n',
|
||||
})
|
||||
|
||||
def test_key_change(self):
|
||||
path = self._create_file(
|
||||
'one.example.com ssh-rsa AAAaetc\n'
|
||||
'two.example.com ssh-rsa BBBBetc\n'
|
||||
)
|
||||
key = 'one.example.com ssh-rsa AAAAetc\n'
|
||||
diff = compute_diff(path, found_line=1, replace_or_add=True, state='present', key=key)
|
||||
self.assertEqual(diff, {
|
||||
'before_header': path,
|
||||
'after_header': path,
|
||||
'before':
|
||||
'one.example.com ssh-rsa AAAaetc\n'
|
||||
'two.example.com ssh-rsa BBBBetc\n',
|
||||
'after':
|
||||
'two.example.com ssh-rsa BBBBetc\n'
|
||||
'one.example.com ssh-rsa AAAAetc\n',
|
||||
})
|
||||
|
||||
def test_key_removal(self):
|
||||
path = self._create_file(
|
||||
'one.example.com ssh-rsa AAAAetc\n'
|
||||
'two.example.com ssh-rsa BBBBetc\n'
|
||||
)
|
||||
key = 'one.example.com ssh-rsa AAAAetc\n'
|
||||
diff = compute_diff(path, found_line=1, replace_or_add=False, state='absent', key=key)
|
||||
self.assertEqual(diff, {
|
||||
'before_header': path,
|
||||
'after_header': path,
|
||||
'before':
|
||||
'one.example.com ssh-rsa AAAAetc\n'
|
||||
'two.example.com ssh-rsa BBBBetc\n',
|
||||
'after':
|
||||
'two.example.com ssh-rsa BBBBetc\n',
|
||||
})
|
||||
|
||||
def test_key_removal_no_change(self):
|
||||
path = self._create_file(
|
||||
'two.example.com ssh-rsa BBBBetc\n'
|
||||
)
|
||||
key = 'one.example.com ssh-rsa AAAAetc\n'
|
||||
diff = compute_diff(path, found_line=None, replace_or_add=False, state='absent', key=key)
|
||||
self.assertEqual(diff, {
|
||||
'before_header': path,
|
||||
'after_header': path,
|
||||
'before':
|
||||
'two.example.com ssh-rsa BBBBetc\n',
|
||||
'after':
|
||||
'two.example.com ssh-rsa BBBBetc\n',
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue