intercept-job -- self-service SSH access

This role is an attempt to allow self-service SSH access to nodes.

Change-Id: Icb6fb50b779c0bf2296e14436e4746355703f2ae
This commit is contained in:
Clint Byrum 2019-08-29 09:56:55 -07:00 committed by Albin Vass
parent 6cd8980fc3
commit 7eab57ab1e
7 changed files with 109 additions and 0 deletions

View File

@ -21,6 +21,7 @@ General Purpose Roles
.. zuul:autorole:: ensure-shake
.. zuul:autorole:: fetch-markdownlint
.. zuul:autorole:: git-prepare-nodecache
.. zuul:autorole:: intercept-job
.. zuul:autorole:: log-inventory
.. zuul:autorole:: markdownlint
.. zuul:autorole:: mirror-workspace-git-repos

View File

@ -0,0 +1,21 @@
If a special SSH key is placed in the right place, stops and waits for user to
SSH in to the node.
This role is intended to be used in pre/post playbooks to allow a smoother
self-service experience than autoholds can offer, at the expense that one can
only access the node for the length of the job timeout.
**Role Variables**
.. zuul:rolevar:: intercept_job_pub_key_path
:default: ``{{ zuul.project.src_dir }}/intercept_job.pub``
If a public key is found here, the intercept-job role will install it, print
details for SSH'ing into this machine, and wait until the
intercept_job_stop_path exists.
.. zuul:rolevar:: intercept_job_stop_path
:default: ``{{ zuul.project.src_dir }}/intercept_job.stop``
If this file exists, the intercept-job role will stop waiting and allow the
playbook to continue.

View File

@ -0,0 +1,2 @@
intercept_job_stop_path: "{{ zuul.project.src_dir }}/intercept_job.stop"
intercept_job_pub_key_path: "{{ zuul.project.src_dir }}/intercept_job.pub"

View File

@ -0,0 +1,16 @@
#!/bin/bash
set -eu
INTERCEPT_STOP_FILE=${1:-}
if [ -z "${INTERCEPT_STOP_FILE}" ] ; then
echo usage: $0 intercept_stop_file
exit 1
fi
echo "to continue job:"
echo touch ${INTERCEPT_STOP_FILE}
echo
echo "to cancel job:"
echo kill $BASHPID
while ! [ -e "${INTERCEPT_STOP_FILE}" ] ; do
sleep 5
done

View File

@ -0,0 +1,8 @@
- name: Check for intercept SSH key
stat:
path: "{{ intercept_job_pub_key_path }}"
register: intercept_key_stat
- name: Wait
when: intercept_key_stat.stat.exists
include_tasks: wait.yaml

View File

@ -0,0 +1,28 @@
- name: Slurp it
slurp:
path: "{{ intercept_job_pub_key_path }}"
register: intercept_key
- name: Add to current user
authorized_key:
key: "{{ intercept_key.content|b64decode }}"
user: "{{ ansible_user }}"
- name: Inform user of connection details
debug:
msg: "ssh {{ ansible_ssh_user }}@{{ ansible_ssh_host }}"
- name: Copy waiter script
copy:
src: waiter.sh
dest: ./waiter.sh
mode: "0755"
- name: Start waiter task
command: ./waiter.sh {{ intercept_job_stop_path }}
- name: Remove key from current user
authorized_key:
key: "{{ intercept_key.content|b64decode }}"
user: "{{ ansible_user }}"
state: absent

View File

@ -0,0 +1,33 @@
- name: Set up async task that will add intercept key
hosts: all
tasks:
- name: Start keygen
command: ssh-keygen -N '' -t ed25519 -f {{ zuul.project.src_dir }}/intercept_job
async: 300
poll: 0
register: keygen
- name: Start background script to stop the waiting
shell: |
sleep 60
touch "{{ zuul.project.src_dir }}/intercept_job.stop"
async: 120
poll: 0
register: touched_file
- async_status:
jid: "{{ keygen.ansible_job_id }}"
register: keygen_check
until: keygen_check.finished == 1
retries: 2
- include_role:
name: intercept-job
- async_status:
jid: "{{ touched_file.ansible_job_id }}"
register: touched_file_check
until: touched_file_check.finished == 1
retries: 3
- stat:
path: "{{ zuul.project.src_dir }}/intercept_job.stop"
register: stop_waiting
- assert:
that:
- stop_waiting.stat.exists