add support for multi-users

This commit is contained in:
RNRod 2023-07-16 22:07:38 +02:00
parent cbe707f618
commit cf5d235cc2
5 changed files with 163 additions and 116 deletions

View File

@ -6,6 +6,12 @@ yq:
version: v4.31.2
binary: yq_linux_amd64
# --------------------------------------
# -- kubectl version
# --------------------------------------
kubectl:
version: v1.26.6
arch: amd64
# --------------------------------------
# -- Path to k8s admin config
# --------------------------------------
k8s_config_path: /etc/kubernetes/admin.conf
@ -44,7 +50,16 @@ role_type: ClusterRole
# -- https://kubernetes.io/docs/reference/access-authn-authz/rbac/
# --------------------------------------
role: cluster-admin
# --------------------------------------
# users:
# - username: "admin"
# cluster: "microk8s-cluster"
# certificate_expires_in: 500
# binding_type: ClusterRoleBinding
# role_type: ClusterRole
# role: cluster-admin
# --------------------------------------
users: []
# --------------------------------------
# -- Use with microk8s
# --------------------------------------

View File

@ -2,4 +2,4 @@
- name: remove certificates
file:
state: absent
path: "{{ working_dir }}"
path: "{{ cert_dir }}"

99
tasks/create-user.yaml Normal file
View File

@ -0,0 +1,99 @@
---
- name: Prepare cert directory
block:
- name: Set workdir as fact
set_fact:
cert_dir: "{{ working_dir }}/.certs/{{ username }}"
- name: Create a directory if it does not exist
ansible.builtin.file:
path: "{{ cert_dir }}"
state: directory
mode: "0775"
- block:
- name: Generate openssl certificate
tags: openssl
block:
- name: Generate an OpenSSL private key
community.crypto.openssl_privatekey:
path: "{{ cert_dir }}/{{ username }}.key"
size: 2048
- name: Generate an OpenSSL Certificate Signing Request
community.crypto.openssl_csr:
path: "{{ cert_dir }}/{{ username }}.csr"
privatekey_path: "{{ cert_dir }}/{{ username }}.key"
common_name: "{{ username }}"
- name: Generate an OpenSSL certificate signed with your own CA certificate
become: true
community.crypto.x509_certificate:
path: "{{ cert_dir }}/{{ username }}.crt"
csr_path: "{{ cert_dir }}/{{ username }}.csr"
ownca_path: "{{ k8s_cert_path }}/{{ k8s_cert_crt_file }}"
ownca_privatekey_path: "{{ k8s_cert_path }}/{{ k8s_cert_key_file }}"
provider: ownca
entrust_not_after: "+{{ certificate_expires_in }}d"
- name: Add user to cluster
block:
# --------------------------------------
# -- Get k8s server from admin.conf
# --------------------------------------
- name: Get k8s server
shell: yq e '.clusters[0] | select(.name == "{{ cluster }}").cluster.server' "{{ k8s_config_path }}"
register: kubernetes_server_output
# --------------------------------------
# -- Get k8s certificate authority data
# -- from admin-conf
# --------------------------------------
- name: Get k8s certificate authority data
shell: yq e '.clusters[0] | select(.name == "{{ cluster }}").cluster.certificate-authority-data' "{{ k8s_config_path }}"
register: kubernetes_cad_output
- name: Get user cert data
shell: cat "{{ cert_dir }}/{{ username }}.crt" | base64 -w 0
register: user_cert_data_output
- name: Get user key data
shell: cat "{{ cert_dir }}/{{ username }}.key" | base64 -w 0
register: user_key_data_output
- name: Set variables for template
set_fact:
kubernetes_server: "{{ kubernetes_server | default(kubernetes_server_output.stdout) }}"
kubernetes_cad: "{{ kubernetes_cad_output.stdout }}"
user_cert_data: " {{ user_cert_data_output.stdout }}"
user_key_data: " {{ user_key_data_output.stdout }}"
- name: Create k8s user
ansible.builtin.shell: |
kubectl config set-credentials "{{ username }}"\
--client-certificate="{{ cert_dir }}/{{ username }}.crt" \
--client-key="{{ cert_dir }}/{{ username }}.key"
notify: remove certificates
- name: Set user context
ansible.builtin.shell: |
kubectl config set-context "{{ username }}@{{ cluster }}" \
--cluster={{ cluster }} --user="{{ username }}"
- name: Create config file from template
template:
src: config.j2
dest: "{{ working_dir }}/{{ username }}.config"
force: false
tags: config
- name: Bind user to role
block:
- name: Generate role binding yaml
template:
src: role-binding.j2
dest: "{{ cert_dir }}/{{ username }}.yaml"
- name: Apply role binding manifest
environment:
KUBECONFIG: "{{ k8s_config_path }}"
shell: kubectl apply -f "{{ cert_dir }}/{{ username }}.yaml"
tags: add_user

View File

@ -7,18 +7,6 @@
# -- 4. Remove certificates (Optional)
# --------------------------------------
---
- name: Prepare working directory
block:
- name: Set workdir as fact
set_fact:
working_dir: "{{ working_dir }}/.certs/{{ username }}"
- name: Create a directory if it does not exist
ansible.builtin.file:
path: "{{ working_dir }}"
state: directory
mode: "0775"
- name: Ensure required packages are installed
tags: packages
block:
@ -26,13 +14,13 @@
# -- Prepare kubectl repo
# -------------------------
- name: Add an apt signing key for Kubernetes
become: yes
become: true
apt_key:
url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
state: present
- name: Adding apt repository for Kubernetes
become: yes
become: true
apt_repository:
repo: deb https://apt.kubernetes.io/ kubernetes-xenial main
state: present
@ -42,110 +30,55 @@
# -- Install yq
# --------------------------------------
- name: Ensure yq is installed
become: yes
become: true
get_url:
url: "https://github.com/mikefarah/yq/releases/download/{{ yq.version }}/{{ yq.binary }}"
dest: /usr/bin/yq
mode: "0777"
- name: Ensure kubectl and openssl are installed
become: yes
package:
name: "{{ packages }}"
state: present
- block:
- name: Download kubectl release
uri:
url: https://dl.k8s.io/release/{{ kubectl.version }}/bin/linux/{{ kubectl.arch }}/kubectl
dest: /tmp
- name: Download the kubectl checksum file
uri:
url: https://dl.k8s.io/{{ kubectl.version }}/bin/linux/{{ kubectl.arch }}/kubectl.sha256
dest: /tmp
- name: Validate the kubectl binary against the checksum file
shell: echo "$(cat /tmp/kubectl.sha256) /tmp/kubectl" | sha256sum --check
register: result
- name: Assert that the kubectl binary is OK
vars:
packages:
- kubectl
- openssl
expected: "/tmp/kubectl: OK"
assert:
that:
- result.stdout == expected
fail_msg: "{{ result.stdout }}"
success_msg: "{{ result.stdout }}"
- name: Generate openssl certificate
tags: openssl
block:
- name: Generate an OpenSSL private key
community.crypto.openssl_privatekey:
path: "{{ working_dir }}/{{ username }}.key"
size: 2048
- name: Ensure openssl is installed
become: true
package:
name: "openssl"
state: present
- name: Generate an OpenSSL Certificate Signing Request
community.crypto.openssl_csr:
path: "{{ working_dir }}/{{ username }}.csr"
privatekey_path: "{{ working_dir }}/{{ username }}.key"
common_name: "{{ username }}"
- name: Create a directory if it does not exist
ansible.builtin.file:
path: "{{ working_dir }}"
state: directory
mode: "0775"
- name: Generate an OpenSSL certificate signed with your own CA certificate
become: yes
community.crypto.x509_certificate:
path: "{{ working_dir }}/{{ username }}.crt"
csr_path: "{{ working_dir }}/{{ username }}.csr"
ownca_path: "{{ k8s_cert_path }}/{{ k8s_cert_crt_file }}"
ownca_privatekey_path: "{{ k8s_cert_path }}/{{ k8s_cert_key_file }}"
provider: ownca
entrust_not_after: "+{{ certificate_expires_in }}d"
- name: Add user to cluster
block:
# --------------------------------------
# -- Get k8s server from admin.conf
# --------------------------------------
- name: Get k8s server
shell: yq e '.clusters[0] | select(.name == "{{ cluster }}").cluster.server' "{{ k8s_config_path }}"
register: kubernetes_server_output
# --------------------------------------
# -- Get k8s certificate authority data
# -- from admin-conf
# --------------------------------------
- name: Get k8s certificate authority data
shell: yq e '.clusters[0] | select(.name == "{{ cluster }}").cluster.certificate-authority-data' "{{ k8s_config_path }}"
register: kubernetes_cad_output
- name: Get user cert data
shell: cat "{{ working_dir }}/{{ username }}.crt" | base64 -w 0
register: user_cert_data_output
- name: Get user key data
shell: cat "{{ working_dir }}/{{ username }}.key" | base64 -w 0
register: user_key_data_output
- name: Set variables for template
set_fact:
kubernetes_server: "{{ kubernetes_server_output.stdout }}"
kubernetes_cad: "{{ kubernetes_cad_output.stdout }}"
user_cert_data: " {{ user_cert_data_output.stdout }}"
user_key_data: " {{ user_key_data_output.stdout }}"
- name: Create k8s user
ansible.builtin.shell: |
kubectl config set-credentials "{{ username }}"\
--client-certificate="{{ working_dir }}/{{ username }}.crt" \
--client-key="{{ working_dir }}/{{ username }}.key"
notify: remove certificates
- name: Set user context
ansible.builtin.shell: |
kubectl config set-context "{{ username }}@{{ cluster }}" \
--cluster={{ cluster }} --user="{{ username }}"
- name: Create config file from template
template:
src: config.j2
dest: "{{ working_dir }}/config"
- name: Storing config on the local machine
ansible.builtin.fetch:
src: "{{ working_dir }}/config"
dest: ./
flat: yes
tags: config
- name: Bind user to role
block:
- name: Generate role binding yaml
template:
src: role-binding.j2
dest: "{{ working_dir }}/{{ username }}.yaml"
- name: Apply role binding manifest
environment:
KUBECONFIG: "{{ k8s_config_path }}"
shell: kubectl apply -f "{{ working_dir }}/{{ username }}.yaml"
tags: add_user
- name: Create kubernetes user
loop: "{{ users }}"
include_tasks: create-user.yaml
vars:
certificate_expires_in: "{{ item.certificate_expires_in | default('500') }}"
username: "{{ item.username }}"
cluster: "{{ item.cluster }}"
binding_type: "{{ item.binding_type | default('ClusterRoleBinding') }}"
role_type: "{{ item.role_type | default('ClusterRole') }}"
role: "{{ item.role | default('cluster-admin') }}"

View File

@ -8,8 +8,8 @@ contexts:
- context:
cluster: {{ cluster }}
user: {{ username }}
name: {{ username }}@{{ cluster }}
current-context: {{ username }}@{{ cluster }}
name: {{ cluster }}
current-context: {{ cluster }}
kind: Config
preferences: {}
users: