From 71ecd8450fdbc9d83e061ccf82c4f51cb17ecc55 Mon Sep 17 00:00:00 2001 From: Sagar Paul Date: Wed, 27 Mar 2024 10:30:49 +0530 Subject: [PATCH 1/3] [ios_acls] add fix to standalone remarks (#1044) * add fix to standalone remarks * fix comment * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update tests and config code * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * changelog * Update doc * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- changelogs/fragments/acl_refactor.yaml | 3 + docs/cisco.ios.ios_acls_module.rst | 343 +++++++++++++++++ .../network/ios/config/acls/acls.py | 128 +++---- .../network/ios/facts/acls/acls.py | 55 ++- .../network/ios/rm_templates/acls.py | 6 +- plugins/modules/ios_acls.py | 346 ++++++++++++++++++ .../ios_acls/tests/cli/remarks_states.yaml | 133 +++++++ .../targets/ios_acls/vars/main.yaml | 285 +++++++++++++++ .../unit/modules/network/ios/test_ios_acls.py | 279 +++++++++++--- 9 files changed, 1453 insertions(+), 125 deletions(-) create mode 100644 changelogs/fragments/acl_refactor.yaml create mode 100644 tests/integration/targets/ios_acls/tests/cli/remarks_states.yaml diff --git a/changelogs/fragments/acl_refactor.yaml b/changelogs/fragments/acl_refactor.yaml new file mode 100644 index 000000000..9dc1cd7b1 --- /dev/null +++ b/changelogs/fragments/acl_refactor.yaml @@ -0,0 +1,3 @@ +--- +bugfixes: + - ios_acls - update module to apply remarks entry with sequence numbers. diff --git a/docs/cisco.ios.ios_acls_module.rst b/docs/cisco.ios.ios_acls_module.rst index a76156dd6..bb0328d87 100644 --- a/docs/cisco.ios.ios_acls_module.rst +++ b/docs/cisco.ios.ios_acls_module.rst @@ -3145,6 +3145,8 @@ Parameters
The remarks/description of the ACL.
The remarks attribute used within an ace with or without a sequence number will produce remarks that are pushed before the ace entry.
Remarks entry used as the only key in as the list option will produce non ace specific remarks, these remarks would be pushed at the end of all the aces for an acl.
+
Remarks is treated a block, for every single remarks updated for an ace all the remarks are negated and added back to maintain the order of remarks mentioned.
+
As the appliance deletes all the remarks once the ace is updated, the set of remarks would be re-applied that is an expected behavior.
@@ -5195,6 +5197,347 @@ Examples # ip access-list extended 150 # 10 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10 + # Using overridden - example remarks specific on multiple sequence + + # Before state: + # ------------- + # + # vios#show running-config | section access-list + # ip access-list extended TEST + # 10 remark FIRST REMARK BEFORE SEQUENCE 10 + # 10 remark ============ + # 10 remark REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE + # 20 remark FIRST REMARK BEFORE SEQUENCE 20 + # 20 remark ============ + # 20 remark ALLOW HOST FROM SEQUENCE 20 + # 20 permit ip host 1.1.1.1 any + # 30 remark FIRST REMARK BEFORE SEQUENCE 30 + # 30 remark ============ + # 30 remark ALLOW HOST FROM SEQUENCE 30 + # 30 permit ip host 2.2.2.2 any + # 40 remark FIRST REMARK BEFORE SEQUENCE 40 + # 40 remark ============ + # 40 remark ALLOW NEW HOST FROM SEQUENCE 40 + # 40 permit ip host 3.3.3.3 any + # remark Remark not specific to sequence + # remark ============ + # remark End Remarks + # ip access-list extended test_acl + # 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 + # ip access-list extended 110 + # 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10 + # ip access-list extended 123 + # 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 + # 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 + # ipv6 access-list R1_TRAFFIC + # sequence 10 deny tcp any eq www any eq telnet ack dscp af11 + + - name: Override remarks and ace configurations + cisco.ios.ios_acls: + config: + - afi: ipv4 + acls: + - name: TEST + acl_type: extended + aces: + - sequence: 10 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 10" + - "============" + - "REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE" + grant: permit + protocol: ip + source: + host: 1.1.1.1 + destination: + any: true + - sequence: 20 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 20" + - "============" + - "ALLOW HOST FROM SEQUENCE 20" + grant: permit + protocol: ip + source: + host: 192.168.0.1 + destination: + any: true + - sequence: 30 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 30" + - "============" + - "ALLOW HOST FROM SEQUENCE 30 updated" + grant: permit + protocol: ip + source: + host: 2.2.2.2 + destination: + any: true + - sequence: 40 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 40" + - "============" + - "ALLOW NEW HOST FROM SEQUENCE 40" + grant: permit + protocol: ip + source: + host: 3.3.3.3 + destination: + any: true + - remarks: + - "Remark not specific to sequence" + - "============" + - "End Remarks 1" + state: overridden + + # Task Output + # ----------- + # + # before: + # - acls: + # - aces: + # - destination: + # address: 192.0.3.0 + # wildcard_bits: 0.0.0.255 + # dscp: ef + # grant: deny + # protocol: icmp + # protocol_options: + # icmp: + # echo: true + # sequence: 10 + # source: + # address: 192.0.2.0 + # wildcard_bits: 0.0.0.255 + # ttl: + # eq: 10 + # acl_type: extended + # name: '110' + # - aces: + # - destination: + # address: 198.51.101.0 + # port_protocol: + # eq: telnet + # wildcard_bits: 0.0.0.255 + # grant: deny + # protocol: tcp + # protocol_options: + # tcp: + # ack: true + # sequence: 10 + # source: + # address: 198.51.100.0 + # wildcard_bits: 0.0.0.255 + # tos: + # service_value: 12 + # - destination: + # address: 192.0.4.0 + # port_protocol: + # eq: www + # wildcard_bits: 0.0.0.255 + # dscp: ef + # grant: deny + # protocol: tcp + # protocol_options: + # tcp: + # ack: true + # sequence: 20 + # source: + # address: 192.0.3.0 + # wildcard_bits: 0.0.0.255 + # ttl: + # lt: 20 + # acl_type: extended + # name: '123' + # - aces: + # - destination: + # any: true + # grant: permit + # protocol: ip + # remarks: + # - FIRST REMARK BEFORE SEQUENCE 20 + # - ============ + # - ALLOW HOST FROM SEQUENCE 20 + # sequence: 20 + # source: + # host: 1.1.1.1 + # - destination: + # any: true + # grant: permit + # protocol: ip + # remarks: + # - FIRST REMARK BEFORE SEQUENCE 30 + # - ============ + # - ALLOW HOST FROM SEQUENCE 30 + # sequence: 30 + # source: + # host: 2.2.2.2 + # - destination: + # any: true + # grant: permit + # protocol: ip + # remarks: + # - FIRST REMARK BEFORE SEQUENCE 40 + # - ============ + # - ALLOW NEW HOST FROM SEQUENCE 40 + # sequence: 40 + # source: + # host: 3.3.3.3 + # - remarks: + # - FIRST REMARK BEFORE SEQUENCE 10 + # - ============ + # - REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE + # sequence: 10 + # - remarks: + # - Remark not specific to sequence + # - ============ + # - End Remarks + # acl_type: extended + # name: TEST + # - aces: + # - destination: + # address: 192.0.3.0 + # port_protocol: + # eq: www + # wildcard_bits: 0.0.0.255 + # grant: deny + # option: + # traceroute: true + # protocol: tcp + # protocol_options: + # tcp: + # fin: true + # sequence: 10 + # source: + # address: 192.0.2.0 + # wildcard_bits: 0.0.0.255 + # ttl: + # eq: 10 + # acl_type: extended + # name: test_acl + # afi: ipv4 + # - acls: + # - aces: + # - destination: + # any: true + # port_protocol: + # eq: telnet + # dscp: af11 + # grant: deny + # protocol: tcp + # protocol_options: + # tcp: + # ack: true + # sequence: 10 + # source: + # any: true + # port_protocol: + # eq: www + # name: R1_TRAFFIC + # afi: ipv6 + # commands: + # - no ipv6 access-list R1_TRAFFIC + # - ip access-list extended TEST + # - no 10 # removes all remarks and ace entry for sequence 10 + # - no 20 permit ip host 1.1.1.1 any # removing the ace automatically removes the remarks + # - no 30 remark # just remove remarks for sequence 30 + # - no remark # remove all remarks at end of acl, that has no sequence + # - 10 remark FIRST REMARK BEFORE SEQUENCE 10 + # - 10 remark ============ + # - 10 remark REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE + # - 10 permit ip host 1.1.1.1 any + # - 20 remark FIRST REMARK BEFORE SEQUENCE 20 + # - 20 remark ============ + # - 20 remark ALLOW HOST FROM SEQUENCE 20 + # - 20 permit ip host 192.168.0.1 any + # - 30 remark FIRST REMARK BEFORE SEQUENCE 30 + # - 30 remark ============ + # - 30 remark ALLOW HOST FROM SEQUENCE 30 updated + # - remark Remark not specific to sequence + # - remark ============ + # - remark End Remarks 1 + # - no ip access-list extended 110 + # - no ip access-list extended 123 + # - no ip access-list extended test_acl + # after: + # - acls: + # - aces: + # - destination: + # any: true + # grant: permit + # protocol: ip + # remarks: + # - FIRST REMARK BEFORE SEQUENCE 10 + # - ============ + # - REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE + # sequence: 10 + # source: + # host: 1.1.1.1 + # - destination: + # any: true + # grant: permit + # protocol: ip + # remarks: + # - FIRST REMARK BEFORE SEQUENCE 20 + # - ============ + # - ALLOW HOST FROM SEQUENCE 20 + # sequence: 20 + # source: + # host: 192.168.0.1 + # - destination: + # any: true + # grant: permit + # protocol: ip + # remarks: + # - FIRST REMARK BEFORE SEQUENCE 30 + # - ============ + # - ALLOW HOST FROM SEQUENCE 30 updated + # sequence: 30 + # source: + # host: 2.2.2.2 + # - destination: + # any: true + # grant: permit + # protocol: ip + # remarks: + # - FIRST REMARK BEFORE SEQUENCE 40 + # - ============ + # - ALLOW NEW HOST FROM SEQUENCE 40 + # sequence: 40 + # source: + # host: 3.3.3.3 + # - remarks: + # - Remark not specific to sequence + # - ============ + # - End Remarks 1 + # acl_type: extended + # name: TEST + # afi: ipv4 + + # After state: + # ------------- + # + # foo#show running-config | section access-list + # ip access-list extended TEST + # 10 remark FIRST REMARK BEFORE SEQUENCE 10 + # 10 remark ============ + # 10 remark REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE + # 10 permit ip host 1.1.1.1 any + # 20 remark FIRST REMARK BEFORE SEQUENCE 20 + # 20 remark ============ + # 20 remark ALLOW HOST FROM SEQUENCE 20 + # 20 permit ip host 192.168.0.1 any + # 30 remark FIRST REMARK BEFORE SEQUENCE 30 + # 30 remark ============ + # 30 remark ALLOW HOST FROM SEQUENCE 30 updated + # 30 permit ip host 2.2.2.2 any + # 40 remark FIRST REMARK BEFORE SEQUENCE 40 + # 40 remark ============ + # 40 remark ALLOW NEW HOST FROM SEQUENCE 40 + # 40 permit ip host 3.3.3.3 any + # remark Remark not specific to sequence + # remark ============ + # remark End Remarks 1 # Using deleted - delete ACL(s) diff --git a/plugins/module_utils/network/ios/config/acls/acls.py b/plugins/module_utils/network/ios/config/acls/acls.py index 7e784ebb1..3eb30b73a 100644 --- a/plugins/module_utils/network/ios/config/acls/acls.py +++ b/plugins/module_utils/network/ios/config/acls/acls.py @@ -169,20 +169,22 @@ def pop_remark(r_entry, afi): else: return {} + # case 1 - loop on want and compare with have data here for wseq, wentry in iteritems(want): hentry = have.pop(wseq, {}) rem_hentry, rem_wentry = {}, {} - if hentry: + if hentry: # if there is have information with same sequence + # the protocol options are processed here hentry = self.sanitize_protocol_options(wentry, hentry) - if hentry != wentry: # will let in if ace is same but remarks is not same - if hentry: + if hentry != wentry: # if want and have is different + if hentry: # separate remarks from have in an ace entry rem_hentry["remarks"] = pop_remark(hentry, afi) - if wentry: + if wentry: # separate remarks from want in an ace entry rem_wentry["remarks"] = pop_remark(wentry, afi) - if hentry: + if hentry: # have aces processing starts here if self.state == "merged": self._module.fail_json( msg="Cannot update existing sequence {0} of ACLs {1} with state merged." @@ -190,80 +192,78 @@ def pop_remark(r_entry, afi): hentry.get("sequence", ""), name, ), - ) - else: # other action states - if rem_hentry.get("remarks"): # remove remark if not in want - for k_hrems, hrems in rem_hentry.get("remarks").items(): - if k_hrems not in rem_wentry.get("remarks", {}).keys(): - if self.state in ["replaced", "overridden"]: - self.addcmd( - { - "remarks": hrems, - "sequence": hentry.get("sequence", ""), - }, - "remarks_no_data", - negate=True, - ) - break - else: - self.addcmd( - { - "remarks": hrems, - "sequence": hentry.get("sequence", ""), - }, - "remarks", - negate=True, - ) - # remove ace if not in want - # we might think why not update it directly, - # if we try to update without negating the entry appliance - # reports % Duplicate sequence number - if hentry != wentry: - self.addcmd(add_afi(hentry, afi), "aces", negate=True) - # once an ace is negated intentionally emptying out have so that - # the remarks are repopulated, as the remarks and ace behavior is sticky - # if an ace is taken out all the remarks is removed automatically. - rem_hentry["remarks"] = {} + ) # if merged then don't update anything and fail + + # i.e if not merged + if rem_hentry.get("remarks") != rem_wentry.get("remarks"): + self.addcmd( + { + "sequence": hentry.get("sequence", None), + }, + "remarks_no_data", + negate=True, + ) # remove all remarks for a ace if want and have don't match + # as if we randomly add aces we cannot maintain order we have to + # add all of them again, for that ace + rem_hentry["remarks"] = {} + # and me empty our have as we would add back + # all our remarks for that ace anyways + + # remove ace if not in want + # we might think why not update it directly, + # if we try to update without negating the entry appliance + # reports % Duplicate sequence number + if hentry != wentry: + self.addcmd(add_afi(hentry, afi), "aces", negate=True) + # once an ace is negated intentionally emptying out have so that + # the remarks are repopulated, as the remarks and ace behavior is sticky + # if an ace is taken out all the remarks is removed automatically. + rem_hentry["remarks"] = {} if rem_wentry.get("remarks"): # add remark if not in have + if rem_hentry.get("remarks"): + self.addcmd( + { + "sequence": hentry.get("sequence", None), + }, + "remarks_no_data", + negate=True, + ) # but delete all remarks before to protect order for k_wrems, wrems in rem_wentry.get("remarks").items(): - if k_wrems not in rem_hentry.get("remarks", {}).keys(): - self.addcmd( - { - "remarks": wrems, - "sequence": hentry.get("sequence", ""), - }, - "remarks", - ) - else: - rem_hentry.get("remarks", {}).pop(k_wrems) - # We remove remarks that are not in the wentry for this ACE - for k_hrems, hrems in rem_hentry.get("remarks", {}).items(): self.addcmd( - {"remarks": hrems, "sequence": hentry.get("sequence", "")}, + { + "remarks": wrems, + "sequence": wentry.get("sequence", ""), + }, "remarks", - negate=True, ) # add ace if not in have if hentry != wentry: - self.addcmd(add_afi(wentry, afi), "aces") - - # remove remaining entries from have aces list + if len(wentry) == 1 and wentry.get( + "sequence", + ): # if the ace entry just has sequence then do nothing + continue + else: # add normal ace entries from want + self.addcmd(add_afi(wentry, afi), "aces") + + # case 2 - loop over remaining have and remove them for hseq in have.values(): - if hseq.get("remarks"): # remove remarks that are extra in have - for krems, rems in hseq.get("remarks").items(): - self.addcmd( - {"remarks": rems, "sequence": hseq.get("sequence", "")}, - "remarks", - negate=True, - ) + if hseq.get("remarks"): # remove all remarks in that + self.addcmd( + { + "sequence": hseq.get("sequence", None), + }, + "remarks_no_data", + negate=True, + ) hseq.pop("remarks") + # deal with the rest of ace entry self.addcmd( add_afi(hseq, afi), "aces", negate=True, - ) # deal with the rest of ace entry + ) def sanitize_protocol_options(self, wace, hace): """handles protocol and protocol options as optional attribute""" diff --git a/plugins/module_utils/network/ios/facts/acls/acls.py b/plugins/module_utils/network/ios/facts/acls/acls.py index 2be369a7a..341491f2e 100644 --- a/plugins/module_utils/network/ios/facts/acls/acls.py +++ b/plugins/module_utils/network/ios/facts/acls/acls.py @@ -105,7 +105,10 @@ def populate_facts(self, connection, ansible_facts, data=None): if namedata: # parse just names to update empty acls - templateObjName = NetworkTemplate(lines=namedata.splitlines(), tmplt=AclsTemplate()) + templateObjName = NetworkTemplate( + lines=namedata.splitlines(), + tmplt=AclsTemplate(), + ) raw_acl_names = templateObjName.parse() raw_acls = self.populate_empty_acls(raw_acls, raw_acl_names) @@ -114,7 +117,10 @@ def populate_facts(self, connection, ansible_facts, data=None): if raw_acls.get("acls"): for k, v in iteritems(raw_acls.get("acls")): - if v.get("afi") == "ipv4" and v.get("acl_type") in ["standard", "extended"]: + if v.get("afi") == "ipv4" and v.get("acl_type") in [ + "standard", + "extended", + ]: del v["afi"] temp_v4.append(v) elif v.get("afi") == "ipv6": @@ -142,10 +148,15 @@ def factor_source_dest(ace, typ): def process_protocol_options(each): for each_ace in each.get("aces"): if each.get("acl_type") == "standard": - if len(each_ace.get("source", {})) == 1 and each_ace.get("source", {}).get( + if len(each_ace.get("source", {})) == 1 and each_ace.get( + "source", + {}, + ).get( "address", ): - each_ace["source"]["host"] = each_ace["source"].pop("address") + each_ace["source"]["host"] = each_ace["source"].pop( + "address", + ) if each_ace.get("source", {}).get("address"): addr = each_ace.get("source", {}).get("address") if addr[-1] == ",": @@ -159,7 +170,10 @@ def process_protocol_options(each): if each_ace.get("icmp_igmp_tcp_protocol"): each_ace["protocol_options"] = { each_ace["protocol"]: { - each_ace.pop("icmp_igmp_tcp_protocol").replace("-", "_"): True, + each_ace.pop("icmp_igmp_tcp_protocol").replace( + "-", + "_", + ): True, }, } if each_ace.get("protocol_number"): @@ -172,13 +186,21 @@ def collect_remarks(aces): ace_entry = [] ace_rem = [] rem = {} + # every remarks is one list item which has a sequence number + # every ace remark is preserved and ordered + # at the end of each sequence it is flushed to a ace entry for i in aces: + # i here denotes an ace, which would be populated with remarks entries if i.get("is_remark_for"): if not rem.get(i.get("is_remark_for")): rem[i.get("is_remark_for")] = {"remarks": []} - rem[i.get("is_remark_for")]["remarks"].append(i.get("the_remark")) + rem[i.get("is_remark_for")]["remarks"].append( + i.get("the_remark"), + ) else: - rem[i.get("is_remark_for")]["remarks"].append(i.get("the_remark")) + rem[i.get("is_remark_for")]["remarks"].append( + i.get("the_remark"), + ) else: if rem: if rem.get(i.get("sequence")): @@ -187,12 +209,27 @@ def collect_remarks(aces): ace_entry.append(i) if rem: # pending remarks - pending_rem = rem.get("remark") - ace_entry.append({"remarks": pending_rem.get("remarks")}) + for pending_rem_seq, pending_rem_val in rem.items(): + # there can be ace entry with just a remarks and no ace actually + # 10 remarks I am a remarks + # 20 ..... so onn + if pending_rem_seq != "remark": + ace_entry.append( + { + "sequence": pending_rem_seq, + "remarks": pending_rem_val.get("remarks"), + }, + ) + else: + # this handles the classic set of remarks at the end, which is not tied to + # any sequence number + pending_rem = rem.get("remark", {}) + ace_entry.append({"remarks": pending_rem.get("remarks")}) return ace_entry for each in temp_v4: if each.get("aces"): + # handling remarks for each ace entry each["aces"] = collect_remarks(each.get("aces")) process_protocol_options(each) diff --git a/plugins/module_utils/network/ios/rm_templates/acls.py b/plugins/module_utils/network/ios/rm_templates/acls.py index 819961e0d..8ccaec0e8 100644 --- a/plugins/module_utils/network/ios/rm_templates/acls.py +++ b/plugins/module_utils/network/ios/rm_templates/acls.py @@ -23,9 +23,9 @@ def remarks_with_sequence(remarks_data): - cmd = "remark " + cmd = "remark" if remarks_data.get("remarks"): - cmd += remarks_data.get("remarks") + cmd += " " + remarks_data.get("remarks") if remarks_data.get("sequence"): cmd = to_text(remarks_data.get("sequence")) + " " + cmd return cmd @@ -206,7 +206,7 @@ def __init__(self, lines=None): r"""(?P^\d+)\s*remark\s(?P.+)$""", re.VERBOSE, ), - "setval": "{{ sequence }} remark", + "setval": remarks_with_sequence, "result": { "acls": { "{{ acl_name|d() }}": { diff --git a/plugins/modules/ios_acls.py b/plugins/modules/ios_acls.py index f81e0e7ab..4636ecb5d 100644 --- a/plugins/modules/ios_acls.py +++ b/plugins/modules/ios_acls.py @@ -471,6 +471,11 @@ - Remarks entry used as the only key in as the list option will produce non ace specific remarks, these remarks would be pushed at the end of all the aces for an acl. + - Remarks is treated a block, for every single remarks updated for + an ace all the remarks are negated and added back to maintain the + order of remarks mentioned. + - As the appliance deletes all the remarks once the ace is updated, + the set of remarks would be re-applied that is an expected behavior. elements: str type: list sequence: @@ -1944,6 +1949,347 @@ # ip access-list extended 150 # 10 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10 +# Using overridden - example remarks specific on multiple sequence + +# Before state: +# ------------- +# +# vios#show running-config | section access-list +# ip access-list extended TEST +# 10 remark FIRST REMARK BEFORE SEQUENCE 10 +# 10 remark ============ +# 10 remark REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE +# 20 remark FIRST REMARK BEFORE SEQUENCE 20 +# 20 remark ============ +# 20 remark ALLOW HOST FROM SEQUENCE 20 +# 20 permit ip host 1.1.1.1 any +# 30 remark FIRST REMARK BEFORE SEQUENCE 30 +# 30 remark ============ +# 30 remark ALLOW HOST FROM SEQUENCE 30 +# 30 permit ip host 2.2.2.2 any +# 40 remark FIRST REMARK BEFORE SEQUENCE 40 +# 40 remark ============ +# 40 remark ALLOW NEW HOST FROM SEQUENCE 40 +# 40 permit ip host 3.3.3.3 any +# remark Remark not specific to sequence +# remark ============ +# remark End Remarks +# ip access-list extended test_acl +# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 +# ip access-list extended 110 +# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10 +# ip access-list extended 123 +# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 +# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 +# ipv6 access-list R1_TRAFFIC +# sequence 10 deny tcp any eq www any eq telnet ack dscp af11 + +- name: Override remarks and ace configurations + cisco.ios.ios_acls: + config: + - afi: ipv4 + acls: + - name: TEST + acl_type: extended + aces: + - sequence: 10 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 10" + - "============" + - "REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE" + grant: permit + protocol: ip + source: + host: 1.1.1.1 + destination: + any: true + - sequence: 20 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 20" + - "============" + - "ALLOW HOST FROM SEQUENCE 20" + grant: permit + protocol: ip + source: + host: 192.168.0.1 + destination: + any: true + - sequence: 30 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 30" + - "============" + - "ALLOW HOST FROM SEQUENCE 30 updated" + grant: permit + protocol: ip + source: + host: 2.2.2.2 + destination: + any: true + - sequence: 40 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 40" + - "============" + - "ALLOW NEW HOST FROM SEQUENCE 40" + grant: permit + protocol: ip + source: + host: 3.3.3.3 + destination: + any: true + - remarks: + - "Remark not specific to sequence" + - "============" + - "End Remarks 1" + state: overridden + +# Task Output +# ----------- +# +# before: +# - acls: +# - aces: +# - destination: +# address: 192.0.3.0 +# wildcard_bits: 0.0.0.255 +# dscp: ef +# grant: deny +# protocol: icmp +# protocol_options: +# icmp: +# echo: true +# sequence: 10 +# source: +# address: 192.0.2.0 +# wildcard_bits: 0.0.0.255 +# ttl: +# eq: 10 +# acl_type: extended +# name: '110' +# - aces: +# - destination: +# address: 198.51.101.0 +# port_protocol: +# eq: telnet +# wildcard_bits: 0.0.0.255 +# grant: deny +# protocol: tcp +# protocol_options: +# tcp: +# ack: true +# sequence: 10 +# source: +# address: 198.51.100.0 +# wildcard_bits: 0.0.0.255 +# tos: +# service_value: 12 +# - destination: +# address: 192.0.4.0 +# port_protocol: +# eq: www +# wildcard_bits: 0.0.0.255 +# dscp: ef +# grant: deny +# protocol: tcp +# protocol_options: +# tcp: +# ack: true +# sequence: 20 +# source: +# address: 192.0.3.0 +# wildcard_bits: 0.0.0.255 +# ttl: +# lt: 20 +# acl_type: extended +# name: '123' +# - aces: +# - destination: +# any: true +# grant: permit +# protocol: ip +# remarks: +# - FIRST REMARK BEFORE SEQUENCE 20 +# - ============ +# - ALLOW HOST FROM SEQUENCE 20 +# sequence: 20 +# source: +# host: 1.1.1.1 +# - destination: +# any: true +# grant: permit +# protocol: ip +# remarks: +# - FIRST REMARK BEFORE SEQUENCE 30 +# - ============ +# - ALLOW HOST FROM SEQUENCE 30 +# sequence: 30 +# source: +# host: 2.2.2.2 +# - destination: +# any: true +# grant: permit +# protocol: ip +# remarks: +# - FIRST REMARK BEFORE SEQUENCE 40 +# - ============ +# - ALLOW NEW HOST FROM SEQUENCE 40 +# sequence: 40 +# source: +# host: 3.3.3.3 +# - remarks: +# - FIRST REMARK BEFORE SEQUENCE 10 +# - ============ +# - REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE +# sequence: 10 +# - remarks: +# - Remark not specific to sequence +# - ============ +# - End Remarks +# acl_type: extended +# name: TEST +# - aces: +# - destination: +# address: 192.0.3.0 +# port_protocol: +# eq: www +# wildcard_bits: 0.0.0.255 +# grant: deny +# option: +# traceroute: true +# protocol: tcp +# protocol_options: +# tcp: +# fin: true +# sequence: 10 +# source: +# address: 192.0.2.0 +# wildcard_bits: 0.0.0.255 +# ttl: +# eq: 10 +# acl_type: extended +# name: test_acl +# afi: ipv4 +# - acls: +# - aces: +# - destination: +# any: true +# port_protocol: +# eq: telnet +# dscp: af11 +# grant: deny +# protocol: tcp +# protocol_options: +# tcp: +# ack: true +# sequence: 10 +# source: +# any: true +# port_protocol: +# eq: www +# name: R1_TRAFFIC +# afi: ipv6 +# commands: +# - no ipv6 access-list R1_TRAFFIC +# - ip access-list extended TEST +# - no 10 # removes all remarks and ace entry for sequence 10 +# - no 20 permit ip host 1.1.1.1 any # removing the ace automatically removes the remarks +# - no 30 remark # just remove remarks for sequence 30 +# - no remark # remove all remarks at end of acl, that has no sequence +# - 10 remark FIRST REMARK BEFORE SEQUENCE 10 +# - 10 remark ============ +# - 10 remark REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE +# - 10 permit ip host 1.1.1.1 any +# - 20 remark FIRST REMARK BEFORE SEQUENCE 20 +# - 20 remark ============ +# - 20 remark ALLOW HOST FROM SEQUENCE 20 +# - 20 permit ip host 192.168.0.1 any +# - 30 remark FIRST REMARK BEFORE SEQUENCE 30 +# - 30 remark ============ +# - 30 remark ALLOW HOST FROM SEQUENCE 30 updated +# - remark Remark not specific to sequence +# - remark ============ +# - remark End Remarks 1 +# - no ip access-list extended 110 +# - no ip access-list extended 123 +# - no ip access-list extended test_acl +# after: +# - acls: +# - aces: +# - destination: +# any: true +# grant: permit +# protocol: ip +# remarks: +# - FIRST REMARK BEFORE SEQUENCE 10 +# - ============ +# - REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE +# sequence: 10 +# source: +# host: 1.1.1.1 +# - destination: +# any: true +# grant: permit +# protocol: ip +# remarks: +# - FIRST REMARK BEFORE SEQUENCE 20 +# - ============ +# - ALLOW HOST FROM SEQUENCE 20 +# sequence: 20 +# source: +# host: 192.168.0.1 +# - destination: +# any: true +# grant: permit +# protocol: ip +# remarks: +# - FIRST REMARK BEFORE SEQUENCE 30 +# - ============ +# - ALLOW HOST FROM SEQUENCE 30 updated +# sequence: 30 +# source: +# host: 2.2.2.2 +# - destination: +# any: true +# grant: permit +# protocol: ip +# remarks: +# - FIRST REMARK BEFORE SEQUENCE 40 +# - ============ +# - ALLOW NEW HOST FROM SEQUENCE 40 +# sequence: 40 +# source: +# host: 3.3.3.3 +# - remarks: +# - Remark not specific to sequence +# - ============ +# - End Remarks 1 +# acl_type: extended +# name: TEST +# afi: ipv4 + +# After state: +# ------------- +# +# foo#show running-config | section access-list +# ip access-list extended TEST +# 10 remark FIRST REMARK BEFORE SEQUENCE 10 +# 10 remark ============ +# 10 remark REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE +# 10 permit ip host 1.1.1.1 any +# 20 remark FIRST REMARK BEFORE SEQUENCE 20 +# 20 remark ============ +# 20 remark ALLOW HOST FROM SEQUENCE 20 +# 20 permit ip host 192.168.0.1 any +# 30 remark FIRST REMARK BEFORE SEQUENCE 30 +# 30 remark ============ +# 30 remark ALLOW HOST FROM SEQUENCE 30 updated +# 30 permit ip host 2.2.2.2 any +# 40 remark FIRST REMARK BEFORE SEQUENCE 40 +# 40 remark ============ +# 40 remark ALLOW NEW HOST FROM SEQUENCE 40 +# 40 permit ip host 3.3.3.3 any +# remark Remark not specific to sequence +# remark ============ +# remark End Remarks 1 # Using deleted - delete ACL(s) diff --git a/tests/integration/targets/ios_acls/tests/cli/remarks_states.yaml b/tests/integration/targets/ios_acls/tests/cli/remarks_states.yaml new file mode 100644 index 000000000..68fd361bd --- /dev/null +++ b/tests/integration/targets/ios_acls/tests/cli/remarks_states.yaml @@ -0,0 +1,133 @@ +--- +- ansible.builtin.debug: + msg: START ios_acls round trip integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Apply the configuration with remarks + register: base_config + cisco.ios.ios_acls: + config: + - afi: ipv4 + acls: + - name: TEST + acl_type: extended + aces: + - sequence: 10 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 10" + - "============" + - "REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE" + - sequence: 20 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 20" + - "============" + - "ALLOW HOST FROM SEQUENCE 20" + grant: permit + protocol: ip + source: + host: 1.1.1.1 + destination: + any: true + - sequence: 30 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 30" + - "============" + - "ALLOW HOST FROM SEQUENCE 30" + grant: permit + protocol: ip + source: + host: 2.2.2.2 + destination: + any: true + - sequence: 40 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 40" + - "============" + - "ALLOW NEW HOST FROM SEQUENCE 40" + grant: permit + protocol: ip + source: + host: 3.3.3.3 + destination: + any: true + - remarks: + - "Remark not specific to sequence" + - "============" + - "End Remarks" + state: merged + + - ansible.builtin.assert: + that: + - base_config.changed == true + - base_config.commands|symmetric_difference(remarks_check.commands) == [] + - base_config.before|symmetric_difference(remarks_check.before) == [] + - base_config.after|symmetric_difference(remarks_check.after) == [] + + - name: Apply enhanced configuration + register: base_config_overridden + cisco.ios.ios_acls: + config: + - afi: ipv4 + acls: + - name: TEST + acl_type: extended + aces: + - sequence: 10 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 10" + - "============" + - "REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE" + grant: permit + protocol: ip + source: + host: 1.1.1.1 + destination: + any: true + - sequence: 20 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 20" + - "============" + - "ALLOW HOST FROM SEQUENCE 20" + grant: permit + protocol: ip + source: + host: 192.168.0.1 + destination: + any: true + - sequence: 30 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 30" + - "============" + - "ALLOW HOST FROM SEQUENCE 30 updated" + grant: permit + protocol: ip + source: + host: 2.2.2.2 + destination: + any: true + - sequence: 40 + remarks: + - "FIRST REMARK BEFORE SEQUENCE 40" + - "============" + - "ALLOW NEW HOST FROM SEQUENCE 40" + grant: permit + protocol: ip + source: + host: 3.3.3.3 + destination: + any: true + - remarks: + - "Remark not specific to sequence" + - "============" + - "End Remarks updated" + state: overridden + + - ansible.builtin.assert: + that: + - base_config_overridden.commands|symmetric_difference(remarks_check_override.commands) == [] + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/ios_acls/vars/main.yaml b/tests/integration/targets/ios_acls/vars/main.yaml index 58bf37004..3188b297d 100644 --- a/tests/integration/targets/ios_acls/vars/main.yaml +++ b/tests/integration/targets/ios_acls/vars/main.yaml @@ -396,3 +396,288 @@ rtt: - no ip access-list extended 150 - ipv6 access-list R1_TRAFFIC - deny tcp any eq www any eq telnet ack dscp af11 sequence 10 +remarks_check: + commands: + - ip access-list extended TEST + - 10 remark FIRST REMARK BEFORE SEQUENCE 10 + - 10 remark ============ + - 10 remark REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE + - 20 remark FIRST REMARK BEFORE SEQUENCE 20 + - 20 remark ============ + - 20 remark ALLOW HOST FROM SEQUENCE 20 + - 20 permit ip host 1.1.1.1 any + - 30 remark FIRST REMARK BEFORE SEQUENCE 30 + - 30 remark ============ + - 30 remark ALLOW HOST FROM SEQUENCE 30 + - 30 permit ip host 2.2.2.2 any + - 40 remark FIRST REMARK BEFORE SEQUENCE 40 + - 40 remark ============ + - 40 remark ALLOW NEW HOST FROM SEQUENCE 40 + - 40 permit ip host 3.3.3.3 any + - remark Remark not specific to sequence + - remark ============ + - remark End Remarks + before: + - acls: + - aces: + - destination: + address: 192.0.3.0 + wildcard_bits: 0.0.0.255 + dscp: ef + grant: deny + protocol: icmp + protocol_options: + icmp: + echo: true + sequence: 10 + source: + address: 192.0.2.0 + wildcard_bits: 0.0.0.255 + ttl: + eq: 10 + acl_type: extended + name: "110" + - aces: + - destination: + address: 198.51.101.0 + port_protocol: + eq: telnet + wildcard_bits: 0.0.0.255 + grant: deny + protocol: tcp + protocol_options: + tcp: + ack: true + sequence: 10 + source: + address: 198.51.100.0 + wildcard_bits: 0.0.0.255 + tos: + service_value: 12 + - destination: + address: 192.0.4.0 + port_protocol: + eq: www + wildcard_bits: 0.0.0.255 + dscp: ef + grant: deny + protocol: tcp + protocol_options: + tcp: + ack: true + sequence: 20 + source: + address: 192.0.3.0 + wildcard_bits: 0.0.0.255 + ttl: + lt: 20 + acl_type: extended + name: "123" + - aces: + - destination: + address: 192.0.3.0 + port_protocol: + eq: www + wildcard_bits: 0.0.0.255 + grant: deny + option: + traceroute: true + protocol: tcp + protocol_options: + tcp: + fin: true + sequence: 10 + source: + address: 192.0.2.0 + wildcard_bits: 0.0.0.255 + ttl: + eq: 10 + acl_type: extended + name: test_acl + afi: ipv4 + - acls: + - aces: + - destination: + any: true + port_protocol: + eq: telnet + dscp: af11 + grant: deny + protocol: tcp + protocol_options: + tcp: + ack: true + sequence: 10 + source: + any: true + port_protocol: + eq: www + name: R1_TRAFFIC + afi: ipv6 + after: + - acls: + - aces: + - destination: + address: 192.0.3.0 + wildcard_bits: 0.0.0.255 + dscp: ef + grant: deny + protocol: icmp + protocol_options: + icmp: + echo: true + sequence: 10 + source: + address: 192.0.2.0 + wildcard_bits: 0.0.0.255 + ttl: + eq: 10 + acl_type: extended + name: "110" + - aces: + - destination: + address: 198.51.101.0 + port_protocol: + eq: telnet + wildcard_bits: 0.0.0.255 + grant: deny + protocol: tcp + protocol_options: + tcp: + ack: true + sequence: 10 + source: + address: 198.51.100.0 + wildcard_bits: 0.0.0.255 + tos: + service_value: 12 + - destination: + address: 192.0.4.0 + port_protocol: + eq: www + wildcard_bits: 0.0.0.255 + dscp: ef + grant: deny + protocol: tcp + protocol_options: + tcp: + ack: true + sequence: 20 + source: + address: 192.0.3.0 + wildcard_bits: 0.0.0.255 + ttl: + lt: 20 + acl_type: extended + name: "123" + - aces: + - destination: + any: true + grant: permit + protocol: ip + remarks: + - FIRST REMARK BEFORE SEQUENCE 20 + - ============ + - ALLOW HOST FROM SEQUENCE 20 + sequence: 20 + source: + host: 1.1.1.1 + - destination: + any: true + grant: permit + protocol: ip + remarks: + - FIRST REMARK BEFORE SEQUENCE 30 + - ============ + - ALLOW HOST FROM SEQUENCE 30 + sequence: 30 + source: + host: 2.2.2.2 + - destination: + any: true + grant: permit + protocol: ip + remarks: + - FIRST REMARK BEFORE SEQUENCE 40 + - ============ + - ALLOW NEW HOST FROM SEQUENCE 40 + sequence: 40 + source: + host: 3.3.3.3 + - remarks: + - FIRST REMARK BEFORE SEQUENCE 10 + - ============ + - REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE + sequence: 10 + - remarks: + - Remark not specific to sequence + - ============ + - End Remarks + acl_type: extended + name: TEST + - aces: + - destination: + address: 192.0.3.0 + port_protocol: + eq: www + wildcard_bits: 0.0.0.255 + grant: deny + option: + traceroute: true + protocol: tcp + protocol_options: + tcp: + fin: true + sequence: 10 + source: + address: 192.0.2.0 + wildcard_bits: 0.0.0.255 + ttl: + eq: 10 + acl_type: extended + name: test_acl + afi: ipv4 + - acls: + - aces: + - destination: + any: true + port_protocol: + eq: telnet + dscp: af11 + grant: deny + protocol: tcp + protocol_options: + tcp: + ack: true + sequence: 10 + source: + any: true + port_protocol: + eq: www + name: R1_TRAFFIC + afi: ipv6 +remarks_check_override: + commands: + - no ipv6 access-list R1_TRAFFIC + - ip access-list extended TEST + - no 10 + - no 20 permit ip host 1.1.1.1 any + - no 30 remark + - no remark + - 10 remark FIRST REMARK BEFORE SEQUENCE 10 + - 10 remark ============ + - 10 remark REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE + - 10 permit ip host 1.1.1.1 any + - 20 remark FIRST REMARK BEFORE SEQUENCE 20 + - 20 remark ============ + - 20 remark ALLOW HOST FROM SEQUENCE 20 + - 20 permit ip host 192.168.0.1 any + - 30 remark FIRST REMARK BEFORE SEQUENCE 30 + - 30 remark ============ + - 30 remark ALLOW HOST FROM SEQUENCE 30 updated + - remark Remark not specific to sequence + - remark ============ + - remark End Remarks updated + - no ip access-list extended 110 + - no ip access-list extended 123 + - no ip access-list extended test_acl diff --git a/tests/unit/modules/network/ios/test_ios_acls.py b/tests/unit/modules/network/ios/test_ios_acls.py index a8dfae2dc..5be581a7a 100644 --- a/tests/unit/modules/network/ios/test_ios_acls.py +++ b/tests/unit/modules/network/ios/test_ios_acls.py @@ -444,64 +444,58 @@ def test_ios_acls_merged_remarks_positional(self): ) result = self.execute_module(changed=True) commands = [ - "ip access-list extended mytest", - "remark I am a test ace", - "remark I am right after the test ace", - "remark I third the test ace", - "100 permit ip host 100.100.100.100 any", - "remark I am the next test ace", - "remark I am the next ace to the next ace", - "110 permit ip host 10.40.150.0 any", - "remark I am the peace ace", - "remark Peace out", "ip access-list extended 199", "10 permit ip 10.40.150.0 0.0.0.255 any", "20 permit ip any 10.40.150.0 0.0.0.255", + "ip access-list standard 42", + "10 permit 10.182.250.0 0.0.0.255", + "ip access-list extended empty_ip_ex_acl", + "remark empty remark 1", + "remark empty remark 2", + "remark empty remark never ends", "ip access-list extended NET-MGMT-VTY", "10 permit tcp 10.57.66.243 0.0.0.7 any eq 22", "20 permit tcp host 10.160.114.111 any eq 22", "30 permit tcp host 10.160.115.22 any eq 22", "40 deny ip any any log", - "ip access-list extended empty_ip_ex_acl", - "remark empty remark 1", - "remark empty remark 2", - "remark empty remark never ends", + "ip access-list extended mytest", + "100 remark I am a test ace", + "100 remark I am right after the test ace", + "100 remark I third the test ace", + "100 permit ip host 100.100.100.100 any", + "110 remark I am the next test ace", + "110 remark I am the next ace to the next ace", + "110 permit ip host 10.40.150.0 any", + "remark I am the peace ace", + "remark Peace out", "ip access-list extended TEST", - "remark FIRST REMARK BEFORE LINE 10", - "remark ============", - "remark ALLOW HOST FROM BUILDING 10", + "10 remark FIRST REMARK BEFORE LINE 10", + "10 remark ============", + "10 remark ALLOW HOST FROM BUILDING 10", "10 permit ip host 1.1.1.1 any", - "remark FIRST REMARK BEFORE LINE 20", - "remark ============", - "remark ALLOW HOST FROM BUILDING 20", + "20 remark FIRST REMARK BEFORE LINE 20", + "20 remark ============", + "20 remark ALLOW HOST FROM BUILDING 20", "20 permit ip host 2.2.2.2 any", - "remark FIRST REMARK BEFORE LINE 30", - "remark ============", - "remark ALLOW NEW HOST FROM BUILDING 10", + "30 remark FIRST REMARK BEFORE LINE 30", + "30 remark ============", + "30 remark ALLOW NEW HOST FROM BUILDING 10", "30 permit ip host 3.3.3.3 any", "remark FIRST REMARK AT END OF ACL", "remark SECOND REMARK AT END OF ACL", - "ip access-list standard 42", - "10 permit 10.182.250.0 0.0.0.255", "ipv6 access-list R1_TRAFFIC", "permit ipv6 2001:ABAD:BEEF:1221::/64 any sequence 10", "deny tcp host 2001:ABAD:BEEF:2345::1 host 2001:ABAD:BEEF:1212::1 eq www sequence 20", "ipv6 access-list empty_ipv6_acl", - "remark empty remark 1", - " sequence 10", - "remark empty remark 2", - " sequence 20", - "remark empty remark never ends", - " sequence 30", + "10 remark empty remark 1", + "20 remark empty remark 2", + "30 remark empty remark never ends", "ipv6 access-list ipv6_acl", - "remark I am a ipv6 ace", - " sequence 10", - "remark I am test", - " sequence 20", + "10 remark I am a ipv6 ace", + "20 remark I am test", "permit tcp any any sequence 30", "permit udp any any sequence 40", - "remark I am new set of ipv6 ace", - " sequence 50", + "50 remark I am new set of ipv6 ace", "permit icmp any any sequence 60", ] self.assertEqual(sorted(result["commands"]), sorted(commands)) @@ -650,17 +644,16 @@ def test_ios_acls_replaced(self): "ip access-list extended replace_acl", "deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos min-monetary-cost", "ip access-list standard test_acl", - "no remark remark check 1", - "no remark some random remark 2", + "no remark", "remark Another remark here", "ip access-list standard testRobustReplace", - "no 20 remark Remarks for 20", + "no 20 remark", "no 20 permit 0.0.0.0 255.0.0.0", - "no 30 remark Remarks for 30", + "no 30 remark", "no 30 permit 172.16.0.0 0.15.255.255", - "no 40 remark Remarks for 40", + "no 40 remark", "no 40 permit 192.0.2.0 0.0.0.255", - "no 50 remark Remarks for 50", + "no 50 remark", "no 50 permit 198.51.100.0 0.0.0.255", ] self.assertEqual(sorted(result["commands"]), sorted(commands)) @@ -888,8 +881,7 @@ def test_ios_acls_replaced_changetype(self): "ip access-list standard 110", "deny 198.51.100.0 0.0.0.255", "ip access-list standard test_acl", - "no remark remark check 1", - "no remark some random remark 2", + "no remark", "remark Another remark here", ] self.assertEqual(sorted(result["commands"]), sorted(commands)) @@ -1193,9 +1185,9 @@ def test_ios_acls_rendered(self): ) commands = [ "ip access-list extended 110", + "10 remark check for remark", + "10 remark remark for acl 110", "10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10", - "remark check for remark", - "remark remark for acl 110", ] result = self.execute_module(changed=False) self.assertEqual(sorted(result["rendered"]), sorted(commands)) @@ -1438,9 +1430,8 @@ def test_ios_acls_overridden_option(self): "permit 433 198.51.101.0 0.0.0.255 198.51.102.0 0.0.0.255 eq telnet log check tos max-throughput", "permit 198.51.105.0 0.0.0.255 198.51.106.0 0.0.0.255 time-range 20 tos max-throughput", "ip access-list standard test_acl", + "no remark", "remark Another remark here", - "no remark remark check 1", - "no remark some random remark 2", ] self.assertEqual(sorted(result["commands"]), sorted(commands)) @@ -1638,6 +1629,11 @@ def test_ios_acls_parsed_multioption(self): dict( running_config=dedent( """\ + ip access-list standard 99 + 10 remark standalone remarks + 20 permit 192.15.0.1 + 30 permit 192.15.0.2 + 40 permit 192.15.0.3 ip access-list standard 2 30 permit 172.16.1.11 20 permit 172.16.1.10 @@ -1769,6 +1765,28 @@ def test_ios_acls_parsed_multioption(self): }, ], }, + { + "name": "99", + "acl_type": "standard", + "aces": [ + { + "sequence": 20, + "grant": "permit", + "source": {"host": "192.15.0.1"}, + }, + { + "sequence": 30, + "grant": "permit", + "source": {"host": "192.15.0.2"}, + }, + { + "sequence": 40, + "grant": "permit", + "source": {"host": "192.15.0.3"}, + }, + {"sequence": 10, "remarks": ["standalone remarks"]}, + ], + }, { "name": "outboundfilters", "acl_type": "extended", @@ -1922,6 +1940,28 @@ def test_ios_acls_rendered_muiltioption(self): }, ], }, + { + "name": "99", + "acl_type": "standard", + "aces": [ + { + "sequence": 20, + "grant": "permit", + "source": {"host": "192.15.0.1"}, + }, + { + "sequence": 30, + "grant": "permit", + "source": {"host": "192.15.0.2"}, + }, + { + "sequence": 40, + "grant": "permit", + "source": {"host": "192.15.0.3"}, + }, + {"sequence": 10, "remarks": ["standalone remarks"]}, + ], + }, { "name": "2", "acl_type": "standard", @@ -2019,6 +2059,11 @@ def test_ios_acls_rendered_muiltioption(self): "50 permit ip any 10.1.1.0 0.0.0.255", "60 permit tcp any host 10.1.1.1 eq telnet", "70 permit tcp 10.1.1.0 0.0.0.255 172.16.1.0 0.0.0.255 eq telnet time-range EVERYOTHERDAY", + "ip access-list standard 99", + "20 permit host 192.15.0.1", + "30 permit host 192.15.0.2", + "40 permit host 192.15.0.3", + "10 remark standalone remarks", "ip access-list standard 2", "30 permit host 172.16.1.11", "20 permit host 172.16.1.10", @@ -2084,9 +2129,145 @@ def test_ios_acls_overridden_sticky_remarks(self): result = self.execute_module(changed=True) commands = [ "ip access-list standard test123", + "no 10 remark", "no 10 permit host 8.8.8.8", "10 remark TEST", "10 remark TEST 2", "10 permit 8.8.128.0 0.0.0.63", ] self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_ios_acls_overridden_remarks_complex(self): + self.execute_show_command.return_value = dedent( + """\ + ip access-list extended TEST + 10 remark FIRST REMARK BEFORE SEQUENCE 10 + 10 remark ============ + 10 remark REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE + 20 remark FIRST REMARK BEFORE SEQUENCE 20 + 20 remark ============ + 20 remark ALLOW HOST FROM SEQUENCE 20 + 20 permit ip host 1.1.1.1 any + 30 remark FIRST REMARK BEFORE SEQUENCE 30 + 30 remark ============ + 30 remark ALLOW HOST FROM SEQUENCE 30 + 30 permit ip host 2.2.2.2 any + 40 remark FIRST REMARK BEFORE SEQUENCE 40 + 40 remark ============ + 40 remark ALLOW NEW HOST FROM SEQUENCE 40 + 40 permit ip host 3.3.3.3 any + remark Remark not specific to sequence + remark ============ + remark End Remarks + ip access-list extended test_acl + 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 + ip access-list extended 110 + 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10 + ip access-list extended 123 + 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 + 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 + ipv6 access-list R1_TRAFFIC + sequence 10 deny tcp any eq www any eq telnet ack dscp af11 + """, + ) + self.execute_show_command_name.return_value = dedent("") + set_module_args( + dict( + config=[ + { + "afi": "ipv4", + "acls": [ + { + "name": "TEST", + "acl_type": "extended", + "aces": [ + { + "sequence": 10, + "remarks": [ + "FIRST REMARK BEFORE SEQUENCE 10", + "============", + "REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE", + ], + "grant": "permit", + "protocol": "ip", + "source": {"host": "1.1.1.1"}, + "destination": {"any": True}, + }, + { + "sequence": 20, + "remarks": [ + "FIRST REMARK BEFORE SEQUENCE 20", + "============", + "ALLOW HOST FROM SEQUENCE 20", + ], + "grant": "permit", + "protocol": "ip", + "source": {"host": "192.168.0.1"}, + "destination": {"any": True}, + }, + { + "sequence": 30, + "remarks": [ + "FIRST REMARK BEFORE SEQUENCE 30", + "============", + "ALLOW HOST FROM SEQUENCE 30 updated", + ], + "grant": "permit", + "protocol": "ip", + "source": {"host": "2.2.2.2"}, + "destination": {"any": True}, + }, + { + "sequence": 40, + "remarks": [ + "FIRST REMARK BEFORE SEQUENCE 40", + "============", + "ALLOW NEW HOST FROM SEQUENCE 40", + ], + "grant": "permit", + "protocol": "ip", + "source": {"host": "3.3.3.3"}, + "destination": {"any": True}, + }, + { + "remarks": [ + "Remark not specific to sequence", + "============", + "End Remarks 1", + ], + }, + ], + }, + ], + }, + ], + state="overridden", + ), + ) + result = self.execute_module(changed=True) + commands = [ + "no ipv6 access-list R1_TRAFFIC", + "ip access-list extended TEST", + "no 10", # removes all remarks and ace entry for sequence 10 + "no 20 permit ip host 1.1.1.1 any", # removing the ace automatically removes the remarks + "no 30 remark", # just remove remarks for sequence 30 + "no remark", # remove all remarks at end of acl, that has no sequence + "10 remark FIRST REMARK BEFORE SEQUENCE 10", + "10 remark ============", + "10 remark REMARKS FOR SEQUENCE 10 NO FOLLOWING ACE", + "10 permit ip host 1.1.1.1 any", + "20 remark FIRST REMARK BEFORE SEQUENCE 20", + "20 remark ============", + "20 remark ALLOW HOST FROM SEQUENCE 20", + "20 permit ip host 192.168.0.1 any", + "30 remark FIRST REMARK BEFORE SEQUENCE 30", + "30 remark ============", + "30 remark ALLOW HOST FROM SEQUENCE 30 updated", + "remark Remark not specific to sequence", + "remark ============", + "remark End Remarks 1", + "no ip access-list extended 110", + "no ip access-list extended 123", + "no ip access-list extended test_acl", + ] + self.assertEqual(sorted(result["commands"]), sorted(commands)) From eb6796dac2babd8acb2a1b92a5e09e44fa12c662 Mon Sep 17 00:00:00 2001 From: Sagar Paul Date: Wed, 27 Mar 2024 10:56:03 +0530 Subject: [PATCH 2/3] py27 compats no longer needed (#1045) * py27 compats no longer needed * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix ci * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- tests/unit/compat/__init__.py | 0 tests/unit/compat/mock.py | 28 --- tests/unit/compat/unittest.py | 41 --- tests/unit/mock/path.py | 9 +- tests/unit/mock/procenv.py | 10 +- .../network/ios/test_ios_acl_interfaces.py | 3 +- .../unit/modules/network/ios/test_ios_acls.py | 3 +- .../modules/network/ios/test_ios_banner.py | 8 +- .../ios/test_ios_bgp_address_family.py | 65 +++-- .../network/ios/test_ios_bgp_global.py | 3 +- .../modules/network/ios/test_ios_command.py | 19 +- .../modules/network/ios/test_ios_config.py | 43 +++- .../modules/network/ios/test_ios_evpn_evi.py | 3 +- .../network/ios/test_ios_evpn_global.py | 3 +- .../modules/network/ios/test_ios_facts.py | 12 +- .../modules/network/ios/test_ios_hostname.py | 3 +- .../network/ios/test_ios_interfaces.py | 30 ++- .../network/ios/test_ios_l2_interfaces.py | 53 +++- .../network/ios/test_ios_l3_interfaces.py | 3 +- .../unit/modules/network/ios/test_ios_lacp.py | 3 +- .../network/ios/test_ios_lacp_interfaces.py | 39 ++- .../network/ios/test_ios_lag_interfaces.py | 45 +++- .../network/ios/test_ios_lldp_global.py | 10 +- .../network/ios/test_ios_lldp_inteface.py | 8 +- .../network/ios/test_ios_logging_global.py | 60 ++++- .../unit/modules/network/ios/test_ios_ntp.py | 2 +- .../network/ios/test_ios_ntp_global.py | 107 ++++++-- .../network/ios/test_ios_ospf_interfaces.py | 3 +- .../modules/network/ios/test_ios_ospfv2.py | 81 ++++-- .../modules/network/ios/test_ios_ospfv3.py | 32 ++- .../unit/modules/network/ios/test_ios_ping.py | 7 +- .../network/ios/test_ios_prefix_lists.py | 149 +++++++++-- .../network/ios/test_ios_route_maps.py | 46 +++- .../modules/network/ios/test_ios_service.py | 3 +- .../network/ios/test_ios_snmp_server.py | 238 ++++++++++++++---- .../network/ios/test_ios_static_routes.py | 46 +++- .../modules/network/ios/test_ios_system.py | 14 +- .../unit/modules/network/ios/test_ios_user.py | 21 +- .../modules/network/ios/test_ios_vlans.py | 3 +- .../unit/modules/network/ios/test_ios_vrf.py | 52 +++- .../network/ios/test_ios_vxlan_vtep.py | 3 +- tests/unit/modules/utils.py | 8 +- tests/unit/plugins/cliconf/test_ios.py | 9 +- 43 files changed, 983 insertions(+), 345 deletions(-) delete mode 100644 tests/unit/compat/__init__.py delete mode 100644 tests/unit/compat/mock.py delete mode 100644 tests/unit/compat/unittest.py diff --git a/tests/unit/compat/__init__.py b/tests/unit/compat/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/unit/compat/mock.py b/tests/unit/compat/mock.py deleted file mode 100644 index e25e8381b..000000000 --- a/tests/unit/compat/mock.py +++ /dev/null @@ -1,28 +0,0 @@ -# pylint: skip-file -# (c) 2014, Toshio Kuratomi -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -# Make coding more python3-ish -from __future__ import absolute_import, division, print_function - - -__metaclass__ = type - -""" -Compat module for Python3.x's unittest.mock module -""" -from unittest.mock import * diff --git a/tests/unit/compat/unittest.py b/tests/unit/compat/unittest.py deleted file mode 100644 index df4266ec9..000000000 --- a/tests/unit/compat/unittest.py +++ /dev/null @@ -1,41 +0,0 @@ -# (c) 2014, Toshio Kuratomi -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -# Make coding more python3-ish -from __future__ import absolute_import, division, print_function - - -__metaclass__ = type - -""" -Compat module for Python2.7's unittest module -""" - -import sys - - -# Allow wildcard import because we really do want to import all of -# unittests's symbols into this compat shim -# pylint: disable=wildcard-import,unused-wildcard-import -if sys.version_info < (2, 7): - try: - # Need unittest2 on python2.6 - from unittest2 import * - except ImportError: - print("You need unittest2 installed on python2.6.x to run tests") -else: - from unittest import * diff --git a/tests/unit/mock/path.py b/tests/unit/mock/path.py index ce2eb1fe0..7d287a5fb 100644 --- a/tests/unit/mock/path.py +++ b/tests/unit/mock/path.py @@ -2,9 +2,12 @@ __metaclass__ = type -from ansible.utils.path import unfrackpath +from unittest.mock import MagicMock -from ansible_collections.cisco.ios.tests.unit.compat.mock import MagicMock +from ansible.utils.path import unfrackpath -mock_unfrackpath_noop = MagicMock(spec_set=unfrackpath, side_effect=lambda x, *args, **kwargs: x) +mock_unfrackpath_noop = MagicMock( + spec_set=unfrackpath, + side_effect=lambda x, *args, **kwargs: x, +) diff --git a/tests/unit/mock/procenv.py b/tests/unit/mock/procenv.py index 111c319c2..e6e09464b 100644 --- a/tests/unit/mock/procenv.py +++ b/tests/unit/mock/procenv.py @@ -27,12 +27,11 @@ from contextlib import contextmanager from io import BytesIO, StringIO +from unittest import TestCase from ansible.module_utils._text import to_bytes from ansible.module_utils.six import PY3 -from ansible_collections.cisco.ios.tests.unit.compat import unittest - @contextmanager def swap_stdin_and_argv(stdin_data="", argv_data=tuple()): @@ -78,10 +77,13 @@ def swap_stdout(): sys.stdout = old_stdout -class ModuleTestCase(unittest.TestCase): +class ModuleTestCase(TestCase): def setUp(self, module_args=None): if module_args is None: - module_args = {"_ansible_remote_tmp": "/tmp", "_ansible_keep_remote_files": False} + module_args = { + "_ansible_remote_tmp": "/tmp", + "_ansible_keep_remote_files": False, + } args = json.dumps(dict(ANSIBLE_MODULE_ARGS=module_args)) diff --git a/tests/unit/modules/network/ios/test_ios_acl_interfaces.py b/tests/unit/modules/network/ios/test_ios_acl_interfaces.py index 6bc99691c..3c8567797 100644 --- a/tests/unit/modules/network/ios/test_ios_acl_interfaces.py +++ b/tests/unit/modules/network/ios/test_ios_acl_interfaces.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_acl_interfaces -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_acls.py b/tests/unit/modules/network/ios/test_ios_acls.py index 5be581a7a..36d96365a 100644 --- a/tests/unit/modules/network/ios/test_ios_acls.py +++ b/tests/unit/modules/network/ios/test_ios_acls.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_acls -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_banner.py b/tests/unit/modules/network/ios/test_ios_banner.py index 85e2736f0..b114d1817 100644 --- a/tests/unit/modules/network/ios/test_ios_banner.py +++ b/tests/unit/modules/network/ios/test_ios_banner.py @@ -18,9 +18,9 @@ __metaclass__ = type +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_banner -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture @@ -77,7 +77,11 @@ def test_ios_banner_idemp(self): def test_ios_banner_create_delimiter(self): for banner_type in ("login", "motd", "exec", "incoming", "slip-ppp"): set_module_args( - dict(banner=banner_type, text="test\nbanner\nstring", multiline_delimiter="c"), + dict( + banner=banner_type, + text="test\nbanner\nstring", + multiline_delimiter="c", + ), ) commands = ["banner {0} c\ntest\nbanner\nstring\nc".format(banner_type)] self.execute_module(changed=True, commands=commands) diff --git a/tests/unit/modules/network/ios/test_ios_bgp_address_family.py b/tests/unit/modules/network/ios/test_ios_bgp_address_family.py index 259da5ece..ea5d279f4 100644 --- a/tests/unit/modules/network/ios/test_ios_bgp_address_family.py +++ b/tests/unit/modules/network/ios/test_ios_bgp_address_family.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_bgp_address_family -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -119,8 +118,12 @@ def test_ios_bgp_address_family_merged(self): dict( neighbor_address="198.51.100.1", remote_as="65.11", - route_maps=[dict(name="test-route-out", out="true")], - prefix_lists=[dict(name="AS65100-PREFIX-OUT", out="true")], + route_maps=[ + dict(name="test-route-out", out="true"), + ], + prefix_lists=[ + dict(name="AS65100-PREFIX-OUT", out="true"), + ], ), ], ), @@ -128,7 +131,9 @@ def test_ios_bgp_address_family_merged(self): afi="nsap", bgp=dict(aggregate_timer=20, dmzlink_bw=True, scan_time=10), default_metric=10, - networks=[dict(address="192.0.1.1", route_map="test_route")], + networks=[ + dict(address="192.0.1.1", route_map="test_route"), + ], ), ], ), @@ -317,18 +322,25 @@ def test_ios_bgp_address_family_merged_idempotent(self): "send": { "cost_community": { "id": 100, - "poi": {"igp_cost": True, "transitive": True}, + "poi": { + "igp_cost": True, + "transitive": True, + }, }, }, }, "local_as": {"number": "10.64760", "set": True}, "neighbor_address": "198.51.100.1", "nexthop_self": {"all": True}, - "prefix_lists": [{"name": "AS65100-PREFIX-OUT", "out": True}], + "prefix_lists": [ + {"name": "AS65100-PREFIX-OUT", "out": True}, + ], "remote_as": 10, "route_maps": [{"name": "test-out", "out": True}], "route_server_client": True, - "slow_peer_options": {"detection": {"threshold": 150}}, + "slow_peer_options": { + "detection": {"threshold": 150}, + }, }, ], "networks": [ @@ -426,7 +438,9 @@ def test_ios_bgp_address_family_replaced(self): address="198.51.110.1", activate=True, remote_as=200, - route_maps=[dict(name="test-replaced-route", out=True)], + route_maps=[ + dict(name="test-replaced-route", out=True), + ], ), ], ), @@ -534,12 +548,17 @@ def test_ios_bgp_address_family_replaced_idempotent(self): send=dict( cost_community=dict( id=100, - poi=dict(igp_cost=True, transitive=True), + poi=dict( + igp_cost=True, + transitive=True, + ), ), ), ), nexthop_self=dict(all=True), - prefix_lists=[dict(name="AS65100-PREFIX-OUT", out="true")], + prefix_lists=[ + dict(name="AS65100-PREFIX-OUT", out="true"), + ], slow_peer=[dict(detection=dict(threshold=150))], remote_as=10, local_as=dict(number=20), @@ -709,12 +728,17 @@ def test_ios_bgp_address_family_overridden_idempotent(self): send=dict( cost_community=dict( id=100, - poi=dict(igp_cost=True, transitive=True), + poi=dict( + igp_cost=True, + transitive=True, + ), ), ), ), nexthop_self=dict(all=True), - prefix_lists=[dict(name="AS65100-PREFIX-OUT", out="true")], + prefix_lists=[ + dict(name="AS65100-PREFIX-OUT", out="true"), + ], slow_peer=[dict(detection=dict(threshold=150))], remote_as=10, local_as=dict(number=20), @@ -937,7 +961,10 @@ def test_ios_bgp_address_family_rendered(self): send=dict( cost_community=dict( id=100, - poi=dict(igp_cost=True, transitive=True), + poi=dict( + igp_cost=True, + transitive=True, + ), ), ), ), @@ -1152,7 +1179,11 @@ def test_ios_bgp_address_family_parsed(self): }, }, "networks": [ - {"address": "198.51.110.10", "mask": "255.255.255.255", "backdoor": True}, + { + "address": "198.51.110.10", + "mask": "255.255.255.255", + "backdoor": True, + }, ], "aggregate_addresses": [ { @@ -1177,7 +1208,9 @@ def test_ios_bgp_address_family_parsed(self): }, }, "route_server_client": True, - "prefix_lists": [{"name": "AS65100-PREFIX-OUT", "out": True}], + "prefix_lists": [ + {"name": "AS65100-PREFIX-OUT", "out": True}, + ], "slow_peer_options": {"detection": {"threshold": 150}}, "route_maps": [{"name": "test-out", "out": True}], }, diff --git a/tests/unit/modules/network/ios/test_ios_bgp_global.py b/tests/unit/modules/network/ios/test_ios_bgp_global.py index 6be8df1d1..16a4c9b5c 100644 --- a/tests/unit/modules/network/ios/test_ios_bgp_global.py +++ b/tests/unit/modules/network/ios/test_ios_bgp_global.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_bgp_global -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import AnsibleFailJson, set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_command.py b/tests/unit/modules/network/ios/test_ios_command.py index 42fee4028..69788ef3e 100644 --- a/tests/unit/modules/network/ios/test_ios_command.py +++ b/tests/unit/modules/network/ios/test_ios_command.py @@ -20,11 +20,11 @@ __metaclass__ = type - import json +from unittest.mock import patch + from ansible_collections.cisco.ios.plugins.modules import ios_command -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture @@ -97,17 +97,26 @@ def test_ios_command_retries_0(self): self.assertEqual(self.run_commands.call_count, 1) def test_ios_command_match_any(self): - wait_for = ['result[0] contains "Cisco IOS"', 'result[0] contains "test string"'] + wait_for = [ + 'result[0] contains "Cisco IOS"', + 'result[0] contains "test string"', + ] set_module_args(dict(commands=["show version"], wait_for=wait_for, match="any")) self.execute_module() def test_ios_command_match_all(self): - wait_for = ['result[0] contains "Cisco IOS"', 'result[0] contains "IOSv Software"'] + wait_for = [ + 'result[0] contains "Cisco IOS"', + 'result[0] contains "IOSv Software"', + ] set_module_args(dict(commands=["show version"], wait_for=wait_for, match="all")) self.execute_module() def test_ios_command_match_all_failure(self): - wait_for = ['result[0] contains "Cisco IOS"', 'result[0] contains "test string"'] + wait_for = [ + 'result[0] contains "Cisco IOS"', + 'result[0] contains "test string"', + ] commands = ["show version", "show version"] set_module_args(dict(commands=commands, wait_for=wait_for, match="all")) self.execute_module(failed=True) diff --git a/tests/unit/modules/network/ios/test_ios_config.py b/tests/unit/modules/network/ios/test_ios_config.py index 778bb1ccb..7fa3931d0 100644 --- a/tests/unit/modules/network/ios/test_ios_config.py +++ b/tests/unit/modules/network/ios/test_ios_config.py @@ -21,10 +21,10 @@ __metaclass__ = type +from unittest.mock import MagicMock, patch from ansible_collections.cisco.ios.plugins.cliconf.ios import Cliconf from ansible_collections.cisco.ios.plugins.modules import ios_config -from ansible_collections.cisco.ios.tests.unit.compat.mock import MagicMock, patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture @@ -123,7 +123,10 @@ def test_ios_config_lines_wo_parents(self): lines = ["hostname foo"] set_module_args(dict(lines=lines)) self.conn.get_diff = MagicMock( - return_value=self.cliconf_obj.get_diff("\n".join(lines), self.running_config), + return_value=self.cliconf_obj.get_diff( + "\n".join(lines), + self.running_config, + ), ) commands = ["hostname foo"] self.execute_module(changed=True, commands=commands) @@ -137,7 +140,10 @@ def test_ios_config_lines_w_parents(self): candidate_config = ios_config.get_candidate_config(module) self.conn.get_diff = MagicMock( - return_value=self.cliconf_obj.get_diff(candidate_config, self.running_config), + return_value=self.cliconf_obj.get_diff( + candidate_config, + self.running_config, + ), ) commands = ["interface GigabitEthernet0/0", "shutdown"] @@ -147,7 +153,10 @@ def test_ios_config_before(self): lines = ["hostname foo"] set_module_args(dict(lines=lines, before=["test1", "test2"])) self.conn.get_diff = MagicMock( - return_value=self.cliconf_obj.get_diff("\n".join(lines), self.running_config), + return_value=self.cliconf_obj.get_diff( + "\n".join(lines), + self.running_config, + ), ) commands = ["test1", "test2", "hostname foo"] self.execute_module(changed=True, commands=commands, sort=False) @@ -156,16 +165,24 @@ def test_ios_config_after(self): lines = ["hostname foo"] set_module_args(dict(lines=lines, after=["test1", "test2"])) self.conn.get_diff = MagicMock( - return_value=self.cliconf_obj.get_diff("\n".join(lines), self.running_config), + return_value=self.cliconf_obj.get_diff( + "\n".join(lines), + self.running_config, + ), ) commands = ["hostname foo", "test1", "test2"] self.execute_module(changed=True, commands=commands, sort=False) def test_ios_config_before_after_no_change(self): lines = ["hostname router"] - set_module_args(dict(lines=lines, before=["test1", "test2"], after=["test3", "test4"])) + set_module_args( + dict(lines=lines, before=["test1", "test2"], after=["test3", "test4"]), + ) self.conn.get_diff = MagicMock( - return_value=self.cliconf_obj.get_diff("\n".join(lines), self.running_config), + return_value=self.cliconf_obj.get_diff( + "\n".join(lines), + self.running_config, + ), ) self.execute_module() @@ -242,7 +259,11 @@ def test_ios_config_match_none2(self): self.execute_module(changed=True, commands=commands, sort=False) def test_ios_config_match_strict(self): - lines = ["ip address 1.2.3.4 255.255.255.0", "description test string", "shutdown"] + lines = [ + "ip address 1.2.3.4 255.255.255.0", + "description test string", + "shutdown", + ] parents = ["interface GigabitEthernet0/0"] set_module_args(dict(lines=lines, parents=parents, match="strict")) @@ -262,7 +283,11 @@ def test_ios_config_match_strict(self): self.execute_module(changed=True, commands=commands, sort=False) def test_ios_config_match_exact(self): - lines = ["ip address 1.2.3.4 255.255.255.0", "description test string", "shutdown"] + lines = [ + "ip address 1.2.3.4 255.255.255.0", + "description test string", + "shutdown", + ] parents = ["interface GigabitEthernet0/0"] set_module_args(dict(lines=lines, parents=parents, match="exact")) diff --git a/tests/unit/modules/network/ios/test_ios_evpn_evi.py b/tests/unit/modules/network/ios/test_ios_evpn_evi.py index 94008b0aa..e1178a21f 100644 --- a/tests/unit/modules/network/ios/test_ios_evpn_evi.py +++ b/tests/unit/modules/network/ios/test_ios_evpn_evi.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_evpn_evi -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_evpn_global.py b/tests/unit/modules/network/ios/test_ios_evpn_global.py index d3bfa1585..76f467411 100644 --- a/tests/unit/modules/network/ios/test_ios_evpn_global.py +++ b/tests/unit/modules/network/ios/test_ios_evpn_global.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_evpn_global -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_facts.py b/tests/unit/modules/network/ios/test_ios_facts.py index c951b58b2..4878d4ad7 100644 --- a/tests/unit/modules/network/ios/test_ios_facts.py +++ b/tests/unit/modules/network/ios/test_ios_facts.py @@ -19,11 +19,11 @@ __metaclass__ = type +from unittest.mock import patch from ansible.module_utils.six import assertCountEqual from ansible_collections.cisco.ios.plugins.modules import ios_facts -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture @@ -80,8 +80,14 @@ def test_ios_facts_stacked(self): set_module_args(dict(gather_subset="default")) result = self.execute_module() self.assertEqual(result["ansible_facts"]["ansible_net_model"], "WS-C3750-24TS") - self.assertEqual(result["ansible_facts"]["ansible_net_serialnum"], "CAT0726R0ZU") - self.assertEqual(result["ansible_facts"]["ansible_net_operatingmode"], "autonomous") + self.assertEqual( + result["ansible_facts"]["ansible_net_serialnum"], + "CAT0726R0ZU", + ) + self.assertEqual( + result["ansible_facts"]["ansible_net_operatingmode"], + "autonomous", + ) self.assertEqual( result["ansible_facts"]["ansible_net_stacked_models"], ["WS-C3750-24TS-E", "WS-C3750-24TS-E", "WS-C3750G-12S-E"], diff --git a/tests/unit/modules/network/ios/test_ios_hostname.py b/tests/unit/modules/network/ios/test_ios_hostname.py index 6b16bddf0..359cf562a 100644 --- a/tests/unit/modules/network/ios/test_ios_hostname.py +++ b/tests/unit/modules/network/ios/test_ios_hostname.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_hostname -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_interfaces.py b/tests/unit/modules/network/ios/test_ios_interfaces.py index caac40ccb..63ee2341b 100644 --- a/tests/unit/modules/network/ios/test_ios_interfaces.py +++ b/tests/unit/modules/network/ios/test_ios_interfaces.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_interfaces -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -150,7 +149,10 @@ def test_ios_interfaces_merged_idempotent(self): set_module_args( { "config": [ - {"description": "Ansible UT interface 1", "name": "GigabitEthernet1"}, + { + "description": "Ansible UT interface 1", + "name": "GigabitEthernet1", + }, { "description": "Ansible UT interface 2", "name": "GigabitEthernet0/1", @@ -204,7 +206,10 @@ def test_ios_interfaces_replaced(self): set_module_args( { "config": [ - {"description": "Ansible UT interface 1", "name": "GigabitEthernet1"}, + { + "description": "Ansible UT interface 1", + "name": "GigabitEthernet1", + }, {"name": "GigabitEthernet0/1", "speed": 1200, "mtu": 1800}, { "name": "GigabitEthernet6", @@ -267,7 +272,10 @@ def test_ios_interfaces_replaced_idempotent(self): set_module_args( { "config": [ - {"description": "Ansible UT interface 1", "name": "GigabitEthernet1"}, + { + "description": "Ansible UT interface 1", + "name": "GigabitEthernet1", + }, { "description": "Ansible UT interface 2", "name": "GigabitEthernet0/1", @@ -570,14 +578,22 @@ def test_ios_interfaces_parsed(self): "mtu": 1500, "enabled": True, }, - {"name": "GigabitEthernet1", "description": "Ansible UT interface 1", "enabled": True}, + { + "name": "GigabitEthernet1", + "description": "Ansible UT interface 1", + "enabled": True, + }, { "name": "GigabitEthernet3", "description": "Ansible UT interface 3", "enabled": False, "duplex": "auto", }, - {"name": "GigabitEthernet4", "description": "Ansible UT interface 4", "enabled": False}, + { + "name": "GigabitEthernet4", + "description": "Ansible UT interface 4", + "enabled": False, + }, { "name": "GigabitEthernet5", "description": "Ansible UT interface 5", diff --git a/tests/unit/modules/network/ios/test_ios_l2_interfaces.py b/tests/unit/modules/network/ios/test_ios_l2_interfaces.py index d9ec2b189..e84846aeb 100644 --- a/tests/unit/modules/network/ios/test_ios_l2_interfaces.py +++ b/tests/unit/modules/network/ios/test_ios_l2_interfaces.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_l2_interfaces -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -136,7 +135,11 @@ def test_ios_l2_interfaces_merged_idempotent(self): set_module_args( dict( config=[ - dict(access=dict(vlan=10), mode="access", name="GigabitEthernet0/1"), + dict( + access=dict(vlan=10), + mode="access", + name="GigabitEthernet0/1", + ), dict( mode="trunk", name="GigabitEthernet0/2", @@ -270,7 +273,11 @@ def test_ios_l2_interfaces_replaced_idempotent(self): set_module_args( dict( config=[ - dict(access=dict(vlan=10), mode="access", name="GigabitEthernet0/1"), + dict( + access=dict(vlan=10), + mode="access", + name="GigabitEthernet0/1", + ), dict( mode="trunk", name="GigabitEthernet0/2", @@ -281,7 +288,11 @@ def test_ios_l2_interfaces_replaced_idempotent(self): pruning_vlans=["10", "20"], ), ), - dict(access=dict(vlan=20), mode="access", name="TwoGigabitEthernet1/0/1"), + dict( + access=dict(vlan=20), + mode="access", + name="TwoGigabitEthernet1/0/1", + ), dict( mode="trunk", name="GigabitEthernet0/3", @@ -416,7 +427,11 @@ def test_ios_l2_interfaces_overridden_idempotent(self): set_module_args( dict( config=[ - dict(access=dict(vlan=10), mode="access", name="GigabitEthernet0/1"), + dict( + access=dict(vlan=10), + mode="access", + name="GigabitEthernet0/1", + ), dict( mode="trunk", name="GigabitEthernet0/2", @@ -427,7 +442,11 @@ def test_ios_l2_interfaces_overridden_idempotent(self): pruning_vlans=["10", "20"], ), ), - dict(access=dict(vlan=20), mode="access", name="TwoGigabitEthernet1/0/1"), + dict( + access=dict(vlan=20), + mode="access", + name="TwoGigabitEthernet1/0/1", + ), dict( mode="trunk", name="GigabitEthernet0/3", @@ -592,7 +611,11 @@ def test_ios_l2_interfaces_parsed(self): }, "mode": "trunk", }, - {"name": "TwoGigabitEthernet1/0/1", "mode": "access", "access": {"vlan": 20}}, + { + "name": "TwoGigabitEthernet1/0/1", + "mode": "access", + "access": {"vlan": 20}, + }, { "name": "GigabitEthernet0/3", "trunk": { @@ -695,7 +718,13 @@ def test_ios_l2_interfaces_merged_mode_change(self): ) set_module_args( dict( - config=[dict(access=dict(vlan=20), mode="trunk", name="TwoGigabitEthernet1/0/1")], + config=[ + dict( + access=dict(vlan=20), + mode="trunk", + name="TwoGigabitEthernet1/0/1", + ), + ], state="merged", ), ) @@ -731,7 +760,11 @@ def test_ios_l2_interfaces_fiveGibBit(self): set_module_args( dict( config=[ - dict(access=dict(vlan=20), mode="trunk", name="FiveGigabitEthernet1/0/1"), + dict( + access=dict(vlan=20), + mode="trunk", + name="FiveGigabitEthernet1/0/1", + ), dict( access=dict(vlan_name="vlan12"), mode="trunk", diff --git a/tests/unit/modules/network/ios/test_ios_l3_interfaces.py b/tests/unit/modules/network/ios/test_ios_l3_interfaces.py index 219191e80..3e3cc038b 100644 --- a/tests/unit/modules/network/ios/test_ios_l3_interfaces.py +++ b/tests/unit/modules/network/ios/test_ios_l3_interfaces.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_l3_interfaces -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_lacp.py b/tests/unit/modules/network/ios/test_ios_lacp.py index 6c56406e6..f4460162a 100644 --- a/tests/unit/modules/network/ios/test_ios_lacp.py +++ b/tests/unit/modules/network/ios/test_ios_lacp.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_lacp -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_lacp_interfaces.py b/tests/unit/modules/network/ios/test_ios_lacp_interfaces.py index f58aa9d65..817c6869c 100644 --- a/tests/unit/modules/network/ios/test_ios_lacp_interfaces.py +++ b/tests/unit/modules/network/ios/test_ios_lacp_interfaces.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_lacp_interfaces -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -83,7 +82,11 @@ def test_ios_lacp_interface_merged(self): set_module_args( dict( config=[ - {"name": "Port-channel10", "fast_switchover": True, "max_bundle": 12}, + { + "name": "Port-channel10", + "fast_switchover": True, + "max_bundle": 12, + }, {"name": "Port-channel40", "max_bundle": 5}, {"name": "GigabitEthernet0/0"}, {"name": "GigabitEthernet0/1", "port_priority": 20}, @@ -121,7 +124,11 @@ def test_ios_lacp_interface_merged_idempotent(self): set_module_args( dict( config=[ - {"name": "Port-channel10", "fast_switchover": True, "max_bundle": 2}, + { + "name": "Port-channel10", + "fast_switchover": True, + "max_bundle": 2, + }, {"name": "Port-channel40", "max_bundle": 5}, {"name": "GigabitEthernet0/0"}, {"name": "GigabitEthernet0/1", "port_priority": 30}, @@ -150,7 +157,11 @@ def test_ios_lacp_interface_replaced(self): set_module_args( dict( config=[ - {"name": "Port-channel10", "fast_switchover": True, "max_bundle": 12}, + { + "name": "Port-channel10", + "fast_switchover": True, + "max_bundle": 12, + }, {"name": "Port-channel40", "max_bundle": 5}, {"name": "GigabitEthernet0/0"}, {"name": "GigabitEthernet0/1", "port_priority": 20}, @@ -188,7 +199,11 @@ def test_ios_lacp_interface_overridden(self): set_module_args( dict( config=[ - {"name": "Port-channel10", "fast_switchover": True, "max_bundle": 12}, + { + "name": "Port-channel10", + "fast_switchover": True, + "max_bundle": 12, + }, {"name": "Port-channel40", "max_bundle": 5}, {"name": "GigabitEthernet0/0"}, {"name": "GigabitEthernet0/1", "port_priority": 20}, @@ -226,7 +241,11 @@ def test_ios_lacp_interface_deleted(self): set_module_args( dict( config=[ - {"name": "Port-channel10", "fast_switchover": True, "max_bundle": 12}, + { + "name": "Port-channel10", + "fast_switchover": True, + "max_bundle": 12, + }, {"name": "Port-channel40", "max_bundle": 5}, {"name": "GigabitEthernet0/0"}, {"name": "GigabitEthernet0/1", "port_priority": 20}, @@ -287,7 +306,11 @@ def test_ios_lacp_interface_rendered(self): set_module_args( dict( config=[ - {"fast_switchover": True, "max_bundle": 2, "name": "Port-channel10"}, + { + "fast_switchover": True, + "max_bundle": 2, + "name": "Port-channel10", + }, {"max_bundle": 5, "name": "Port-channel40"}, {"name": "GigabitEthernet0/0"}, {"name": "GigabitEthernet0/1", "port_priority": 30}, diff --git a/tests/unit/modules/network/ios/test_ios_lag_interfaces.py b/tests/unit/modules/network/ios/test_ios_lag_interfaces.py index 1f97bef24..71d6ff933 100644 --- a/tests/unit/modules/network/ios/test_ios_lag_interfaces.py +++ b/tests/unit/modules/network/ios/test_ios_lag_interfaces.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_lag_interfaces -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -73,7 +72,11 @@ def test_ios_lag_interfaces_merged(self): "members": [ {"member": "GigabitEthernet0/2", "mode": "active"}, {"member": "GigabitEthernet0/3", "mode": "passive"}, - {"link": 20, "member": "GigabitEthernet0/4", "mode": "active"}, + { + "link": 20, + "member": "GigabitEthernet0/4", + "mode": "active", + }, {"link": 22, "member": "GigabitEthernet0/5"}, ], "name": "Port-channel22", @@ -120,7 +123,11 @@ def test_ios_lag_interfaces_merged_idempotent(self): "members": [ {"member": "GigabitEthernet0/2", "mode": "active"}, {"member": "GigabitEthernet0/3", "mode": "active"}, - {"link": 20, "member": "GigabitEthernet0/4", "mode": "active"}, + { + "link": 20, + "member": "GigabitEthernet0/4", + "mode": "active", + }, {"link": 22, "member": "GigabitEthernet0/5"}, ], "name": "Port-channel22", @@ -164,7 +171,11 @@ def test_ios_lag_interfaces_replaced(self): "members": [ {"member": "GigabitEthernet0/1", "mode": "active"}, {"member": "GigabitEthernet0/3", "mode": "on"}, - {"link": 20, "member": "GigabitEthernet0/4", "mode": "active"}, + { + "link": 20, + "member": "GigabitEthernet0/4", + "mode": "active", + }, {"link": 22, "member": "GigabitEthernet0/5"}, ], "name": "Port-channel22", @@ -219,7 +230,11 @@ def test_ios_lag_interfaces_replaced_idempotent(self): "members": [ {"member": "GigabitEthernet0/2", "mode": "active"}, {"member": "GigabitEthernet0/3", "mode": "active"}, - {"link": 20, "member": "GigabitEthernet0/4", "mode": "active"}, + { + "link": 20, + "member": "GigabitEthernet0/4", + "mode": "active", + }, {"link": 22, "member": "GigabitEthernet0/5"}, ], "name": "Port-channel22", @@ -259,7 +274,11 @@ def test_ios_lag_interfaces_overridden(self): "members": [ {"member": "GigabitEthernet0/2", "mode": "active"}, {"member": "GigabitEthernet0/3", "mode": "active"}, - {"link": 20, "member": "GigabitEthernet0/4", "mode": "active"}, + { + "link": 20, + "member": "GigabitEthernet0/4", + "mode": "active", + }, {"link": 22, "member": "GigabitEthernet0/5"}, ], "name": "Port-channel22", @@ -314,7 +333,11 @@ def test_ios_lag_interfaces_overridden_idempotent(self): "members": [ {"member": "GigabitEthernet0/2", "mode": "active"}, {"member": "GigabitEthernet0/3", "mode": "active"}, - {"link": 20, "member": "GigabitEthernet0/4", "mode": "active"}, + { + "link": 20, + "member": "GigabitEthernet0/4", + "mode": "active", + }, {"link": 22, "member": "GigabitEthernet0/5"}, ], "name": "Port-channel22", @@ -459,7 +482,11 @@ def test_ios_lag_interfaces_rendered(self): "members": [ {"member": "GigabitEthernet0/2", "mode": "active"}, {"member": "GigabitEthernet0/3", "mode": "active"}, - {"link": 20, "member": "GigabitEthernet0/4", "mode": "active"}, + { + "link": 20, + "member": "GigabitEthernet0/4", + "mode": "active", + }, {"link": 22, "member": "GigabitEthernet0/5"}, ], "name": "Port-channel22", diff --git a/tests/unit/modules/network/ios/test_ios_lldp_global.py b/tests/unit/modules/network/ios/test_ios_lldp_global.py index 4c54ef5c9..2c5eb1c40 100644 --- a/tests/unit/modules/network/ios/test_ios_lldp_global.py +++ b/tests/unit/modules/network/ios/test_ios_lldp_global.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_lldp_global -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -154,7 +153,12 @@ def test_ios_lldp_global_deleted(self): state="deleted", ), ) - commands = ["no lldp holdtime", "no lldp run", "no lldp timer", "no lldp reinit"] + commands = [ + "no lldp holdtime", + "no lldp run", + "no lldp timer", + "no lldp reinit", + ] result = self.execute_module(changed=True) self.assertEqual(result["commands"], commands) diff --git a/tests/unit/modules/network/ios/test_ios_lldp_inteface.py b/tests/unit/modules/network/ios/test_ios_lldp_inteface.py index a3dfe9706..04a25993a 100644 --- a/tests/unit/modules/network/ios/test_ios_lldp_inteface.py +++ b/tests/unit/modules/network/ios/test_ios_lldp_inteface.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_lldp_interfaces -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -241,7 +240,10 @@ def test_ios_lldp_interfaces_deleted(self): ) set_module_args( dict( - config=[dict(name="GigabitEthernet0/2"), dict(name="GigabitEthernet0/1")], + config=[ + dict(name="GigabitEthernet0/2"), + dict(name="GigabitEthernet0/1"), + ], state="deleted", ), ) diff --git a/tests/unit/modules/network/ios/test_ios_logging_global.py b/tests/unit/modules/network/ios/test_ios_logging_global.py index c3024636a..f1b3eada3 100644 --- a/tests/unit/modules/network/ios/test_ios_logging_global.py +++ b/tests/unit/modules/network/ios/test_ios_logging_global.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_logging_global -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -120,7 +119,10 @@ def test_ios_logging_global_merged_idempotent(self): reload=dict(severity="alerts"), server_arp=True, snmp_trap=["errors"], - source_interface=[dict(interface="GBit1/0"), dict(interface="CTunnel2")], + source_interface=[ + dict(interface="GBit1/0"), + dict(interface="CTunnel2"), + ], trap="errors", userinfo=True, ), @@ -250,7 +252,10 @@ def test_ios_logging_global_deleted_list(self): ], message_counter=["log", "debug"], snmp_trap=["errors"], - source_interface=[dict(interface="GBit1/0"), dict(interface="CTunnel2")], + source_interface=[ + dict(interface="GBit1/0"), + dict(interface="CTunnel2"), + ], ), ) deleted = [ @@ -317,7 +322,10 @@ def test_ios_logging_global_overridden(self): ], message_counter=["log", "debug"], snmp_trap=["errors"], - source_interface=[dict(interface="GBit1/0"), dict(interface="CTunnel2")], + source_interface=[ + dict(interface="GBit1/0"), + dict(interface="CTunnel2"), + ], ), ) overridden = [ @@ -402,9 +410,16 @@ def test_ios_logging_global_merged(self): ipv6="2001:0db8:85a3:0000:0000:8a2e:0370:7304", discriminator="msglog01 severity includes 5", ), - dict(ipv6="2001:0db8:85a3:0000:0000:8a2e:0370:7314", sequence_num_session=True), + dict( + ipv6="2001:0db8:85a3:0000:0000:8a2e:0370:7314", + sequence_num_session=True, + ), dict(ipv6="2001:0db8:85a3:0000:0000:8a2e:0370:7324", vrf="vpn1"), - dict(ipv6="2001:0db8:85a3:0000:0000:8a2e:0370:7334", stream=10, filtered=True), + dict( + ipv6="2001:0db8:85a3:0000:0000:8a2e:0370:7334", + stream=10, + filtered=True, + ), dict( ipv6="2001:0db8:85a3:0000:0000:8a2e:0370:7344", session_id=dict(tag="ipv4"), @@ -416,7 +431,9 @@ def test_ios_logging_global_merged(self): dict( ipv6="2001:0db8:85a3:0000:0000:8a2e:0370:7374", vrf="Apn2", - transport=dict(udp=dict(discriminator="msglog01 severity includes 5")), + transport=dict( + udp=dict(discriminator="msglog01 severity includes 5"), + ), ), dict( ipv6="2001:0db8:85a3:0000:0000:8a2e:0370:7384", @@ -509,7 +526,13 @@ def test_ios_logging_global_gathered_host(self): ) set_module_args(dict(state="gathered")) gathered = dict( - hosts=[dict(hostname="172.16.1.1", vrf="vpn-1", transport=dict(tcp=dict(audit=True)))], + hosts=[ + dict( + hostname="172.16.1.1", + vrf="vpn-1", + transport=dict(tcp=dict(audit=True)), + ), + ], ) result = self.execute_module(changed=False) @@ -617,9 +640,14 @@ def test_ios_logging_global_replaced(self): """, ) playbook = dict( - config=dict(hosts=[dict(hostname="172.16.2.15", session_id=dict(text="Test"))]), + config=dict( + hosts=[dict(hostname="172.16.2.15", session_id=dict(text="Test"))], + ), ) - replaced = ["no logging host 172.16.1.1", "logging host 172.16.2.15 session-id string Test"] + replaced = [ + "no logging host 172.16.1.1", + "logging host 172.16.2.15 session-id string Test", + ] playbook["state"] = "replaced" set_module_args(playbook) result = self.execute_module(changed=True) @@ -651,8 +679,14 @@ def test_ios_logging_global_replaced_ordering_host(self): {"hostname": "172.16.0.4", "vrf": "Mgmt-intf"}, ], "origin_id": {"tag": "hostname"}, - "rate_limit": {"console": True, "except_severity": "errors", "size": 10}, - "source_interface": [{"interface": "GigabitEthernet0", "vrf": "Mgmt-intf"}], + "rate_limit": { + "console": True, + "except_severity": "errors", + "size": 10, + }, + "source_interface": [ + {"interface": "GigabitEthernet0", "vrf": "Mgmt-intf"}, + ], "trap": "informational", }, } diff --git a/tests/unit/modules/network/ios/test_ios_ntp.py b/tests/unit/modules/network/ios/test_ios_ntp.py index 3e73fdfd4..fe11b77b7 100644 --- a/tests/unit/modules/network/ios/test_ios_ntp.py +++ b/tests/unit/modules/network/ios/test_ios_ntp.py @@ -18,9 +18,9 @@ __metaclass__ = type +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_ntp -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture diff --git a/tests/unit/modules/network/ios/test_ios_ntp_global.py b/tests/unit/modules/network/ios/test_ios_ntp_global.py index a9d0392c1..e955c2929 100644 --- a/tests/unit/modules/network/ios/test_ios_ntp_global.py +++ b/tests/unit/modules/network/ios/test_ios_ntp_global.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_ntp_global -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -86,7 +85,12 @@ def test_ios_ntp_global_merged_idempotent(self): allow=dict(control=dict(rate_limit=4)), authenticate=True, authentication_keys=[ - dict(algorithm="md5", encryption=7, id=2, key="SomeSecurePassword"), + dict( + algorithm="md5", + encryption=7, + id=2, + key="SomeSecurePassword", + ), ], broadcast_delay=22, logging=True, @@ -98,8 +102,18 @@ def test_ios_ntp_global_merged_idempotent(self): panic_update=True, peers=[ dict(peer="172.16.1.10", version=2), - dict(key_id=2, minpoll=5, peer="172.16.1.11", prefer=True, version=2), - dict(peer="checkPeerDomainIpv4.com", prefer=True, use_ipv4=True), + dict( + key_id=2, + minpoll=5, + peer="172.16.1.11", + prefer=True, + version=2, + ), + dict( + peer="checkPeerDomainIpv4.com", + prefer=True, + use_ipv4=True, + ), dict(peer="checkPeerDomainIpv6.com", use_ipv6=True), dict(peer="testPeerDomainIpv6.com", prefer=True, use_ipv6=True), ], @@ -109,7 +123,10 @@ def test_ios_ntp_global_merged_idempotent(self): dict(server="checkServerDomainIpv6.com", use_ipv6=True), ], source="GigabitEthernet0/1", - trusted_keys=[dict(range_start=21), dict(range_end=13, range_start=3)], + trusted_keys=[ + dict(range_start=21), + dict(range_end=13, range_start=3), + ], update_calendar=True, ), state="merged", @@ -138,7 +155,12 @@ def test_ios_ntp_global_merged(self): allow=dict(control=dict(rate_limit=4)), authenticate=True, authentication_keys=[ - dict(algorithm="md5", encryption=7, id=2, key="SomeSecurePassword"), + dict( + algorithm="md5", + encryption=7, + id=2, + key="SomeSecurePassword", + ), ], broadcast_delay=22, logging=True, @@ -150,8 +172,18 @@ def test_ios_ntp_global_merged(self): panic_update=True, peers=[ dict(peer="172.16.1.10", version=2), - dict(key=2, minpoll=5, peer="172.16.1.11", prefer=True, version=2), - dict(peer="checkPeerDomainIpv4.com", prefer=True, use_ipv4=True), + dict( + key=2, + minpoll=5, + peer="172.16.1.11", + prefer=True, + version=2, + ), + dict( + peer="checkPeerDomainIpv4.com", + prefer=True, + use_ipv4=True, + ), dict(peer="checkPeerDomainIpv6.com", use_ipv6=True), dict(peer="testPeerDomainIpv6.com", prefer=True, use_ipv6=True), ], @@ -162,7 +194,10 @@ def test_ios_ntp_global_merged(self): dict(server="checkServerDomainIpv6.com", use_ipv6=True), ], source="GigabitEthernet0/1", - trusted_keys=[dict(range_start=21), dict(range_end=13, range_start=3)], + trusted_keys=[ + dict(range_start=21), + dict(range_end=13, range_start=3), + ], update_calendar=True, ), state="merged", @@ -324,7 +359,12 @@ def test_ios_ntp_global_replaced_overridden(self): allow=dict(control=dict(rate_limit=4)), authenticate=True, authentication_keys=[ - dict(algorithm="md5", encryption=7, id=2, key="SomeSecurePassword"), + dict( + algorithm="md5", + encryption=7, + id=2, + key="SomeSecurePassword", + ), ], broadcast_delay=22, logging=True, @@ -336,8 +376,18 @@ def test_ios_ntp_global_replaced_overridden(self): panic_update=True, peers=[ dict(peer="172.16.1.10", version=2), - dict(key=2, minpoll=5, peer="172.16.1.11", prefer=True, version=2), - dict(peer="checkPeerDomainIpv4.com", prefer=True, use_ipv4=True), + dict( + key=2, + minpoll=5, + peer="172.16.1.11", + prefer=True, + version=2, + ), + dict( + peer="checkPeerDomainIpv4.com", + prefer=True, + use_ipv4=True, + ), dict(peer="checkPeerDomainIpv6.com", use_ipv6=True), dict(peer="testPeerDomainIpv6.com", prefer=True, use_ipv6=True), ], @@ -347,7 +397,10 @@ def test_ios_ntp_global_replaced_overridden(self): dict(server="checkServerDomainIpv6.com", use_ipv6=True), ], source="GigabitEthernet0/1", - trusted_keys=[dict(range_start=21), dict(range_end=13, range_start=3)], + trusted_keys=[ + dict(range_start=21), + dict(range_end=13, range_start=3), + ], update_calendar=True, ), state="replaced", @@ -415,7 +468,12 @@ def test_ios_ntp_global_replaced_overridden_idempotent(self): allow=dict(control=dict(rate_limit=4)), authenticate=True, authentication_keys=[ - dict(algorithm="md5", encryption=7, id=2, key="SomeSecurePassword"), + dict( + algorithm="md5", + encryption=7, + id=2, + key="SomeSecurePassword", + ), ], broadcast_delay=22, logging=True, @@ -426,15 +484,28 @@ def test_ios_ntp_global_replaced_overridden_idempotent(self): orphan=4, panic_update=True, peers=[ - dict(key_id=2, minpoll=5, peer="172.16.1.11", prefer=True, version=2), - dict(peer="checkPeerDomainIpv4.com", prefer=True, use_ipv4=True), + dict( + key_id=2, + minpoll=5, + peer="172.16.1.11", + prefer=True, + version=2, + ), + dict( + peer="checkPeerDomainIpv4.com", + prefer=True, + use_ipv4=True, + ), ], servers=[ dict(server="172.16.1.13", source="GigabitEthernet0/1"), dict(server="checkServerDomainIpv6.com", use_ipv6=True), ], source="Loopback888", - trusted_keys=[dict(range_start=21), dict(range_end=13, range_start=3)], + trusted_keys=[ + dict(range_start=21), + dict(range_end=13, range_start=3), + ], update_calendar=True, ), state="overridden", diff --git a/tests/unit/modules/network/ios/test_ios_ospf_interfaces.py b/tests/unit/modules/network/ios/test_ios_ospf_interfaces.py index 3721ba3ba..ea500f540 100644 --- a/tests/unit/modules/network/ios/test_ios_ospf_interfaces.py +++ b/tests/unit/modules/network/ios/test_ios_ospf_interfaces.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_ospf_interfaces -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_ospfv2.py b/tests/unit/modules/network/ios/test_ios_ospfv2.py index a8bc97105..e14def8d8 100644 --- a/tests/unit/modules/network/ios/test_ios_ospfv2.py +++ b/tests/unit/modules/network/ios/test_ios_ospfv2.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_ospfv2 -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -76,13 +75,24 @@ def test_ios_ospfv2_merged(self): ), ), network=[ - dict(address="198.51.100.0", wildcard_bits="0.0.0.255", area=5), - dict(address="192.0.2.0", wildcard_bits="0.0.0.255", area=5), + dict( + address="198.51.100.0", + wildcard_bits="0.0.0.255", + area=5, + ), + dict( + address="192.0.2.0", + wildcard_bits="0.0.0.255", + area=5, + ), ], domain_id=dict(ip_address=dict(address="192.0.3.1")), max_metric=dict(on_startup=dict(time=100), router_lsa=True), passive_interfaces=dict( - interface=dict(set_interface=False, name=["GigabitEthernet0/2"]), + interface=dict( + set_interface=False, + name=["GigabitEthernet0/2"], + ), ), vrf="blue", ), @@ -284,11 +294,17 @@ def test_ios_ospfv2_overridden(self): "areas": [ { "area_id": "5", - "authentication": {"enable": True, "message_digest": True}, + "authentication": { + "enable": True, + "message_digest": True, + }, }, { "area_id": "10", - "authentication": {"enable": True, "message_digest": True}, + "authentication": { + "enable": True, + "message_digest": True, + }, "capability": True, "default_cost": 10, "filter_list": [ @@ -470,7 +486,10 @@ def test_ios_ospfv2_overridden(self): "passive_interfaces": { "default": True, "interface": { - "name": ["GigabitEthernet0/1", "GigabitEthernet0/2"], + "name": [ + "GigabitEthernet0/1", + "GigabitEthernet0/2", + ], "set_interface": False, }, }, @@ -602,7 +621,10 @@ def test_ios_ospfv2_deleted(self): """, ) set_module_args( - dict(config=dict(processes=[dict(process_id="200", vrf="blue")]), state="deleted"), + dict( + config=dict(processes=[dict(process_id="200", vrf="blue")]), + state="deleted", + ), ) commands = ["no router ospf 200 vrf blue"] self.execute_module(changed=True, commands=commands) @@ -633,7 +655,11 @@ def test_ios_ospfv2_parsed(self): "processes": [ { "areas": [ - {"area_id": "5", "authentication": {"enable": True}, "capability": True}, + { + "area_id": "5", + "authentication": {"enable": True}, + "capability": True, + }, ], "process_id": 1, }, @@ -678,11 +704,17 @@ def test_ios_ospfv2_rendered(self): "areas": [ { "area_id": "5", - "authentication": {"enable": True, "message_digest": True}, + "authentication": { + "enable": True, + "message_digest": True, + }, }, { "area_id": "10", - "authentication": {"enable": True, "message_digest": True}, + "authentication": { + "enable": True, + "message_digest": True, + }, "capability": True, "default_cost": 10, "filter_list": [ @@ -863,7 +895,10 @@ def test_ios_ospfv2_rendered(self): "passive_interfaces": { "default": True, "interface": { - "name": ["GigabitEthernet0/1", "GigabitEthernet0/2"], + "name": [ + "GigabitEthernet0/1", + "GigabitEthernet0/2", + ], "set_interface": False, }, }, @@ -1031,13 +1066,19 @@ def test_ios_ospfv2_overridden_2(self): "lsa_group": 25, }, }, - "max_metric": {"router_lsa": True, "on_startup": {"time": 100}}, + "max_metric": { + "router_lsa": True, + "on_startup": {"time": 100}, + }, "areas": [{"area_id": "10", "capability": True}], "passive_interfaces": { "default": True, "interface": { "set_interface": False, - "name": ["GigabitEthernet0/2", "GigabitEthernet0/1"], + "name": [ + "GigabitEthernet0/2", + "GigabitEthernet0/1", + ], }, }, }, @@ -1143,13 +1184,19 @@ def test_ios_ospfv2_overridden_idempotent(self): ], }, "domain_id": {"ip_address": {"address": "192.0.3.1"}}, - "max_metric": {"router_lsa": True, "on_startup": {"time": 100}}, + "max_metric": { + "router_lsa": True, + "on_startup": {"time": 100}, + }, "areas": [{"area_id": "10", "capability": True}], "passive_interfaces": { "default": True, "interface": { "set_interface": False, - "name": ["GigabitEthernet0/2", "GigabitEthernet0/1"], + "name": [ + "GigabitEthernet0/2", + "GigabitEthernet0/1", + ], }, }, }, diff --git a/tests/unit/modules/network/ios/test_ios_ospfv3.py b/tests/unit/modules/network/ios/test_ios_ospfv3.py index 30c646123..efaae19ac 100644 --- a/tests/unit/modules/network/ios/test_ios_ospfv3.py +++ b/tests/unit/modules/network/ios/test_ios_ospfv3.py @@ -7,9 +7,9 @@ __metaclass__ = type +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_ospfv3 -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture @@ -58,7 +58,10 @@ def test_ios_ospfv3_merged(self): afi="ipv4", unicast=True, vrf="blue", - adjacency=dict(min_adjacency=100, max_adjacency=100), + adjacency=dict( + min_adjacency=100, + max_adjacency=100, + ), ), ], ), @@ -89,7 +92,9 @@ def test_ios_ospfv3_merged_idempotent(self): areas=[ dict( area_id=10, - nssa=dict(default_information_originate=dict(metric=10)), + nssa=dict( + default_information_originate=dict(metric=10), + ), ), ], address_family=[ @@ -132,7 +137,10 @@ def test_ios_ospfv3_replaced(self): afi="ipv4", unicast=True, vrf="blue", - adjacency=dict(min_adjacency=100, max_adjacency=100), + adjacency=dict( + min_adjacency=100, + max_adjacency=100, + ), ), ], ), @@ -164,7 +172,9 @@ def test_ios_ospfv3_replaced_idempotent(self): areas=[ dict( area_id=10, - nssa=dict(default_information_originate=dict(metric=10)), + nssa=dict( + default_information_originate=dict(metric=10), + ), ), ], address_family=[ @@ -205,7 +215,9 @@ def test_ios_ospfv3_overridden(self): areas=[ dict( area_id=10, - nssa=dict(default_information_originate=dict(metric=10)), + nssa=dict( + default_information_originate=dict(metric=10), + ), ), ], address_family=[ @@ -256,7 +268,9 @@ def test_ios_ospfv3_overridden_idempotent(self): areas=[ dict( area_id=10, - nssa=dict(default_information_originate=dict(metric=10)), + nssa=dict( + default_information_originate=dict(metric=10), + ), ), ], address_family=[ @@ -287,7 +301,9 @@ def test_ios_ospfv3_overridden_idempotent(self): self.execute_module(changed=False, commands=[]) def test_ios_ospfv3_deleted(self): - set_module_args(dict(config=dict(processes=[dict(process_id="1")]), state="deleted")) + set_module_args( + dict(config=dict(processes=[dict(process_id="1")]), state="deleted"), + ) commands = ["no router ospfv3 1"] self.execute_module(changed=True, commands=commands) diff --git a/tests/unit/modules/network/ios/test_ios_ping.py b/tests/unit/modules/network/ios/test_ios_ping.py index bdb822e62..02969ffe0 100644 --- a/tests/unit/modules/network/ios/test_ios_ping.py +++ b/tests/unit/modules/network/ios/test_ios_ping.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_ping -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -61,7 +60,9 @@ def test_ios_ping_v6(self): Success rate is 100 percent (2/2), round-trip min/avg/max = 25/25/25 ms """, ) - set_module_args(dict(count=2, dest="2001:db8:ffff:ffff:ffff:ffff:ffff:ffff", afi="ipv6")) + set_module_args( + dict(count=2, dest="2001:db8:ffff:ffff:ffff:ffff:ffff:ffff", afi="ipv6"), + ) result = self.execute_module() mock_res = { "commands": "ping ipv6 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff repeat 2", diff --git a/tests/unit/modules/network/ios/test_ios_prefix_lists.py b/tests/unit/modules/network/ios/test_ios_prefix_lists.py index 2aac373dd..0df4be859 100644 --- a/tests/unit/modules/network/ios/test_ios_prefix_lists.py +++ b/tests/unit/modules/network/ios/test_ios_prefix_lists.py @@ -7,9 +7,9 @@ __metaclass__ = type +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_prefix_lists -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture @@ -74,7 +74,12 @@ def test_ios_prefix_lists_merged(self): prefix="35.0.0.0/8", sequence=5, ), - dict(action="deny", ge=20, prefix="35.0.0.0/8", sequence=10), + dict( + action="deny", + ge=20, + prefix="35.0.0.0/8", + sequence=10, + ), ], name="test_prefix", ), @@ -121,9 +126,24 @@ def test_ios_prefix_lists_merged_idempotent(self): dict( description="this is test description", entries=[ - dict(action="deny", le=15, prefix="1.0.0.0/8", sequence=5), - dict(action="deny", ge=10, prefix="35.0.0.0/8", sequence=10), - dict(action="deny", ge=15, prefix="12.0.0.0/8", sequence=15), + dict( + action="deny", + le=15, + prefix="1.0.0.0/8", + sequence=5, + ), + dict( + action="deny", + ge=10, + prefix="35.0.0.0/8", + sequence=10, + ), + dict( + action="deny", + ge=15, + prefix="12.0.0.0/8", + sequence=15, + ), dict( action="deny", ge=20, @@ -137,7 +157,12 @@ def test_ios_prefix_lists_merged_idempotent(self): dict( description="this is test", entries=[ - dict(action="deny", ge=15, prefix="12.0.0.0/8", sequence=50), + dict( + action="deny", + ge=15, + prefix="12.0.0.0/8", + sequence=50, + ), ], name="test", ), @@ -151,7 +176,12 @@ def test_ios_prefix_lists_merged_idempotent(self): prefix="35.0.0.0/8", sequence=5, ), - dict(action="deny", ge=20, prefix="35.0.0.0/8", sequence=10), + dict( + action="deny", + ge=20, + prefix="35.0.0.0/8", + sequence=10, + ), ], name="test_prefix", ), @@ -190,7 +220,12 @@ def test_ios_prefix_lists_replaced(self): dict( description="this is replace test", entries=[ - dict(action="deny", ge=15, prefix="12.0.0.0/8", sequence=15), + dict( + action="deny", + ge=15, + prefix="12.0.0.0/8", + sequence=15, + ), dict( action="deny", ge=20, @@ -204,7 +239,12 @@ def test_ios_prefix_lists_replaced(self): dict( description="this is replace test", entries=[ - dict(action="deny", ge=20, prefix="35.0.0.0/8", sequence=10), + dict( + action="deny", + ge=20, + prefix="35.0.0.0/8", + sequence=10, + ), ], name="test_replace", ), @@ -255,9 +295,24 @@ def test_ios_prefix_lists_replaced_idempotent(self): dict( description="this is test description", entries=[ - dict(action="deny", le=15, prefix="1.0.0.0/8", sequence=5), - dict(action="deny", ge=10, prefix="35.0.0.0/8", sequence=10), - dict(action="deny", ge=15, prefix="12.0.0.0/8", sequence=15), + dict( + action="deny", + le=15, + prefix="1.0.0.0/8", + sequence=5, + ), + dict( + action="deny", + ge=10, + prefix="35.0.0.0/8", + sequence=10, + ), + dict( + action="deny", + ge=15, + prefix="12.0.0.0/8", + sequence=15, + ), dict( action="deny", ge=20, @@ -271,7 +326,12 @@ def test_ios_prefix_lists_replaced_idempotent(self): dict( description="this is test", entries=[ - dict(action="deny", ge=15, prefix="12.0.0.0/8", sequence=50), + dict( + action="deny", + ge=15, + prefix="12.0.0.0/8", + sequence=50, + ), ], name="test", ), @@ -285,7 +345,12 @@ def test_ios_prefix_lists_replaced_idempotent(self): prefix="35.0.0.0/8", sequence=5, ), - dict(action="deny", ge=20, prefix="35.0.0.0/8", sequence=10), + dict( + action="deny", + ge=20, + prefix="35.0.0.0/8", + sequence=10, + ), ], name="test_prefix", ), @@ -324,7 +389,12 @@ def test_ios_prefix_lists_overridden(self): dict( description="this is override test", entries=[ - dict(action="deny", ge=15, prefix="12.0.0.0/8", sequence=15), + dict( + action="deny", + ge=15, + prefix="12.0.0.0/8", + sequence=15, + ), dict( action="deny", ge=20, @@ -338,7 +408,12 @@ def test_ios_prefix_lists_overridden(self): dict( description="this is override test", entries=[ - dict(action="deny", ge=20, prefix="35.0.0.0/8", sequence=10), + dict( + action="deny", + ge=20, + prefix="35.0.0.0/8", + sequence=10, + ), ], name="test_override", ), @@ -391,9 +466,24 @@ def test_ios_prefix_lists_overridden_idempotent(self): dict( description="this is test description", entries=[ - dict(action="deny", le=15, prefix="1.0.0.0/8", sequence=5), - dict(action="deny", ge=10, prefix="35.0.0.0/8", sequence=10), - dict(action="deny", ge=15, prefix="12.0.0.0/8", sequence=15), + dict( + action="deny", + le=15, + prefix="1.0.0.0/8", + sequence=5, + ), + dict( + action="deny", + ge=10, + prefix="35.0.0.0/8", + sequence=10, + ), + dict( + action="deny", + ge=15, + prefix="12.0.0.0/8", + sequence=15, + ), dict( action="deny", ge=20, @@ -407,7 +497,12 @@ def test_ios_prefix_lists_overridden_idempotent(self): dict( description="this is test", entries=[ - dict(action="deny", ge=15, prefix="12.0.0.0/8", sequence=50), + dict( + action="deny", + ge=15, + prefix="12.0.0.0/8", + sequence=50, + ), ], name="test", ), @@ -421,7 +516,12 @@ def test_ios_prefix_lists_overridden_idempotent(self): prefix="35.0.0.0/8", sequence=5, ), - dict(action="deny", ge=20, prefix="35.0.0.0/8", sequence=10), + dict( + action="deny", + ge=20, + prefix="35.0.0.0/8", + sequence=10, + ), ], name="test_prefix", ), @@ -491,7 +591,12 @@ def test_ios_prefix_lists_rendered(self): prefix="35.0.0.0/8", sequence=5, ), - dict(action="deny", ge=20, prefix="35.0.0.0/8", sequence=10), + dict( + action="deny", + ge=20, + prefix="35.0.0.0/8", + sequence=10, + ), ], name="test_prefix", ), diff --git a/tests/unit/modules/network/ios/test_ios_route_maps.py b/tests/unit/modules/network/ios/test_ios_route_maps.py index 0e450f908..27c5aa7f6 100644 --- a/tests/unit/modules/network/ios/test_ios_route_maps.py +++ b/tests/unit/modules/network/ios/test_ios_route_maps.py @@ -7,9 +7,9 @@ __metaclass__ = type +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_route_maps -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture @@ -58,7 +58,10 @@ def test_ios_route_maps_merged(self): additional_paths=dict(all=True), as_path=dict(acls=[100, 120]), clns=dict(address="test_osi"), - community=dict(exact_match=True, name=["new_merge"]), + community=dict( + exact_match=True, + name=["new_merge"], + ), ip=dict(address=dict(acls=[10, 100])), length=dict(maximum=50000, minimum=5000), mpls_label=True, @@ -213,7 +216,10 @@ def test_ios_route_maps_merged_idempotent(self): vpn_distinguisher=dict(address="192.0.2.1:12"), ), global_route=True, - interfaces=["GigabitEthernet0/2", "GigabitEthernet0/1"], + interfaces=[ + "GigabitEthernet0/2", + "GigabitEthernet0/1", + ], level=dict(level_1_2=True), lisp="test_lisp", local_preference=100, @@ -249,7 +255,10 @@ def test_ios_route_maps_replaced(self): additional_paths=dict(all=True), as_path=dict(acls=[100, 120]), clns=dict(address="test_osi"), - community=dict(exact_match=True, name=["new_replace"]), + community=dict( + exact_match=True, + name=["new_replace"], + ), ip=dict(address=dict(acls=[10, 100])), length=dict(maximum=50000, minimum=5000), mpls_label=True, @@ -418,7 +427,10 @@ def test_ios_route_maps_replaced_idempotent(self): vpn_distinguisher=dict(address="192.0.2.1:12"), ), global_route=True, - interfaces=["GigabitEthernet0/2", "GigabitEthernet0/1"], + interfaces=[ + "GigabitEthernet0/2", + "GigabitEthernet0/1", + ], level=dict(level_1_2=True), lisp="test_lisp", local_preference=100, @@ -454,7 +466,10 @@ def test_ios_route_maps_overridden(self): additional_paths=dict(all=True), as_path=dict(acls=[100, 120]), clns=dict(address="test_osi"), - community=dict(exact_match=True, name=["new_override"]), + community=dict( + exact_match=True, + name=["new_override"], + ), ip=dict(address=dict(acls=[10, 100])), length=dict(maximum=50000, minimum=5000), mpls_label=True, @@ -623,7 +638,10 @@ def test_ios_route_maps_overridden_idempotent(self): vpn_distinguisher=dict(address="192.0.2.1:12"), ), global_route=True, - interfaces=["GigabitEthernet0/2", "GigabitEthernet0/1"], + interfaces=[ + "GigabitEthernet0/2", + "GigabitEthernet0/1", + ], level=dict(level_1_2=True), lisp="test_lisp", local_preference=100, @@ -676,7 +694,10 @@ def test_ios_route_maps_rendered(self): name=["99", "98", "test_1", "test_2"], ), extcommunity=["110", "130"], - interfaces=["GigabitEthernet0/1", "GigabitEthernet0/2"], + interfaces=[ + "GigabitEthernet0/1", + "GigabitEthernet0/2", + ], ip=dict(address=dict(acls=[10, 100])), ipv6=dict(route_source=dict(acl="test_ipv6")), length=dict(maximum=10000, minimum=1000), @@ -702,7 +723,9 @@ def test_ios_route_maps_rendered(self): sequence=30, set=dict( as_path=dict( - prepend=dict(as_number=["65512", 65522, "65532", 65543]), + prepend=dict( + as_number=["65512", 65522, "65532", 65543], + ), ), ), ), @@ -727,7 +750,10 @@ def test_ios_route_maps_rendered(self): vpn_distinguisher=dict(address="192.0.2.1:12"), ), global_route=True, - interfaces=["GigabitEthernet0/2", "GigabitEthernet0/1"], + interfaces=[ + "GigabitEthernet0/2", + "GigabitEthernet0/1", + ], level=dict(level_1_2=True), lisp="test_lisp", local_preference=100, diff --git a/tests/unit/modules/network/ios/test_ios_service.py b/tests/unit/modules/network/ios/test_ios_service.py index cbf9a9fd7..fa92efcdc 100644 --- a/tests/unit/modules/network/ios/test_ios_service.py +++ b/tests/unit/modules/network/ios/test_ios_service.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_service -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_snmp_server.py b/tests/unit/modules/network/ios/test_ios_snmp_server.py index 28a11fd7c..0b8f797a1 100644 --- a/tests/unit/modules/network/ios/test_ios_snmp_server.py +++ b/tests/unit/modules/network/ios/test_ios_snmp_server.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_snmp_server -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -168,10 +167,19 @@ def test_ios_snmp_server_merged_idempotent(self): "context": ["contextWord2", "contextWord1"], "engine_id": [ {"id": "AB0C5342FA0A", "local": True}, - {"id": "AB0C5342FAAA", "remote": {"host": "172.16.0.1", "udp_port": 22}}, - {"id": "AB0C5342FAAB", "remote": {"host": "172.16.0.2", "udp_port": 23}}, + { + "id": "AB0C5342FAAA", + "remote": {"host": "172.16.0.1", "udp_port": 22}, + }, + { + "id": "AB0C5342FAAB", + "remote": {"host": "172.16.0.2", "udp_port": 23}, + }, ], - "file_transfer": {"access_group": "testAcl", "protocol": ["ftp", "rcp"]}, + "file_transfer": { + "access_group": "testAcl", + "protocol": ["ftp", "rcp"], + }, "groups": [ {"group": "group0", "version": "v3", "version_option": "auth"}, { @@ -182,7 +190,11 @@ def test_ios_snmp_server_merged_idempotent(self): "version": "v1", }, {"group": "group2", "version": "v3", "version_option": "priv"}, - {"group": "replaceUser", "version": "v3", "version_option": "noauth"}, + { + "group": "replaceUser", + "version": "v3", + "version_option": "noauth", + }, {"acl_v6": "ipv6acl", "group": "group3", "version": "v1"}, {"acl_v4": "2", "group": "group4", "version": "v1"}, ], @@ -221,8 +233,16 @@ def test_ios_snmp_server_merged_idempotent(self): "traps": ["msdp"], "version": "2c", }, - {"community_string": "check", "host": "172.16.2.99", "traps": ["slb"]}, - {"community_string": "checktrap", "host": "172.16.2.99", "traps": ["isis"]}, + { + "community_string": "check", + "host": "172.16.2.99", + "traps": ["slb"], + }, + { + "community_string": "checktrap", + "host": "172.16.2.99", + "traps": ["isis"], + }, ], "inform": {"pending": 2}, "ip": {"dscp": 2}, @@ -304,7 +324,12 @@ def test_ios_snmp_server_merged_idempotent(self): }, "ipmulticast": True, "ipsec": { - "cryptomap": {"add": True, "attach": True, "delete": True, "detach": True}, + "cryptomap": { + "add": True, + "attach": True, + "delete": True, + "detach": True, + }, "too_many_sas": True, "tunnel": {"start": True, "stop": True}, }, @@ -357,7 +382,12 @@ def test_ios_snmp_server_merged_idempotent(self): }, }, "users": [ - {"acl_v4": "24", "group": "newfamily", "username": "newuser", "version": "v1"}, + { + "acl_v4": "24", + "group": "newfamily", + "username": "newuser", + "version": "v1", + }, { "acl_v4": "ipv4acl", "acl_v6": "ipv6acl", @@ -365,7 +395,11 @@ def test_ios_snmp_server_merged_idempotent(self): "username": "paul", "version": "v3", }, - {"group": "replaceUser", "username": "replaceUser", "version": "v3"}, + { + "group": "replaceUser", + "username": "replaceUser", + "version": "v3", + }, ], }, } @@ -441,9 +475,15 @@ def test_ios_snmp_server_merged(self): "id": "AB0C5342FAAA", "remote": {"host": "172.16.0.1", "udp_port": 22, "vrf": "mgmt"}, }, - {"id": "AB0C5342FAAB", "remote": {"host": "172.16.0.2", "udp_port": 23}}, + { + "id": "AB0C5342FAAB", + "remote": {"host": "172.16.0.2", "udp_port": 23}, + }, ], - "file_transfer": {"access_group": "testAcl", "protocol": ["ftp", "rcp"]}, + "file_transfer": { + "access_group": "testAcl", + "protocol": ["ftp", "rcp"], + }, "groups": [ {"group": "group0", "version": "v3", "version_option": "auth"}, { @@ -454,7 +494,11 @@ def test_ios_snmp_server_merged(self): "version": "v1", }, {"group": "group2", "version": "v3", "version_option": "priv"}, - {"group": "replaceUser", "version": "v3", "version_option": "noauth"}, + { + "group": "replaceUser", + "version": "v3", + "version_option": "noauth", + }, {"acl_v6": "ipv6acl", "group": "group3", "version": "v1"}, {"acl_v4": "2", "group": "group4", "version": "v1"}, ], @@ -493,8 +537,16 @@ def test_ios_snmp_server_merged(self): "traps": ["msdp"], "version": "2c", }, - {"community_string": "check", "host": "172.16.2.99", "traps": ["slb"]}, - {"community_string": "checktrap", "host": "172.16.2.99", "traps": ["isis"]}, + { + "community_string": "check", + "host": "172.16.2.99", + "traps": ["slb"], + }, + { + "community_string": "checktrap", + "host": "172.16.2.99", + "traps": ["isis"], + }, ], "inform": {"pending": 2}, "ip": {"dscp": 2}, @@ -586,7 +638,12 @@ def test_ios_snmp_server_merged(self): }, "ipmulticast": True, "ipsec": { - "cryptomap": {"add": True, "attach": True, "delete": True, "detach": True}, + "cryptomap": { + "add": True, + "attach": True, + "delete": True, + "detach": True, + }, "too_many_sas": True, "tunnel": {"start": True, "stop": True}, }, @@ -639,15 +696,29 @@ def test_ios_snmp_server_merged(self): }, }, "users": [ - {"acl_v4": "24", "group": "newfamily", "username": "newuser", "version": "v1"}, + { + "acl_v4": "24", + "group": "newfamily", + "username": "newuser", + "version": "v1", + }, { "acl_v6": "ipv6only", "group": "familypaul", "username": "paul", "version": "v3", }, - {"group": "replaceUser", "username": "replaceUser", "version": "v3"}, - {"acl_v4": "27", "group": "mfamily", "username": "flow", "version": "v3"}, + { + "group": "replaceUser", + "username": "replaceUser", + "version": "v3", + }, + { + "acl_v4": "27", + "group": "mfamily", + "username": "flow", + "version": "v3", + }, ], }, } @@ -1122,10 +1193,19 @@ def test_ios_snmp_server_overridden(self): "context": ["contextWord2", "contextWord1"], "engine_id": [ {"id": "AB0C5342FA0A", "local": True}, - {"id": "AB0C5342FAAA", "remote": {"host": "172.16.0.1", "udp_port": 22}}, - {"id": "AB0C5342FAAB", "remote": {"host": "172.16.0.2", "udp_port": 23}}, + { + "id": "AB0C5342FAAA", + "remote": {"host": "172.16.0.1", "udp_port": 22}, + }, + { + "id": "AB0C5342FAAB", + "remote": {"host": "172.16.0.2", "udp_port": 23}, + }, ], - "file_transfer": {"access_group": "testAcl", "protocol": ["ftp", "rcp"]}, + "file_transfer": { + "access_group": "testAcl", + "protocol": ["ftp", "rcp"], + }, "groups": [ {"group": "group0", "version": "v3", "version_option": "auth"}, { @@ -1136,7 +1216,11 @@ def test_ios_snmp_server_overridden(self): "version": "v1", }, {"group": "group2", "version": "v3", "version_option": "priv"}, - {"group": "replaceUser", "version": "v3", "version_option": "noauth"}, + { + "group": "replaceUser", + "version": "v3", + "version_option": "noauth", + }, ], "hosts": [ { @@ -1173,8 +1257,16 @@ def test_ios_snmp_server_overridden(self): "traps": ["msdp"], "version": "2c", }, - {"community_string": "check", "host": "172.16.2.99", "traps": ["slb"]}, - {"community_string": "checktrap", "host": "172.16.2.99", "traps": ["isis"]}, + { + "community_string": "check", + "host": "172.16.2.99", + "traps": ["slb"], + }, + { + "community_string": "checktrap", + "host": "172.16.2.99", + "traps": ["isis"], + }, ], "inform": {"pending": 2}, "ip": {"dscp": 2}, @@ -1256,7 +1348,12 @@ def test_ios_snmp_server_overridden(self): }, "ipmulticast": True, "ipsec": { - "cryptomap": {"add": True, "attach": True, "delete": True, "detach": True}, + "cryptomap": { + "add": True, + "attach": True, + "delete": True, + "detach": True, + }, "too_many_sas": True, "tunnel": {"start": True, "stop": True}, }, @@ -1309,18 +1406,35 @@ def test_ios_snmp_server_overridden(self): }, }, "users": [ - {"acl_v4": "24", "group": "newfamily", "username": "newuser", "version": "v1"}, + { + "acl_v4": "24", + "group": "newfamily", + "username": "newuser", + "version": "v1", + }, { "acl_v6": "ipv6acl", "group": "familypaul", "username": "paul", "version": "v3", }, - {"group": "replaceUser", "username": "replaceUser", "version": "v3"}, + { + "group": "replaceUser", + "username": "replaceUser", + "version": "v3", + }, ], "views": [ - {"name": "no-write.test", "family_name": "testiso", "excluded": True}, - {"name": "newView", "family_name": "TestFamilyName", "included": True}, + { + "name": "no-write.test", + "family_name": "testiso", + "excluded": True, + }, + { + "name": "newView", + "family_name": "TestFamilyName", + "included": True, + }, ], }, } @@ -1393,7 +1507,11 @@ def test_ios_snmp_server_replaced_idempotent(self): "traps": ["msdp"], "version": "2c", }, - {"community_string": "check", "host": "172.16.2.99", "traps": ["slb"]}, + { + "community_string": "check", + "host": "172.16.2.99", + "traps": ["slb"], + }, ], }, } @@ -1445,10 +1563,18 @@ def test_ios_snmp_server_parsed(self): parsed = { "engine_id": [ {"id": "AB0C5342FA0A", "local": True}, - {"id": "AB0C5342FAAB", "remote": {"host": "172.16.0.2", "udp_port": 23}}, + { + "id": "AB0C5342FAAB", + "remote": {"host": "172.16.0.2", "udp_port": 23}, + }, ], "users": [ - {"username": "paul", "group": "familypaul", "version": "v3", "acl_v6": "ipv6acl"}, + { + "username": "paul", + "group": "familypaul", + "version": "v3", + "acl_v6": "ipv6acl", + }, ], "traps": { "ospf": { @@ -1525,8 +1651,16 @@ def test_ios_snmp_server_parsed(self): "traps": ["msdp", "stun"], "version": "2c", }, - {"host": "172.16.2.99", "community_string": "check", "traps": ["slb", "pki"]}, - {"host": "172.16.2.99", "community_string": "checktrap", "traps": ["isis", "hsrp"]}, + { + "host": "172.16.2.99", + "community_string": "check", + "traps": ["slb", "pki"], + }, + { + "host": "172.16.2.99", + "community_string": "checktrap", + "traps": ["isis", "hsrp"], + }, ], "groups": [ { @@ -1614,7 +1748,11 @@ def test_ios_snmp_server_gathered(self): "version": "3", "version_option": "noauth", }, - {"host": "172.16.2.99", "community_string": "checktrap", "traps": ["isis", "hsrp"]}, + { + "host": "172.16.2.99", + "community_string": "checktrap", + "traps": ["isis", "hsrp"], + }, ], "users": [ { @@ -1663,7 +1801,10 @@ def test_ios_snmp_server_rendered(self): "config": { "engine_id": [ {"id": "AB0C5342FA0A", "local": True}, - {"id": "AB0C5342FAAB", "remote": {"host": "172.16.0.2", "udp_port": 23}}, + { + "id": "AB0C5342FAAB", + "remote": {"host": "172.16.0.2", "udp_port": 23}, + }, ], "views": [ {"family_name": "iso", "name": "ro"}, @@ -1759,8 +1900,16 @@ def test_ios_snmp_server_rendered(self): "traps": ["msdp"], "version": "2c", }, - {"host": "172.16.2.99", "community_string": "check", "traps": ["slb"]}, - {"host": "172.16.2.99", "community_string": "checktrap", "traps": ["isis"]}, + { + "host": "172.16.2.99", + "community_string": "check", + "traps": ["slb"], + }, + { + "host": "172.16.2.99", + "community_string": "checktrap", + "traps": ["isis"], + }, ], }, "state": "rendered", @@ -1808,7 +1957,10 @@ def test_ios_snmp_server_rendered_user_options(self): "username": "paul", "group": "familypaul", "version": "v3", - "authentication": {"algorithm": "md5", "password": "somepass"}, + "authentication": { + "algorithm": "md5", + "password": "somepass", + }, "encryption": { "priv": "aes", "priv_option": 128, @@ -1820,7 +1972,9 @@ def test_ios_snmp_server_rendered_user_options(self): "state": "rendered", }, ) - rendered = ["snmp-server user paul familypaul v3 auth md5 somepass priv aes 128 somepass"] + rendered = [ + "snmp-server user paul familypaul v3 auth md5 somepass priv aes 128 somepass", + ] result = self.execute_module(changed=False) self.maxDiff = None self.assertEqual(sorted(result["rendered"]), sorted(rendered)) diff --git a/tests/unit/modules/network/ios/test_ios_static_routes.py b/tests/unit/modules/network/ios/test_ios_static_routes.py index d1046cc72..57a416433 100644 --- a/tests/unit/modules/network/ios/test_ios_static_routes.py +++ b/tests/unit/modules/network/ios/test_ios_static_routes.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_static_routes -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule @@ -232,7 +231,10 @@ def test_ios_static_routes_merged_idempotent(self): "routes": [ { "next_hops": [ - {"forward_router_address": "10.1.1.2", "track": 10}, + { + "forward_router_address": "10.1.1.2", + "track": 10, + }, { "forward_router_address": "10.1.1.3", "distance_metric": 22, @@ -422,7 +424,10 @@ def test_ios_static_routes_replaced(self): "routes": [ { "next_hops": [ - {"forward_router_address": "10.1.1.2", "track": 10}, + { + "forward_router_address": "10.1.1.2", + "track": 10, + }, { "forward_router_address": "10.1.1.3", "distance_metric": 22, @@ -639,7 +644,10 @@ def test_ios_static_routes_replaced_idempotent(self): "routes": [ { "next_hops": [ - {"forward_router_address": "10.1.1.2", "track": 10}, + { + "forward_router_address": "10.1.1.2", + "track": 10, + }, { "forward_router_address": "10.1.1.3", "distance_metric": 22, @@ -829,7 +837,10 @@ def test_ios_static_routes_overridden(self): "routes": [ { "next_hops": [ - {"forward_router_address": "10.1.1.2", "track": 10}, + { + "forward_router_address": "10.1.1.2", + "track": 10, + }, { "forward_router_address": "10.1.1.3", "distance_metric": 22, @@ -1046,7 +1057,10 @@ def test_ios_static_routes_overridden_idempotent(self): "routes": [ { "next_hops": [ - {"forward_router_address": "10.1.1.2", "track": 10}, + { + "forward_router_address": "10.1.1.2", + "track": 10, + }, { "forward_router_address": "10.1.1.3", "distance_metric": 22, @@ -1236,7 +1250,10 @@ def test_ios_delete_static_route_config_del_all(self): "routes": [ { "next_hops": [ - {"forward_router_address": "10.1.1.2", "track": 10}, + { + "forward_router_address": "10.1.1.2", + "track": 10, + }, { "forward_router_address": "10.1.1.3", "distance_metric": 22, @@ -1716,7 +1733,9 @@ def test_ios_delete_static_route_vrf_based(self): config=[ dict( vrf="testVrf2", - address_families=[dict(afi="ipv4", routes=[dict(dest="192.0.2.0/24")])], + address_families=[ + dict(afi="ipv4", routes=[dict(dest="192.0.2.0/24")]), + ], ), dict( vrf="testVrfv6", @@ -1840,7 +1859,10 @@ def test_ios_static_route_rendered(self): "routes": [ { "next_hops": [ - {"forward_router_address": "10.1.1.2", "track": 10}, + { + "forward_router_address": "10.1.1.2", + "track": 10, + }, { "forward_router_address": "10.1.1.3", "distance_metric": 22, @@ -2127,7 +2149,9 @@ def test_ios_static_route_gathered(self): "routes": [ { "dest": "10.0.0.0/8", - "next_hops": [{"interface": "Null0", "permanent": True}], + "next_hops": [ + {"interface": "Null0", "permanent": True}, + ], }, ], }, diff --git a/tests/unit/modules/network/ios/test_ios_system.py b/tests/unit/modules/network/ios/test_ios_system.py index b82d7ae48..915d7a1f7 100644 --- a/tests/unit/modules/network/ios/test_ios_system.py +++ b/tests/unit/modules/network/ios/test_ios_system.py @@ -21,9 +21,9 @@ __metaclass__ = type +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_system -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture @@ -70,7 +70,12 @@ def test_ios_system_domain_name(self): def test_ios_system_domain_name_complex(self): set_module_args( - dict(domain_name=[{"name": "test.com", "vrf": "test"}, {"name": "eng.example.net"}]), + dict( + domain_name=[ + {"name": "test.com", "vrf": "test"}, + {"name": "eng.example.net"}, + ], + ), ) commands = [ "ip domain name vrf test test.com", @@ -107,7 +112,10 @@ def test_ios_system_lookup_source(self): def test_ios_system_name_servers(self): name_servers = ["8.8.8.8", "8.8.4.4"] set_module_args(dict(name_servers=name_servers)) - commands = ["no ip name-server vrf management 8.8.8.8", "ip name-server 8.8.4.4"] + commands = [ + "no ip name-server vrf management 8.8.8.8", + "ip name-server 8.8.4.4", + ] self.execute_module(changed=True, commands=commands, sort=False) def rest_ios_system_name_servers_complex(self): diff --git a/tests/unit/modules/network/ios/test_ios_user.py b/tests/unit/modules/network/ios/test_ios_user.py index 3dd03ab81..a13467afb 100644 --- a/tests/unit/modules/network/ios/test_ios_user.py +++ b/tests/unit/modules/network/ios/test_ios_user.py @@ -20,9 +20,9 @@ __metaclass__ = type +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_user -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture @@ -117,18 +117,26 @@ def test_ios_user_view(self): self.assertEqual(result["commands"], ["username ansible view test"]) def test_ios_user_update_password_changed(self): - set_module_args(dict(name="test", configured_password="test", update_password="on_create")) + set_module_args( + dict(name="test", configured_password="test", update_password="on_create"), + ) result = self.execute_module(changed=True) self.assertEqual(result["commands"], ["username test secret test"]) def test_ios_user_update_password_on_create_ok(self): set_module_args( - dict(name="ansible", configured_password="test", update_password="on_create"), + dict( + name="ansible", + configured_password="test", + update_password="on_create", + ), ) self.execute_module() def test_ios_user_update_password_always(self): - set_module_args(dict(name="ansible", configured_password="test", update_password="always")) + set_module_args( + dict(name="ansible", configured_password="test", update_password="always"), + ) result = self.execute_module(changed=True) self.assertEqual(result["commands"], ["username ansible secret test"]) @@ -169,7 +177,10 @@ def test_add_hashed_password(self): ), ) result = self.execute_module(changed=True) - self.assertEqual(result["commands"], [f"username ansible secret 9 {hashed_password_val}"]) + self.assertEqual( + result["commands"], + [f"username ansible secret 9 {hashed_password_val}"], + ) def test_add_hpassword_with_type(self): set_module_args( diff --git a/tests/unit/modules/network/ios/test_ios_vlans.py b/tests/unit/modules/network/ios/test_ios_vlans.py index e949bb258..a8a848020 100644 --- a/tests/unit/modules/network/ios/test_ios_vlans.py +++ b/tests/unit/modules/network/ios/test_ios_vlans.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_vlans -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/network/ios/test_ios_vrf.py b/tests/unit/modules/network/ios/test_ios_vrf.py index d36ea41e1..f39061989 100644 --- a/tests/unit/modules/network/ios/test_ios_vrf.py +++ b/tests/unit/modules/network/ios/test_ios_vrf.py @@ -21,9 +21,9 @@ __metaclass__ = type +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_vrf -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule, load_fixture @@ -58,7 +58,11 @@ def tearDown(self): def load_fixtures(self, commands=None): self.get_config.return_value = load_fixture("ios_vrf_config.cfg") - self.exec_command.return_value = (0, load_fixture("ios_vrf_config.cfg").strip(), None) + self.exec_command.return_value = ( + 0, + load_fixture("ios_vrf_config.cfg").strip(), + None, + ) self.load_config.return_value = None def test_ios_vrf_name(self): @@ -158,7 +162,11 @@ def test_ios_vrfs_local_override_description(self): def test_ios_vrfs_local_override_state(self): vrfs = [{"name": "test_1", "state": "absent"}, {"name": "test_2"}] set_module_args(dict(vrfs=vrfs, description="test string")) - commands = ["no vrf definition test_1", "vrf definition test_2", "description test string"] + commands = [ + "no vrf definition test_1", + "vrf definition test_2", + "description test string", + ] self.execute_module(changed=True, commands=commands, sort=False) def test_ios_vrf_route_both(self): @@ -178,7 +186,9 @@ def test_ios_vrf_route_both(self): self.execute_module(changed=True, commands=commands, sort=False) def test_ios_vrf_route_import(self): - set_module_args(dict(name="test_6", rd="3:100", route_import=["3:100", "4:100"])) + set_module_args( + dict(name="test_6", rd="3:100", route_import=["3:100", "4:100"]), + ) commands = [ "vrf definition test_6", "rd 3:100", @@ -188,7 +198,9 @@ def test_ios_vrf_route_import(self): self.execute_module(changed=True, commands=commands, sort=False) def test_ios_vrf_route_export(self): - set_module_args(dict(name="test_7", rd="4:100", route_export=["3:100", "4:100"])) + set_module_args( + dict(name="test_7", rd="4:100", route_export=["3:100", "4:100"]), + ) commands = [ "vrf definition test_7", "rd 4:100", @@ -210,7 +222,11 @@ def test_ios_vrf_route_both_mixed(self): def test_ios_vrf_route_both_ipv4(self): set_module_args( - dict(name="test_9", rd="168.0.0.9:100", route_both_ipv4=["168.0.0.9:100", "3:100"]), + dict( + name="test_9", + rd="168.0.0.9:100", + route_both_ipv4=["168.0.0.9:100", "3:100"], + ), ) commands = [ "vrf definition test_9", @@ -281,7 +297,11 @@ def test_ios_vrf_route_both_ipv4_mixed(self): def test_ios_vrf_route_both_ipv6(self): set_module_args( - dict(name="test_13", rd="2:100", route_both_ipv6=["2:100", "168.0.0.13:100"]), + dict( + name="test_13", + rd="2:100", + route_both_ipv6=["2:100", "168.0.0.13:100"], + ), ) commands = [ "vrf definition test_13", @@ -301,7 +321,11 @@ def test_ios_vrf_route_both_ipv6(self): def test_ios_vrf_route_import_ipv6(self): set_module_args( - dict(name="test_14", rd="3:100", route_import_ipv6=["3:100", "168.0.0.14:100"]), + dict( + name="test_14", + rd="3:100", + route_import_ipv6=["3:100", "168.0.0.14:100"], + ), ) commands = [ "vrf definition test_14", @@ -317,7 +341,11 @@ def test_ios_vrf_route_import_ipv6(self): def test_ios_vrf_route_export_ipv6(self): set_module_args( - dict(name="test_15", rd="4:100", route_export_ipv6=["168.0.0.15:100", "4:100"]), + dict( + name="test_15", + rd="4:100", + route_export_ipv6=["168.0.0.15:100", "4:100"], + ), ) commands = [ "vrf definition test_15", @@ -386,7 +414,11 @@ def test_ios_vrf_all_route_both_idempotent(self): def test_ios_vrf_interface_brownfield(self): set_module_args(dict(name="test_19", interfaces=["Ethernet1"])) - commands = ["interface Ethernet1", "vrf forwarding test_19", "ip address 1.2.3.4/5"] + commands = [ + "interface Ethernet1", + "vrf forwarding test_19", + "ip address 1.2.3.4/5", + ] self.execute_module(changed=True, commands=commands, sort=False) def test_ios_mdt(self): diff --git a/tests/unit/modules/network/ios/test_ios_vxlan_vtep.py b/tests/unit/modules/network/ios/test_ios_vxlan_vtep.py index 25b0bc8a6..13e6a5380 100644 --- a/tests/unit/modules/network/ios/test_ios_vxlan_vtep.py +++ b/tests/unit/modules/network/ios/test_ios_vxlan_vtep.py @@ -7,11 +7,10 @@ __metaclass__ = type - from textwrap import dedent +from unittest.mock import patch from ansible_collections.cisco.ios.plugins.modules import ios_vxlan_vtep -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args from .ios_module import TestIosModule diff --git a/tests/unit/modules/utils.py b/tests/unit/modules/utils.py index 6184c48c3..87be9cf8e 100644 --- a/tests/unit/modules/utils.py +++ b/tests/unit/modules/utils.py @@ -4,12 +4,12 @@ __metaclass__ = type import json +from unittest import TestCase +from unittest.mock import patch + from ansible.module_utils import basic from ansible.module_utils._text import to_bytes -from ansible_collections.cisco.ios.tests.unit.compat import unittest -from ansible_collections.cisco.ios.tests.unit.compat.mock import patch - def set_module_args(args): if "_ansible_remote_tmp" not in args: @@ -40,7 +40,7 @@ def fail_json(*args, **kwargs): raise AnsibleFailJson(kwargs) -class ModuleTestCase(unittest.TestCase): +class ModuleTestCase(TestCase): def setUp(self): self.mock_module = patch.multiple( basic.AnsibleModule, diff --git a/tests/unit/plugins/cliconf/test_ios.py b/tests/unit/plugins/cliconf/test_ios.py index 0b7cf8704..eb094b2c7 100644 --- a/tests/unit/plugins/cliconf/test_ios.py +++ b/tests/unit/plugins/cliconf/test_ios.py @@ -31,10 +31,11 @@ except ImportError: from mock import MagicMock +from unittest import TestCase + from ansible.module_utils._text import to_bytes from ansible_collections.cisco.ios.plugins.cliconf import ios -from ansible_collections.cisco.ios.tests.unit.compat import unittest b_FIXTURE_DIR = b"%s/fixtures/ios" % ( @@ -49,7 +50,9 @@ def _connection_side_effect(*args, **kwargs): else: value = kwargs.get("command") - fixture_path = path.abspath(b"%s/%s" % (b_FIXTURE_DIR, b"_".join(value.split(b" ")))) + fixture_path = path.abspath( + b"%s/%s" % (b_FIXTURE_DIR, b"_".join(value.split(b" "))), + ) with open(fixture_path, "rb") as file_desc: return file_desc.read() except (OSError, IOError): @@ -63,7 +66,7 @@ def _connection_side_effect(*args, **kwargs): return "Nope" -class TestPluginCLIConfIOS(unittest.TestCase): +class TestPluginCLIConfIOS(TestCase): """Test class for IOS CLI Conf Methods""" def setUp(self): From cd326fe6d775e8f118fb9466c1d59f59b94462ee Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:28:38 +0530 Subject: [PATCH 3/3] [pre-commit.ci] pre-commit autoupdate (#1021) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/psf/black: 23.12.1 → 24.3.0](https://github.com/psf/black/compare/23.12.1...24.3.0) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Sagar Paul --- .pre-commit-config.yaml | 2 +- plugins/module_utils/network/ios/config/acls/acls.py | 6 +++--- .../network/ios/config/route_maps/route_maps.py | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fe243a843..46f7a2815 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,6 +41,6 @@ repos: args: ["--filter-files"] - repo: https://github.com/psf/black - rev: 23.12.1 + rev: 24.3.0 hooks: - id: black diff --git a/plugins/module_utils/network/ios/config/acls/acls.py b/plugins/module_utils/network/ios/config/acls/acls.py index 3eb30b73a..f604e4360 100644 --- a/plugins/module_utils/network/ios/config/acls/acls.py +++ b/plugins/module_utils/network/ios/config/acls/acls.py @@ -322,9 +322,9 @@ def list_to_dict(self, param): for k, v in ( ace.get("destination", {}).get("port_protocol", {}).items() ): - ace["destination"]["port_protocol"][ - k - ] = self.port_protocl_no_to_protocol(v) + ace["destination"]["port_protocol"][k] = ( + self.port_protocl_no_to_protocol(v) + ) if acl.get("acl_type") == "standard": for ks in list(ace.keys()): if ks not in [ diff --git a/plugins/module_utils/network/ios/config/route_maps/route_maps.py b/plugins/module_utils/network/ios/config/route_maps/route_maps.py index d8a1bec9f..f02fbfdfb 100644 --- a/plugins/module_utils/network/ios/config/route_maps/route_maps.py +++ b/plugins/module_utils/network/ios/config/route_maps/route_maps.py @@ -304,11 +304,11 @@ def convert_to_dict(inner_match, key): "acl", ) elif match["ip"][each_ip_param].get("prefix_lists"): - match["ip"][each_ip_param][ - "prefix_lists" - ] = convert_to_dict( - match["ip"][each_ip_param]["prefix_lists"], - "prefix_list", + match["ip"][each_ip_param]["prefix_lists"] = ( + convert_to_dict( + match["ip"][each_ip_param]["prefix_lists"], + "prefix_list", + ) ) if match.get("local_preference") and match.get("local_preference").get( "value",