diff options
| author | Joshua Harlow <harlowja@yahoo-inc.com> | 2014-11-21 17:54:30 -0800 | 
|---|---|---|
| committer | Joshua Harlow <harlowja@yahoo-inc.com> | 2014-11-21 17:54:30 -0800 | 
| commit | 61882a004937d5e6d922a6cdc4d65aa5a6315ea8 (patch) | |
| tree | 49014d11dcc69ebeec9d54acc39a89a0abd72363 | |
| parent | 94565bc8607f35557225589d9dde6d2954d49731 (diff) | |
| parent | 5d168a9d11e905dd19e24d0596b7d1145e6b8aa1 (diff) | |
| download | vyos-cloud-init-61882a004937d5e6d922a6cdc4d65aa5a6315ea8.tar.gz vyos-cloud-init-61882a004937d5e6d922a6cdc4d65aa5a6315ea8.zip  | |
Fix parse_ssh_config failing in ssh_util.py
This fix handles '=' as a delimiter in SSH config and
adds appropriate test methods to ensure this functionality
continues to work correctly.
| -rw-r--r-- | ChangeLog | 1 | ||||
| -rw-r--r-- | cloudinit/ssh_util.py | 5 | ||||
| -rw-r--r-- | test-requirements.txt | 1 | ||||
| -rw-r--r-- | tests/unittests/test_sshutil.py | 73 | 
4 files changed, 77 insertions, 3 deletions
@@ -10,6 +10,7 @@   - Fix the digital ocean test case on python 2.6   - Increase the usefulness, robustness, configurability of the chef module     so that it is more useful, more documented and better for users + - Fix how '=' signs are not handled that well in ssh_utils (LP: #1391303)  0.7.6:   - open 0.7.6   - Enable vendordata on CloudSigma datasource (LP: #1303986) diff --git a/cloudinit/ssh_util.py b/cloudinit/ssh_util.py index 70a577bc..14d0cb0f 100644 --- a/cloudinit/ssh_util.py +++ b/cloudinit/ssh_util.py @@ -293,7 +293,10 @@ def parse_ssh_config(fname):          if not line or line.startswith("#"):              lines.append(SshdConfigLine(line))              continue -        (key, val) = line.split(None, 1) +        try: +            key, val = line.split(None, 1) +        except ValueError: +            key, val = line.split('=', 1)          lines.append(SshdConfigLine(line, key, val))      return lines diff --git a/test-requirements.txt b/test-requirements.txt index 2edb8066..230f0404 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,5 @@  httpretty>=0.7.1 +mock  mocker  nose  pep8==1.5.7 diff --git a/tests/unittests/test_sshutil.py b/tests/unittests/test_sshutil.py index d8662cac..3b317121 100644 --- a/tests/unittests/test_sshutil.py +++ b/tests/unittests/test_sshutil.py @@ -1,5 +1,7 @@ +from mock import patch + +from . import helpers as test_helpers  from cloudinit import ssh_util -from unittest import TestCase  VALID_CONTENT = { @@ -35,7 +37,7 @@ TEST_OPTIONS = ("no-port-forwarding,no-agent-forwarding,no-X11-forwarding,"      'user \"root\".\';echo;sleep 10"') -class TestAuthKeyLineParser(TestCase): +class TestAuthKeyLineParser(test_helpers.TestCase):      def test_simple_parse(self):          # test key line with common 3 fields (keytype, base64, comment)          parser = ssh_util.AuthKeyLineParser() @@ -98,4 +100,71 @@ class TestAuthKeyLineParser(TestCase):          self.assertFalse(key.valid()) +class TestParseSSHConfig(test_helpers.TestCase): + +    def setUp(self): +        self.load_file_patch = patch('cloudinit.ssh_util.util.load_file') +        self.load_file = self.load_file_patch.start() +        self.isfile_patch = patch('cloudinit.ssh_util.os.path.isfile') +        self.isfile = self.isfile_patch.start() +        self.isfile.return_value = True + +    def tearDown(self): +        self.load_file_patch.stop() +        self.isfile_patch.stop() + +    def test_not_a_file(self): +        self.isfile.return_value = False +        self.load_file.side_effect = IOError +        ret = ssh_util.parse_ssh_config('not a real file') +        self.assertEqual([], ret) + +    def test_empty_file(self): +        self.load_file.return_value = '' +        ret = ssh_util.parse_ssh_config('some real file') +        self.assertEqual([], ret) + +    def test_comment_line(self): +        comment_line = '# This is a comment' +        self.load_file.return_value = comment_line +        ret = ssh_util.parse_ssh_config('some real file') +        self.assertEqual(1, len(ret)) +        self.assertEqual(comment_line, ret[0].line) + +    def test_blank_lines(self): +        lines = ['', '\t', ' '] +        self.load_file.return_value = '\n'.join(lines) +        ret = ssh_util.parse_ssh_config('some real file') +        self.assertEqual(len(lines), len(ret)) +        for line in ret: +            self.assertEqual('', line.line) + +    def test_lower_case_config(self): +        self.load_file.return_value = 'foo bar' +        ret = ssh_util.parse_ssh_config('some real file') +        self.assertEqual(1, len(ret)) +        self.assertEqual('foo', ret[0].key) +        self.assertEqual('bar', ret[0].value) + +    def test_upper_case_config(self): +        self.load_file.return_value = 'Foo Bar' +        ret = ssh_util.parse_ssh_config('some real file') +        self.assertEqual(1, len(ret)) +        self.assertEqual('foo', ret[0].key) +        self.assertEqual('Bar', ret[0].value) + +    def test_lower_case_with_equals(self): +        self.load_file.return_value = 'foo=bar' +        ret = ssh_util.parse_ssh_config('some real file') +        self.assertEqual(1, len(ret)) +        self.assertEqual('foo', ret[0].key) +        self.assertEqual('bar', ret[0].value) + +    def test_upper_case_with_equals(self): +        self.load_file.return_value = 'Foo=bar' +        ret = ssh_util.parse_ssh_config('some real file') +        self.assertEqual(1, len(ret)) +        self.assertEqual('foo', ret[0].key) +        self.assertEqual('bar', ret[0].value) +  # vi: ts=4 expandtab  | 
