From f3cb9bd0efeee665e197b545554e64dbb4978516 Mon Sep 17 00:00:00 2001 From: Kaio Oliveira Date: Wed, 14 Oct 2026 17:14:10 -0300 Subject: [PATCH] fix [AAP-92389]: reconcile removed UI placement fields Ensure EDA UI placement is reconciled when configuration is removed from the EDA CR. The UI Deployment was applied from its template, but removed placement values could remain in its PodTemplate. Explicitly compare and reconcile nodeSelector, tolerations, affinity, and topologySpreadConstraints after rendering the UI Deployment. This restores the expected declarative behavior: removing a UI placement setting from the EDA CR removes it from the Deployment and allows the rollout to recover. Assisted-By: GPT 5.6-Terra --- molecule/default/tasks/eda_test.yml | 53 +++++++++++++++++++++++++++++ roles/eda/tasks/deploy_eda.yml | 52 +++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/molecule/default/tasks/eda_test.yml b/molecule/default/tasks/eda_test.yml index 16687c12..2476be96 100644 --- a/molecule/default/tasks/eda_test.yml +++ b/molecule/default/tasks/eda_test.yml @@ -130,3 +130,56 @@ fail_msg: "API Deployment topologySpreadConstraints do not match the CR: {{ _constraints }}" vars: _constraints: "{{ api_deployment.resources[0].spec.template.spec.topologySpreadConstraints }}" + +- name: Add a node selector for the UI pods to the EDA CR + kubernetes.core.k8s: + state: patched + api_version: eda.ansible.com/v1alpha1 + kind: EDA + namespace: '{{ namespace }}' + name: '{{ eda_cr_name }}' + definition: + spec: + ui: + node_selector: + kubernetes.io/os: linux + when: not (ui_disabled | bool) + +- name: Wait for the UI Deployment to pick up the node selector + kubernetes.core.k8s_info: + api_version: apps/v1 + kind: Deployment + namespace: '{{ namespace }}' + name: '{{ eda_cr_name }}-ui' + register: ui_deployment + until: + - ui_deployment.resources | length > 0 + - "ui_deployment.resources[0].spec.template.spec.nodeSelector == {'kubernetes.io/os': 'linux'}" + retries: 30 + delay: 10 + when: not (ui_disabled | bool) + +- name: Remove the UI node selector from the EDA CR + kubernetes.core.k8s_json_patch: + api_version: eda.ansible.com/v1alpha1 + kind: EDA + namespace: '{{ namespace }}' + name: '{{ eda_cr_name }}' + patch: + - op: remove + path: /spec/ui/node_selector/kubernetes.io~1os + when: not (ui_disabled | bool) + +- name: Wait for the UI Deployment to remove the node selector + kubernetes.core.k8s_info: + api_version: apps/v1 + kind: Deployment + namespace: '{{ namespace }}' + name: '{{ eda_cr_name }}-ui' + register: ui_deployment + until: + - ui_deployment.resources | length > 0 + - (ui_deployment.resources[0].spec.template.spec.nodeSelector | default({}, true)) == {} + retries: 30 + delay: 10 + when: not (ui_disabled | bool) diff --git a/roles/eda/tasks/deploy_eda.yml b/roles/eda/tasks/deploy_eda.yml index eef89c73..f42a0ab5 100644 --- a/roles/eda/tasks/deploy_eda.yml +++ b/roles/eda/tasks/deploy_eda.yml @@ -76,13 +76,63 @@ - name: Apply UI deployment resources if UI is enabled k8s: - state: "{{ 'present' if not ui_disabled else 'absent' }}" + apply: yes + state: present + definition: "{{ lookup('template', item + '.yaml.j2') }}" + wait: no + loop: + - 'eda-ui.service' + - 'eda-ui.deployment' + - 'eda-ui.ingress' + when: not ui_disabled + +- name: Read UI deployment placement + kubernetes.core.k8s_info: + api_version: apps/v1 + kind: Deployment + name: "{{ ansible_operator_meta.name }}-ui" + namespace: "{{ ansible_operator_meta.namespace }}" + register: _ui_deployment + when: not ui_disabled + +- name: Reconcile UI deployment placement + kubernetes.core.k8s_json_patch: + api_version: apps/v1 + kind: Deployment + name: "{{ ansible_operator_meta.name }}-ui" + namespace: "{{ ansible_operator_meta.namespace }}" + patch: + - op: add + path: /spec/template/spec/nodeSelector + value: "{{ combined_ui.node_selector }}" + - op: add + path: /spec/template/spec/tolerations + value: "{{ combined_ui.tolerations }}" + - op: add + path: /spec/template/spec/affinity + value: "{{ combined_ui.affinity }}" + - op: add + path: /spec/template/spec/topologySpreadConstraints + value: "{{ combined_ui.topology_spread_constraints | default([]) }}" + when: + - not ui_disabled + - _ui_deployment.resources | length > 0 + - >- + (_ui_deployment.resources[0].spec.template.spec.nodeSelector | default({}, true)) != combined_ui.node_selector + or (_ui_deployment.resources[0].spec.template.spec.tolerations | default([], true)) != combined_ui.tolerations + or (_ui_deployment.resources[0].spec.template.spec.affinity | default({}, true)) != combined_ui.affinity + or (_ui_deployment.resources[0].spec.template.spec.topologySpreadConstraints | default([], true)) != (combined_ui.topology_spread_constraints | default([])) + +- name: Remove UI deployment resources if UI is disabled + k8s: + state: absent definition: "{{ lookup('template', item + '.yaml.j2') }}" wait: no loop: - 'eda-ui.service' - 'eda-ui.deployment' - 'eda-ui.ingress' + when: ui_disabled - name: Apply API Route or Ingress if UI is disabled k8s: