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)