-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Collection: cisco.nd
Version: 1.4.0
Module: nd_rest
Environment:
Python: 3.10.4
Ansible: 2.17.6
cisco.nd: 1.4.0
OS: macOS 15.3 (Darwin 25.3.0 arm64)
NDFC Version: 4.1.1 (Nexus Dashboard Fabric Controller)
Problem Summary:
The nd_rest module crashes with a TypeError when the NDFC API returns an empty/null response body on a successful POST request. This happens with certain NDFC endpoints that return HTTP 200 with no body, such as the VPC pair creation endpoint.
Steps to repro:
- name: Create VPC pair
cisco.nd.nd_rest:
host: "{{ ansible_host }}"
username: "{{ ansible_user }}"
password: "{{ ansible_password }}"
use_ssl: true
validate_certs: false
login_domain: local
path: /appcenter/cisco/ndfc/api/v1/lan-fabric/rest/vpcpair
method: POST
content: |
{
"useVirtualPeerLink": false,
"peerOneId": "SERIAL1",
"peerTwoId": "SERIAL2",
"templateName": "vpc_pair",
"nvPairs": { ... }
}
Expected Behavior
Module completes successfully and reports changed: true when VPC pair is created.
Actual Behavior:
TypeError: object to sanitize can only be of type list or dict. Got <class 'NoneType'>
Traceback:
File ".../cisco/nd/plugins/modules/nd_rest.py", line 262, in main
File ".../cisco/nd/plugins/module_utils/nd.py", line 66, in sanitize
TypeError: object to sanitize can only be of type list or dict. Got <class 'NoneType'>
Note: The API call itself succeeds — the VPC pair is created in NDFC. The error occurs when the module tries to parse the response.
The sanitize() function in plugins/module_utils/nd.py (line 55-66) only accepts list or dict:
def sanitize(obj_to_sanitize, keys=None, values=None, recursive=True, remove_none_values=True):
if isinstance(obj_to_sanitize, dict):
return sanitize_dict(...)
elif isinstance(obj_to_sanitize, list):
return sanitize_list(...)
else:
raise TypeError("object to sanitize can only be of type list or dict. Got {}".format(type(obj_to_sanitize)))
Possible fix to handle None gracefully:
def sanitize(obj_to_sanitize, keys=None, values=None, recursive=True, remove_none_values=True):
"""Clean up a Python object of type list or dict from specific keys, values and None values if specified"""
if obj_to_sanitize is None:
return {} # or return None, depending on desired behavior
if isinstance(obj_to_sanitize, dict):
return sanitize_dict(obj_to_sanitize, keys, values, recursive, remove_none_values)
elif isinstance(obj_to_sanitize, list):
return sanitize_list(obj_to_sanitize, keys, values, recursive, recursive, remove_none_values)
else:
raise TypeError("object to sanitize can only be of type list or dict. Got {}".format(type(obj_to_sanitize)))