From e5ff8e340754411639c573509fcbe15e684cfa19 Mon Sep 17 00:00:00 2001 From: Nihlaeth Date: Thu, 17 Aug 2017 21:38:39 +0200 Subject: [PATCH] Don't remove comment from public key, and improve error message for duplicate keys (github_key) (#22282) * improve error message for duplicate public keys * don't consider self when searching for duplicates * don't strip comment from key --- .../modules/source_control/github_key.py | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/ansible/modules/source_control/github_key.py b/lib/ansible/modules/source_control/github_key.py index 1286e0acab..c8b80eceeb 100644 --- a/lib/ansible/modules/source_control/github_key.py +++ b/lib/ansible/modules/source_control/github_key.py @@ -132,12 +132,12 @@ class GitHubSession(object): def get_all_keys(session): url = API_BASE + '/user/keys' + result = [] while url: r = session.request('GET', url) - for key in r.json(): - yield key - + result.extend(r.json()) url = r.links().get('next') + return result def create_key(session, name, pubkey, check_mode): @@ -176,11 +176,20 @@ def ensure_key_absent(session, name, check_mode): 'deleted_keys': to_delete} -def ensure_key_present(session, name, pubkey, force, check_mode): - matching_keys = [k for k in get_all_keys(session) if k['title'] == name] +def ensure_key_present(module, session, name, pubkey, force, check_mode): + all_keys = get_all_keys(session) + matching_keys = [k for k in all_keys if k['title'] == name] deleted_keys = [] - if matching_keys and force and matching_keys[0]['key'] != pubkey: + new_signature = pubkey.split(' ')[1] + for key in all_keys: + existing_signature = key['key'].split(' ')[1] + if new_signature == existing_signature and key['title'] != name: + module.fail_json(msg=( + "another key with the same content is already registered " + "under the name |{}|").format(key['title'])) + + if matching_keys and force and matching_keys[0]['key'].split(' ')[1] != new_signature: delete_keys(session, matching_keys, check_mode=check_mode) (deleted_keys, matching_keys) = (matching_keys, []) @@ -221,15 +230,12 @@ def main(): # Keys consist of a protocol, the key data, and an optional comment. if len(pubkey_parts) < 2: module.fail_json(msg='"pubkey" parameter has an invalid format') - - # Strip out comment so we can compare to the keys GitHub returns. - pubkey = ' '.join(pubkey_parts[:2]) elif state == 'present': module.fail_json(msg='"pubkey" is required when state=present') session = GitHubSession(module, token) if state == 'present': - result = ensure_key_present(session, name, pubkey, force=force, + result = ensure_key_present(module, session, name, pubkey, force=force, check_mode=module.check_mode) elif state == 'absent': result = ensure_key_absent(session, name, check_mode=module.check_mode)