--- # Ensures a project exists and is configured in accordance with ICHP rules: # # - has correct RBAC (user role binding) # - has network policies # - has quota and limitranges # - has an EgressIP allocated # # Requires the following structure: # # role: # state: present or absent # requester: the user requesting the project # name: the name of the project # displayname: optional displayname (defaults to name) # rbac_level: cluster role to assign to requester # egress_ip: an available egress IP to allocate to the project # quota: compute resourcequotas # requests: compute reservation # cpu: max cpu reserved (1500m, 1.5 CPU) # memory: max memory reserved (2048Mi, 2Gi) # limits: compute limits # cpu: max cpu consumed (4000m, 4 CPUs) # memory: max memory consumed (4096Mi, 4Gi) # lrange: compute limitranges, for both container and pod # default: default limits and requests # limit: # cpu: role.lrange.min.cpu * role.lrange.ratio.cpu # memory: role.lrange.min.memory * role.lrange.ratio.memory # request: # cpu: defaults to whatever role.lrange.min.cpu is # memory: defaults to whatever role.lrange.min.memory is # max: maximum limits # cpu: maximum cpu limit (4000m, 4 cpus) # memory: maximum memory limit (4096Mi, 4Gi) # min: minimum requests # cpu: minimum requested cpu (50m, 5%) # memory: minimum requested memory (64Mi) # ratio: max limit-to-request ratio (x-to-1) # cpu: cpu lrr (4) # memory: memory lrr (4) # # IMPORTANT: XXX: ALL COMPUTE UNITS MUST BE IN milicores AND Mi! # # TODO: remove egress IPs without their corresponding projects # - name: Show the values at verbosity 1+ ansible.builtin.debug: var: role verbosity: 1 # TODO: conditional block for state: present - name: Check the values and apply sanity if state=present. block: - name: Verify that the requesting user exists. kubernetes.core.k8s_info: kubeconfig: tmp/kubeconfig-ocp4 validate_certs: no api_version: user.openshift.io/v1 kind: user name: "{{ role.requester }}" register: requester - name: Fail if the user is missing. ansible.builtin.assert: that: - requester.resources is defined - requester.resources | length == 1 success_msg: "OK, requester exists as an OpenShift user." fail_msg: "FATAL: requester ({{ role.requester }}) does not exist as an OpenShift user." - name: Ensure that the project is not there yet. kubernetes.core.k8s_info: kubeconfig: tmp/kubeconfig-ocp4 validate_certs: no api_version: v1 kind: namespace name: "{{ role.name }}" register: namespace - name: Fail if the namespace exists. ansible.builtin.assert: that: - namespace.resources is defined - namespace.resources | length == 0 success_msg: "OK, project does not exist yet." fail_msg: "FATAL: project \"{{ role.name }}\" already exists; remove it using delete-project.yml and retry." - name: Ensure that the clusterrole exists. kubernetes.core.k8s_info: kubeconfig: tmp/kubeconfig-ocp4 validate_certs: no api_version: rbac.authorization.k8s.io/v1 kind: clusterrole name: "{{ role.rbac_level }}" register: clusterrole - name: Fail if the requested cluster role is missing. ansible.builtin.assert: that: - clusterrole.resources is defined - clusterrole.resources | length == 1 success_msg: "OK, clusterrole exists." fail_msg: "FATAL: clusterrole ({{ role.rbac_level }}) does not exist." - name: Get a list of allocated egress IPs kubernetes.core.k8s_info: kubeconfig: tmp/kubeconfig-ocp4 validate_certs: no api_version: k8s.ovn.org/v1 kind: egressip register: egressips - name: Find an available egress IP from openshift.egress_range, or... debug: var: egressips | community.general.json_query('resources[*].status.items[*].egressIP') #- name: ...if egress IP was specified, ensure it is available and in openshift.egress_range. when: role.state == "present" - name: Apply the project template to the cluster with correct state set. kubernetes.core.k8s: kubeconfig: tmp/kubeconfig-ocp4 validate_certs: no template: templates/project-template.yml state: "{{ role.state | default('present') }}" ...