From e45b30d033ff3e050bb72ba05daead96b5fdd8fd Mon Sep 17 00:00:00 2001
From: Steve Mitchell <steve@sgmitchell.net>
Date: Tue, 7 Nov 2017 09:06:16 -0500
Subject: [PATCH] Add etcd key and cert environment variables for use with
 client auth

---
 roles/etcd/defaults/main.yml                               | 3 +++
 roles/etcd/handlers/backup.yml                             | 2 ++
 roles/etcd/handlers/main.yml                               | 2 ++
 roles/etcd/tasks/configure.yml                             | 3 +++
 roles/etcd/tasks/join_member.yml                           | 6 ++++++
 roles/etcd/tasks/set_cluster_health.yml                    | 3 +++
 roles/etcd/templates/etcd.env.j2                           | 2 ++
 roles/kubernetes/master/tasks/pre-upgrade.yml              | 2 ++
 roles/network_plugin/calico/rr/tasks/main.yml              | 3 +++
 roles/network_plugin/calico/tasks/main.yml                 | 2 ++
 roles/network_plugin/canal/tasks/main.yml                  | 3 +++
 roles/network_plugin/canal/templates/cni-canal.conflist.j2 | 3 +++
 scripts/collect-info.yaml                                  | 5 +++++
 13 files changed, 39 insertions(+)

diff --git a/roles/etcd/defaults/main.yml b/roles/etcd/defaults/main.yml
index e2b1b83c7..caf2662f4 100644
--- a/roles/etcd/defaults/main.yml
+++ b/roles/etcd/defaults/main.yml
@@ -30,3 +30,6 @@ etcd_node_cert_hosts: "{{ groups['k8s-cluster'] | union(groups.get('calico-rr',
 etcd_compaction_retention: "8"
 
 etcd_vault_mount_path: etcd
+
+# Force clients like etcdctl to use TLS certs (different than peer security)
+etcd_secure_client: true
diff --git a/roles/etcd/handlers/backup.yml b/roles/etcd/handlers/backup.yml
index 9be90a5b1..247b2ae00 100644
--- a/roles/etcd/handlers/backup.yml
+++ b/roles/etcd/handlers/backup.yml
@@ -48,5 +48,7 @@
       snapshot save {{ etcd_backup_directory }}/snapshot.db
   environment:
     ETCDCTL_API: 3
+    ETCDCTL_CERT: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
   retries: 3
   delay: "{{ retry_stagger | random + 3 }}"
diff --git a/roles/etcd/handlers/main.yml b/roles/etcd/handlers/main.yml
index 2575c25a4..aca8522f5 100644
--- a/roles/etcd/handlers/main.yml
+++ b/roles/etcd/handlers/main.yml
@@ -22,6 +22,8 @@
   uri:
     url: "https://{% if is_etcd_master %}{{ etcd_address }}{% else %}127.0.0.1{% endif %}:2379/health"
     validate_certs: no
+    client_cert: "{{ etcd_cert_dir }}/member-{{ inventory_hostname }}.pem"
+    client_key: "{{ etcd_cert_dir }}/member-{{ inventory_hostname }}-key.pem"
   register: result
   until: result.status is defined and result.status == 200
   retries: 10
diff --git a/roles/etcd/tasks/configure.yml b/roles/etcd/tasks/configure.yml
index e6fabaffb..02bc23172 100644
--- a/roles/etcd/tasks/configure.yml
+++ b/roles/etcd/tasks/configure.yml
@@ -8,6 +8,9 @@
   when: is_etcd_master
   tags:
     - facts
+  environment:
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
 
 - name: Install etcd launch script
   template:
diff --git a/roles/etcd/tasks/join_member.yml b/roles/etcd/tasks/join_member.yml
index 53841a144..60315203b 100644
--- a/roles/etcd/tasks/join_member.yml
+++ b/roles/etcd/tasks/join_member.yml
@@ -6,6 +6,9 @@
   retries: 4
   delay: "{{ retry_stagger | random + 3 }}"
   when: target_node == inventory_hostname
+  environment:
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
 
 - include: refresh_config.yml
   vars:
@@ -39,3 +42,6 @@
   tags:
     - facts
   when: target_node == inventory_hostname
+  environment:
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
diff --git a/roles/etcd/tasks/set_cluster_health.yml b/roles/etcd/tasks/set_cluster_health.yml
index ec3a8b988..955208633 100644
--- a/roles/etcd/tasks/set_cluster_health.yml
+++ b/roles/etcd/tasks/set_cluster_health.yml
@@ -8,3 +8,6 @@
   when: is_etcd_master
   tags:
     - facts
+  environment:
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
diff --git a/roles/etcd/templates/etcd.env.j2 b/roles/etcd/templates/etcd.env.j2
index 00ac5d844..5f14d05b6 100644
--- a/roles/etcd/templates/etcd.env.j2
+++ b/roles/etcd/templates/etcd.env.j2
@@ -18,6 +18,8 @@ ETCD_AUTO_COMPACTION_RETENTION={{ etcd_compaction_retention }}
 ETCD_TRUSTED_CA_FILE={{ etcd_cert_dir }}/ca.pem
 ETCD_CERT_FILE={{ etcd_cert_dir }}/member-{{ inventory_hostname }}.pem
 ETCD_KEY_FILE={{ etcd_cert_dir }}/member-{{ inventory_hostname }}-key.pem
+ETCD_CLIENT_CERT_AUTH={{ etcd_secure_client | lower}}
+
 ETCD_PEER_TRUSTED_CA_FILE={{ etcd_cert_dir }}/ca.pem
 ETCD_PEER_CERT_FILE={{ etcd_cert_dir }}/member-{{ inventory_hostname }}.pem
 ETCD_PEER_KEY_FILE={{ etcd_cert_dir }}/member-{{ inventory_hostname }}-key.pem
diff --git a/roles/kubernetes/master/tasks/pre-upgrade.yml b/roles/kubernetes/master/tasks/pre-upgrade.yml
index 81da33433..3a9fe6417 100644
--- a/roles/kubernetes/master/tasks/pre-upgrade.yml
+++ b/roles/kubernetes/master/tasks/pre-upgrade.yml
@@ -3,6 +3,8 @@
   command: "{{ bin_dir }}/etcdctl --peers={{ etcd_access_addresses }} ls /registry/minions"
   environment:
     ETCDCTL_API: 2
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
   register: old_data_exists
   delegate_to: "{{groups['etcd'][0]}}"
   changed_when: false
diff --git a/roles/network_plugin/calico/rr/tasks/main.yml b/roles/network_plugin/calico/rr/tasks/main.yml
index 2dad16fb1..5b893f38e 100644
--- a/roles/network_plugin/calico/rr/tasks/main.yml
+++ b/roles/network_plugin/calico/rr/tasks/main.yml
@@ -57,6 +57,9 @@
   retries: 4
   delay: "{{ retry_stagger | random + 3 }}"
   delegate_to: "{{groups['etcd'][0]}}"
+  environment:
+    ETCDCTL_CERT: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
 
 - meta: flush_handlers
 
diff --git a/roles/network_plugin/calico/tasks/main.yml b/roles/network_plugin/calico/tasks/main.yml
index a3c540437..2a2d2f6f8 100644
--- a/roles/network_plugin/calico/tasks/main.yml
+++ b/roles/network_plugin/calico/tasks/main.yml
@@ -83,6 +83,8 @@
   uri:
     url: https://localhost:2379/health
     validate_certs: no
+    client_cert: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
+    client_key: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
   register: result
   until: result.status == 200 or result.status == 401
   retries: 10
diff --git a/roles/network_plugin/canal/tasks/main.yml b/roles/network_plugin/canal/tasks/main.yml
index 4e83292c8..7eeb93919 100644
--- a/roles/network_plugin/canal/tasks/main.yml
+++ b/roles/network_plugin/canal/tasks/main.yml
@@ -34,6 +34,9 @@
   delegate_to: "{{groups['etcd'][0]}}"
   changed_when: false
   run_once: true
+  environment:
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
 
 - name: Canal | Create canal node manifests
   template:
diff --git a/roles/network_plugin/canal/templates/cni-canal.conflist.j2 b/roles/network_plugin/canal/templates/cni-canal.conflist.j2
index 04a88c5b9..13b58a0db 100644
--- a/roles/network_plugin/canal/templates/cni-canal.conflist.j2
+++ b/roles/network_plugin/canal/templates/cni-canal.conflist.j2
@@ -7,6 +7,9 @@
       "delegate": {
         "type": "calico",
         "etcd_endpoints": "{{ etcd_access_addresses }}",
+        "etcd_key_file": "{{ canal_cert_dir }}/key.pem",
+        "etcd_cert_file": "{{ canal_cert_dir }}/cert.crt",
+        "etcd_ca_cert_file": "{{ canal_cert_dir }}/ca_cert.crt",
         "log_level": "info",
         "policy": {
           "type": "k8s"
diff --git a/scripts/collect-info.yaml b/scripts/collect-info.yaml
index e10cb7b2c..1a0e2307b 100644
--- a/scripts/collect-info.yaml
+++ b/scripts/collect-info.yaml
@@ -8,6 +8,7 @@
     bin_dir: /usr/local/bin
     system_namespace: kube-system
     ansible_ssh_pipelining: true
+    etcd_cert_dir: /etc/ssl/etcd/ssl
     commands:
       - name: timedate_info
         cmd: timedatectl status
@@ -85,6 +86,10 @@
       - /var/log/calico/felix/current
       - /var/log/calico/confd/current
 
+  environment:
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+
   tasks:
     - set_fact:
         etcd_access_addresses: |-
-- 
GitLab