From 58f6b00d680c598b5d234dbf1b84aa5c3cc5c16d Mon Sep 17 00:00:00 2001 From: jo Date: Mon, 26 May 2025 10:25:19 +0200 Subject: [PATCH] fix: add ssh_public_key_md5_fingerprint util --- plugins/module_utils/ssh.py | 15 +++++++++++++++ tests/unit/module_utils/test_ssh.py | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 plugins/module_utils/ssh.py create mode 100644 tests/unit/module_utils/test_ssh.py diff --git a/plugins/module_utils/ssh.py b/plugins/module_utils/ssh.py new file mode 100644 index 0000000..a38b570 --- /dev/null +++ b/plugins/module_utils/ssh.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from base64 import b64decode +from hashlib import md5 + + +def ssh_public_key_md5_fingerprint(value: str) -> str: + parts = value.strip().split() + if len(parts) < 2: + raise ValueError("invalid ssh public key") + + raw = b64decode(parts[1].encode("ascii")) + digest = md5(raw).hexdigest() + + return ":".join(a + b for a, b in zip(digest[::2], digest[1::2])) diff --git a/tests/unit/module_utils/test_ssh.py b/tests/unit/module_utils/test_ssh.py new file mode 100644 index 0000000..3881272 --- /dev/null +++ b/tests/unit/module_utils/test_ssh.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +import pytest +from ansible_collections.hetzner.hcloud.plugins.module_utils.ssh import ( + ssh_public_key_md5_fingerprint, +) + + +@pytest.mark.parametrize( + ("public_key", "fingerprint"), + [ + ( + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILNWUEdTk1oxrjUZ5erbKUmJM3VxQ9DLocgt/HFohCf6 comment", + "ce:cf:37:b9:38:40:ad:80:b2:8b:2c:5c:83:b5:af:0b", + ), + ( + "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBABOUmmgxbhhauMg97GMwHcjWXM35MwFmlSKx7klWpPr3jMbabGQzINFVXexgf6Tru0D5a7NU/Hkx9t2yOtqKHJOIQB5/NKktqYelul4X56WYV/64RSm6xIjcolNao9fUbawnIwh9mvaQQg5v1BiJfPJ6p6LcWPunzfm6DztU1tHwLtjTw== comment", + "bf:61:7b:7f:ab:c7:af:25:aa:d7:d5:e8:5f:87:5c:66", + ), + ], +) +def test_ssh_public_key_md5_fingerprint(public_key: str, fingerprint: str): + assert ssh_public_key_md5_fingerprint(public_key) == fingerprint