openshift admin prune auth (#130)

* openshift admin prune auth

* update change scope
This commit is contained in:
abikouo
2021-11-30 14:16:22 +01:00
committed by GitHub
parent 6b2efa180f
commit 496cdba4e8
5 changed files with 1141 additions and 0 deletions

View File

@@ -0,0 +1,326 @@
- block:
- set_fact:
test_sa: "clusterrole-sa"
test_ns: "clusterrole-ns"
- name: Ensure namespace
kubernetes.core.k8s:
kind: Namespace
name: "{{ test_ns }}"
- name: Get cluster information
kubernetes.core.k8s_cluster_info:
register: cluster_info
no_log: true
- set_fact:
cluster_host: "{{ cluster_info['connection']['host'] }}"
- name: Create Service account
kubernetes.core.k8s:
definition:
apiVersion: v1
kind: ServiceAccount
metadata:
name: "{{ test_sa }}"
namespace: "{{ test_ns }}"
- name: Read Service Account
kubernetes.core.k8s_info:
kind: ServiceAccount
namespace: "{{ test_ns }}"
name: "{{ test_sa }}"
register: result
- set_fact:
secret_token: "{{ result.resources[0]['secrets'][0]['name'] }}"
- name: Get secret details
kubernetes.core.k8s_info:
kind: Secret
namespace: '{{ test_ns }}'
name: '{{ secret_token }}'
register: _secret
retries: 10
delay: 10
until:
- ("'openshift.io/token-secret.value' in _secret.resources[0]['metadata']['annotations']") or ("'token' in _secret.resources[0]['data']")
- set_fact:
api_token: "{{ _secret.resources[0]['metadata']['annotations']['openshift.io/token-secret.value'] }}"
when: "'openshift.io/token-secret.value' in _secret.resources[0]['metadata']['annotations']"
- set_fact:
api_token: "{{ _secret.resources[0]['data']['token'] | b64decode }}"
when: "'token' in _secret.resources[0]['data']"
- name: list Node should failed (forbidden user)
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Node
register: error
ignore_errors: true
- assert:
that:
- error is failed
# - '"nodes is forbidden: User" in error.msg'
- name: list Pod for all namespace should failed
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Pod
register: error
ignore_errors: true
- assert:
that:
- error is failed
# - '"pods is forbidden: User" in error.msg'
- name: list Pod for test namespace should failed
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Pod
namespace: "{{ test_ns }}"
register: error
ignore_errors: true
- assert:
that:
- error is failed
# - '"pods is forbidden: User" in error.msg'
- set_fact:
test_labels:
phase: dev
cluster_roles:
- name: pod-manager
resources:
- pods
verbs:
- list
api_version_binding: "authorization.openshift.io/v1"
- name: node-manager
resources:
- nodes
verbs:
- list
api_version_binding: "rbac.authorization.k8s.io/v1"
- name: Create cluster roles
kubernetes.core.k8s:
definition:
kind: ClusterRole
apiVersion: "rbac.authorization.k8s.io/v1"
metadata:
name: "{{ item.name }}"
labels: "{{ test_labels }}"
rules:
- apiGroups: [""]
resources: "{{ item.resources }}"
verbs: "{{ item.verbs }}"
with_items: '{{ cluster_roles }}'
- name: Create Role Binding (namespaced)
kubernetes.core.k8s:
definition:
kind: RoleBinding
apiVersion: "rbac.authorization.k8s.io/v1"
metadata:
name: "{{ cluster_roles[0].name }}-binding"
namespace: "{{ test_ns }}"
labels: "{{ test_labels }}"
subjects:
- kind: ServiceAccount
name: "{{ test_sa }}"
namespace: "{{ test_ns }}"
apiGroup: ""
roleRef:
kind: ClusterRole
name: "{{ cluster_roles[0].name }}"
apiGroup: ""
- name: list Pod for all namespace should failed
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Pod
register: error
ignore_errors: true
- assert:
that:
- error is failed
# - '"pods is forbidden: User" in error.msg'
- name: list Pod for test namespace should succeed
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Pod
namespace: "{{ test_ns }}"
no_log: true
- name: Create Cluster role Binding
kubernetes.core.k8s:
definition:
kind: ClusterRoleBinding
apiVersion: "{{ item.api_version_binding }}"
metadata:
name: "{{ item.name }}-binding"
labels: "{{ test_labels }}"
subjects:
- kind: ServiceAccount
name: "{{ test_sa }}"
namespace: "{{ test_ns }}"
apiGroup: ""
roleRef:
kind: ClusterRole
name: "{{ item.name }}"
apiGroup: ""
with_items: "{{ cluster_roles }}"
- name: list Pod for all namespace should succeed
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Pod
no_log: true
- name: list Pod for test namespace should succeed
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Pod
namespace: "{{ test_ns }}"
no_log: true
- name: list Node using ServiceAccount
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Node
namespace: "{{ test_ns }}"
no_log: true
- name: Prune clusterroles (check mode)
community.okd.openshift_adm_prune_auth:
resource: clusterroles
label_selectors:
- phase=dev
register: check
check_mode: true
- name: validate clusterrole binding candidates for prune
assert:
that:
- '"{{ item.name }}-binding" in check.cluster_role_binding'
- '"{{ test_ns }}/{{ cluster_roles[0].name }}-binding" in check.role_binding'
with_items: "{{ cluster_roles }}"
- name: Prune Cluster Role for managing Pod
community.okd.openshift_adm_prune_auth:
resource: clusterroles
name: "{{ cluster_roles[0].name }}"
- name: list Pod for all namespace should failed
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Pod
register: error
no_log: true
ignore_errors: true
- assert:
that:
- error is failed
# - '"pods is forbidden: User" in error.msg'
- name: list Pod for test namespace should failed
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Pod
namespace: "{{ test_ns }}"
register: error
no_log: true
ignore_errors: true
- assert:
that:
- error is failed
# - '"pods is forbidden: User" in error.msg'
- name: list Node using ServiceAccount
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Node
namespace: "{{ test_ns }}"
no_log: true
- name: Prune clusterroles (remaining)
community.okd.openshift_adm_prune_auth:
resource: clusterroles
label_selectors:
- phase=dev
- name: list Node using ServiceAccount
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
kind: Node
namespace: "{{ test_ns }}"
register: error
ignore_errors: true
- assert:
that:
- error is failed
# - '"nodes is forbidden: User" in error.msg'
always:
- name: Ensure namespace is deleted
kubernetes.core.k8s:
state: absent
kind: Namespace
name: "{{ test_ns }}"
wait: yes
ignore_errors: true
- name: Delete ClusterRoleBinding
kubernetes.core.k8s:
kind: ClusterRoleBinding
api_version: "rbac.authorization.k8s.io/v1"
name: "{{ item.name }}-binding"
state: absent
ignore_errors: true
with_items: "{{ cluster_roles }}"
when: cluster_roles is defined
- name: Delete ClusterRole
kubernetes.core.k8s:
kind: ClusterRole
api_version: "rbac.authorization.k8s.io/v1"
name: "{{ item.name }}"
state: absent
ignore_errors: true
with_items: "{{ cluster_roles }}"
when: cluster_roles is defined

View File

@@ -0,0 +1,344 @@
- block:
- set_fact:
test_ns: "prune-roles"
sa_name: "roles-sa"
pod_name: "pod-prune"
role_definition:
- name: pod-list
labels:
action: list
verbs:
- list
role_binding:
api_version: rbac.authorization.k8s.io/v1
- name: pod-create
labels:
action: create
verbs:
- create
- get
role_binding:
api_version: authorization.openshift.io/v1
- name: pod-delete
labels:
action: delete
verbs:
- delete
role_binding:
api_version: rbac.authorization.k8s.io/v1
- name: Ensure namespace
kubernetes.core.k8s:
kind: Namespace
name: '{{ test_ns }}'
- name: Get cluster information
kubernetes.core.k8s_cluster_info:
register: cluster_info
no_log: true
- set_fact:
cluster_host: "{{ cluster_info['connection']['host'] }}"
- name: Create Service account
kubernetes.core.k8s:
definition:
apiVersion: v1
kind: ServiceAccount
metadata:
name: '{{ sa_name }}'
namespace: '{{ test_ns }}'
- name: Read Service Account
kubernetes.core.k8s_info:
kind: ServiceAccount
namespace: '{{ test_ns }}'
name: '{{ sa_name }}'
register: sa_out
- set_fact:
secret_token: "{{ sa_out.resources[0]['secrets'][0]['name'] }}"
- name: Get secret details
kubernetes.core.k8s_info:
kind: Secret
namespace: '{{ test_ns }}'
name: '{{ secret_token }}'
register: r_secret
retries: 10
delay: 10
until:
- ("'openshift.io/token-secret.value' in r_secret.resources[0]['metadata']['annotations']") or ("'token' in r_secret.resources[0]['data']")
- set_fact:
api_token: "{{ r_secret.resources[0]['metadata']['annotations']['openshift.io/token-secret.value'] }}"
when: "'openshift.io/token-secret.value' in r_secret.resources[0]['metadata']['annotations']"
- set_fact:
api_token: "{{ r_secret.resources[0]['data']['token'] | b64decode }}"
when: "'token' in r_secret.resources[0]['data']"
- name: list resources using service account
kubernetes.core.k8s_info:
api_key: '{{ api_token }}'
host: '{{ cluster_host }}'
validate_certs: no
kind: Pod
namespace: '{{ test_ns }}'
register: error
ignore_errors: true
- assert:
that:
- error is failed
# - '"pods is forbidden: User" in error.module_stderr'
- name: Create a role to manage Pod from namespace "{{ test_ns }}"
kubernetes.core.k8s:
definition:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: "{{ test_ns }}"
name: "{{ item.name }}"
labels: "{{ item.labels }}"
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: "{{ item.verbs }}"
with_items: "{{ role_definition }}"
- name: Create Role Binding
kubernetes.core.k8s:
definition:
kind: RoleBinding
apiVersion: "{{ item.role_binding.api_version }}"
metadata:
name: "{{ item.name }}-bind"
namespace: "{{ test_ns }}"
subjects:
- kind: ServiceAccount
name: "{{ sa_name }}"
namespace: "{{ test_ns }}"
apiGroup: ""
roleRef:
kind: Role
name: "{{ item.name }}"
namespace: "{{ test_ns }}"
apiGroup: ""
with_items: "{{ role_definition }}"
- name: Create Pod should succeed
kubernetes.core.k8s:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
namespace: "{{ test_ns }}"
definition:
kind: Pod
metadata:
name: "{{ pod_name }}"
spec:
containers:
- name: python
image: python:3.7-alpine
command:
- /bin/sh
- -c
- while true; do echo $(date); sleep 15; done
imagePullPolicy: IfNotPresent
register: result
- name: assert pod creation succeed
assert:
that:
- result is successful
- name: List Pod
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
namespace: "{{ test_ns }}"
kind: Pod
register: result
- name: assert user is still authorize to list pods
assert:
that:
- result is successful
- name: Prune auth roles (check mode)
community.okd.openshift_adm_prune_auth:
resource: roles
namespace: "{{ test_ns }}"
register: check
check_mode: true
- name: validate that list role binding are candidates for prune
assert:
that: '"{{ test_ns }}/{{ item.name }}-bind" in check.role_binding'
with_items: "{{ role_definition }}"
- name: Prune resource using label_selectors option
community.okd.openshift_adm_prune_auth:
resource: roles
namespace: "{{ test_ns }}"
label_selectors:
- action=delete
register: prune
- name: assert that role binding 'delete' was pruned
assert:
that:
- prune is changed
- '"{{ test_ns }}/{{ role_definition[2].name }}-bind" in check.role_binding'
- name: assert that user could not delete pod anymore
kubernetes.core.k8s:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
state: absent
namespace: "{{ test_ns }}"
kind: Pod
name: "{{ pod_name }}"
register: result
ignore_errors: true
- name: assert pod deletion failed due to forbidden user
assert:
that:
- result is failed
# - '"forbidden: User" in error.module_stderr'
- name: List Pod
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
namespace: "{{ test_ns }}"
kind: Pod
register: result
- name: assert user is still able to list pods
assert:
that:
- result is successful
- name: Create Pod should succeed
kubernetes.core.k8s:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
namespace: "{{ test_ns }}"
definition:
kind: Pod
metadata:
name: "{{ pod_name }}-1"
spec:
containers:
- name: python
image: python:3.7-alpine
command:
- /bin/sh
- -c
- while true; do echo $(date); sleep 15; done
imagePullPolicy: IfNotPresent
register: result
- name: assert user is still authorize to create pod
assert:
that:
- result is successful
- name: Prune role using name
community.okd.openshift_adm_prune_auth:
resource: roles
namespace: "{{ test_ns }}"
name: "{{ role_definition[1].name }}"
register: prune
- name: assert that role binding 'create' was pruned
assert:
that:
- prune is changed
- '"{{ test_ns }}/{{ role_definition[1].name }}-bind" in check.role_binding'
- name: Create Pod (should failed)
kubernetes.core.k8s:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
namespace: "{{ test_ns }}"
definition:
kind: Pod
metadata:
name: "{{ pod_name }}-2"
spec:
containers:
- name: python
image: python:3.7-alpine
command:
- /bin/sh
- -c
- while true; do echo $(date); sleep 15; done
imagePullPolicy: IfNotPresent
register: result
ignore_errors: true
- name: assert user is not authorize to create pod anymore
assert:
that:
- result is failed
# - '"forbidden: User" in error.module_stderr'
- name: List Pod
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
namespace: "{{ test_ns }}"
kind: Pod
register: result
- name: assert user is still able to list pods
assert:
that:
- result is successful
- name: Prune all role for namespace (neither name nor label_selectors are specified)
community.okd.openshift_adm_prune_auth:
resource: roles
namespace: "{{ test_ns }}"
register: prune
- name: assert that role binding 'list' was pruned
assert:
that:
- prune is changed
- '"{{ test_ns }}/{{ role_definition[0].name }}-bind" in check.role_binding'
- name: List Pod
kubernetes.core.k8s_info:
api_key: "{{ api_token }}"
host: "{{ cluster_host }}"
validate_certs: no
namespace: "{{ test_ns }}"
kind: Pod
register: result
ignore_errors: true
- name: assert user is not authorize to list pod anymore
assert:
that:
- result is failed
# - '"forbidden: User" in error.module_stderr'
always:
- name: Ensure namespace is deleted
kubernetes.core.k8s:
state: absent
kind: Namespace
name: "{{ test_ns }}"
ignore_errors: true

View File

@@ -61,6 +61,8 @@
- import_tasks: tasks/validate_not_installed.yml
- import_tasks: tasks/openshift_auth.yml
- import_tasks: tasks/openshift_adm_prune_auth_clusterroles.yml
- import_tasks: tasks/openshift_adm_prune_auth_roles.yml
- import_tasks: tasks/openshift_route.yml
- block:
- name: Create namespace