Skip to content

Commit

Permalink
Merge branch 'main' into nxos_evpn_vni_check_issue
Browse files Browse the repository at this point in the history
  • Loading branch information
heathdbrown authored Jan 17, 2025
2 parents 6376edc + 56ad042 commit d71b388
Show file tree
Hide file tree
Showing 30 changed files with 362 additions and 46 deletions.
3 changes: 3 additions & 0 deletions changelogs/fragments/lag_interfaces_error.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
bugfixes:
- "lag_interfaces - Fix bug where lag interfaces was not erroring on command failure. (https://github.com/ansible-collections/cisco.nxos/pull/923)"
2 changes: 2 additions & 0 deletions changelogs/fragments/nxos_facts_cpu_utilization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- "Fixed hardware fact gathering failure for CPU utilization parsing on NX-OS 9.3(3) by handling both list and single value formats of onemin_percent"
3 changes: 3 additions & 0 deletions changelogs/fragments/nxos_l2_interfaces.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
bugfixes:
- "nxos_l2_interfaces - Fixed handling of 'none' value in allowed_vlans to properly set trunk VLAN none"
2 changes: 2 additions & 0 deletions changelogs/fragments/nxos_telemetry_overridden.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- "nxos_telemetry - Added support for 'overridden' state to provide complete configuration override capabilities."
3 changes: 3 additions & 0 deletions changelogs/fragments/purged_user.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
bugfixes:
- Fixes nxos_user purge deleting non-local users,ensuring only local users are removed.
5 changes: 5 additions & 0 deletions changelogs/fragments/tests_fix.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
bugfixes:
- Fixes mixed usage of f-string and format string in action plugin for consistency.
trivial:
- Added tests fixes for nxos_facts.
28 changes: 27 additions & 1 deletion docs/cisco.nxos.nxos_telemetry_module.rst
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ Parameters
<li>replaced</li>
<li>deleted</li>
<li>gathered</li>
<li>overridden</li>
</ul>
</td>
<td>
Expand Down Expand Up @@ -653,7 +654,7 @@ Examples
# This action will replace telemetry configuration on the device with the
# telemetry configuration defined in the playbook.
- name: Override Telemetry Configuration
- name: Replace Telemetry Configuration
cisco.nxos.nxos_telemetry:
config:
certificate:
Expand All @@ -674,6 +675,31 @@ Examples
destination_group: 55
state: replaced
# Using overridden
# This action will override all telemetry configuration on the device with the
# telemetry configuration defined in the playbook.
- name: Override Telemetry Configuration
cisco.nxos.nxos_telemetry:
config:
certificate:
key: /bootflash/server.key
hostname: localhost
compression: gzip
source_interface: Ethernet1/1
vrf: management
destination_groups:
- id: 2
destination:
ip: 192.168.0.2
port: 50001
protocol: gRPC
encoding: GPB
subscriptions:
- id: 5
destination_group: 55
state: overridden
Return Values
Expand Down
2 changes: 1 addition & 1 deletion galaxy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ readme: README.md
repository: https://github.com/ansible-collections/cisco.nxos
issues: https://github.com/ansible-collections/cisco.nxos/issues
tags: [cisco, nxos, networking, nxapi, netconf]
version: 9.2.1
version: 9.2.2-devel
3 changes: 1 addition & 2 deletions plugins/action/nxos.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ def run(self, tmp=None, task_vars=None):
"msg": (
f"Connection type must be fully qualified name for "
f"network_cli connection type, got {self._play_context.connection}"
)
% self._play_context.connection,
),
}

conn = Connection(self._connection.socket_path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class TelemetryArgs(object): # pylint: disable=R0903
"type": "dict",
},
"state": {
"choices": ["merged", "replaced", "deleted", "gathered"],
"choices": ["merged", "replaced", "deleted", "gathered", "overridden"],
"default": "merged",
"type": "str",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,13 @@ def expand_trunk_allowed_vlans(self, d):
return None
if "trunk" in d and d["trunk"]:
if "allowed_vlans" in d["trunk"]:
allowed_vlans = vlan_range_to_list(d["trunk"]["allowed_vlans"])
vlans_list = [str(line) for line in sorted(allowed_vlans)]
d["trunk"]["allowed_vlans"] = ",".join(vlans_list)
if d["trunk"]["allowed_vlans"]:
if d["trunk"]["allowed_vlans"].lower() == "none":
return
else:
allowed_vlans = vlan_range_to_list(d["trunk"]["allowed_vlans"])
vlans_list = [str(line) for line in sorted(allowed_vlans)]
d["trunk"]["allowed_vlans"] = ",".join(vlans_list)

def set_state(self, want, have):
"""Select the appropriate function based on the state provided
Expand Down Expand Up @@ -347,5 +351,8 @@ def _reconstruct_commands(self, cmds):
)
if match:
data = match.groupdict()
unparsed = vlan_list_to_range(data["vlans"].split(","))
if data["vlans"].lower() != "none":
unparsed = vlan_list_to_range(data["vlans"].split(","))
else:
unparsed = "none"
cmds[idx] = data["cmd"] + " " + unparsed
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ def execute_module(self):
err_str = item
if err_str.lower().startswith("cannot add"):
self._module.fail_json(msg=err_str)
elif err_str.lower().startswith("command failed"):
self._module.fail_json(msg=err_str)
result["changed"] = True

if self.state in self.ACTION_STATES:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ def execute_module(self):
warnings = list()

state = self._module.params["state"]
if "overridden" in state:
self._module.fail_json(msg="State <overridden> is invalid for this module.")
# When state is 'deleted', the module_params should not contain data
# under the 'config' key
if "deleted" in state and self._module.params.get("config"):
Expand Down Expand Up @@ -153,7 +151,7 @@ def set_state(self, want, have):
# and does not require any processing using NxosCmdRef objects.
if state == "deleted":
return self._state_deleted(want, have)
elif state == "replaced":
elif state in ["replaced", "overridden"]:
if want == have:
return []
return self._state_replaced(want, have)
Expand Down
6 changes: 5 additions & 1 deletion plugins/module_utils/network/nxos/facts/legacy/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ def populate(self):
self.facts["cpu_utilization"] = self.parse_cpu_utilization(data)

def parse_cpu_utilization(self, data):
onemin = data.get("onemin_percent", ["0"])
if not isinstance(onemin, list):
onemin = [str(onemin)]
onemin_value = onemin[0]
return {
"core": {
"five_minutes": int(data.get("fivemin_percent", 0)),
Expand All @@ -178,7 +182,7 @@ def parse_cpu_utilization(self, data):
"five_seconds_interrupt": int(
data.get("fivesec_intr_percent", 0),
),
"one_minute": int(data.get("onemin_percent", 0)),
"one_minute": int(onemin_value),
},
}

Expand Down
28 changes: 27 additions & 1 deletion plugins/modules/nxos_telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@
- replaced
- deleted
- gathered
- overridden
default: merged
"""
Expand Down Expand Up @@ -267,7 +268,7 @@
# This action will replace telemetry configuration on the device with the
# telemetry configuration defined in the playbook.
- name: Override Telemetry Configuration
- name: Replace Telemetry Configuration
cisco.nxos.nxos_telemetry:
config:
certificate:
Expand All @@ -287,6 +288,31 @@
- id: 5
destination_group: 55
state: replaced
# Using overridden
# This action will override all telemetry configuration on the device with the
# telemetry configuration defined in the playbook.
- name: Override Telemetry Configuration
cisco.nxos.nxos_telemetry:
config:
certificate:
key: /bootflash/server.key
hostname: localhost
compression: gzip
source_interface: Ethernet1/1
vrf: management
destination_groups:
- id: 2
destination:
ip: 192.168.0.2
port: 50001
protocol: gRPC
encoding: GPB
subscriptions:
- id: 5
destination_group: 55
state: overridden
"""
RETURN = """
before:
Expand Down
24 changes: 21 additions & 3 deletions plugins/modules/nxos_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,19 @@ def update_objects(want, have):
return updates


def get_configured_usernames(module):
config_output = run_commands(
module,
[{"command": "show running-config | section ^username", "output": "text"}],
)
usernames = set()
for line in config_output[0].splitlines():
if line.startswith("username "):
username = line.split()[1]
usernames.add(username)
return usernames


def main():
"""main entry point for module execution"""
element_spec = dict(
Expand Down Expand Up @@ -457,9 +470,14 @@ def main():
commands = map_obj_to_commands(update_objects(want, have), module)

if module.params["purge"]:
want_users = [x["name"] for x in want]
have_users = [x["name"] for x in have]
for item in set(have_users).difference(want_users):
want_users = set([x["name"] for x in want])
have_users = set([x["name"] for x in have])

configured_usernames = get_configured_usernames(module)

non_local_users = have_users.difference(want_users).difference(configured_usernames)

for item in configured_usernames.difference(non_local_users):
if item != "admin":
item = item.replace("\\", "\\\\")
commands.append("no username %s" % item)
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/targets/nxos_facts/vars/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ available_network_resources:
- static_routes
- telemetry
- vlans
- vrf_address_family
- vrf_global
- vrf_interfaces
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

- ansible.builtin.assert:
that:
- result is search("argument 'file_pull_timeout' is of type .* and we were unable to convert to int")
- result.msg is ansible.builtin.search("argument 'file_pull_timeout' is of type .* and we were unable to convert to int", multiline=true)

- name: Input validation - param should be type <bool>
register: result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,12 @@
parents: "interface {{ nxos_int2 }}"
vars:
ansible_connection: ansible.netcommon.network_cli

- name: Set VLAN trunking properties with "none"
cisco.nxos.nxos_config:
lines:
- "switchport"
- "switchport trunk allowed vlan none"
parents: "interface {{ nxos_int3 }}"
vars:
ansible_connection: ansible.netcommon.network_cli
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@
- ansible.builtin.debug:
msg: Start nxos_l2_interfaces replaced integration tests connection={{ ansible_connection }}

- name: Set a fact for 'test_int1' and 'test_int2'
- name: Set a fact for 'test_int1','test_int2'name and 'test_int3'
ansible.builtin.set_fact:
test_int1: "{{ nxos_int1 }}"
test_int2: "{{ nxos_int2 }}"
test_int3: "{{ nxos_int3 }}"

- name: Setup1
ignore_errors: true
cisco.nxos.nxos_config: &id003
lines:
- "default interface {{ test_int1 }}"
- "default interface {{ test_int2 }}"
- "default interface {{ test_int3 }}"

- block:
- name: Setup2
Expand All @@ -30,6 +32,13 @@
- "switchport trunk allowed vlan 25-27"
parents: "interface {{ test_int2 }}"

- name: Setup4
cisco.nxos.nxos_config:
lines:
- "switchport"
- "switchport trunk allowed vlan 100-200"
parents: "interface {{ test_int3 }}"

- name: Gather l2_interfaces facts
cisco.nxos.nxos_facts: &id001
gather_subset:
Expand All @@ -50,6 +59,10 @@
- name: "{{ test_int2 }}"
trunk:
allowed_vlans: 25-27

- name: "{{ test_int3 }}"
trunk:
allowed_vlans: none
state: replaced

- ansible.builtin.assert:
Expand All @@ -60,7 +73,9 @@
- "'switchport trunk allowed vlan 10-12' in result.commands"
- "'interface {{ test_int2 }}' in result.commands"
- "'no switchport trunk native vlan' in result.commands"
- result.commands|length == 5
- "'interface {{ test_int3 }}' in result.commands"
- "'switchport trunk allowed vlan none' in result.commands"
- result.commands|length == 7

- name: Gather l2_interfaces post facts
cisco.nxos.nxos_facts: *id001
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
- name: Main task for vrf_global module
when: not nxos_skip_marked | default(true)
ansible.builtin.include_tasks: cli.yaml
tags:
- network_cli
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
cisco.nxos.nxos_vrf_interfaces: &id001
config:
- name: Ethernet1/2
vrf_name: test
- name: Ethernet1/6
vrf_name: test2
state: deleted

- name: Assert that correct set of commands were generated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@
ansible.builtin.assert:
that:
- not result.changed
- "{{ gathered['config'] | symmetric_difference(result['gathered']) |length == 0 }}"
- >
{{
result['gathered']
| selectattr('name', 'in', 'Ethernet1/2,Ethernet1/6')
| symmetric_difference(gathered['config'])
| length == 0
}}
always:
- ansible.builtin.include_tasks: _remove_config.yaml
Loading

0 comments on commit d71b388

Please sign in to comment.