Skip to content

dcnm_policy: KeyError: 'description' on NDFC 12.5 / ND 4.2 — policy GET response no longer includes 'description' field #655

@juburnet

Description

@juburnet

Summary

cisco.dcnm.dcnm_policy crashes with KeyError: 'description' when use_desc_as_key: true and NDFC 12.5 is in use, because NDFC 12.5 no longer includes the description field in policy objects returned by the GET API. The crash is on the self.have dict (the NDFC API response), not the self.want dict.

Affected Version

  • cisco.dcnm collection, develop branch (version 3.11.0-dev)
  • Nexus Dashboard 4.2 / NDFC 12.5

Traceback

File "dcnm_policy.py", line 836, in dcnm_policy_get_diff_merge
File "dcnm_policy.py", line 777, in dcnm_policy_compare_policies
KeyError: 'description'

Root Cause (Verified)

The collection calls dcnm_policy with use_desc_as_key: true. In dcnm_policy_compare_policies():

# Line 769-774: key selection
if policy.get("policyId", None) is not None:
    key = "policyId"
elif self.use_desc_as_key:
    key = "description"   # ← this branch is taken
else:
    key = "templateName"

# Line 776-777: the crash
for have in self.have:
    if (have[key] == policy[key]) and (  # ← have["description"] → KeyError

self.have is populated from the raw NDFC GET API response (dcnm_policy_get_all_policies()). On NDFC 12.5, the policy GET API omits the description field entirely from policy objects. So have["description"] raises KeyError at line 777.

self.want (the policy argument) is NOT the problem — it's built by dcnm_get_policy_payload_with_template_name() which always sets policy_payload["description"] = pelem["description"], and description has a default of "" in the module's argument spec (line 512). So policy["description"] is always present.

Line 790 (policy["description"]) is a secondary issue — it would also crash if policy ever lacked description, but in practice the current code always sets it. Still, have.get("description", None) == policy["description"] is inconsistent style; using .get() on both sides is safer.

Precise Fix

Line 777 — change have[key] to have.get(key, ""):

# Before
if (have[key] == policy[key]) and (

# After
if (have.get(key, "") == policy.get(key, "")) and (

Line 790 — change policy["description"] to policy.get("description", None):

# Before
if have.get("description", None) == policy["description"]:

# After  
if have.get("description", None) == policy.get("description", None):

These changes preserve the existing comparison semantics while tolerating missing description keys in NDFC 12.5 API responses.

Reproduction

  • Fabric type: eBGP_VXLAN
  • Task: cisco.dcnm.dcnm_policy with use_desc_as_key: true, state: merged
  • Trigger condition: Policies already exist on the fabric (non-empty self.have from NDFC GET)
  • NDFC 12.5 GET response omits description key in policy objects → have["description"]KeyError

Environment

  • Nexus Dashboard: 4.2
  • NDFC: 12.5
  • Ansible: 2.16+
  • Python: 3.10
  • cisco.dcnm: develop branch (3.11.0-dev)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions