diff --git a/common-requirements.txt b/common-requirements.txt index 93eebf8b9c..68e6bc2003 100644 --- a/common-requirements.txt +++ b/common-requirements.txt @@ -1,7 +1,9 @@ ansible-core>=2.14.0 oauthlib>=3.2.0 # k8s lib that requires manual upgrade kubernetes +kubernetes-validate openstacksdk +jsonschema>=4.20.0 # Allows to unpin cryptography pyOpenSSL>=22.1.0 diff --git a/hooks/crds/.gitkeep b/hooks/crs/.gitkeep similarity index 100% rename from hooks/crds/.gitkeep rename to hooks/crs/.gitkeep diff --git a/roles/run_hook/README.md b/roles/run_hook/README.md index be7359f69b..c6b0b14616 100644 --- a/roles/run_hook/README.md +++ b/roles/run_hook/README.md @@ -1,13 +1,16 @@ # run_hook + Run hooks during a playbook. Hooks may be in the form of a playbook, or a plain CRD. ## Privilege escalation + None from the module, but a hooked playbook may require privilege escalation. Note that, in such a case, the password prompt will be masked, and the overall play has a great chance of failure. ## Parameters + * `hooks`: A list of hooks * `step`: (String) Prefix for the hooks you want to run. Mandatory. @@ -22,9 +25,11 @@ name: * `post_infra_my_hook` will end as `My hook` ## Hooks expected format + ### Playbook #### Single hook in its own parameter + * `config_file`: (String) Ansible configuration file. Defaults to `ansible_config_file`. * `connection`: (String) Set the connection type for ansible. Defaults to `omit`. * `creates`: (String) Refer to the `ansible.builtin.command` "creates" parameter. Defaults to `omit`. @@ -34,6 +39,7 @@ name: * `extra_vars`: (Dict) Structure listing the extra variables you want to pass down #### Multiple hooks in a list + * `config_file`: (String) Ansible configuration file. Defaults to `ansible_config_file`. * `connection`: (String) Set the connection type for ansible. Defaults to `omit`. * `creates`: (String) Refer to the `ansible.builtin.command` "creates" parameter. Defaults to `omit`. @@ -44,8 +50,10 @@ name: * `extra_vars`: (Dict) Structure listing the extra variables you want to pass down #### Hook callback + A hook may generate new parameters that will be fed into the main play. In order to do so, the hook playbook has to create a YAML file as follows: + ```YAML - name: Feed generated content to main play ansible.builtin.copy: @@ -54,6 +62,7 @@ to do so, the hook playbook has to create a YAML file as follows: foo: bar star: {{ my_favorit }} ``` + The location and name are fixed. Both `cifmw_basedir`, `step` and `hook_name` are passed down to the hook playbook. Note that the value of `cifmw_basedir` will default to `~/ci-framework-data` if you don't pass it. @@ -66,6 +75,7 @@ the various hook "timing" (`pre_infra`, `post_infra`, etc). The `hook_name` is a cleaned version of the `name` parameter you pass down in the hook description. #### Examples + ```YAML pre_deploy: - name: My hook @@ -79,30 +89,23 @@ pre_infra_my_nice_hook: type: playbook ``` +### CR -### CRD +#### Single hook -#### Single hook in its own parameter -* `type`: (String) Type of the hook. In this case, set it to `crd`. -* `source`: (String) Source of the CRD. If it's a filename, the CRD is expected in `hooks/crds`. It can be an absolute path. -* `host`: (String) Cluster API endpoint. Defaults to `https://api.crc.testing:6443`. -* `username`: (String) Username for authentication against the cluster. Defaults to `kubeadmin`. -* `password`: (String) Password for authentication against the cluster. Defaults to `12345678`. -* `state`: (String) State of the service. Can be `present` or `absent`. Defaults to `present`. +* `type`: (String) Type of the hook. In this case, set it to `cr`. +* `source`: (String) Source of the CR. If it's a filename, the CR is expected in `hooks/crs`. It can be an absolute path. +* `state`: (String) State of the service. Can be `absent | patched | present`. Defaults to `present`. * `validate_certs`: (Boolean) Whether to validate or not the cluster certificates. * `wait_condition`: (Dict) Wait condition for the service. +* `definition` (Dict) Mapping holding information or configuration of the k8s object. -#### Multiple hooks in a list -* `type`: (String) Type of the hook. In this case, set it to `crd`. -* `source`: (String) Source of the CRD. If it's a filename, the CRD is expected in `hooks/crds`. It can be an absolute path. -* `host`: (String) Cluster API endpoint. Defaults to `https://api.crc.testing:6443`. -* `name`: (String) Describe the hook. -* `username`: (String) Username for authentication against the cluster. Defaults to `kubeadmin`. -* `password`: (String) Password for authentication against the cluster. Defaults to `12345678`. -* `state`: (String) State of the service. Can be `present` or `absent`. Defaults to `present`. -* `validate_certs`: (Boolean) Whether to validate or not the cluster certificates. -* `wait_condition`: (Dict) Wait condition for the service. +#### Multiple hooks + +Users can choose to pass a list of the above parameters. Note that the `wait_condition` must match the format used by the `kubernetes.core.k8s` module. More information here: https://docs.ansible.com/ansible/latest/collections/kubernetes/core/k8s_module.html + +OpenShift cluster is accessed using `cifmw_openshift_kubeconfig`. diff --git a/roles/run_hook/tasks/cr.yml b/roles/run_hook/tasks/cr.yml new file mode 100644 index 0000000000..44ec1a9168 --- /dev/null +++ b/roles/run_hook/tasks/cr.yml @@ -0,0 +1,47 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +- name: "Set custom resource definition path for {{ hook.name }}" + when: + - hook.source is defined + ansible.builtin.set_fact: + crd_path: >- + {%- if hook.source is not ansible.builtin.abs -%} + {{ + ( + ansible.builtin.role_path, + '../../hooks/crds', + hook.src + ) | ansible.builtin.path_join | ansible.builtin.realpath + }} + {%- else -%} + {{ hook.source | ansible.builtin.realpath}} + {%- endif -%} + +- name: "Manage the k8s object" + kubernetes.core.k8s: + definition: "{{ hook.definition | default(omit) }}" + kind: "{{ hook.kind | default(omit) }}" + kubeconfig: "{{ cifmw_openshift_kubeconfig }}" + name: "{{ hook.resource_name | default(omit) }}" + src: "{{ crd_path | default(omit) }}" + state: "{{ hook.state | default(present) }}" + validate: + fail_on_error: true + wait: true + wait_condition: "{{ hook.wait_condition | default(omit) }}" + validate_certs: "{{ hook.validate_certs | default(false) }}" diff --git a/roles/run_hook/tasks/crd.yml b/roles/run_hook/tasks/crd.yml deleted file mode 100644 index 342793ce83..0000000000 --- a/roles/run_hook/tasks/crd.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- name: "Set CRD path for {{ hook.name }}" - ansible.builtin.set_fact: - crd_path: >- - {%- if hook.source is not ansible.builtin.abs -%} - {{ role_path }}/../../hooks/crds/{{ hook.src }} - {%- else -%} - {{ hook.source }} - {%- endif -%} - -- name: "Load and run {{ crd_path | realpath }}" - kubernetes.core.k8s: - host: "{{ hook.host | default('https://api.crc.testing:6443') }}" - username: "{{ hook.username | default('kubeadmin') }}" - password: "{{ hook.password | default('12345678') }}" - state: "{{ hook.state | default(present) }}" - src: "{{ crd_path | realpath }}" - validate: - fail_on_error: true - validate_certs: "{{ hook.validate_certs | default(omit) }}" - wait_condition: "{{ hook.wait_condition | default(omit) }}"