From 9342c2aa6dfd023d0eadb4894569fbc6164850a8 Mon Sep 17 00:00:00 2001
From: Clark Boylan <clark.boylan@gmail.com>
Date: Mon, 24 Sep 2018 15:21:08 -0700
Subject: [PATCH] Add zuul user to bridge.openstack.org

We want to trigger ansible runs on bridge.o.o from zuul jobs. First
iteration of this tried to login as root but this is not allowed by our
ssh config. That config seems reasonable so we add a zuul user instead
which we can ssh in as then run things as root from zuul jobs. This
makes use of our existing user management system.

Change-Id: I257ebb6ffbade4eb645a08d3602a7024069e60b3
---
 playbooks/bridge.yaml                         |  9 ---------
 playbooks/group_vars/all.yaml                 |  8 ++++++++
 playbooks/host_vars/bridge.openstack.org.yaml |  2 ++
 playbooks/zuul/run-production-playbook.yaml   | 10 +++++++++-
 testinfra/test_bridge.py                      | 17 +++++++++++++++--
 5 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/playbooks/bridge.yaml b/playbooks/bridge.yaml
index d5446b7d29..2142fb6d5b 100644
--- a/playbooks/bridge.yaml
+++ b/playbooks/bridge.yaml
@@ -24,12 +24,3 @@
     - ansible-cron
     - cloud-launcher-cron
     - edit-secrets-script
-  tasks:
-    - name: Allow Zuul to trigger Ansible
-      authorized_key:
-        state: present
-        user: root
-        key: "{{ item }}"
-      loop:
-        - "https://zuul.openstack.org/api/project-ssh-key/openstack-infra/system-config.pub"
-        - "https://zuul.openstack.org/api/project-ssh-key/openstack-infra/project-config.pub"
diff --git a/playbooks/group_vars/all.yaml b/playbooks/group_vars/all.yaml
index 292b3507c4..69ae053a4c 100644
--- a/playbooks/group_vars/all.yaml
+++ b/playbooks/group_vars/all.yaml
@@ -156,6 +156,14 @@ all_users:
     uid: 2030
     gid: 2030
 
+  zuulcd:
+    comment: Zuul CICD
+    key: |
+      ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcXd/QJDEprSLh6N6bULnhchf9M+uzYBEJ2b51Au67FON+5M6VEj5Ut+DlkEPhabOP+tSv9Cn1HpmpBjdEOXdmBj6JS7G/gBb4w28oZDyNjrPT2ebpRw/XnVEkGfikR2J+j3o7CV+ybhLDalXm2TUDReVXnONUq3YzZbjRzoYs0xxrxyss47vZP0xFpsAt9jCMAJW2k6H589VUY38k9LFyhZUZ72FB6eJ68B9GN0TimBYm2DqvupBGQrRhkP8OZ0WoBV8PulKXaHVFdmfBNHB7E7FLlZKuiM6nkV4bOWMGOB/TF++wXBK86t9po3pWCM7+kr72xGRTE+6LuZ2z1K+h zuul-system-config-20180924
+      ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQbidZ1wW8moNtPGBhZ3oDm1kcDtiAemI51euL6KZslwpG8CKMT0KBSYw1vpCYc5dYCerq63dQtg2Bm1rhc2gC/U2bbMlvnNPwlkS7eykVfrPDfJHVbff+qHv7l1e1ZoCVAEvVxXG/FgFUiqIKwEhMqG/Etegw07H7vERNETGE5RyRA8cMnK9Cj4oL0OUpZAv7o1a+A+gXRv1EMdWL7g9M6OImikO48w+ZSLOA8uD+0MmN23nh335k2VG609u+ZxTkZAB4GtW0HSCTFu5MCmJFaY1+5cCNedsC9O4ekaXNQxYelFxasN5Qe7miRWcR+Ax8g3HjHpG3Hc1LSc/6XVcj zuul-project-config-20180924
+    uid: 2031
+    gid: 2031
+
 # List of users to install on all hosts
 base_users:
   - mordred
diff --git a/playbooks/host_vars/bridge.openstack.org.yaml b/playbooks/host_vars/bridge.openstack.org.yaml
index f8324a2176..9636e4280b 100644
--- a/playbooks/host_vars/bridge.openstack.org.yaml
+++ b/playbooks/host_vars/bridge.openstack.org.yaml
@@ -1,3 +1,5 @@
 ansible_python_interpreter: python3
 bastion_key_exclusive: false
 kube_config_template: clouds/bridge_kube_config.yaml.j2
+extra_users:
+  - zuulcd
diff --git a/playbooks/zuul/run-production-playbook.yaml b/playbooks/zuul/run-production-playbook.yaml
index d641b4f990..2ad0191cfc 100644
--- a/playbooks/zuul/run-production-playbook.yaml
+++ b/playbooks/zuul/run-production-playbook.yaml
@@ -3,9 +3,17 @@
     - name: Add bridge.o.o to inventory
       add_host:
         name: bridge.openstack.org
-        ansible_user: root
+        ansible_user: zuulcd
+
+- hosts: localhost
+  tasks:
+    - name: Add bridge.o.o hostkey to known hosts
+      known_hosts:
+        name: bridge.openstack.org
+        key: "bridge.openstack.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxRzDkWvvVQtsLTAqAwedRWA84/42KKVdFS0QP8lZFsMpgTXUhjipJ7VcFun5gM87tnt0J71rlN+ospBh0/1wfp2jASEskUyGhXAa5xHjnJN7veUyW+AggEosK/OTunvZgf54p1sQg45Sq/uCjc0Ua0fRMOq2o5z/mgpl6rSjLOlWi9wKA/6axnUbs9w4iD5esyBQ+VcISSJOTqhAo/3UG0NwCU+6Ggwwhg0nl5iCMpQfq4A207IbJ72MkJzlQgW3edsRb5POzdZcGxkTYvVdP3kgHP4Bof3MFFZjBUMz6SuRQyNV5poysMtbtlO0SvgAJNhXr6Vn0GA9XhqFP6+HT"
 
 - hosts: bridge.openstack.org
   tasks:
     - name: Run specified playbook on bridge.o.o
+      become: yes
       command: ansible-playbook -f {{ ansible_forks }} /opt/system-config/playbooks/{{ playbook_name }}
diff --git a/testinfra/test_bridge.py b/testinfra/test_bridge.py
index 64e27fc0e7..b36a6247bd 100644
--- a/testinfra/test_bridge.py
+++ b/testinfra/test_bridge.py
@@ -51,13 +51,13 @@ def test_cloud_launcher_cron(host):
         assert 'run_cloud_launcher.sh' in crontab
 
 
-def test_authorized_keys(host):
+def test_root_authorized_keys(host):
     authorized_keys = host.file('/root/.ssh/authorized_keys')
     assert authorized_keys.exists
 
     content = authorized_keys.content.decode('utf8')
     lines = content.split('\n')
-    assert len(lines) >= 3
+    assert len(lines) >= 2
 
 
 def test_ara(host):
@@ -77,3 +77,16 @@ def test_kube_config(host):
 def test_kubectl(host):
     kube = host.run('kubectl help')
     assert kube.rc == 0
+
+
+def test_zuulcd_authorized_keys(host):
+    authorized_keys = host.file('/home/zuulcd/.ssh/authorized_keys')
+    assert authorized_keys.exists
+
+    content = authorized_keys.content.decode('utf8')
+    lines = content.split('\n')
+    # Remove empty lines
+    keys = list(filter(None, lines))
+    assert len(keys) >= 2
+    for key in keys:
+        assert 'ssh-rsa' in key