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 version: v4.31.2
binary: yq_linux_amd64 binary: yq_linux_amd64
# -------------------------------------- # --------------------------------------
# -- kubectl version
# --------------------------------------
kubectl:
version: v1.26.6
arch: amd64
# --------------------------------------
# -- Path to k8s admin config # -- Path to k8s admin config
# -------------------------------------- # --------------------------------------
k8s_config_path: /etc/kubernetes/admin.conf k8s_config_path: /etc/kubernetes/admin.conf
@ -44,7 +50,16 @@ role_type: ClusterRole
# -- https://kubernetes.io/docs/reference/access-authn-authz/rbac/ # -- https://kubernetes.io/docs/reference/access-authn-authz/rbac/
# -------------------------------------- # --------------------------------------
role: cluster-admin 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 # -- Use with microk8s
# -------------------------------------- # --------------------------------------

View File

@ -2,4 +2,4 @@
- name: remove certificates - name: remove certificates
file: file:
state: absent 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) # -- 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 - name: Ensure required packages are installed
tags: packages tags: packages
block: block:
@ -26,13 +14,13 @@
# -- Prepare kubectl repo # -- Prepare kubectl repo
# ------------------------- # -------------------------
- name: Add an apt signing key for Kubernetes - name: Add an apt signing key for Kubernetes
become: yes become: true
apt_key: apt_key:
url: https://packages.cloud.google.com/apt/doc/apt-key.gpg url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
state: present state: present
- name: Adding apt repository for Kubernetes - name: Adding apt repository for Kubernetes
become: yes become: true
apt_repository: apt_repository:
repo: deb https://apt.kubernetes.io/ kubernetes-xenial main repo: deb https://apt.kubernetes.io/ kubernetes-xenial main
state: present state: present
@ -42,110 +30,55 @@
# -- Install yq # -- Install yq
# -------------------------------------- # --------------------------------------
- name: Ensure yq is installed - name: Ensure yq is installed
become: yes become: true
get_url: get_url:
url: "https://github.com/mikefarah/yq/releases/download/{{ yq.version }}/{{ yq.binary }}" url: "https://github.com/mikefarah/yq/releases/download/{{ yq.version }}/{{ yq.binary }}"
dest: /usr/bin/yq dest: /usr/bin/yq
mode: "0777" mode: "0777"
- name: Ensure kubectl and openssl are installed - block:
become: yes - 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:
expected: "/tmp/kubectl: OK"
assert:
that:
- result.stdout == expected
fail_msg: "{{ result.stdout }}"
success_msg: "{{ result.stdout }}"
- name: Ensure openssl is installed
become: true
package: package:
name: "{{ packages }}" name: "openssl"
state: present state: present
vars:
packages:
- kubectl
- openssl
- name: Generate openssl certificate - name: Create a directory if it does not exist
tags: openssl ansible.builtin.file:
block: path: "{{ working_dir }}"
- name: Generate an OpenSSL private key state: directory
community.crypto.openssl_privatekey: mode: "0775"
path: "{{ working_dir }}/{{ username }}.key"
size: 2048
- name: Generate an OpenSSL Certificate Signing Request - name: Create kubernetes user
community.crypto.openssl_csr: loop: "{{ users }}"
path: "{{ working_dir }}/{{ username }}.csr" include_tasks: create-user.yaml
privatekey_path: "{{ working_dir }}/{{ username }}.key" vars:
common_name: "{{ username }}" certificate_expires_in: "{{ item.certificate_expires_in | default('500') }}"
username: "{{ item.username }}"
- name: Generate an OpenSSL certificate signed with your own CA certificate cluster: "{{ item.cluster }}"
become: yes binding_type: "{{ item.binding_type | default('ClusterRoleBinding') }}"
community.crypto.x509_certificate: role_type: "{{ item.role_type | default('ClusterRole') }}"
path: "{{ working_dir }}/{{ username }}.crt" role: "{{ item.role | default('cluster-admin') }}"
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

View File

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