diff --git a/playbooks/operator_deploy.yml b/playbooks/operator_deploy.yml index 9758b4d..aca1567 100644 --- a/playbooks/operator_deploy.yml +++ b/playbooks/operator_deploy.yml @@ -9,6 +9,7 @@ - role: install_settings # set pattern-install specific vars - role: validate_prereq # ensure installation dependencies are present - role: validate_cluster # ensure a cluster is connected and has a default storage class + - role: validate_ocp_version - role: pattern_install_template # render the pattern-install helm chart tasks: diff --git a/playbooks/validate_cluster.yml b/playbooks/validate_cluster.yml index 82e475e..15de505 100644 --- a/playbooks/validate_cluster.yml +++ b/playbooks/validate_cluster.yml @@ -1,5 +1,5 @@ --- -- name: Validates that we are logged into a cluster with a default storage class +- name: Validates cluster connectivity, storage class, and OCP version compatibility hosts: localhost connection: local gather_facts: false @@ -7,3 +7,4 @@ - role: pattern_settings # set general pattern vars - role: install_settings # set pattern-install specific vars - role: validate_cluster + - role: validate_ocp_version diff --git a/roles/validate_ocp_version/defaults/main.yml b/roles/validate_ocp_version/defaults/main.yml new file mode 100644 index 0000000..e606989 --- /dev/null +++ b/roles/validate_ocp_version/defaults/main.yml @@ -0,0 +1,3 @@ +--- +# Minimum OCP version considered supported when not specified in pattern-metadata.yaml +default_minimum_supported_ocp_version: "4.18" diff --git a/roles/validate_ocp_version/tasks/main.yml b/roles/validate_ocp_version/tasks/main.yml new file mode 100644 index 0000000..45d7269 --- /dev/null +++ b/roles/validate_ocp_version/tasks/main.yml @@ -0,0 +1,128 @@ +--- +- name: Check for VP_DISABLE_OCP_VERSION_CHECK override + ansible.builtin.set_fact: + _disable_ocp_version_check: "{{ lookup('env', 'VP_DISABLE_OCP_VERSION_CHECK') | default('false', true) | bool }}" + +- name: OCP version check disabled + ansible.builtin.debug: + msg: "OCP version compatibility check disabled (VP_DISABLE_OCP_VERSION_CHECK=true)." + when: _disable_ocp_version_check + +- name: Run OCP version compatibility check + when: not _disable_ocp_version_check + block: + - name: Check pattern-metadata.yaml exists + ansible.builtin.stat: + path: "{{ pattern_dir }}/pattern-metadata.yaml" + register: _metadata_file + + - name: Skip version check when pattern-metadata.yaml is missing + ansible.builtin.debug: + msg: "No pattern-metadata.yaml found — skipping OCP version compatibility check." + when: not _metadata_file.stat.exists + + - name: Validate OCP version compatibility + when: _metadata_file.stat.exists + block: + - name: Read pattern-metadata.yaml + ansible.builtin.slurp: + src: "{{ pattern_dir }}/pattern-metadata.yaml" + register: _metadata_raw + + - name: Parse pattern-metadata.yaml + block: + - name: Decode and parse pattern-metadata.yaml + ansible.builtin.set_fact: + _pattern_metadata: "{{ _metadata_raw.content | b64decode | from_yaml }}" + rescue: + - name: Fail on malformed pattern-metadata.yaml + ansible.builtin.fail: + msg: "pattern-metadata.yaml exists but contains invalid YAML. Please fix the file before proceeding." + + - name: Check if ocp_versions section exists in metadata + ansible.builtin.set_fact: + _has_ocp_versions: "{{ _pattern_metadata.ocp_versions is defined and _pattern_metadata.ocp_versions is mapping }}" + + - name: Skip version check when metadata has no ocp_versions section + ansible.builtin.debug: + msg: "No ocp_versions section found in pattern-metadata.yaml — skipping OCP version compatibility check." + when: not _has_ocp_versions + + - name: Check OCP version against compatibility matrix + when: _has_ocp_versions + block: + - name: Fetch ClusterVersion from CVO + kubernetes.core.k8s_info: + api_version: config.openshift.io/v1 + kind: ClusterVersion + name: version + register: _cluster_version_info + + - name: Assert ClusterVersion is available + ansible.builtin.assert: + that: + - _cluster_version_info.resources | default([]) | length > 0 + - _cluster_version_info.resources[0].status.desired.version is defined + fail_msg: | + Could not retrieve the ClusterVersion resource from the cluster. + Ensure you are connected to an OpenShift cluster (not vanilla Kubernetes). + + - name: Extract OCP version from ClusterVersion + ansible.builtin.set_fact: + _cluster_ocp_version: >- + {{ _cluster_version_info.resources[0].status.desired.version + | regex_search('^(\d+\.\d+)') }} + + - name: Resolve minimum supported OCP version + ansible.builtin.set_fact: + _minimum_ocp_version: "{{ _pattern_metadata.ocp_versions.minimum | default(default_minimum_supported_ocp_version) }}" + + - name: Collect unsupported versions list + ansible.builtin.set_fact: + _unsupported_versions: "{{ _pattern_metadata.ocp_versions.unsupported | default([]) }}" + + - name: Build unsupported version strings for lookup + ansible.builtin.set_fact: + _unsupported_version_strings: "{{ _unsupported_versions | map(attribute='version') | list }}" + + - name: Display detected OCP version + ansible.builtin.debug: + msg: "Detected cluster OCP version: {{ _cluster_ocp_version }}" + + - name: Check if cluster version is explicitly unsupported + ansible.builtin.set_fact: + _is_unsupported: "{{ _cluster_ocp_version in _unsupported_version_strings }}" + + - name: Find unsupported version details + ansible.builtin.set_fact: + _unsupported_reason: "{{ (_unsupported_versions | selectattr('version', 'equalto', _cluster_ocp_version) | first).reason | default('No reason specified.') }}" + when: _is_unsupported + + - name: Fail on explicitly unsupported OCP version + ansible.builtin.fail: + msg: >- + OCP {{ _cluster_ocp_version }} is not supported by + {{ _pattern_metadata.display_name | default(_pattern_metadata.name | default('this pattern')) }}. + Reason: {{ _unsupported_reason }} + To override this check (e.g. for testing), re-run with: + VP_DISABLE_OCP_VERSION_CHECK=true ./pattern.sh make install + when: _is_unsupported + + - name: Check if cluster version is below minimum supported + ansible.builtin.set_fact: + _is_below_minimum: "{{ _cluster_ocp_version is version(_minimum_ocp_version, '<') }}" + + - name: Warn when OCP version is below minimum supported + ansible.builtin.debug: + msg: >- + WARNING: Your cluster is running OCP {{ _cluster_ocp_version }}, which is below the + minimum supported version ({{ _minimum_ocp_version }}) for this pattern. + The installation will proceed, but you may encounter issues with + operator availability or component compatibility. + For the best experience, please use OCP {{ _minimum_ocp_version }} or later. + when: _is_below_minimum + + - name: Confirm OCP version is compatible + ansible.builtin.debug: + msg: "OK: OCP {{ _cluster_ocp_version }} is compatible with this pattern (minimum: {{ _minimum_ocp_version }})." + when: not _is_below_minimum and not _is_unsupported