From 16715adfa009a60f25cdd5d094ca8689102746ab Mon Sep 17 00:00:00 2001
From: Seongjin Cho <w4-sjcho@users.noreply.github.com>
Date: Wed, 26 Dec 2018 18:52:53 +0900
Subject: [PATCH] Adds support for webhook token auth. (#3939)

Webhook token auth:
https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication

Fixes #3063.
---
 roles/kubernetes/master/defaults/main.yml       |  4 ++++
 roles/kubernetes/master/tasks/main.yml          |  6 ++++++
 .../templates/kubeadm-config.v1alpha1.yaml.j2   | 10 +++++++++-
 .../templates/kubeadm-config.v1alpha2.yaml.j2   | 10 +++++++++-
 .../templates/kubeadm-config.v1alpha3.yaml.j2   | 10 +++++++++-
 .../templates/kubeadm-config.v1beta1.yaml.j2    | 10 +++++++++-
 .../templates/webhook-token-auth-config.yaml.j2 | 17 +++++++++++++++++
 7 files changed, 63 insertions(+), 4 deletions(-)
 create mode 100644 roles/kubernetes/master/templates/webhook-token-auth-config.yaml.j2

diff --git a/roles/kubernetes/master/defaults/main.yml b/roles/kubernetes/master/defaults/main.yml
index e40a9d1aa..ab1106918 100644
--- a/roles/kubernetes/master/defaults/main.yml
+++ b/roles/kubernetes/master/defaults/main.yml
@@ -100,6 +100,7 @@ kube_api_runtime_config:
 kube_basic_auth: false
 kube_token_auth: false
 kube_oidc_auth: false
+kube_webhook_token_auth: false
 
 ## Variables for OpenID Connect Configuration https://kubernetes.io/docs/admin/authentication/
 ## To use OpenID you have to deploy additional an OpenID Provider (e.g Dex, Keycloak, ...)
@@ -113,6 +114,9 @@ kube_oidc_auth: false
 # kube_oidc_groups_claim: groups
 # kube_oidc_groups_prefix: oidc:
 
+## Variables for webhook token auth https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication
+# kube_webhook_token_auth_url: https://...
+
 ## Variables for custom flags
 apiserver_custom_flags: []
 
diff --git a/roles/kubernetes/master/tasks/main.yml b/roles/kubernetes/master/tasks/main.yml
index f7faf43f8..43d9f9fa9 100644
--- a/roles/kubernetes/master/tasks/main.yml
+++ b/roles/kubernetes/master/tasks/main.yml
@@ -7,6 +7,12 @@
   when:
     - kube_basic_auth|default(true)
 
+- name: Create webhook token auth config
+  template:
+    src: webhook-token-auth-config.yaml.j2
+    dest: "{{ kube_config_dir }}/webhook-token-auth-config.yaml"
+  when: kube_webhook_token_auth|default(false)
+
 - import_tasks: encrypt-at-rest.yml
   when:
     - kube_encrypt_secret_data
diff --git a/roles/kubernetes/master/templates/kubeadm-config.v1alpha1.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.v1alpha1.yaml.j2
index 5ffbb97f6..41e744bc7 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.v1alpha1.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.v1alpha1.yaml.j2
@@ -99,6 +99,9 @@ apiServerExtraArgs:
   oidc-groups-claim: {{ kube_oidc_groups_claim }}
 {%   endif %}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+  authentication-token-webhook-config-file: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kube_encrypt_secret_data %}
   experimental-encryption-provider-config: {{ kube_cert_dir }}/secrets_encryption.yaml
 {% endif %}
@@ -152,7 +155,7 @@ schedulerExtraArgs:
   {{ key }}: "{{ kube_kubeadm_scheduler_extra_args[key] }}"
 {% endfor %}
 {% endif %}
-{% if kube_basic_auth|default(true) or kube_token_auth|default(true) %}
+{% if kube_basic_auth|default(true) or kube_token_auth|default(true) or kube_webhook_token_auth|default(false) %}
 apiServerExtraVolumes:
 {% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "external"] %}
 - name: cloud-config
@@ -169,6 +172,11 @@ apiServerExtraVolumes:
   hostPath: {{ kube_token_dir }}
   mountPath: {{ kube_token_dir }}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+- name: webhook-token-auth-config
+  hostPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+  mountPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% endif %}
 apiServerCertSANs:
 {% for san in  apiserver_sans.split() | unique %}
diff --git a/roles/kubernetes/master/templates/kubeadm-config.v1alpha2.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.v1alpha2.yaml.j2
index cf7331293..141087d3d 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.v1alpha2.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.v1alpha2.yaml.j2
@@ -84,6 +84,9 @@ apiServerExtraArgs:
   oidc-groups-claim: {{ kube_oidc_groups_claim }}
 {%   endif %}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+  authentication-token-webhook-config-file: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kube_encrypt_secret_data %}
   experimental-encryption-provider-config: {{ kube_cert_dir }}/secrets_encryption.yaml
 {% endif %}
@@ -146,7 +149,7 @@ controllerManagerExtraVolumes:
   mountPath: {{ kube_config_dir }}/cloud_config
 {% endif %}
 {% endif %}
-{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) %}
+{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) or kube_webhook_token_auth|default(false) %}
 apiServerExtraVolumes:
 {% if kube_basic_auth|default(true) %}
 - name: basic-auth-config
@@ -158,6 +161,11 @@ apiServerExtraVolumes:
   hostPath: {{ kube_token_dir }}
   mountPath: {{ kube_token_dir }}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+- name: webhook-token-auth-config
+  hostPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+  mountPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kubernetes_audit %}
 - name: {{ audit_policy_name }}
   hostPath: {{ audit_policy_hostpath }}
diff --git a/roles/kubernetes/master/templates/kubeadm-config.v1alpha3.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.v1alpha3.yaml.j2
index 6238dffd9..9cba6a40f 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.v1alpha3.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.v1alpha3.yaml.j2
@@ -94,6 +94,9 @@ apiServerExtraArgs:
   oidc-groups-claim: {{ kube_oidc_groups_claim }}
 {%   endif %}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+  authentication-token-webhook-config-file: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kube_encrypt_secret_data %}
   experimental-encryption-provider-config: {{ kube_cert_dir }}/secrets_encryption.yaml
 {% endif %}
@@ -147,7 +150,7 @@ schedulerExtraArgs:
   {{ key }}: "{{ kube_kubeadm_scheduler_extra_args[key] }}"
 {% endfor %}
 {% endif %}
-{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) or ( cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws"] ) or apiserver_extra_volumes %}
+{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) or kube_webhook_token_auth|default(false) or ( cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws"] ) or apiserver_extra_volumes %}
 apiServerExtraVolumes:
 {% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "external"] %}
 - name: cloud-config
@@ -164,6 +167,11 @@ apiServerExtraVolumes:
   hostPath: {{ kube_token_dir }}
   mountPath: {{ kube_token_dir }}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+- name: webhook-token-auth-config
+  hostPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+  mountPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kubernetes_audit %}
 - name: {{ audit_policy_name }}
   hostPath: {{ audit_policy_hostpath }}
diff --git a/roles/kubernetes/master/templates/kubeadm-config.v1beta1.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.v1beta1.yaml.j2
index 6a346cd83..f2589c9bb 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.v1beta1.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.v1beta1.yaml.j2
@@ -92,6 +92,9 @@ apiServer:
     oidc-groups-claim: {{ kube_oidc_groups_claim }}
 {%   endif %}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+    authentication-token-webhook-config-file: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kube_encrypt_secret_data %}
     encryption-provider-config: {{ kube_cert_dir }}/secrets_encryption.yaml
 {% endif %}
@@ -119,7 +122,7 @@ apiServer:
 {% elif cloud_provider is defined and cloud_provider in ["external"] %}
     cloud-config: {{ kube_config_dir }}/cloud_config
 {% endif %}
-{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) or ( cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws"] ) or apiserver_extra_volumes %}
+{% if kubernetes_audit or kube_basic_auth|default(true) or kube_token_auth|default(true) or kube_webhook_token_auth|default(false) or ( cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws"] ) or apiserver_extra_volumes %}
   extraVolumes:
 {% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "external"] %}
   - name: cloud-config
@@ -136,6 +139,11 @@ apiServer:
     hostPath: {{ kube_token_dir }}
     mountPath: {{ kube_token_dir }}
 {% endif %}
+{% if kube_webhook_token_auth|default(false) %}
+  - name: webhook-token-auth-config
+    hostPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+    mountPath: {{ kube_config_dir }}/webhook-token-auth-config.yaml
+{% endif %}
 {% if kubernetes_audit %}
   - name: {{ audit_policy_name }}
     hostPath: {{ audit_policy_hostpath }}
diff --git a/roles/kubernetes/master/templates/webhook-token-auth-config.yaml.j2 b/roles/kubernetes/master/templates/webhook-token-auth-config.yaml.j2
new file mode 100644
index 000000000..15559732c
--- /dev/null
+++ b/roles/kubernetes/master/templates/webhook-token-auth-config.yaml.j2
@@ -0,0 +1,17 @@
+# clusters refers to the remote service.
+clusters:
+- name: webhook-token-auth-cluster
+  cluster:
+    server: {{ kube_webhook_token_auth_url }}
+
+# users refers to the API server's webhook configuration.
+users:
+- name: webhook-token-auth-user
+
+# kubeconfig files require a context. Provide one for the API server.
+current-context: webhook-token-auth
+contexts:
+- context:
+    cluster: webhook-token-auth-cluster
+    user: webhook-token-auth-user
+  name: webhook-token-auth
\ No newline at end of file