From ebd8533ee0b616569388207d777442fce1dde75c Mon Sep 17 00:00:00 2001
From: Timotej Lazar <timotej.lazar@fri.uni-lj.si>
Date: Mon, 24 Mar 2025 18:28:46 +0100
Subject: [PATCH] =?UTF-8?q?facts:=20get=20admins=E2=80=99=20SSH=20keys=20f?=
 =?UTF-8?q?rom=20password=20store?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Also install them into root’s authorized_keys on alpine.

This doesn’t take care of removing old keys.
---
 roles/alpine/tasks/main.yml |  6 ++++++
 roles/facts/tasks/main.yml  | 23 +++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/roles/alpine/tasks/main.yml b/roles/alpine/tasks/main.yml
index 626ebe6..6cce486 100644
--- a/roles/alpine/tasks/main.yml
+++ b/roles/alpine/tasks/main.yml
@@ -115,3 +115,9 @@
   template:
     dest: /etc/motd
     src: motd.j2
+
+- name: Set authorized SSH keys
+  authorized_key:
+    user: root
+    exclusive: true
+    key: "{{ ssh_keys | join('\n') }}"
diff --git a/roles/facts/tasks/main.yml b/roles/facts/tasks/main.yml
index f49d5ff..536242a 100644
--- a/roles/facts/tasks/main.yml
+++ b/roles/facts/tasks/main.yml
@@ -1,5 +1,6 @@
 # Make expensive lookups to NetBox once for later reference by any host.
 - when: lookup("env", "NETBOX_API") != ""
+  delegate_to: localhost
   block:
     - name: Lookup networks and prefixes
       set_fact:
@@ -21,5 +22,27 @@
           loop: '{{ cluster.custom_fields.services | map(attribute="id") | map("string") }}'
 
 - name: Fetch passwords
+  delegate_to: localhost
   set_fact:
     password: '{{ lookup("passwordstore", ("vm/" if is_virtual else "host/")~inventory_hostname, returnall=true, missing="empty") | from_yaml }}'
+
+- name: Get SSH keys
+  delegate_to: localhost
+  check_mode: false
+  run_once: true
+  block:
+    - name: Get GPG key IDs
+      shell: cat ${PASSWORD_STORE_DIR:-~/.password-store}/.gpg-id
+      changed_when: false
+      register: gpg_ids
+
+    - name: Export public SSH keys
+      shell: echo "$(gpg --export-ssh-key {{ item }} | cut -d ' ' -f 1,2) $(gpg --list-keys --with-colons {{ item }} | sed -n 's@uid:.*<\(.*\)>.*@\1@p')"
+      loop: '{{ gpg_ids.stdout_lines }}'
+      changed_when: false
+      register: ssh_export
+
+    - name: Set SSH keys to deploy on servers
+      set_fact:
+        ssh_keys: '{{ ssh_export.results | map(attribute="stdout") }}'
+      failed_when: not ssh_keys # something must be terribly wrong so let’s not lock everyone out