From a2572f264e73d2e4d81c7b57f3fa4ff0b0d69727 Mon Sep 17 00:00:00 2001 From: Itay Matza Date: Sat, 7 Mar 2026 12:09:34 +0200 Subject: [PATCH] [adoption_osp_deploy] Allow overriding scenario stack CLI args Add cifmw_adoption_osp_deploy_stack_args_remove and cifmw_adoption_osp_deploy_stack_args_add variables to allow callers to modify the TripleO overcloud deploy CLI arguments from the DPA scenario. TripleO CLI arguments like --libvirt-type generate internal heat environments applied after all user-provided -e files, so they cannot be overridden via the existing cifmw_adoption_osp_deploy_overcloud_extra_args mechanism. The new variables use Ansible's reject filter to remove unwanted args (preserving order) and append replacements. Also adds: - Input validation for the new variables in validate_scenario - Molecule test coverage for the args override logic - README documentation for both new parameters Assisted-By: Claude Code Signed-off-by: Itay Matza --- roles/adoption_osp_deploy/README.md | 7 ++ roles/adoption_osp_deploy/defaults/main.yml | 3 + .../molecule/default/converge.yml | 88 +++++++++++++++++++ .../molecule/default/verify.yml | 47 ++++++++++ .../tasks/deploy_overcloud.yml | 6 +- .../tasks/validate_scenario.yml | 13 +++ 6 files changed, 163 insertions(+), 1 deletion(-) diff --git a/roles/adoption_osp_deploy/README.md b/roles/adoption_osp_deploy/README.md index 27c8f64363..b305e7500b 100644 --- a/roles/adoption_osp_deploy/README.md +++ b/roles/adoption_osp_deploy/README.md @@ -28,6 +28,13 @@ configure the OSP17.1 deployment. * `cifmw_adoption_osp_deploy_overcloud_extra_args`: (String) The content of a file which will be used with the -e option in the overcloud deploy command. This is useful to specify private/restricted parameters. +* `cifmw_adoption_osp_deploy_stack_args_remove`: (List) List of CLI argument + strings to remove from the scenario's `stack.args` before running overcloud + deploy. Each entry must exactly match an element in `stack.args`. Defaults + to `[]`. +* `cifmw_adoption_osp_deploy_stack_args_add`: (List) List of CLI argument + strings to append to the scenario's `stack.args` after removals are applied. + Defaults to `[]`. * `cifmw_adoption_osp_deploy_bgp`: (Boolean) Enable BGP support for the OSP deployment. When enabled, uses BGP-specific network configurations and templates. Defaults to `false`. diff --git a/roles/adoption_osp_deploy/defaults/main.yml b/roles/adoption_osp_deploy/defaults/main.yml index 73fc43fc21..083596bbbe 100644 --- a/roles/adoption_osp_deploy/defaults/main.yml +++ b/roles/adoption_osp_deploy/defaults/main.yml @@ -31,6 +31,9 @@ cifmw_adoption_osp_deploy_adoption_vars_exclude_nets: cifmw_adoption_osp_deploy_overcloud_extra_args: '' +cifmw_adoption_osp_deploy_stack_args_remove: [] +cifmw_adoption_osp_deploy_stack_args_add: [] + cifmw_adoption_osp_deploy_bgp: false cifmw_adoption_osp_deploy_freeipa_admin_password: "nomoresecrets" diff --git a/roles/adoption_osp_deploy/molecule/default/converge.yml b/roles/adoption_osp_deploy/molecule/default/converge.yml index 9e88ebe7d3..dd2dd6ff9e 100644 --- a/roles/adoption_osp_deploy/molecule/default/converge.yml +++ b/roles/adoption_osp_deploy/molecule/default/converge.yml @@ -24,3 +24,91 @@ ansible.builtin.set_fact: tripleo_nodes_stack: "{{ _tripleo_nodes_stack }}" cacheable: true + + - name: Test stack args override logic + vars: + _mock_args: + - "--override-ansible-cfg /home/zuul/ansible_config.cfg" + - "--templates /usr/share/openstack-tripleo-heat-templates" + - "--libvirt-type qemu" + - "--timeout 90" + - "--deployed-server" + block: + - name: Test default (no remove, no add) preserves args + ansible.builtin.set_fact: + _result_default: >- + {{ + ((_mock_args | + reject('in', []) | + list) + + []) | + join(' ') + }} + + - name: Test removing a single arg + ansible.builtin.set_fact: + _result_remove: >- + {{ + ((_mock_args | + reject('in', ['--libvirt-type qemu']) | + list) + + []) | + join(' ') + }} + + - name: Test adding an arg + ansible.builtin.set_fact: + _result_add: >- + {{ + ((_mock_args | + reject('in', []) | + list) + + ['--libvirt-type kvm']) | + join(' ') + }} + + - name: Test removing and adding (replace pattern) + ansible.builtin.set_fact: + _result_replace: >- + {{ + ((_mock_args | + reject('in', ['--libvirt-type qemu']) | + list) + + ['--libvirt-type kvm']) | + join(' ') + }} + + - name: Test removing multiple args + ansible.builtin.set_fact: + _result_remove_multi: >- + {{ + ((_mock_args | + reject('in', ['--libvirt-type qemu', + '--timeout 90']) | + list) + + []) | + join(' ') + }} + + - name: Test removing non-existent arg is a no-op + ansible.builtin.set_fact: + _result_remove_noop: >- + {{ + ((_mock_args | + reject('in', ['--nonexistent-flag']) | + list) + + []) | + join(' ') + }} + + - name: Store args override results for verification + ansible.builtin.set_fact: + args_override_results: + mock_args_joined: "{{ _mock_args | join(' ') }}" + default: "{{ _result_default }}" + remove: "{{ _result_remove }}" + add: "{{ _result_add }}" + replace: "{{ _result_replace }}" + remove_multi: "{{ _result_remove_multi }}" + remove_noop: "{{ _result_remove_noop }}" + cacheable: true diff --git a/roles/adoption_osp_deploy/molecule/default/verify.yml b/roles/adoption_osp_deploy/molecule/default/verify.yml index 23756be169..a47db98d4e 100644 --- a/roles/adoption_osp_deploy/molecule/default/verify.yml +++ b/roles/adoption_osp_deploy/molecule/default/verify.yml @@ -21,3 +21,50 @@ loop: "{{ stacks }}" loop_control: loop_var: _stack + + - name: "Load args override results" + ansible.builtin.set_fact: + args_override_results: "{{ hostvars[inventory_hostname].args_override_results }}" + + - name: "Assert default args are preserved when no overrides" + ansible.builtin.assert: + that: + - "args_override_results.default == args_override_results.mock_args_joined" + fail_msg: >- + Default args mismatch. + Got: '{{ args_override_results.default }}' + Expected: '{{ args_override_results.mock_args_joined }}' + + - name: "Assert removing an arg works" + ansible.builtin.assert: + that: + - "'--libvirt-type qemu' not in args_override_results.remove" + - "'--timeout 90' in args_override_results.remove" + - "'--deployed-server' in args_override_results.remove" + + - name: "Assert adding an arg appends it" + ansible.builtin.assert: + that: + - "'--libvirt-type kvm' in args_override_results.add" + - "'--libvirt-type qemu' in args_override_results.add" + - "args_override_results.add.endswith('--libvirt-type kvm')" + + - name: "Assert replace pattern (remove + add)" + ansible.builtin.assert: + that: + - "'--libvirt-type qemu' not in args_override_results.replace" + - "'--libvirt-type kvm' in args_override_results.replace" + - "args_override_results.replace.endswith('--libvirt-type kvm')" + - "'--timeout 90' in args_override_results.replace" + + - name: "Assert removing multiple args works" + ansible.builtin.assert: + that: + - "'--libvirt-type qemu' not in args_override_results.remove_multi" + - "'--timeout 90' not in args_override_results.remove_multi" + - "'--deployed-server' in args_override_results.remove_multi" + + - name: "Assert removing non-existent arg is a no-op" + ansible.builtin.assert: + that: + - "args_override_results.remove_noop == args_override_results.default" diff --git a/roles/adoption_osp_deploy/tasks/deploy_overcloud.yml b/roles/adoption_osp_deploy/tasks/deploy_overcloud.yml index 59136b57e0..2635da1ae7 100644 --- a/roles/adoption_osp_deploy/tasks/deploy_overcloud.yml +++ b/roles/adoption_osp_deploy/tasks/deploy_overcloud.yml @@ -38,7 +38,11 @@ _network_data_file_dest: "{{ ansible_user_dir }}/network_data_{{ _overcloud_name }}.yaml" _overcloud_args: >- {{ - _stack.args | join(' ') + ((_stack.args | + reject('in', cifmw_adoption_osp_deploy_stack_args_remove) | + list) + + cifmw_adoption_osp_deploy_stack_args_add) | + join(' ') }} _overcloud_vars: >- {{ diff --git a/roles/adoption_osp_deploy/tasks/validate_scenario.yml b/roles/adoption_osp_deploy/tasks/validate_scenario.yml index 95d5fda8ae..63aff73665 100644 --- a/roles/adoption_osp_deploy/tasks/validate_scenario.yml +++ b/roles/adoption_osp_deploy/tasks/validate_scenario.yml @@ -14,6 +14,19 @@ # License for the specific language governing permissions and limitations # under the License. +- name: Validate stack args override variables + ansible.builtin.assert: + that: + - cifmw_adoption_osp_deploy_stack_args_remove is not string + - cifmw_adoption_osp_deploy_stack_args_remove is not mapping + - cifmw_adoption_osp_deploy_stack_args_remove is iterable + - cifmw_adoption_osp_deploy_stack_args_add is not string + - cifmw_adoption_osp_deploy_stack_args_add is not mapping + - cifmw_adoption_osp_deploy_stack_args_add is iterable + msg: >- + cifmw_adoption_osp_deploy_stack_args_remove and + cifmw_adoption_osp_deploy_stack_args_add must be lists. + - name: Validate scenario format ansible.builtin.assert: that: