You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
If you are interested in working on this issue or have submitted a pull request, please leave a comment
Ansible Version and collection version
cisco.dcnm 3.12.0 (logic present since VerifyPlaybookParams was introduced)
DCNM version
All (validation-logic issue, controller-independent)
VerifyPlaybookParams aggregates three validity sources for each dependency-rule evaluation: playbook config, controller config, and fabric-template defaults (update_decision_set()). For an existing fabric whose dependent parameter is stored as "" on the controller, the three sources interact so that the template default is silently never evaluated:
playbook_param_is_valid() returns None — parameter not in the playbook.
controller_param_is_valid() converts "" to None via make_none() and returns None — "no usable controller value".
default_param_is_valid() early-returns None because the parameter merely exists in config_controller — without checking whether its value is usable:
So the one source that could still decide validity (the template default) is removed from consideration precisely in the case where the controller value was already discarded as empty. All three sources return None, the decision set is empty, and update_decision_set() then treats the empty set as valid:
# If the decision_set is empty, add True.iflen(decision_set) ==0:
decision_set= {True}
Net effect: for updates to existing fabrics, "no evidence at all" is scored as "valid", and the intended fallback to template defaults never actually runs. Validation passes and the module relies on the controller to populate defaults server-side — an assumption that holds on the ND 4.1/4.2 legacy API but is not something the module verifies.
Expected Behavior
default_param_is_valid() should fall through to evaluating the template default when the controller's stored value is empty/unusable (i.e., the same make_none(make_int(make_boolean(...))) conversion used by controller_param_is_valid() yields None), so the decision set reflects the value the controller will actually end up with.
Actual Behavior
Presence of the key in config_controller — even with value "" — removes the template default from consideration; the empty decision set defaults to valid.
Steps to Reproduce
Create a fabric with a minimal config so dependent parameters are stored as "" on the controller.
Run a merged-state update enabling a parent feature (e.g. FEATURE_PTP: true) without its dependent parameters (PTP_DOMAIN_ID, PTP_LB_ID).
Enable debug logging: controller_param_is_valid returns None (empty value), default_param_is_valid returns None (early return, param in controller config), decision set is empty and is set to {True}.
Notes
This is validation hygiene, not the cause of a runtime failure by itself — but it means update-time validation cannot catch missing dependent parameters on any controller that does not fill defaults server-side.
Behavior change warning: tightening this will newly evaluate rules that were previously skipped, and could fail playbooks that pass today. It deserves maintainer discussion (and possibly coupling to skip_validation) before implementation.
Community Note
Ansible Version and collection version
DCNM version
Affected module(s)
plugins/module_utils/fabric/verify_playbook_params.py)Problem
VerifyPlaybookParamsaggregates three validity sources for each dependency-rule evaluation: playbook config, controller config, and fabric-template defaults (update_decision_set()). For an existing fabric whose dependent parameter is stored as""on the controller, the three sources interact so that the template default is silently never evaluated:playbook_param_is_valid()returnsNone— parameter not in the playbook.controller_param_is_valid()converts""toNoneviamake_none()and returnsNone— "no usable controller value".default_param_is_valid()early-returnsNonebecause the parameter merely exists inconfig_controller— without checking whether its value is usable:So the one source that could still decide validity (the template default) is removed from consideration precisely in the case where the controller value was already discarded as empty. All three sources return
None, the decision set is empty, andupdate_decision_set()then treats the empty set as valid:Net effect: for updates to existing fabrics, "no evidence at all" is scored as "valid", and the intended fallback to template defaults never actually runs. Validation passes and the module relies on the controller to populate defaults server-side — an assumption that holds on the ND 4.1/4.2 legacy API but is not something the module verifies.
Expected Behavior
default_param_is_valid()should fall through to evaluating the template default when the controller's stored value is empty/unusable (i.e., the samemake_none(make_int(make_boolean(...)))conversion used bycontroller_param_is_valid()yieldsNone), so the decision set reflects the value the controller will actually end up with.Actual Behavior
Presence of the key in
config_controller— even with value""— removes the template default from consideration; the empty decision set defaults to valid.Steps to Reproduce
""on the controller.FEATURE_PTP: true) without its dependent parameters (PTP_DOMAIN_ID,PTP_LB_ID).controller_param_is_validreturnsNone(empty value),default_param_is_validreturnsNone(early return, param in controller config), decision set is empty and is set to{True}.Notes
skip_validation) before implementation.update.py; this issue is the validation-side counterpart inverify_playbook_params.py. The two are independent — either can land without the other.References