Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve idempotency issue in SNMP Server user attribute handling #1014

Merged
merged 9 commits into from
Jan 31, 2024
3 changes: 3 additions & 0 deletions changelogs/fragments/snmp_idempotancy_fix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
bugfixes:
- ios_snmp_server - fixed config issue with snmp user password update being idempotent on consecutive runs.
45 changes: 13 additions & 32 deletions plugins/module_utils/network/ios/config/snmp_server/snmp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,39 +237,20 @@ def _compare(self, want, have):
def _compare_lists_attrs(self, want, have):
"""Compare list of dict"""
for _parser in self.list_parsers:
if _parser == "users":
i_want = want.get(_parser, {})
i_have = have.get(_parser, {})
for key, wanting in iteritems(i_want):
wanting_compare = deepcopy(wanting)
if (
"authentication" in wanting_compare
and "password" in wanting_compare["authentication"]
):
wanting_compare["authentication"].pop("password")
if (
"encryption" in wanting_compare
and "password" in wanting_compare["encryption"]
):
wanting_compare["encryption"].pop("password")
haveing = i_have.pop(key, {})
if wanting_compare != haveing:
if haveing and self.state in ["overridden", "replaced"]:
i_want = want.get(_parser, {})
i_have = have.get(_parser, {})
for key, wanting in iteritems(i_want):
haveing = i_have.pop(key, {})
if wanting != haveing:
if haveing and self.state in ["overridden", "replaced"]:
if not (
_parser == "users"
and wanting.get("username") == haveing.get("username")
):
self.addcmd(haveing, _parser, negate=True)
self.addcmd(wanting, _parser)
for key, haveing in iteritems(i_have):
self.addcmd(haveing, _parser, negate=True)
else:
i_want = want.get(_parser, {})
i_have = have.get(_parser, {})
for key, wanting in iteritems(i_want):
haveing = i_have.pop(key, {})
if wanting != haveing:
if haveing and self.state in ["overridden", "replaced"]:
self.addcmd(haveing, _parser, negate=True)
self.addcmd(wanting, _parser)
for key, haveing in iteritems(i_have):
self.addcmd(haveing, _parser, negate=True)
self.addcmd(wanting, _parser)
for key, haveing in iteritems(i_have):
self.addcmd(haveing, _parser, negate=True)

def _snmp_list_to_dict(self, data):
"""Convert all list of dicts to dicts of dicts"""
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/modules/network/ios/test_ios_snmp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1933,10 +1933,11 @@ def test_ios_snmpv3_user_server_overridden(self):
},
}
overridden = [
"no snmp-server user flow mfamily v3 access 27",
"snmp-server user replaceUser replaceUser v3 auth md5 replaceUser access 22",
"snmp-server user flow mfamily v3 access 27",
"no snmp-server user newuser newfamily v1 access 24",
]

roverflow marked this conversation as resolved.
Show resolved Hide resolved
playbook["state"] = "overridden"
set_module_args(playbook)
result = self.execute_module(changed=True)
Expand Down