diff --git a/.flake8 b/.flake8 index 4795515e8..03be69242 100644 --- a/.flake8 +++ b/.flake8 @@ -39,19 +39,14 @@ extend-exclude = # IMPORTANT: avoid using ignore option, always use extend-ignore instead # Completely and unconditionally ignore the following errors: extend-ignore = - # Safeguard neutering of flake8-quotes : https://github.com/zheller/flake8-quotes/issues/105 - Q, - # annoy black by allowing white space before : https://github.com/psf/black/issues/315 - E203, - # duplicate of pylint W0611 (unused-import) - F401, - # duplicate of pylint E0602 (undefined-variable) - F821, - # duplicate of pylint W0612 (unused-variable) F841, + # line-length + E501, + # module level import not at top of file + E402 # Accessibility/large fonts and PEP8 unfriendly: -max-line-length = 100 +max-line-length = 120 # Allow certain violations in certain files: # Please keep both sections of this list sorted, as it will be easier for others to find and add entries in the future @@ -62,7 +57,7 @@ per-file-ignores = # these will need to be added to that line as well. - # S101: Allow the use of assert within the tests directory, since tests require it. + # S101: Allow the use of assert within the tests directory, since tests require it. tests/**.py: S101 # The following were present during the initial implementation. diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 27291dc81..bf7ade86c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,6 +16,8 @@ jobs: changelog: uses: ansible/ansible-content-actions/.github/workflows/changelog.yaml@main if: github.event_name == 'pull_request' + build-import: + uses: ansible/ansible-content-actions/.github/workflows/build_import.yaml@main ansible-lint: uses: ansible/ansible-content-actions/.github/workflows/ansible_lint.yaml@main sanity: @@ -32,6 +34,7 @@ jobs: if: ${{ always() }} needs: - changelog + - build-import - sanity - unit-galaxy - ansible-lint @@ -41,6 +44,7 @@ jobs: python -c "assert 'failure' not in set([ '${{ needs.changelog.result }}', + '${{ needs.build-import.result }}', '${{ needs.sanity.result }}', '${{ needs.unit-galaxy.result }}' '${{ needs.ansible-lint.result }}' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 46f7a2815..031505895 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -44,3 +44,8 @@ repos: rev: 24.3.0 hooks: - id: black + + - repo: https://github.com/pycqa/flake8 + rev: 7.0.0 + hooks: + - id: flake8 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 65264d307..9fdf040df 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,34 @@ Cisco Ios Collection Release Notes .. contents:: Topics +v8.0.0 +====== + +Major Changes +------------- + +- Update the netcommon base version 6.1.0 to support cli_restore plugin. + +Minor Changes +------------- + +- Add support for cli_restore functionality. +- Please refer the PR to know more about core changes (https://github.com/ansible-collections/ansible.netcommon/pull/618). +- cli_restore module is part of netcommon. + +v7.0.0 +====== + +Major Changes +------------- + +- ios_ntp - Remove deprecated ntp legacy module + +Removed Features (previously deprecated) +---------------------------------------- + +- Deprecated ios_ntp module in favor of ios_ntp_global. + v6.1.4 ====== @@ -658,7 +686,7 @@ Documentation Changes New Modules ----------- -- ios_hostname - hostname resource module +- ios_hostname - Resource module to configure hostname. v2.6.0 ====== @@ -689,7 +717,7 @@ Documentation Changes New Modules ----------- -- ios_snmp_server - snmp_server resource module +- ios_snmp_server - Resource module to configure snmp server. v2.5.0 ====== @@ -722,7 +750,7 @@ Documentation Changes New Modules ----------- -- ios_ntp_global - ntp_global resource module +- ios_ntp_global - Resource module to configure NTP. v2.4.0 ====== @@ -809,8 +837,8 @@ Bugfixes New Modules ----------- -- ios_logging_global - Logging resource module. -- ios_prefix_lists - Prefix Lists resource module. +- ios_logging_global - Resource module to configure logging. +- ios_prefix_lists - Resource module to configure prefix lists. v2.1.0 ====== @@ -834,7 +862,7 @@ Bugfixes New Modules ----------- -- ios_route_maps - Route Maps resource module. +- ios_route_maps - Resource module to configure route maps. v2.0.1 ====== @@ -879,7 +907,7 @@ Bugfixes New Modules ----------- -- ios_bgp_address_family - BGP Address Family resource module. +- ios_bgp_address_family - Resource module to configure BGP Address family. v1.3.0 ====== @@ -902,7 +930,7 @@ Bugfixes New Modules ----------- -- ios_bgp_global - BGP Global resource module +- ios_bgp_global - Resource module to configure BGP. v1.2.1 ====== @@ -933,7 +961,7 @@ Bugfixes New Modules ----------- -- ios_ospf_interfaces - OSPF Interfaces resource module +- ios_ospf_interfaces - Resource module to configure OSPF interfaces. v1.1.0 ====== @@ -954,7 +982,7 @@ Bugfixes New Modules ----------- -- ios_ospfv3 - OSPFv3 resource module +- ios_ospfv3 - Resource module to configure OSPFv3. v1.0.3 ====== @@ -1006,34 +1034,26 @@ Cliconf New Modules ----------- -- ios_acl_interfaces - ACL interfaces resource module -- ios_acls - ACLs resource module -- ios_banner - Manage multiline banners on Cisco IOS devices -- ios_bgp - Configure global BGP protocol settings on Cisco IOS. -- ios_command - Run commands on remote devices running Cisco IOS -- ios_config - Manage Cisco IOS configuration sections -- ios_facts - Collect facts from remote devices running Cisco IOS -- ios_interface - (deprecated, removed after 2022-06-01) Manage Interface on Cisco IOS network devices -- ios_interfaces - Interfaces resource module -- ios_l2_interface - (deprecated, removed after 2022-06-01) Manage Layer-2 interface on Cisco IOS devices. -- ios_l2_interfaces - L2 interfaces resource module -- ios_l3_interface - (deprecated, removed after 2022-06-01) Manage Layer-3 interfaces on Cisco IOS network devices. -- ios_l3_interfaces - L3 interfaces resource module -- ios_lacp - LACP resource module -- ios_lacp_interfaces - LACP interfaces resource module -- ios_lag_interfaces - LAG interfaces resource module -- ios_linkagg - Manage link aggregation groups on Cisco IOS network devices -- ios_lldp - Manage LLDP configuration on Cisco IOS network devices. -- ios_lldp_global - LLDP resource module -- ios_lldp_interfaces - LLDP interfaces resource module -- ios_logging - Manage logging on network devices -- ios_ntp - Manages core NTP configuration. -- ios_ospfv2 - OSPFv2 resource module -- ios_ping - Tests reachability using ping from Cisco IOS network devices -- ios_static_route - (deprecated, removed after 2022-06-01) Manage static IP routes on Cisco IOS network devices -- ios_static_routes - Static routes resource module -- ios_system - Manage the system attributes on Cisco IOS devices -- ios_user - Manage the aggregate of local users on Cisco IOS device -- ios_vlan - (deprecated, removed after 2022-06-01) Manage VLANs on IOS network devices -- ios_vlans - VLANs resource module -- ios_vrf - Manage the collection of VRF definitions on Cisco IOS devices +- ios_acl_interfaces - Resource module to configure ACL interfaces. +- ios_acls - Resource module to configure ACLs. +- ios_banner - Module to configure multiline banners. +- ios_command - Module to run commands on remote devices. +- ios_config - Module to manage configuration sections. +- ios_facts - Module to collect facts from remote devices. +- ios_interfaces - Resource module to configure interfaces. +- ios_l2_interfaces - Resource module to configure L2 interfaces. +- ios_l3_interfaces - Resource module to configure L3 interfaces. +- ios_lacp - Resource module to configure LACP. +- ios_lacp_interfaces - Resource module to configure LACP interfaces. +- ios_lag_interfaces - Resource module to configure LAG interfaces. +- ios_linkagg - Module to configure link aggregation groups. +- ios_lldp - (deprecated, removed after 2024-06-01) Manage LLDP configuration on Cisco IOS network devices. +- ios_lldp_global - Resource module to configure LLDP. +- ios_lldp_interfaces - Resource module to configure LLDP interfaces. +- ios_ospfv2 - Resource module to configure OSPFv2. +- ios_ping - Tests reachability using ping from IOS switch. +- ios_static_routes - Resource module to configure static routes. +- ios_system - Module to manage the system attributes. +- ios_user - Module to manage the aggregates of local users. +- ios_vlans - Resource module to configure VLANs. +- ios_vrf - Module to configure VRF definitions. diff --git a/README.md b/README.md index f43002977..15af82239 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,6 @@ Name | Description [cisco.ios.ios_lldp_global](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_lldp_global_module.rst)|Resource module to configure LLDP. [cisco.ios.ios_lldp_interfaces](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_lldp_interfaces_module.rst)|Resource module to configure LLDP interfaces. [cisco.ios.ios_logging_global](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_logging_global_module.rst)|Resource module to configure logging. -[cisco.ios.ios_ntp](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_ntp_module.rst)|(deprecated, removed after 2024-01-01) Manages core NTP configuration. [cisco.ios.ios_ntp_global](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_ntp_global_module.rst)|Resource module to configure NTP. [cisco.ios.ios_ospf_interfaces](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_ospf_interfaces_module.rst)|Resource module to configure OSPF interfaces. [cisco.ios.ios_ospfv2](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_ospfv2_module.rst)|Resource module to configure OSPFv2. diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index c03288448..e57571cd7 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -2,107 +2,75 @@ ancestor: null releases: 1.0.0: modules: - - description: ACL interfaces resource module + - description: Resource module to configure ACL interfaces. name: ios_acl_interfaces namespace: "" - - description: ACLs resource module + - description: Resource module to configure ACLs. name: ios_acls namespace: "" - - description: Manage multiline banners on Cisco IOS devices + - description: Module to configure multiline banners. name: ios_banner namespace: "" - - description: Configure global BGP protocol settings on Cisco IOS. - name: ios_bgp - namespace: "" - - description: Run commands on remote devices running Cisco IOS + - description: Module to run commands on remote devices. name: ios_command namespace: "" - - description: Manage Cisco IOS configuration sections + - description: Module to manage configuration sections. name: ios_config namespace: "" - - description: Collect facts from remote devices running Cisco IOS + - description: Module to collect facts from remote devices. name: ios_facts namespace: "" - - description: - (deprecated, removed after 2022-06-01) Manage Interface on Cisco - IOS network devices - name: ios_interface - namespace: "" - - description: Interfaces resource module + - description: Resource module to configure interfaces. name: ios_interfaces namespace: "" - - description: - (deprecated, removed after 2022-06-01) Manage Layer-2 interface - on Cisco IOS devices. - name: ios_l2_interface - namespace: "" - - description: L2 interfaces resource module + - description: Resource module to configure L2 interfaces. name: ios_l2_interfaces namespace: "" - - description: - (deprecated, removed after 2022-06-01) Manage Layer-3 interfaces - on Cisco IOS network devices. - name: ios_l3_interface - namespace: "" - - description: L3 interfaces resource module + - description: Resource module to configure L3 interfaces. name: ios_l3_interfaces namespace: "" - - description: LACP resource module + - description: Resource module to configure LACP. name: ios_lacp namespace: "" - - description: LACP interfaces resource module + - description: Resource module to configure LACP interfaces. name: ios_lacp_interfaces namespace: "" - - description: LAG interfaces resource module + - description: Resource module to configure LAG interfaces. name: ios_lag_interfaces namespace: "" - - description: Manage link aggregation groups on Cisco IOS network devices + - description: Module to configure link aggregation groups. name: ios_linkagg namespace: "" - - description: Manage LLDP configuration on Cisco IOS network devices. + - description: + (deprecated, removed after 2024-06-01) Manage LLDP configuration + on Cisco IOS network devices. name: ios_lldp namespace: "" - - description: LLDP resource module + - description: Resource module to configure LLDP. name: ios_lldp_global namespace: "" - - description: LLDP interfaces resource module + - description: Resource module to configure LLDP interfaces. name: ios_lldp_interfaces namespace: "" - - description: Manage logging on network devices - name: ios_logging - namespace: "" - - description: Manages core NTP configuration. - name: ios_ntp - namespace: "" - - description: OSPFv2 resource module + - description: Resource module to configure OSPFv2. name: ios_ospfv2 namespace: "" - - description: Tests reachability using ping from Cisco IOS network devices + - description: Tests reachability using ping from IOS switch. name: ios_ping namespace: "" - - description: - (deprecated, removed after 2022-06-01) Manage static IP routes - on Cisco IOS network devices - name: ios_static_route - namespace: "" - - description: Static routes resource module + - description: Resource module to configure static routes. name: ios_static_routes namespace: "" - - description: Manage the system attributes on Cisco IOS devices + - description: Module to manage the system attributes. name: ios_system namespace: "" - - description: Manage the aggregate of local users on Cisco IOS device + - description: Module to manage the aggregates of local users. name: ios_user namespace: "" - - description: - (deprecated, removed after 2022-06-01) Manage VLANs on IOS network - devices - name: ios_vlan - namespace: "" - - description: VLANs resource module + - description: Resource module to configure VLANs. name: ios_vlans namespace: "" - - description: Manage the collection of VRF definitions on Cisco IOS devices + - description: Module to configure VRF definitions. name: ios_vrf namespace: "" plugins: @@ -153,7 +121,7 @@ releases: minor_changes: - Add ios_ospfv3 module. modules: - - description: OSPFv3 resource module + - description: Resource module to configure OSPFv3. name: ios_ospfv3 namespace: "" release_date: "2020-10-01" @@ -172,7 +140,7 @@ releases: minor_changes: - Add ios_ospf_interfaces module. modules: - - description: OSPF Interfaces resource module + - description: Resource module to configure OSPF interfaces. name: ios_ospf_interfaces namespace: "" release_date: "2020-11-01" @@ -196,7 +164,7 @@ releases: minor_changes: - Add ios_bgp_global module. modules: - - description: BGP Global resource module + - description: Resource module to configure BGP. name: ios_bgp_global namespace: "" release_date: "2021-01-29" @@ -214,7 +182,7 @@ releases: - Add ios_bgp_address_family Resource Module. (https://github.com/ansible-collections/cisco.ios/pull/219). - Adds support for single_user_mode command output caching. (https://github.com/ansible-collections/cisco.ios/pull/204). modules: - - description: BGP Address Family resource module. + - description: Resource module to configure BGP Address family. name: ios_bgp_address_family namespace: "" release_date: "2021-02-25" @@ -246,7 +214,7 @@ releases: security_fixes: - To fix Cisco IOS no log issue and add ignore txt for 2.12 (https://github.com/ansible-collections/cisco.ios/pull/304). modules: - - description: Route Maps resource module. + - description: Resource module to configure route maps. name: ios_route_maps namespace: "" release_date: "2021-04-27" @@ -265,10 +233,10 @@ releases: - Add ios_logging_global module. - IOS Prefix list resource module. modules: - - description: Logging resource module. + - description: Resource module to configure logging. name: ios_logging_global namespace: "" - - description: Prefix Lists resource module. + - description: Resource module to configure prefix lists. name: ios_prefix_lists namespace: "" release_date: "2021-05-18" @@ -377,7 +345,7 @@ releases: - sd_wan_support.yaml - set_allow_duplicates.yaml modules: - - description: ntp_global resource module + - description: Resource module to configure NTP. name: ios_ntp_global namespace: "" release_date: "2021-09-24" @@ -409,7 +377,7 @@ releases: - sanity-213.yaml - snmp_server_resource_module.yaml modules: - - description: snmp_server resource module + - description: Resource module to configure snmp server. name: ios_snmp_server namespace: "" release_date: "2021-12-07" @@ -452,7 +420,7 @@ releases: - snmp_server_feature_user.yaml - static_route_interface_issue.yaml modules: - - description: hostname resource module + - description: Resource module to configure hostname. name: ios_hostname namespace: "" release_date: "2022-01-31" @@ -1171,3 +1139,24 @@ releases: - acl_refactor.yaml - json_serializable_issue.yaml release_date: "2024-03-27" + 7.0.0: + changes: + major_changes: + - ios_ntp - Remove deprecated ntp legacy module + removed_features: + - Deprecated ios_ntp module in favor of ios_ntp_global. + fragments: + - remove_deprecated.yml + release_date: "2024-04-01" + 8.0.0: + changes: + major_changes: + - Update the netcommon base version 6.1.0 to support cli_restore plugin. + minor_changes: + - Add support for cli_restore functionality. + - Please refer the PR to know more about core changes (https://github.com/ansible-collections/ansible.netcommon/pull/618). + - cli_restore module is part of netcommon. + fragments: + - add_restore_support.yaml + - sanityfix.yml + release_date: "2024-04-12" diff --git a/changelogs/fragments/ios_service_fix.yml b/changelogs/fragments/ios_service_fix.yml new file mode 100644 index 000000000..3ec24d6a9 --- /dev/null +++ b/changelogs/fragments/ios_service_fix.yml @@ -0,0 +1,4 @@ +--- +bugfixes: + - ios_service - Fix timestamps attribute, to generate right configuration. + - ios_service - Add tcp_small_servers and udp_small_servers attributes, to generate configuration. diff --git a/changelogs/fragments/l3_sinterface_parser.yml b/changelogs/fragments/l3_sinterface_parser.yml new file mode 100644 index 000000000..c16a5e179 --- /dev/null +++ b/changelogs/fragments/l3_sinterface_parser.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - ios_l3_interfaces - Fix gathering wrong facts for source interface in ipv4. diff --git a/changelogs/fragments/snmp_server_host.yml b/changelogs/fragments/snmp_server_host.yml new file mode 100644 index 000000000..b8bbe1ee0 --- /dev/null +++ b/changelogs/fragments/snmp_server_host.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - snmp_server - Fix wrong syntax of snmp-server host command generation. diff --git a/docs/cisco.ios.ios_ntp_module.rst b/docs/cisco.ios.ios_ntp_module.rst deleted file mode 100644 index 9979a45ae..000000000 --- a/docs/cisco.ios.ios_ntp_module.rst +++ /dev/null @@ -1,291 +0,0 @@ -.. _cisco.ios.ios_ntp_module: - - -***************** -cisco.ios.ios_ntp -***************** - -**(deprecated, removed after 2024-01-01) Manages core NTP configuration.** - - -Version added: 1.0.0 - -.. contents:: - :local: - :depth: 1 - -DEPRECATED ----------- -:Removed in collection release after 2024-01-01 -:Why: Updated module released with more functionality. -:Alternative: ios_ntp_global - - - -Synopsis --------- -- Manages core NTP configuration. - - - - -Parameters ----------- - -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterChoices/DefaultsComments
-
- acl - -
- string -
-
- -
ACL for peer/server access restricition.
-
-
- auth - -
- boolean -
-
-
    Choices: -
  • no ←
  • -
  • yes
  • -
-
-
Enable NTP authentication. Data type boolean.
-
-
- auth_key - -
- string -
-
- -
md5 NTP authentication key of tye 7.
-
-
- key_id - -
- string -
-
- -
auth_key id. Data type string
-
-
- logging - -
- boolean -
-
-
    Choices: -
  • no ←
  • -
  • yes
  • -
-
-
Enable NTP logs. Data type boolean.
-
-
- server - -
- string -
-
- -
Network address of NTP server.
-
-
- source_int - -
- string -
-
- -
Source interface for NTP packets.
-
-
- state - -
- string -
-
-
    Choices: -
  • present ←
  • -
  • absent
  • -
-
-
Manage the state of the resource.
-
-
- vrf - -
- string -
-
- -
VRF configuration for NTP servers
-
-
- - -Notes ------ - -.. note:: - - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` - - For more information on using Ansible to manage Cisco devices see the `Cisco integration page `_. - - - -Examples --------- - -.. code-block:: yaml - - # Set new NTP server and source interface - - name: Example ntp play - cisco.ios.ios_ntp: - server: 10.0.255.10 - source_int: Loopback0 - logging: false - state: present - - # Remove NTP ACL and logging - - name: Example ntp play absent - cisco.ios.ios_ntp: - acl: NTP_ACL - logging: true - state: absent - - # Set NTP authentication - - name: Example ntp play auth - cisco.ios.ios_ntp: - key_id: 10 - auth_key: 15435A030726242723273C21181319000A - auth: true - state: present - - # Set new NTP configuration - - name: Example ntp play auth - cisco.ios.ios_ntp: - server: 10.0.255.10 - source_int: Loopback0 - acl: NTP_ACL - logging: true - vrf: mgmt - key_id: 10 - auth_key: 15435A030726242723273C21181319000A - auth: true - state: present - - - -Return Values -------------- -Common return values are documented `here `_, the following are the fields unique to this module: - -.. raw:: html - - - - - - - - - - - - -
KeyReturnedDescription
-
- commands - -
- list -
-
always -
command sent to the device
-
-
Sample:
-
['no ntp server 10.0.255.10', 'no ntp source Loopback0']
-
-

- - -Status ------- - - -- This module will be removed in a release after 2024-01-01. *[deprecated]* -- For more information see `DEPRECATED`_. - - -Authors -~~~~~~~ - -- Federico Olivieri (@Federico87) -- Joanie Sylvain (@JoanieAda) diff --git a/docs/cisco.ios.ios_service_module.rst b/docs/cisco.ios.ios_service_module.rst index ed859129d..a2d5eef38 100644 --- a/docs/cisco.ios.ios_service_module.rst +++ b/docs/cisco.ios.ios_service_module.rst @@ -45,7 +45,7 @@ Parameters -
A dictionnary of service configuration
+
A dictionary of service configuration
@@ -658,7 +658,7 @@ Parameters -
TCP and UDP small servers are servers (daemons, in Unix parlance) that run in the router which are useful for diagnostics.
+
TCP small servers are servers (daemons, in Unix parlance) that run in the router which are useful for diagnostics.
@@ -690,14 +690,35 @@ Parameters max_servers
- string + integer
Set number of allowable TCP small servers
-
1 to 2147483647 or no-limit
+
1 to 2147483647
+ + + + + + +
+ no_limit + +
+ boolean +
+ + +
    Choices: +
  • no
  • +
  • yes
  • +
+ + +
No limit on number of allowable TCP small servers
@@ -921,7 +942,7 @@ Parameters -
TCP and UDP small servers are servers (daemons, in Unix parlance) that run in the router which are useful for diagnostics.
+
UDP small servers are servers (daemons, in Unix parlance) that run in the router which are useful for diagnostics.
@@ -953,14 +974,35 @@ Parameters max_servers
- string + integer
-
Set number of allowable TCP small servers
-
1 to 2147483647 or no-limit
+
Set number of allowable UDP small servers
+
1 to 2147483647
+ + + + + + +
+ no_limit + +
+ boolean +
+ + +
    Choices: +
  • no
  • +
  • yes
  • +
+ + +
No limit on number of allowable UDP small servers
@@ -1036,7 +1078,7 @@ Notes ----- .. note:: - - Tested against Cisco IOSXE Version 16.9 + - Tested against Cisco IOSXE Version 17.9.1a on CML. - This module works with connection ``network_cli``. See https://docs.ansible.com/ansible/latest/network/user_guide/platform_ios.html @@ -1556,3 +1598,4 @@ Authors ~~~~~~~ - Ambroise Rosset (@earendilfr) +- Sagar Paul (@KB-perByte) diff --git a/galaxy.yml b/galaxy.yml index d7f905996..22c3d2613 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -2,7 +2,7 @@ authors: - Ansible Network Community (ansible-network) dependencies: - "ansible.netcommon": ">=6.0.0" + "ansible.netcommon": ">=6.1.0" license_file: LICENSE name: ios namespace: cisco @@ -11,4 +11,4 @@ readme: README.md repository: https://github.com/ansible-collections/cisco.ios issues: https://github.com/ansible-collections/cisco.ios/issues tags: [cisco, ios, iosxe, networking] -version: "6.1.4" +version: "8.0.0" diff --git a/meta/runtime.yml b/meta/runtime.yml index 5b9f3c9a0..c7d437cb8 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -31,10 +31,6 @@ plugin_routing: deprecation: removal_date: "2024-06-01" warning_text: See the plugin documentation for more details - ios_ntp: - deprecation: - removal_date: "2024-01-01" - warning_text: See the plugin documentation for more details l2_interfaces: redirect: cisco.ios.ios_l2_interfaces l3_interfaces: @@ -61,11 +57,6 @@ plugin_routing: redirect: cisco.ios.ios_lldp_interfaces logging_global: redirect: cisco.ios.ios_logging_global - ntp: - deprecation: - removal_date: "2024-01-01" - warning_text: See the plugin documentation for more details - redirect: cisco.ios.ios_ntp ntp_global: redirect: cisco.ios.ios_ntp_global ospfv2: diff --git a/plugins/action/ntp.py b/plugins/action/ntp.py deleted file mode 120000 index 7747aa9dd..000000000 --- a/plugins/action/ntp.py +++ /dev/null @@ -1 +0,0 @@ -ios.py \ No newline at end of file diff --git a/plugins/cliconf/ios.py b/plugins/cliconf/ios.py index be62c3724..324b7f000 100644 --- a/plugins/cliconf/ios.py +++ b/plugins/cliconf/ios.py @@ -180,6 +180,13 @@ def get_config(self, source="running", flags=None, format=None): return self.send_command(cmd) + @enable_mode + def restore(self, filename=None, path=""): + if not filename: + raise ValueError("'file_name' value is required for restore") + cmd = f"configure replace {path}{filename} force" + return self.send_command(cmd) + def get_diff( self, candidate=None, diff --git a/plugins/module_utils/network/ios/argspec/service/service.py b/plugins/module_utils/network/ios/argspec/service/service.py index 238fc64a2..647eeb3d2 100644 --- a/plugins/module_utils/network/ios/argspec/service/service.py +++ b/plugins/module_utils/network/ios/argspec/service/service.py @@ -68,7 +68,8 @@ class ServiceArgs(object): # pylint: disable=R0903 "tcp_small_servers": { "options": { "enable": {"type": "bool"}, - "max_servers": {"type": "str"}, + "max_servers": {"type": "int"}, + "no_limit": {"type": "bool"}, }, "type": "dict", }, @@ -97,7 +98,8 @@ class ServiceArgs(object): # pylint: disable=R0903 "udp_small_servers": { "options": { "enable": {"type": "bool"}, - "max_servers": {"type": "str"}, + "max_servers": {"type": "int"}, + "no_limit": {"type": "bool"}, }, "type": "dict", }, diff --git a/plugins/module_utils/network/ios/config/service/service.py b/plugins/module_utils/network/ios/config/service/service.py index 6a4c8a1ff..603e1060b 100644 --- a/plugins/module_utils/network/ios/config/service/service.py +++ b/plugins/module_utils/network/ios/config/service/service.py @@ -75,7 +75,9 @@ def __init__(self, module): "slave_log", "tcp_keepalives_in", "tcp_keepalives_out", + "tcp_small_servers", "telnet_zeroidle", + "udp_small_servers", "unsupported_transceiver", ] @@ -138,9 +140,9 @@ def _compare_lists_attrs(self, want, have): for key, wanting in iteritems(i_want): haveing = i_have.pop(key, {}) if wanting != haveing: - self.addcmd(wanting, "timestamps") + self.addcmd(wanting, key + "_timestamps", False) for key, haveing in iteritems(i_have): - self.addcmd(haveing, "timestamps", negate=True) + self.addcmd(haveing, key + "_timestamps", negate=True) def _service_list_to_dict(self, data): """Convert all list of dicts to dicts of dicts""" diff --git a/plugins/module_utils/network/ios/facts/service/service.py b/plugins/module_utils/network/ios/facts/service/service.py index df2dcf993..6ada10748 100644 --- a/plugins/module_utils/network/ios/facts/service/service.py +++ b/plugins/module_utils/network/ios/facts/service/service.py @@ -33,7 +33,7 @@ def __init__(self, module, subspec="config", options="options"): self.argument_spec = ServiceArgs.argument_spec def get_service_data(self, connection): - return connection.get("show running-config all | section ^service ") + return connection.get("show running-config all | section ^service") def populate_facts(self, connection, ansible_facts, data=None): """Populate the facts for Service network resource @@ -59,7 +59,11 @@ def populate_facts(self, connection, ansible_facts, data=None): ansible_facts["ansible_network_resources"].pop("service", None) params = utils.remove_empties( - service_parser.validate_config(self.argument_spec, {"config": objs}, redact=True), + service_parser.validate_config( + self.argument_spec, + {"config": objs}, + redact=True, + ), ) facts["service"] = params.get("config", {}) diff --git a/plugins/module_utils/network/ios/rm_templates/l3_interfaces.py b/plugins/module_utils/network/ios/rm_templates/l3_interfaces.py index bd337befa..f049d061b 100644 --- a/plugins/module_utils/network/ios/rm_templates/l3_interfaces.py +++ b/plugins/module_utils/network/ios/rm_templates/l3_interfaces.py @@ -166,7 +166,7 @@ def __init__(self, lines=None, module=None): "name": "ipv4.source_interface", "getval": re.compile( r"""\s+ip\sunnumbered - (\s(?P\S+)) + (\s(?P\S+)) (\s(?Ppoll))? (\s(?Ppoint-to-point))? $""", @@ -180,7 +180,7 @@ def __init__(self, lines=None, module=None): "ipv4": [ { "source_interface": { - "name": "{{ True if name is defined }}", + "name": "{{ src_name }}", "poll": "{{ True if poll is defined }}", "point_to_point": "{{ True if point_to_point is defined }}", }, diff --git a/plugins/module_utils/network/ios/rm_templates/service.py b/plugins/module_utils/network/ios/rm_templates/service.py index 992892db8..c81593226 100644 --- a/plugins/module_utils/network/ios/rm_templates/service.py +++ b/plugins/module_utils/network/ios/rm_templates/service.py @@ -22,6 +22,21 @@ ) +def handleTimestamp(config_data): + command = "service timestamps" + command += " " + config_data.get("msg") if config_data.get("msg") else "" + command += " " + config_data.get("timestamp") if config_data.get("timestamp") else "" + + if config_data.get("datetime_options"): + datetime_op = config_data.get("datetime_options") + command += " mesc" if datetime_op.get("msec") else "" + command += " localtime" if datetime_op.get("localtime") else "" + command += " show-timezone" if datetime_op.get("show_timezone") else "" + command += " year" if datetime_op.get("year") else "" + + return command + + class ServiceTemplate(NetworkTemplate): def __init__(self, lines=None, module=None): super(ServiceTemplate, self).__init__(lines=lines, tmplt=self, module=module) @@ -32,36 +47,36 @@ def __init__(self, lines=None, module=None): "name": "call_home", "getval": re.compile( r""" - ^service\s(?Pcall-home) + ^service\scall-home """, re.VERBOSE, ), "setval": "service call-home", "result": { - "call_home": "{{ not not call_home }}", + "call_home": True, }, }, { "name": "compress_config", "getval": re.compile( r""" - ^service\s(?Pcompress-config) + ^service\scompress-config """, re.VERBOSE, ), "setval": "service compress-config", "result": { - "compress_config": "{{ not not compress_config }}", + "compress_config": True, }, }, { "name": "config", "getval": re.compile( r""" - ^service\s(?Pconfig) + ^service\sconfig """, re.VERBOSE, ), "setval": "service config", "result": { - "config": "{{ not not config }}", + "config": True, }, }, { @@ -92,120 +107,120 @@ def __init__(self, lines=None, module=None): "name": "disable_ip_fast_frag", "getval": re.compile( r""" - ^service\s(?Pdisable-ip-fast-frag) + ^service\sdisable-ip-fast-frag """, re.VERBOSE, ), "setval": "service disable-ip-fast-frag", "result": { - "disable_ip_fast_frag": "{{ not not disable_ip_fast_frag }}", + "disable_ip_fast_frag": True, }, }, { "name": "exec_callback", "getval": re.compile( r""" - ^service\s(?Pexec-callback) + ^service\sexec-callback """, re.VERBOSE, ), "setval": "service exec-callback", "result": { - "exec_callback": "{{ not not exec_callback }}", + "exec_callback": True, }, }, { "name": "exec_wait", "getval": re.compile( r""" - ^service\s(?Pexec-wait) + ^service\sexec-wait """, re.VERBOSE, ), "setval": "service exec-wait", "return": { - "exec_wait": "{{ not not exec_wait }}", + "exec_wait": True, }, }, { "name": "hide_telnet_addresses", "getval": re.compile( r""" - ^service\s(?Phide-telnet-addresses) + ^service\shide-telnet-addresses """, re.VERBOSE, ), "setval": "service hide-telnet-addresses", "result": { - "hide_telnet_addresses": "{{ not not hide_telnet_addresses }}", + "hide_telnet_addresses": True, }, }, { "name": "internal", "getval": re.compile( r""" - ^service\s(?Pinternal) + ^service\sinternal """, re.VERBOSE, ), "setval": "service internal", "result": { - "internal": "{{ not not internal }}", + "internal": True, }, }, { "name": "linenumber", "getval": re.compile( r""" - ^service\s(?Plinenumber) + ^service\slinenumber """, re.VERBOSE, ), "setval": "service linenumber", "result": { - "linenumber": "{{ not not linenumber }}", + "linenumber": True, }, }, { "name": "log", "getval": re.compile( r""" - ^service\slog(\s(?Pbacktrace))? + ^service\slog\sbacktrace? """, re.VERBOSE, ), "setval": "service log backtrace", "result": { - "log": "{{ not not backtrace }}", + "log": True, }, }, { "name": "log_hidden", "getval": re.compile( r""" - ^service\s(?Plog-hidden) + ^service\slog-hidden """, re.VERBOSE, ), "setval": "service log-hidden", "result": { - "log_hidden": "{{ not not log_hidden }}", + "log_hidden": True, }, }, { "name": "nagle", "getval": re.compile( r""" - ^service\s(?Pnagle) + ^service\snagle """, re.VERBOSE, ), "setval": "service nagle", "result": { - "nagle": "{{ not not nagle }}", + "nagle": True, }, }, { "name": "old_slip_prompts", "getval": re.compile( r""" - ^service\s(?Pold-slip-prompts) + ^service\sold-slip-prompts """, re.VERBOSE, ), "setval": "service old-slip-prompts", "result": { - "old_slip_prompts": "{{ not not old_slip_prompts }}", + "old_slip_prompts": True, }, }, { @@ -260,12 +275,12 @@ def __init__(self, lines=None, module=None): "name": "password_encryption", "getval": re.compile( r""" - ^service\s(?Ppassword-encryption) + ^service\spassword-encryption """, re.VERBOSE, ), "setval": "service password-encryption", "result": { - "password_encryption": "{{ not not password_encryption }}", + "password_encryption": True, }, }, { @@ -309,48 +324,48 @@ def __init__(self, lines=None, module=None): "name": "pt_vty_logging", "getval": re.compile( r""" - ^service\s(?Ppt-vty-logging) + ^service\spt-vty-logging """, re.VERBOSE, ), "setval": "service pt-vty-logging", "result": { - "pt_vty_logging": "{{ not not pt_vty_logging }}", + "pt_vty_logging": True, }, }, { "name": "scripting", "getval": re.compile( r""" - ^service\s(?Pscripting) + ^service\sscripting """, re.VERBOSE, ), "setval": "service scripting", "result": { - "scripting": "{{ not not scripting }}", + "scripting": True, }, }, { "name": "sequence_numbers", "getval": re.compile( r""" - ^service\s(?Psequence-numbers) + ^service\ssequence-numbers """, re.VERBOSE, ), "setval": "service sequence-numbers", "result": { - "sequence_numbers": "{{ not not sequence_numbers }}", + "sequence_numbers": True, }, }, { "name": "slave_coredump", "getval": re.compile( r""" - ^service\s(?Pslave-coredump) + ^service\sslave-coredump """, re.VERBOSE, ), "setval": "service slave-coredump", "result": { - "slave_coredump": "{{ not not slave_coredump }}", + "slave_coredump": True, }, }, { @@ -389,6 +404,46 @@ def __init__(self, lines=None, module=None): "tcp_keepalives_out": True, }, }, + { + "name": "tcp_small_servers", + "getval": re.compile( + r""" + ^service\stcp-small-servers + (\s(?P\d+))? + (\s(?Pno-limit))? + """, re.VERBOSE, + ), + "setval": "service tcp-small-servers" + "{{ (' ' + tcp_small_servers.max_servers|string) if tcp_small_servers.max_servers is defined else '' }}" + "{{ (' no-limit') if tcp_small_servers.no_limit|d(False) else '' }}", + "result": { + "tcp_small_servers": { + "enable": True, + "max_servers": "{{ max_servers }}", + "no_limit": "{{ not not no_limit }}", + }, + }, + }, + { + "name": "udp_small_servers", + "getval": re.compile( + r""" + ^service\sudp-small-servers + (\s(?P\d+))? + (\s(?Pno-limit))? + """, re.VERBOSE, + ), + "setval": "{{ ('service udp-small-servers') if udp_small_servers.enable|d(False) else '' }}" + "{{ (' ' + udp_small_servers.max_servers|string) if udp_small_servers.max_servers is defined else '' }}" + "{{ (' no-limit') if udp_small_servers.no_limit|d(False) else '' }}", + "result": { + "udp_small_servers": { + "enable": True, + "max_servers": "{{ max_servers }}", + "no_limit": "{{ not not no_limit }}", + }, + }, + }, { "name": "telnet_zeroidle", "getval": re.compile( @@ -402,11 +457,39 @@ def __init__(self, lines=None, module=None): }, }, { - "name": "timestamps", + "name": "log_timestamps", + "getval": re.compile( + r""" + ^service\stimestamps\slog + (\s(?P\S+))? + (\s(?Pmsec))? + (\s(?Plocaltime))? + (\s(?Pshow-timezone))? + (\s(?Pyear))? + """, re.VERBOSE, + ), + "remval": "service timestamps log", + "setval": handleTimestamp, + "result": { + "timestamps": [ + { + "msg": "log", + "timestamp": "{{ timestamp if timestamp is defined else 'uptime' }}", + "datetime_options": { + "msec": "{{ True if msec else False}}", + "localtime": "{{ True if localtime else False }}", + "show_timezone": "{{ True if show_timezone else False }}", + "year": "{{ True if year else False }}", + }, + }, + ], + }, + }, + { + "name": "debug_timestamps", "getval": re.compile( r""" - ^service\stimestamps - (\s(?P\S+))? + ^service\stimestamps\sdebug (\s(?P\S+))? (\s(?Pmsec))? (\s(?Plocaltime))? @@ -414,23 +497,12 @@ def __init__(self, lines=None, module=None): (\s(?Pyear))? """, re.VERBOSE, ), - "remval": "service timestamps{{ (' ' + msg) if msg is defined else '' }}", - "setval": "service timestamps" - "{{ (' ' + msg) if msg is defined else '' }}" - "{% if msg is defined %}" - "{{ (' ' + timestamp) if timestamp is defined else '' }}" - "{% if timestamp == 'datetime' and datetime_options is defined %}" - "{{ ' msec' if datetime_options.msec else '' }}" - "{{ ' localtime' if datetime_options.localtime else '' }}" - "{{ ' show-timezone' if datetime_options.show_timezone else '' }}" - "{{ ' year' if datetime_options.year else '' }}" - "{% endif %}" - "{% endif %}" - "", + "remval": "service timestamps debug", + "setval": handleTimestamp, "result": { "timestamps": [ { - "msg": "{{ msg if msg is defined else 'debug' }}", + "msg": "debug", "timestamp": "{{ timestamp if timestamp is defined else 'uptime' }}", "datetime_options": { "msec": "{{ True if msec else False}}", diff --git a/plugins/module_utils/network/ios/rm_templates/snmp_server.py b/plugins/module_utils/network/ios/rm_templates/snmp_server.py index 45cabaae9..6f0c04c69 100644 --- a/plugins/module_utils/network/ios/rm_templates/snmp_server.py +++ b/plugins/module_utils/network/ios/rm_templates/snmp_server.py @@ -63,12 +63,12 @@ def cmd_option_hosts(config_data): # contain sub list attr cmd += " {host}".format(host=config_data.get("host")) if config_data.get("informs"): cmd += " informs" + if config_data.get("vrf"): + cmd += " vrf {vrf}".format(vrf=config_data.get("vrf")) if config_data.get("version"): cmd += " version {version}".format(version=config_data.get("version")) if config_data.get("version_option"): cmd += " {version}".format(version=config_data.get("version_option")) - if config_data.get("vrf"): - cmd += " vrf {vrf}".format(vrf=config_data.get("vrf")) if config_data.get("community_string"): cmd += " {community_string}".format( community_string=config_data.get("community_string"), diff --git a/plugins/modules/ios_linkagg.py b/plugins/modules/ios_linkagg.py index 4572afe42..01267865f 100644 --- a/plugins/modules/ios_linkagg.py +++ b/plugins/modules/ios_linkagg.py @@ -265,11 +265,11 @@ def parse_mode(module, config, group, member): def parse_members(module, config, group): members = [] for line in config.strip().split("!"): - l = line.strip() - if l.startswith("interface"): - match_group = re.findall("channel-group {0} mode".format(group), l, re.M) + lineStrip = line.strip() + if lineStrip.startswith("interface"): + match_group = re.findall("channel-group {0} mode".format(group), lineStrip, re.M) if match_group: - match = re.search("interface (\\S+)", l, re.M) + match = re.search("interface (\\S+)", lineStrip, re.M) if match: members.append(match.group(1)) return members @@ -291,8 +291,8 @@ def map_config_to_obj(module): objs = list() config = get_config(module) for line in config.split("\n"): - l = line.strip() - match = re.search("interface Port-channel(\\S+)", l, re.M) + lStrip = line.strip() + match = re.search("interface Port-channel(\\S+)", lStrip, re.M) if match: obj = {} group = match.group(1) diff --git a/plugins/modules/ios_ntp.py b/plugins/modules/ios_ntp.py deleted file mode 100644 index 065054411..000000000 --- a/plugins/modules/ios_ntp.py +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/python -# -# 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 . -# -from __future__ import absolute_import, division, print_function - - -__metaclass__ = type - -DOCUMENTATION = """ -module: ios_ntp -extends_documentation_fragment: - - cisco.ios.ios -short_description: (deprecated, removed after 2024-01-01) Manages core NTP configuration. -description: - - Manages core NTP configuration. -version_added: 1.0.0 -deprecated: - alternative: ios_ntp_global - why: Updated module released with more functionality. - removed_at_date: "2024-01-01" -author: - - Federico Olivieri (@Federico87) - - Joanie Sylvain (@JoanieAda) -options: - server: - description: - - Network address of NTP server. - type: str - source_int: - description: - - Source interface for NTP packets. - type: str - acl: - description: - - ACL for peer/server access restricition. - type: str - logging: - description: - - Enable NTP logs. Data type boolean. - type: bool - default: false - auth: - description: - - Enable NTP authentication. Data type boolean. - type: bool - default: false - auth_key: - description: - - md5 NTP authentication key of tye 7. - type: str - key_id: - description: - - auth_key id. Data type string - type: str - state: - description: - - Manage the state of the resource. - default: present - choices: - - present - - absent - type: str - vrf: - description: - - VRF configuration for NTP servers - type: str -""" - -EXAMPLES = """ -# Set new NTP server and source interface -- name: Example ntp play - cisco.ios.ios_ntp: - server: 10.0.255.10 - source_int: Loopback0 - logging: false - state: present - -# Remove NTP ACL and logging -- name: Example ntp play absent - cisco.ios.ios_ntp: - acl: NTP_ACL - logging: true - state: absent - -# Set NTP authentication -- name: Example ntp play auth - cisco.ios.ios_ntp: - key_id: 10 - auth_key: 15435A030726242723273C21181319000A - auth: true - state: present - -# Set new NTP configuration -- name: Example ntp play auth - cisco.ios.ios_ntp: - server: 10.0.255.10 - source_int: Loopback0 - acl: NTP_ACL - logging: true - vrf: mgmt - key_id: 10 - auth_key: 15435A030726242723273C21181319000A - auth: true - state: present -""" - -RETURN = """ -commands: - description: command sent to the device - returned: always - type: list - sample: ["no ntp server 10.0.255.10", "no ntp source Loopback0"] -""" - -import re - -from ansible.module_utils.basic import AnsibleModule - -from ansible_collections.cisco.ios.plugins.module_utils.network.ios.ios import ( - get_config, - load_config, -) - - -def parse_server(line, dest): - if dest == "server": - vrf, server = None, None - match = re.search( - "(ntp\\sserver\\s)(vrf\\s\\w+\\s)?(\\d+\\.\\d+\\.\\d+\\.\\d+)", - line, - re.M, - ) - - if match and match.group(2) and match.group(3): - vrf = match.group(2) - server = match.group(3) - return vrf, server - - if match and match.group(3): - server = match.group(3) - return vrf, server - - -def parse_source_int(line, dest): - if dest == "source": - match = re.search("(ntp\\ssource\\s)(\\S+)", line, re.M) - if match: - source = match.group(2) - return source - - -def parse_acl(line, dest): - if dest == "access-group": - match = re.search("ntp\\saccess-group\\s(?:peer|serve)(?:\\s+)(\\S+)", line, re.M) - if match: - acl = match.group(1) - return acl - - -def parse_logging(line, dest): - if dest == "logging": - logging = dest - return logging - - -def parse_auth_key(line, dest): - if dest == "authentication-key": - match = re.search("(ntp\\sauthentication-key\\s\\d+\\smd5\\s)(\\w+)", line, re.M) - if match: - auth_key = match.group(2) - return auth_key - - -def parse_key_id(line, dest): - if dest == "trusted-key": - match = re.search("(ntp\\strusted-key\\s)(\\d+)", line, re.M) - if match: - auth_key = match.group(2) - return auth_key - - -def parse_auth(dest): - if dest == "authenticate": - return dest - - -def map_config_to_obj(module): - obj_dict = dict() - obj = list() - server_list = list() - config = get_config(module, flags=["| include ntp"]) - for line in config.splitlines(): - match = re.search("ntp\\s(\\S+)", line, re.M) - - if match: - dest = match.group(1) - server = parse_server(line, dest) - source_int = parse_source_int(line, dest) - acl = parse_acl(line, dest) - logging = parse_logging(line, dest) - auth = parse_auth(dest) - auth_key = parse_auth_key(line, dest) - key_id = parse_key_id(line, dest) - - if server: - if server[0] is None: - server_list.append((server[0], server[1])) - else: - server_list.append((server[0].split()[1], server[1])) - if source_int: - obj_dict["source_int"] = source_int - if acl: - obj_dict["acl"] = acl - if logging: - obj_dict["logging"] = True - if auth: - obj_dict["auth"] = True - if auth_key: - obj_dict["auth_key"] = auth_key - if key_id: - obj_dict["key_id"] = key_id - obj_dict["server"] = server_list - obj.append(obj_dict) - return obj - - -def map_params_to_obj(module): - obj = list() - - obj.append( - { - "state": module.params["state"], - "server": module.params["server"], - "source_int": module.params["source_int"], - "logging": module.params["logging"], - "acl": module.params["acl"], - "auth": module.params["auth"], - "auth_key": module.params["auth_key"], - "key_id": module.params["key_id"], - "vrf": module.params["vrf"], - }, - ) - - return obj - - -def map_obj_to_commands(want, have, module): - commands = list() - - server_have = have[0].get("server", None) - source_int_have = have[0].get("source_int", None) - acl_have = have[0].get("acl", None) - logging_have = have[0].get("logging", None) - auth_have = have[0].get("auth", None) - auth_key_have = have[0].get("auth_key", None) - key_id_have = have[0].get("key_id", None) - - for w in want: - server = w["server"] - source_int = w["source_int"] - acl = w["acl"] - logging = w["logging"] - state = w["state"] - auth = w["auth"] - auth_key = w["auth_key"] - key_id = w["key_id"] - vrf = w["vrf"] - if vrf == "": - vrf = None - - if state == "absent": - if server_have and (vrf, server) in server_have: - if vrf is not None: - commands.append("no ntp server vrf {0} {1}".format(vrf, server)) - else: - commands.append("no ntp server {0}".format(server)) - if source_int and source_int_have: - commands.append("no ntp source {0}".format(source_int)) - if acl and acl_have: - commands.append("no ntp access-group peer {0}".format(acl)) - if logging is True and logging_have: - commands.append("no ntp logging") - if auth is True and auth_have: - commands.append("no ntp authenticate") - if key_id and key_id_have: - commands.append("no ntp trusted-key {0}".format(key_id)) - if auth_key and auth_key_have: - if key_id and key_id_have: - commands.append( - "no ntp authentication-key {0} md5 {1} 7".format(key_id, auth_key), - ) - elif state == "present": - if server is not None and (vrf, server) not in server_have: - if vrf is not None: - commands.append("ntp server vrf {0} {1}".format(vrf, server)) - else: - commands.append("ntp server {0}".format(server)) - if source_int is not None and source_int != source_int_have: - commands.append("ntp source {0}".format(source_int)) - if acl is not None and acl != acl_have: - commands.append("ntp access-group peer {0}".format(acl)) - if logging is not None and logging != logging_have and logging is not False: - commands.append("ntp logging") - if auth is not None and auth != auth_have and auth is not False: - commands.append("ntp authenticate") - if key_id is not None and key_id != key_id_have: - commands.append("ntp trusted-key {0}".format(key_id)) - if auth_key is not None and auth_key != auth_key_have: - if key_id is not None: - commands.append("ntp authentication-key {0} md5 {1} 7".format(key_id, auth_key)) - return commands - - -def main(): - argument_spec = dict( - server=dict(), - source_int=dict(), - acl=dict(), - logging=dict(type="bool", default=False), - auth=dict(type="bool", default=False), - auth_key=dict(no_log=True), - key_id=dict(), - state=dict(choices=["absent", "present"], default="present"), - vrf=dict(), - ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - result = {"changed": False} - warnings = list() - if warnings: - result["warnings"] = warnings - want = map_params_to_obj(module) - have = map_config_to_obj(module) - commands = map_obj_to_commands(want, have, module) - result["commands"] = commands - if commands: - if not module.check_mode: - load_config(module, commands) - result["changed"] = True - module.exit_json(**result) - - -if __name__ == "__main__": - main() diff --git a/plugins/modules/ios_service.py b/plugins/modules/ios_service.py index 46c456569..ebe0e7881 100644 --- a/plugins/modules/ios_service.py +++ b/plugins/modules/ios_service.py @@ -22,13 +22,14 @@ version_added: 4.6.0 author: - Ambroise Rosset (@earendilfr) + - Sagar Paul (@KB-perByte) notes: - - Tested against Cisco IOSXE Version 16.9 + - Tested against Cisco IOSXE Version 17.9.1a on CML. - This module works with connection C(network_cli). See U(https://docs.ansible.com/ansible/latest/network/user_guide/platform_ios.html) options: config: - description: A dictionnary of service configuration + description: A dictionary of service configuration suboptions: call_home: description: Cisco call-home service @@ -128,7 +129,7 @@ type: bool tcp_small_servers: description: - - TCP and UDP small servers are servers (daemons, in Unix parlance) that run in the + - TCP small servers are servers (daemons, in Unix parlance) that run in the router which are useful for diagnostics. suboptions: enable: @@ -137,8 +138,11 @@ max_servers: description: - Set number of allowable TCP small servers - - 1 to 2147483647 or no-limit - type: str + - 1 to 2147483647 + type: int + no_limit: + description: No limit on number of allowable TCP small servers + type: bool type: dict telnet_zeroidle: description: Set TCP window 0 when connection is idle @@ -181,7 +185,7 @@ type: list udp_small_servers: description: - - TCP and UDP small servers are servers (daemons, in Unix parlance) that run in the + - UDP small servers are servers (daemons, in Unix parlance) that run in the router which are useful for diagnostics. suboptions: enable: @@ -189,9 +193,12 @@ type: bool max_servers: description: - - Set number of allowable TCP small servers - - 1 to 2147483647 or no-limit - type: str + - Set number of allowable UDP small servers + - 1 to 2147483647 + type: int + no_limit: + description: No limit on number of allowable UDP small servers + type: bool type: dict unsupported_transceiver: description: enable support for third-party transceivers diff --git a/tests/integration/targets/ios_bgp_address_family/tasks/main.yaml b/tests/integration/targets/ios_bgp_address_family/tasks/main.yaml index 8b66c1ad5..6b04c2ccc 100644 --- a/tests/integration/targets/ios_bgp_address_family/tasks/main.yaml +++ b/tests/integration/targets/ios_bgp_address_family/tasks/main.yaml @@ -1,4 +1,8 @@ --- +- name: Set a fact for 'skip_test' + ansible.builtin.set_fact: + skip_test: false + - name: Main task for bgp_address_family module ansible.builtin.include_tasks: cli.yaml tags: diff --git a/tests/integration/targets/ios_bgp_address_family/tests/cli/merged.yaml b/tests/integration/targets/ios_bgp_address_family/tests/cli/merged.yaml index 81aa0512d..e0d2a452c 100644 --- a/tests/integration/targets/ios_bgp_address_family/tests/cli/merged.yaml +++ b/tests/integration/targets/ios_bgp_address_family/tests/cli/merged.yaml @@ -11,22 +11,23 @@ cisco.ios.ios_bgp_address_family: &id001 config: address_family: - - afi: l2vpn - safi: evpn - neighbor: - - address: 198.51.100.1 - activate: true - inherit: LEAF-EVPN-PEER-POLICY - - afi: ipv4 - vrf: green - redistribute: - - static: - set: true - - connected: - set: true - advertise: - afi: l2vpn - safi: evpn + # L2 specific configuration + # - afi: l2vpn + # safi: evpn + # neighbor: + # - address: 198.51.100.1 + # activate: true + # inherit: LEAF-EVPN-PEER-POLICY + # - afi: ipv4 + # vrf: green + # redistribute: + # - static: + # set: true + # - connected: + # set: true + # advertise: + # afi: l2vpn + # safi: evpn - afi: ipv4 redistribute: - connected: diff --git a/tests/integration/targets/ios_bgp_address_family/vars/main.yaml b/tests/integration/targets/ios_bgp_address_family/vars/main.yaml index e22a90dc0..9198405ac 100644 --- a/tests/integration/targets/ios_bgp_address_family/vars/main.yaml +++ b/tests/integration/targets/ios_bgp_address_family/vars/main.yaml @@ -4,13 +4,13 @@ merged: commands: - router bgp 65000 - - address-family l2vpn evpn - - neighbor 198.51.100.1 activate - - neighbor 198.51.100.1 inherit peer-policy LEAF-EVPN-PEER-POLICY - - address-family ipv4 vrf green - - advertise l2vpn evpn - - redistribute connected - - redistribute static + # - address-family l2vpn evpn + # - neighbor 198.51.100.1 activate + # - neighbor 198.51.100.1 inherit peer-policy LEAF-EVPN-PEER-POLICY + # - address-family ipv4 vrf green + # - advertise l2vpn evpn + # - redistribute connected + # - redistribute static - address-family ipv4 multicast - default-metric 12 - distance bgp 10 10 100 diff --git a/tests/integration/targets/ios_evpn_evi/tasks/cli.yaml b/tests/integration/targets/ios_evpn_evi/tasks/cli.yaml index 6f505600c..843294310 100644 --- a/tests/integration/targets/ios_evpn_evi/tasks/cli.yaml +++ b/tests/integration/targets/ios_evpn_evi/tasks/cli.yaml @@ -13,6 +13,7 @@ delegate_to: localhost - name: Run test case (connection=ansible.netcommon.network_cli) + when: skip_test ansible.builtin.include_tasks: "{{ test_case_to_run }}" vars: ansible_connection: ansible.netcommon.network_cli diff --git a/tests/integration/targets/ios_evpn_evi/tasks/main.yaml b/tests/integration/targets/ios_evpn_evi/tasks/main.yaml index 39c4567e9..ccf906bc5 100644 --- a/tests/integration/targets/ios_evpn_evi/tasks/main.yaml +++ b/tests/integration/targets/ios_evpn_evi/tasks/main.yaml @@ -1,4 +1,8 @@ --- +- name: Set a fact for 'skip_test' + ansible.builtin.set_fact: + skip_test: false + - name: Main task for EVPN EVI module ansible.builtin.include_tasks: cli.yaml tags: diff --git a/tests/integration/targets/ios_evpn_global/tasks/cli.yaml b/tests/integration/targets/ios_evpn_global/tasks/cli.yaml index 6f505600c..843294310 100644 --- a/tests/integration/targets/ios_evpn_global/tasks/cli.yaml +++ b/tests/integration/targets/ios_evpn_global/tasks/cli.yaml @@ -13,6 +13,7 @@ delegate_to: localhost - name: Run test case (connection=ansible.netcommon.network_cli) + when: skip_test ansible.builtin.include_tasks: "{{ test_case_to_run }}" vars: ansible_connection: ansible.netcommon.network_cli diff --git a/tests/integration/targets/ios_evpn_global/tasks/main.yaml b/tests/integration/targets/ios_evpn_global/tasks/main.yaml index 83b543a3f..601063522 100644 --- a/tests/integration/targets/ios_evpn_global/tasks/main.yaml +++ b/tests/integration/targets/ios_evpn_global/tasks/main.yaml @@ -1,4 +1,8 @@ --- +- name: Set a fact for 'skip_test' + ansible.builtin.set_fact: + skip_test: false + - name: Main task for evpn_global module ansible.builtin.include_tasks: cli.yaml tags: diff --git a/tests/integration/targets/ios_evpn_global/tests/cli/deleted.yaml b/tests/integration/targets/ios_evpn_global/tests/cli/deleted.yaml index 6ed823307..05320aa1f 100644 --- a/tests/integration/targets/ios_evpn_global/tests/cli/deleted.yaml +++ b/tests/integration/targets/ios_evpn_global/tests/cli/deleted.yaml @@ -30,6 +30,7 @@ - name: Ios_evpn_global deleted - play (idempotent) register: result cisco.ios.ios_evpn_global: *id001 + - name: Ios_evpn_global deleted - assert above task was idempotent ansible.builtin.assert: that: diff --git a/tests/integration/targets/ios_evpn_global/tests/cli/merged.yaml b/tests/integration/targets/ios_evpn_global/tests/cli/merged.yaml index 485c85778..7ee2196d7 100644 --- a/tests/integration/targets/ios_evpn_global/tests/cli/merged.yaml +++ b/tests/integration/targets/ios_evpn_global/tests/cli/merged.yaml @@ -42,6 +42,7 @@ - name: Ios_evpn_global merged - play (idempotent) register: result cisco.ios.ios_evpn_global: *id001 + - name: Ios_evpn_global merged - assert above task was idempotent ansible.builtin.assert: that: diff --git a/tests/integration/targets/ios_evpn_global/tests/cli/replaced.yaml b/tests/integration/targets/ios_evpn_global/tests/cli/replaced.yaml index 47a9bb62f..48d230d37 100644 --- a/tests/integration/targets/ios_evpn_global/tests/cli/replaced.yaml +++ b/tests/integration/targets/ios_evpn_global/tests/cli/replaced.yaml @@ -37,6 +37,7 @@ - name: Ios_evpn_global replaced - play (idempotent) register: result cisco.ios.ios_evpn_global: *id001 + - name: Ios_evpn_global replaced - assert above task was idempotent ansible.builtin.assert: that: diff --git a/tests/integration/targets/ios_facts/tests/cli/all_facts.yaml b/tests/integration/targets/ios_facts/tests/cli/all_facts.yaml index 44d57ed9b..e01263fe4 100644 --- a/tests/integration/targets/ios_facts/tests/cli/all_facts.yaml +++ b/tests/integration/targets/ios_facts/tests/cli/all_facts.yaml @@ -19,8 +19,9 @@ - result.ansible_facts.ansible_net_memfree_mb > 1 - result.ansible_facts.ansible_net_memtotal_mb > 1 -- ansible.builtin.assert: - that: "{{ my_var.value.spacetotal_kb }} > {{ my_var.value.spacefree_kb }}" +- name: Assert that free spacee is less than total space + ansible.builtin.assert: + that: "my_var.value.spacetotal_kb > my_var.value.spacefree_kb" loop: "{{ lookup('dict', result.ansible_facts.ansible_net_filesystems_info, wantlist=True) }}" loop_control: loop_var: my_var diff --git a/tests/integration/targets/ios_interfaces/tests/cli/_remove_config.yaml b/tests/integration/targets/ios_interfaces/tests/cli/_remove_config.yaml index a3f5b0a44..6225d4a84 100644 --- a/tests/integration/targets/ios_interfaces/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/ios_interfaces/tests/cli/_remove_config.yaml @@ -15,4 +15,5 @@ - name: Port-channel11 - name: Port-channel22 - name: Port-channel40 + - name: Loopback1 state: purged diff --git a/tests/integration/targets/ios_l3_interfaces/tests/cli/_remove_config.yaml b/tests/integration/targets/ios_l3_interfaces/tests/cli/_remove_config.yaml index 554173b64..56083c1b5 100644 --- a/tests/integration/targets/ios_l3_interfaces/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/ios_l3_interfaces/tests/cli/_remove_config.yaml @@ -6,3 +6,13 @@ \ ipv6 address\n" ansible.netcommon.cli_config: config: "{{ lines }}" + +- name: Delete attributes of all configured interfaces + register: result + cisco.ios.ios_interfaces: + config: + - name: Loopback1 + - name: Vlan101 + - name: Vlan901 + - name: Vlan902 + state: purged diff --git a/tests/integration/targets/ios_l3_interfaces/tests/cli/merged.yaml b/tests/integration/targets/ios_l3_interfaces/tests/cli/merged.yaml index 75217f5e5..8169e8584 100644 --- a/tests/integration/targets/ios_l3_interfaces/tests/cli/merged.yaml +++ b/tests/integration/targets/ios_l3_interfaces/tests/cli/merged.yaml @@ -23,10 +23,6 @@ - address: 198.51.100.2/24 ipv6: - address: 2001:db8:0:3::/64 - - name: Vlan101 - ipv4: - - address: 198.51.100.2/24 - mac_address: dead:beef:abcd - name: Vlan901 autostate: false ipv4: @@ -38,6 +34,8 @@ autostate: true ipv6: - enable: true + - name: Vlan101 + autostate: false state: merged - name: L3_interface merged - assert that correct set of commands were generated diff --git a/tests/integration/targets/ios_l3_interfaces/vars/main.yaml b/tests/integration/targets/ios_l3_interfaces/vars/main.yaml index 73996896e..1d869bf08 100644 --- a/tests/integration/targets/ios_l3_interfaces/vars/main.yaml +++ b/tests/integration/targets/ios_l3_interfaces/vars/main.yaml @@ -25,6 +25,8 @@ merged: - ipv6 enable - interface Vlan902 - ipv6 enable + - interface Vlan101 + - no autostate after: - name: Loopback888 - ipv4: @@ -46,10 +48,7 @@ merged: - address: 2001:DB8:0:3::/64 name: GigabitEthernet3 - name: GigabitEthernet4 - - name: Vlan101 - ipv4: - - address: 198.51.100.2/24 - mac_address: dead:beef:abcd + - name: Loopback1 - name: Vlan901 ipv4: - source_interface: @@ -61,6 +60,8 @@ merged: ipv6: - enable: true autostate: true + - name: Vlan101 + autostate: false replaced: before: diff --git a/tests/integration/targets/ios_lacp_interfaces/tests/cli/_remove_config.yaml b/tests/integration/targets/ios_lacp_interfaces/tests/cli/_remove_config.yaml index 8544171de..df035f588 100644 --- a/tests/integration/targets/ios_lacp_interfaces/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/ios_lacp_interfaces/tests/cli/_remove_config.yaml @@ -12,6 +12,7 @@ register: result cisco.ios.ios_interfaces: config: + - name: Loopback1 - name: Port-channel10 - name: Port-channel11 - name: Port-channel22 diff --git a/tests/integration/targets/ios_ntp/defaults/main.yaml b/tests/integration/targets/ios_ntp/defaults/main.yaml deleted file mode 100644 index 5f709c5aa..000000000 --- a/tests/integration/targets/ios_ntp/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" diff --git a/tests/integration/targets/ios_ntp/meta/main.yml b/tests/integration/targets/ios_ntp/meta/main.yml deleted file mode 100644 index ab3ad91bc..000000000 --- a/tests/integration/targets/ios_ntp/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -dependencies: - - prepare_ios_tests diff --git a/tests/integration/targets/ios_ntp/tasks/cli.yaml b/tests/integration/targets/ios_ntp/tasks/cli.yaml deleted file mode 100644 index cd8c04990..000000000 --- a/tests/integration/targets/ios_ntp/tasks/cli.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -- name: Collect all CLI test cases - ansible.builtin.find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: Set test_items - ansible.builtin.set_fact: - test_items: "{{ test_cases.files | map(attribute='path') | list }}" - -- name: Run test cases (connection=ansible.netcommon.network_cli) - ansible.builtin.include_tasks: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: network_cli diff --git a/tests/integration/targets/ios_ntp/tasks/main.yaml b/tests/integration/targets/ios_ntp/tasks/main.yaml deleted file mode 100644 index 3d2666f3e..000000000 --- a/tests/integration/targets/ios_ntp/tasks/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -- name: Main task for ntp module - ansible.builtin.include_tasks: cli.yaml diff --git a/tests/integration/targets/ios_ntp/tests/cli/ntp_configuration.yaml b/tests/integration/targets/ios_ntp/tests/cli/ntp_configuration.yaml deleted file mode 100644 index 92063dfb5..000000000 --- a/tests/integration/targets/ios_ntp/tests/cli/ntp_configuration.yaml +++ /dev/null @@ -1,87 +0,0 @@ ---- -- ansible.builtin.debug: msg="START connection={{ ansible_connection }} ios_ntp sanity test" - -- name: Remove ntp (if set) - ignore_errors: true - cisco.ios.ios_ntp: &id007 - server: 10.75.32.5 - source_int: "{{ test_interface }}" - acl: NTP_ACL - logging: true - key_id: 10 - auth_key: 15435A030726242723273C21181319000A - auth: true - state: absent - -- block: - - name: Configure ntp - register: result - cisco.ios.ios_ntp: &id001 - server: 10.75.32.5 - source_int: "{{ test_interface }}" - state: present - - - ansible.builtin.assert: &id002 - that: - - result.changed == true - - - name: Idempotent check - register: result - cisco.ios.ios_ntp: *id001 - - ansible.builtin.assert: &id004 - that: - - result.changed == false - - - name: Load ACL ntp_acl into device - register: result - cisco.ios.ios_config: - lines: - - 10 permit ip host 192.0.2.1 any log - parents: ip access-list extended NTP_ACL - - - ansible.builtin.assert: *id002 - - name: Configure ntp - register: result - cisco.ios.ios_ntp: &id003 - acl: NTP_ACL - logging: true - state: present - - - ansible.builtin.assert: *id002 - - name: Idempotent check - register: result - cisco.ios.ios_ntp: *id003 - - ansible.builtin.assert: *id004 - - name: Configure ntp with different values - register: result - cisco.ios.ios_ntp: &id005 - key_id: 10 - auth_key: 15435A030726242723273C21181319000A - auth: true - vrf: my_mgmt_vrf - state: present - - - ansible.builtin.assert: *id002 - - name: Idempotent check - register: result - cisco.ios.ios_ntp: *id005 - - ansible.builtin.assert: *id004 - - name: Remove part of configuration - register: result - cisco.ios.ios_ntp: &id006 - acl: NTP_ACL - logging: true - state: absent - - - ansible.builtin.assert: *id002 - - name: Idempotent check - register: result - cisco.ios.ios_ntp: *id006 - - ansible.builtin.assert: *id004 - always: - - name: Remove ntp configuration - cisco.ios.ios_ntp: *id007 - - name: Remove ntp_acl from device - cisco.ios.ios_config: - lines: - - no ip access-list extended NTP_ACL diff --git a/tests/integration/targets/ios_ospf_interfaces/tests/cli/_remove_config.yaml b/tests/integration/targets/ios_ospf_interfaces/tests/cli/_remove_config.yaml index 2979674f4..3e45f6a9a 100644 --- a/tests/integration/targets/ios_ospf_interfaces/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/ios_ospf_interfaces/tests/cli/_remove_config.yaml @@ -13,6 +13,7 @@ register: result cisco.ios.ios_interfaces: config: + - name: Loopback1 - name: Port-channel10 - name: Port-channel11 - name: Port-channel22 diff --git a/tests/integration/targets/ios_vlans/tasks/cli.yaml b/tests/integration/targets/ios_vlans/tasks/cli.yaml index 25c50045a..37e561a6b 100644 --- a/tests/integration/targets/ios_vlans/tasks/cli.yaml +++ b/tests/integration/targets/ios_vlans/tasks/cli.yaml @@ -16,10 +16,14 @@ cisco.ios.ios_facts: gather_subset: all +- name: Set filtered paths to run only non l2 tests + ansible.builtin.set_fact: + filtered_file_paths: "{{ test_items | reject('search', 'vlan_config') | list }}" + - name: Run test case (connection=ansible.netcommon.network_cli) ansible.builtin.include_tasks: "{{ test_case_to_run }}" vars: ansible_connection: ansible.netcommon.network_cli - with_items: "{{ test_items }}" + with_items: "{{ filtered_file_paths }}" loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/ios_vlans/tasks/main.yaml b/tests/integration/targets/ios_vlans/tasks/main.yaml index 0bf380edb..e741ecb68 100644 --- a/tests/integration/targets/ios_vlans/tasks/main.yaml +++ b/tests/integration/targets/ios_vlans/tasks/main.yaml @@ -1,4 +1,8 @@ --- +- name: Set a fact for 'skip_test' + ansible.builtin.set_fact: + skip_test: false + - name: Main task for vlans module ansible.builtin.include_tasks: cli.yaml tags: diff --git a/tests/integration/targets/ios_vlans/tests/cli/deleted_vlan_config.yaml b/tests/integration/targets/ios_vlans/tests/cli/deleted_vlan_config.yaml index ae7215669..2bc9234a9 100644 --- a/tests/integration/targets/ios_vlans/tests/cli/deleted_vlan_config.yaml +++ b/tests/integration/targets/ios_vlans/tests/cli/deleted_vlan_config.yaml @@ -30,6 +30,7 @@ - name: Delete vlans attributes for all configured vlans (idempotent) register: result cisco.ios.ios_vlans: *id001 + - name: Assert that the previous task was idempotent ansible.builtin.assert: that: diff --git a/tests/integration/targets/ios_vlans/tests/cli/merged_vlan_config.yaml b/tests/integration/targets/ios_vlans/tests/cli/merged_vlan_config.yaml index 5af123bcd..68674c3e3 100644 --- a/tests/integration/targets/ios_vlans/tests/cli/merged_vlan_config.yaml +++ b/tests/integration/targets/ios_vlans/tests/cli/merged_vlan_config.yaml @@ -37,6 +37,7 @@ - name: Merge provided configuration with device configuration (idempotent) register: result cisco.ios.ios_vlans: *id001 + - name: Assert that the previous task was idempotent ansible.builtin.assert: that: diff --git a/tests/integration/targets/ios_vlans/tests/cli/overridden_vlan_config.yaml b/tests/integration/targets/ios_vlans/tests/cli/overridden_vlan_config.yaml index a739c6117..146c03572 100644 --- a/tests/integration/targets/ios_vlans/tests/cli/overridden_vlan_config.yaml +++ b/tests/integration/targets/ios_vlans/tests/cli/overridden_vlan_config.yaml @@ -39,6 +39,7 @@ - name: Override device configuration of all interfaces with provided configuration (idempotent) register: result cisco.ios.ios_vlans: *id001 + - name: Assert that task was idempotent ansible.builtin.assert: that: diff --git a/tests/integration/targets/ios_vlans/tests/cli/rendered.yaml b/tests/integration/targets/ios_vlans/tests/cli/rendered.yaml index 38b0304c8..43fcd910c 100644 --- a/tests/integration/targets/ios_vlans/tests/cli/rendered.yaml +++ b/tests/integration/targets/ios_vlans/tests/cli/rendered.yaml @@ -24,8 +24,9 @@ shutdown: enabled state: rendered - - ansible.builtin.assert: + - name: Assert that correct set of commands were generated + ansible.builtin.assert: that: - result.changed == false - - result.rendered|symmetric_difference(rendered.commands) == [] + - "{{ rendered['commands'] | symmetric_difference(result['rendered']) | length == 0 }}" when: ansible_net_version != "15.6(2)T" diff --git a/tests/integration/targets/ios_vlans/vars/main.yaml b/tests/integration/targets/ios_vlans/vars/main.yaml index 6092684a9..4160dee6f 100644 --- a/tests/integration/targets/ios_vlans/vars/main.yaml +++ b/tests/integration/targets/ios_vlans/vars/main.yaml @@ -573,11 +573,11 @@ rendered: - name Vlan_20 - state active - mtu 610 - - shutdown + - no shutdown - vlan 30 - name Vlan_30 - state suspend - - shutdown + - no shutdown rendered_vlan_config: commands: diff --git a/tests/integration/targets/ios_vxlan_vtep/tasks/cli.yaml b/tests/integration/targets/ios_vxlan_vtep/tasks/cli.yaml index 6f505600c..843294310 100644 --- a/tests/integration/targets/ios_vxlan_vtep/tasks/cli.yaml +++ b/tests/integration/targets/ios_vxlan_vtep/tasks/cli.yaml @@ -13,6 +13,7 @@ delegate_to: localhost - name: Run test case (connection=ansible.netcommon.network_cli) + when: skip_test ansible.builtin.include_tasks: "{{ test_case_to_run }}" vars: ansible_connection: ansible.netcommon.network_cli diff --git a/tests/integration/targets/ios_vxlan_vtep/tasks/main.yaml b/tests/integration/targets/ios_vxlan_vtep/tasks/main.yaml index d80ee1ae2..a19087c8d 100644 --- a/tests/integration/targets/ios_vxlan_vtep/tasks/main.yaml +++ b/tests/integration/targets/ios_vxlan_vtep/tasks/main.yaml @@ -1,4 +1,8 @@ --- +- name: Set a fact for 'skip_test' + ansible.builtin.set_fact: + skip_test: false + - name: Main task for VXLAN VTEP module ansible.builtin.include_tasks: cli.yaml tags: diff --git a/tests/sanity/ignore-2.18.txt b/tests/sanity/ignore-2.18.txt new file mode 100644 index 000000000..d7ff17ca8 --- /dev/null +++ b/tests/sanity/ignore-2.18.txt @@ -0,0 +1 @@ +plugins/action/ios.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` 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 3e3cc038b..f0d593afa 100644 --- a/tests/unit/modules/network/ios/test_ios_l3_interfaces.py +++ b/tests/unit/modules/network/ios/test_ios_l3_interfaces.py @@ -407,7 +407,6 @@ def test_ios_l3_interfaces_merged(self): "ipv6 enable", "no autostate", ] - result = self.execute_module(changed=True) self.assertEqual(sorted(result["commands"]), sorted(commands)) @@ -524,3 +523,31 @@ def test_ios_l3_interfaces_remove_primary_replaced(self): ] result = self.execute_module(changed=True) self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_ios_l3_interfaces_gathered(self): + self.execute_show_command.return_value = dedent( + """\ + interface GigabitEthernet0/1 + no autostate + interface Vlan901 + ip unnumbered Loopback2 + """, + ) + set_module_args( + dict( + state="gathered", + ), + ) + result = self.execute_module(changed=False) + gathered = [ + { + "name": "GigabitEthernet0/1", + "autostate": False, + }, + { + "name": "Vlan901", + "ipv4": [{"source_interface": {"name": "Loopback2"}}], + "autostate": True, + }, + ] + self.assertEqual(result["gathered"], gathered) diff --git a/tests/unit/modules/network/ios/test_ios_ntp.py b/tests/unit/modules/network/ios/test_ios_ntp.py deleted file mode 100644 index fe11b77b7..000000000 --- a/tests/unit/modules/network/ios/test_ios_ntp.py +++ /dev/null @@ -1,110 +0,0 @@ -# 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 -from unittest.mock import patch - -from ansible_collections.cisco.ios.plugins.modules import ios_ntp -from ansible_collections.cisco.ios.tests.unit.modules.utils import set_module_args - -from .ios_module import TestIosModule, load_fixture - - -class TestIosNtpModule(TestIosModule): - module = ios_ntp - - def setUp(self): - super(TestIosNtpModule, self).setUp() - - self.mock_get_config = patch( - "ansible_collections.cisco.ios.plugins.modules.ios_ntp.get_config", - ) - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch( - "ansible_collections.cisco.ios.plugins.modules.ios_ntp.load_config", - ) - self.load_config = self.mock_load_config.start() - - def tearDown(self): - super(TestIosNtpModule, self).tearDown() - self.mock_get_config.stop() - self.mock_load_config.stop() - - def load_fixtures(self, commands=None): - self.get_config.return_value = load_fixture("ios_ntp_config.cfg").strip() - self.load_config.return_value = dict(diff=None, session="session") - - def test_ios_ntp_idempotent(self): - set_module_args( - dict( - server="10.75.32.5", - source_int="Loopback0", - acl="NTP_ACL", - logging=True, - auth=True, - auth_key="15435A030726242723273C21181319000A", - key_id="10", - vrf="my_mgmt_vrf", - state="present", - ), - ) - commands = [] - self.execute_module(changed=False, commands=commands) - - def test_ios_ntp_config(self): - set_module_args( - dict( - server="10.75.33.5", - source_int="Vlan2", - acl="NTP_ACL", - logging=True, - auth=True, - auth_key="15435A030726242723273C21181319000A", - key_id="10", - state="present", - ), - ) - commands = ["ntp server 10.75.33.5", "ntp source Vlan2"] - self.execute_module(changed=True, commands=commands) - - def test_ios_ntp_remove(self): - set_module_args( - dict( - server="10.75.32.5", - source_int="Loopback0", - acl="NTP_ACL", - logging=True, - auth=True, - auth_key="15435A030726242723273C21181319000A", - key_id="10", - vrf="my_mgmt_vrf", - state="absent", - ), - ) - commands = [ - "no ntp server vrf my_mgmt_vrf 10.75.32.5", - "no ntp source Loopback0", - "no ntp access-group peer NTP_ACL", - "no ntp logging", - "no ntp authenticate", - "no ntp trusted-key 10", - "no ntp authentication-key 10 md5 15435A030726242723273C21181319000A 7", - ] - self.execute_module(changed=True, commands=commands) diff --git a/tests/unit/modules/network/ios/test_ios_service.py b/tests/unit/modules/network/ios/test_ios_service.py index fa92efcdc..69af87eda 100644 --- a/tests/unit/modules/network/ios/test_ios_service.py +++ b/tests/unit/modules/network/ios/test_ios_service.py @@ -128,14 +128,13 @@ def test_ios_service_merged(self): }, } merged = [ - "service timestamps debug uptime", - "service timestamps log datetime msec localtime show-timezone year", "service password-encryption", + "service timestamps debug uptime mesc", + "service timestamps log datetime mesc localtime show-timezone year", ] playbook["state"] = "merged" set_module_args(playbook) result = self.execute_module(changed=True) - self.assertEqual(sorted(result["commands"]), sorted(merged)) def test_ios_snm_server_deleted(self): @@ -213,18 +212,17 @@ def test_ios_service_overridden(self): overridden = [ "no service call-home", "no service config", - "no service pad", "service counters max age 5", + "no service pad", "service password-encryption", "service tcp-keepalives-in", "service tcp-keepalives-out", + "service timestamps log datetime mesc localtime show-timezone year", "service timestamps debug datetime", - "service timestamps log datetime msec localtime show-timezone year", ] playbook["state"] = "overridden" set_module_args(playbook) result = self.execute_module(changed=True) - self.assertEqual(sorted(result["commands"]), sorted(overridden)) def test_ios_service_replaced(self): @@ -258,6 +256,10 @@ def test_ios_service_replaced(self): { "msg": "debug", "timestamp": "datetime", + "datetime_options": { + "localtime": True, + "msec": True, + }, }, ], "tcp_keepalives_in": True, @@ -269,18 +271,17 @@ def test_ios_service_replaced(self): replaced = [ "no service call-home", "no service config", - "no service pad", "service counters max age 5", + "no service pad", "service password-encryption", "service tcp-keepalives-in", "service tcp-keepalives-out", - "service timestamps debug datetime", - "service timestamps log datetime msec localtime show-timezone year", + "service timestamps log datetime mesc localtime show-timezone year", + "service timestamps debug datetime mesc localtime", ] playbook["state"] = "replaced" set_module_args(playbook) result = self.execute_module(changed=True) - self.assertEqual(sorted(result["commands"]), sorted(replaced)) def test_ios_service_replaced_idempotent(self): @@ -368,8 +369,6 @@ def test_ios_service_replaced_idempotent_old(self): self.assertEqual(sorted(result["commands"]), sorted(replaced)) - #################### - def test_ios_service_parsed(self): set_module_args( dict( @@ -426,36 +425,36 @@ def test_ios_service_gathered(self): service timestamps log datetime msec localtime show-timezone year service timestamps debug uptime service call-home + service udp-small-servers + service tcp-small-servers no-limit """, ) set_module_args(dict(state="gathered")) gathered = { "timestamps": [ - { - "msg": "debug", - "timestamp": "uptime", - }, { "msg": "log", "timestamp": "datetime", "datetime_options": { - "localtime": True, "msec": True, + "localtime": True, "show_timezone": True, "year": True, }, }, + {"msg": "debug", "timestamp": "uptime"}, ], "call_home": True, - "dhcp": True, + "udp_small_servers": {"enable": True}, + "tcp_small_servers": {"enable": True, "no_limit": True}, "counters": 0, + "dhcp": True, "password_recovery": True, "prompt": True, "slave_log": True, } result = self.execute_module(changed=False) self.maxDiff = None - self.assertEqual(sorted(result["gathered"]), sorted(gathered)) def test_ios_service_rendered(self): @@ -472,6 +471,9 @@ def test_ios_service_rendered(self): { "msg": "debug", "timestamp": "uptime", + "datetime_options": { + "localtime": True, + }, }, { "msg": "log", @@ -497,10 +499,9 @@ def test_ios_service_rendered(self): "service slave-log", "service tcp-keepalives-in", "service tcp-keepalives-out", - "service timestamps debug uptime", - "service timestamps log datetime msec localtime show-timezone year", + "service timestamps debug uptime localtime", + "service timestamps log datetime mesc localtime show-timezone year", ] 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_snmp_server.py b/tests/unit/modules/network/ios/test_ios_snmp_server.py index 0b8f797a1..9674c894d 100644 --- a/tests/unit/modules/network/ios/test_ios_snmp_server.py +++ b/tests/unit/modules/network/ios/test_ios_snmp_server.py @@ -1928,7 +1928,7 @@ def test_ios_snmp_server_rendered(self): "snmp-server enable traps ospf state-change", "snmp-server enable traps ethernet cfm cc mep-up mep-down cross-connect loop config", "snmp-server enable traps ethernet cfm crosscheck mep-missing mep-unknown service-up", - "snmp-server host 172.16.1.1 version 3 auth vrf mgmt group0 tty", + "snmp-server host 172.16.1.1 vrf mgmt version 3 auth group0 tty", "snmp-server host 172.16.2.1 version 3 priv newtera rsrb", "snmp-server host 172.16.2.1 version 3 noauth replaceUser slb", "snmp-server host 172.16.2.1 version 2c trapsac tty", diff --git a/tests/unit/modules/network/ios/test_ios_vlans.py b/tests/unit/modules/network/ios/test_ios_vlans.py index a8a848020..10b30e140 100644 --- a/tests/unit/modules/network/ios/test_ios_vlans.py +++ b/tests/unit/modules/network/ios/test_ios_vlans.py @@ -726,7 +726,7 @@ def test_ios_delete_vlans_config(self): "no state active", "no mtu 1500", "no remote-span", - "no no shutdown", + "shutdown", ] self.assertEqual(result["commands"], commands) @@ -1240,7 +1240,7 @@ def test_ios_vlans_config_overridden(self): ] self.assertEqual(result["commands"], commands) - def test_ios_delete_vlans_config(self): + def test_ios_delete_vlans_config_2(self): self.mock_l2_device_command.side_effect = True self.mock_execute_show_command_conf.side_effect = "" self.execute_show_command.return_value = dedent( diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 6ada631cb..000000000 --- a/tox.ini +++ /dev/null @@ -1,31 +0,0 @@ -[tox] -minversion = 1.4.2 -envlist = linters -skipsdist = True - -[testenv] -deps = -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt - -[testenv:black] -install_command = pip install {opts} {packages} -commands = - black -v {toxinidir} - -[testenv:linters] -install_command = pip install {opts} {packages} -commands = - black -v --diff --check {toxinidir} - flake8 {posargs} - -[testenv:venv] -commands = {posargs} - -[flake8] -# E123, E125 skipped as they are invalid PEP-8. - -show-source = True -ignore = E123,E125,E203,E402,E501,E741,F401,F811,F841,W503 -max-line-length = 160 -builtins = _ -exclude = .git,.tox,tests/unit/compat/