diff --git a/changelogs/fragments/33-fix-boot-ssh-key-setting.yaml b/changelogs/fragments/33-fix-boot-ssh-key-setting.yaml new file mode 100644 index 0000000..3134b04 --- /dev/null +++ b/changelogs/fragments/33-fix-boot-ssh-key-setting.yaml @@ -0,0 +1,2 @@ +bugfixes: + - boot - fix incorrect handling of SSH authorized keys (https://github.com/ansible-collections/community.hrobot/issues/32, https://github.com/ansible-collections/community.hrobot/pull/33). diff --git a/plugins/modules/boot.py b/plugins/modules/boot.py index 18a81a2..1d524d3 100644 --- a/plugins/modules/boot.py +++ b/plugins/modules/boot.py @@ -392,7 +392,10 @@ def main(): should = module.params[option_name][option_key] if should is None: continue + # unfold the return object for the idempotence check to work correctly has = existing.get(data_key) + if has and option_key == 'authorized_keys': + has = [x['key']['fingerprint'] for x in has] if isinstance(has, list): has = sorted(has) if not isinstance(should, list): @@ -415,7 +418,7 @@ def main(): result, dummy = fetch_url_json( module, url, - data=urlencode(data), + data=urlencode(data, True), headers=headers, method='POST', ) diff --git a/tests/unit/plugins/modules/test_boot.py b/tests/unit/plugins/modules/test_boot.py index 86c01df..427676c 100644 --- a/tests/unit/plugins/modules/test_boot.py +++ b/tests/unit/plugins/modules/test_boot.py @@ -157,15 +157,40 @@ def test_rescue_idempotent_2(self, mocker): 'os': 'linux', 'arch': 32, 'authorized_keys': [ - 'abc', - 'def', - 'afz', + 'e4:47:42:71:81:62:bf:06:1c:23:fa:f3:8f:7b:6f:d0', + 'aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99', + '0f:1e:2d:3c:4b:5a:69:78:87:96:a5:b4:c3:d2:e1:f0', ], }, }, [ FetchUrlCall('GET', 200) .result_json(_amend_boot({ - 'rescue': create_rescue_active(os='linux', arch=32, authorized_key=['def', 'afz', 'abc']), + 'rescue': create_rescue_active(os='linux', arch=32, authorized_key=[ + { + 'key': { + 'fingerprint': 'e4:47:42:71:81:62:bf:06:1c:23:fa:f3:8f:7b:6f:d0', + 'name': 'baz', + 'size': 4096, + 'type': 'RSA', + }, + }, + { + 'key': { + 'fingerprint': 'aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99', + 'name': 'foo bar', + 'size': 2048, + 'type': 'RSA', + }, + }, + { + 'key': { + 'fingerprint': '0f:1e:2d:3c:4b:5a:69:78:87:96:a5:b4:c3:d2:e1:f0', + 'name': 'test', + 'size': 3072, + 'type': 'RSA', + }, + }, + ]), })) .expect_url('{0}/boot/23'.format(BASE_URL)), ]) @@ -333,15 +358,40 @@ def test_install_linux_idempotent_2(self, mocker): 'arch': 32, 'lang': 'de', 'authorized_keys': [ - 'abc', - 'def', - 'afz', + 'e4:47:42:71:81:62:bf:06:1c:23:fa:f3:8f:7b:6f:d0', + '0f:1e:2d:3c:4b:5a:69:78:87:96:a5:b4:c3:d2:e1:f0', + 'aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99', ], }, }, [ FetchUrlCall('GET', 200) .result_json(_amend_boot({ - 'linux': create_linux_active(dist='Arch Linux latest minimal', arch=32, lang='de', authorized_key=['def', 'afz', 'abc']), + 'linux': create_linux_active(dist='Arch Linux latest minimal', arch=32, lang='de', authorized_key=[ + { + 'key': { + 'fingerprint': 'e4:47:42:71:81:62:bf:06:1c:23:fa:f3:8f:7b:6f:d0', + 'name': 'abc', + 'size': 4096, + 'type': 'RSA', + }, + }, + { + 'key': { + 'fingerprint': 'aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99', + 'name': 'buzz', + 'size': 2048, + 'type': 'RSA', + }, + }, + { + 'key': { + 'fingerprint': '0f:1e:2d:3c:4b:5a:69:78:87:96:a5:b4:c3:d2:e1:f0', + 'name': 'afz', + 'size': 2048, + 'type': 'RSA', + }, + }, + ]), })) .expect_url('{0}/boot/23'.format(BASE_URL)), ]) @@ -404,8 +454,8 @@ def test_install_linux_reactivate(self, mocker): 'arch': 32, 'lang': 'fr', 'authorized_keys': [ - 'asdf', - 'foo bar', + 'e4:47:42:71:81:62:bf:06:1c:23:fa:f3:8f:7b:6f:d0', + 'aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99', ], }, }, [ @@ -421,10 +471,27 @@ def test_install_linux_reactivate(self, mocker): .expect_form_value('arch', '32') .expect_form_value('lang', 'fr') .expect_form_present('authorized_key') - # .expect_form_value('authorized_key', 'asdf') - # .expect_form_value('authorized_key', 'foo bar') + # .expect_form_value('authorized_key', 'e4:47:42:71:81:62:bf:06:1c:23:fa:f3:8f:7b:6f:d0') + # .expect_form_value('authorized_key', 'aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99') .result_json({ - 'linux': create_linux_active(dist='Debian 11 base', lang='fr', arch=32, authorized_key=['foo bar', 'asdf']), + 'linux': create_linux_active(dist='Debian 11 base', lang='fr', arch=32, authorized_key=[ + { + 'key': { + 'fingerprint': 'aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99', + 'name': 'foo bar', + 'size': 4096, + 'type': 'RSA', + }, + }, + { + 'key': { + 'fingerprint': 'e4:47:42:71:81:62:bf:06:1c:23:fa:f3:8f:7b:6f:d0', + 'name': 'bar', + 'size': 2048, + 'type': 'RSA', + }, + }, + ]), }) .expect_url('{0}/boot/23/linux'.format(BASE_URL)), ])