Skip to content

Commit

Permalink
Merge pull request #568 from abakanovskii/feature/add_path_option_aut…
Browse files Browse the repository at this point in the history
…horized_key

authorized_key: Allow local path to a key

SUMMARY

Add option to specify an absolute path to file with SSH key(s) for authorized_key

ISSUE TYPE

Feature Pull Request

COMPONENT NAME

authorized_key

ADDITIONAL INFORMATION


Before this change you would need to get key using ansible.builtin.slurp or something like ansible.builtin.command: cat <file> with register
I tried to keep it as simple as possible

# Now this is possible
- name: Set authorized keys taken from path
  ansible.posix.authorized_key:
    user: charlie
    state: present
    key: /home/charlie/.ssh/id_rsa.pub

Reviewed-by: Hideki Saito <[email protected]>
Reviewed-by: alexander
  • Loading branch information
softwarefactory-project-zuul[bot] authored Sep 30, 2024
2 parents 5321a9e + 5f3f851 commit 0821768
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 1 deletion.
3 changes: 3 additions & 0 deletions changelogs/fragments/568_update_authorized_key.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- authorized_keys - allow using absolute path to a file as a SSH key(s) source (https://github.com/ansible-collections/ansible.posix/pull/568)
23 changes: 22 additions & 1 deletion plugins/modules/authorized_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
key:
description:
- The SSH public key(s), as a string or (since Ansible 1.9) url (https://github.com/username.keys).
- You can also use V(file://) prefix to search remote for a file with SSH key(s).
type: str
required: true
path:
Expand Down Expand Up @@ -96,6 +97,12 @@
state: present
key: https://github.com/charlie.keys
- name: Set authorized keys taken from path on controller node
ansible.posix.authorized_key:
user: charlie
state: present
key: file:///home/charlie/.ssh/id_rsa.pub
- name: Set authorized keys taken from url using lookup
ansible.posix.authorized_key:
user: charlie
Expand Down Expand Up @@ -223,6 +230,7 @@
from ansible.module_utils._text import to_native
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.urls import fetch_url
from ansible.module_utils.six.moves.urllib.parse import urlparse


class keydict(dict):
Expand Down Expand Up @@ -556,7 +564,7 @@ def enforce_state(module, params):
follow = params.get('follow', False)
error_msg = "Error getting key from: %s"

# if the key is a url, request it and use it as key source
# if the key is a url or file, request it and use it as key source
if key.startswith("http"):
try:
resp, info = fetch_url(module, key)
Expand All @@ -570,6 +578,19 @@ def enforce_state(module, params):
# resp.read gives bytes on python3, convert to native string type
key = to_native(key, errors='surrogate_or_strict')

if key.startswith("file"):
# if the key is an absolute path, check for existense and use it as a key source
key_path = urlparse(key).path
if not os.path.exists(key_path):
module.fail_json(msg="Path to a key file not found: %s" % key_path)
if not os.path.isfile(key_path):
module.fail_json(msg="Path to a key is a directory and must be a file: %s" % key_path)
try:
with open(key_path, 'r') as source_fh:
key = source_fh.read()
except OSError as e:
module.fail_json(msg="Failed to read key file %s : %s" % (key_path, to_native(e)))

# extract individual keys into an array, skipping blank lines and comments
new_keys = [s for s in key.splitlines() if s and not s.startswith('#')]

Expand Down
2 changes: 2 additions & 0 deletions tests/integration/targets/authorized_key/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ multiple_keys_comments: |
ssh-rsa DATA_BASIC 1@testing
# I like adding comments yo-dude-this-is-not-a-key INVALID_DATA 2@testing
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
key_path: /tmp/id_rsa.pub
32 changes: 32 additions & 0 deletions tests/integration/targets/authorized_key/tasks/check_path.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
- name: Create key file for test
ansible.builtin.copy:
dest: "{{ key_path }}"
content: "{{ rsa_key_basic }}"
mode: "0600"

- name: Add key using path
ansible.posix.authorized_key:
user: root
key: file://{{ key_path }}
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result

- name: Assert that the key was added
ansible.builtin.assert:
that:
- result.changed == true

- name: Add key using path again
ansible.posix.authorized_key:
user: root
key: file://{{ key_path }}
state: present
path: "{{ output_dir | expanduser }}/authorized_keys"
register: result

- name: Assert that no changes were applied
ansible.builtin.assert:
that:
- result.changed == false
3 changes: 3 additions & 0 deletions tests/integration/targets/authorized_key/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@

- name: Test for the management of comments with key
ansible.builtin.import_tasks: comments.yml

- name: Test for specifying key as a path
ansible.builtin.import_tasks: check_path.yml

0 comments on commit 0821768

Please sign in to comment.