Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix missing PoE port graphs for Cisco Catalyst 9K #11698

Merged
merged 4 commits into from Jun 5, 2020
Merged

Fix missing PoE port graphs for Cisco Catalyst 9K #11698

merged 4 commits into from Jun 5, 2020

Conversation

ajsiersema
Copy link
Contributor

@ajsiersema ajsiersema commented May 25, 2020

The PoE port graphs are missing on Cisco Catalyst 9K devices.
Polling code assumes interfaces named *Ethernet[SLOT#]/[SUBSLOT#]/[PORT#] will have corresponding entries in the SNMP table, e.g. cpeExtStuff.3.0.1 for GigabitEthernet3/0/1
However, Cisco decided to omit the 0 of the SUBSLOT, the SNMP entry is thus cpeExtStuff.3.1

This pull requests registers both variations in order to match both the Cat 9K devices, and any devices conforming to the existing assumption with regard to interface name<->SNMP name relation.
The change will not break existing behavior, but only adds the Cat 9K case.
AFAIK there are no ios/iosxe devices that have both
GigabitEthernet[1-9]+/0/[0-9]+ i.e. slot/subslot/port
as well as
GigabitEthernet[1-9]+/[0-9]+ i.e. slot/port
All the slots with subslots start at 1, with possibly a single OOB interface GigabitEthernet0/0 (in slot 0.)

Tested on IOS-XE 16.9.x

DO NOT DELETE THE UNDERLYING TEXT

Please note

Please read this information carefully. You can run ./scripts/pre-commit.php to check your code before submitting.

  • [ X] Have you followed our code guidelines?
  • If my Pull Request does some changes/fixes/enhancements in the WebUI, I have inserted a screenshot of it.

Testers

If you would like to test this pull request then please run: ./scripts/github-apply <pr_id>, i.e ./scripts/github-apply 5926
After you are done testing, you can remove the changes with ./scripts/github-remove. If there are schema changes, you can ask on discord how to revert.

@ajsiersema
Copy link
Contributor Author

Fixing codeclimate "Avoid deeply nested control flow statements" requires extensive code rewrite.
The same codeclimate issue popped up in other PR's, where the consensus seems to be that we can ignore this message in these cases.

@murrant murrant added the Needs Tests 🦄 https://docs.librenms.org/Developing/os/Test-Units/ label May 25, 2020
@label-actions
Copy link

label-actions bot commented May 25, 2020

Please add test data so we can ensure your change is not broken in the future.

Read the docs to find out how: https://docs.librenms.org/Developing/os/Test-Units

@murrant murrant added the Device 🖥️ New or added device support label May 25, 2020
devices that do include the subslot (for subslot == 0)
*/
$iface_parts = explode('/', $matches[1]);
while (1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while (1) needs to change, you could honestly update the regex above and drop most of this code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left the regexp from the original code as we still need to match ethernet interfaces and capture the slot[/subslot]/port part (to be able replace '/' by '.' later.)
Capturing repeated subgroups in PHP's PCRE would make for a hard to read regexp. Maybe that was your intention ? I'm not quite sure what you meant by 'update the regexp'.

We also still need to add both slot.subslot.port and slot.port to $port_ent_to_if, i.e. two assignments (at least). Otherwise we'd break the poller for non-cat9K devices.
We don't want to strip the subslot element if it's non-zero, i.e. we need to check that part of the interface notation.
Maybe your assumption is that there will always be either slot/subslot/port or slot/port interfaces, and not e.g. slot/subslot/subsubslot/port. The PR code doesn't make any assumptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The while (1) is in effect a do..while, preventing a duplication of the assignment statements.
I'll see if a variation on that theme with a for loop or some such is less offensive to the eyes :)

Copy link
Member

@murrant murrant May 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 if (preg_match('/^[a-z]+ethernet(\d+)\/(\d+)(?:\/(\d+))?$/i', $if_descr['ifDescr'], $matches)) {
port_ent_to_if[$matches[1] . '.' . ($matches[3] ?: $matches[2])] = ['portIfIndex' => $if_index];
}

Should be it. Specifically only matches XethernetX/X or XethernetX/X/X

If cpeExtPsePortEntry can be indexed differently, this code is probably slightly wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be it. Specifically only matches XethernetX/X or XethernetX/X/X
If cpeExtPsePortEntry can be indexed differently, this code is probably slightly wrong.

That's indeed the catch: I fully expect there to be an existing ios(xe) device that indexes XethernetA/B/C in cpeExtPsePortEntry with a.b.c. even with B == 0. Breaking the poller is bad, hence the code to add both A.B.C. and A.C to $port_ent_to_if, for arbitrary 'depths' of interface names.

However, if we're working with the assumption that there will only ever be XethernetX/X or XethernetX/X/X (i.e. two or three parts notation), we can refactor the PR as two assignment statements, like so:

if (preg_match('/^\w+ethernet(\d+)\/(\d+)(?:\/(\d+))?$/i', $if_descr['ifDescr'], $matches)) {
    foreach (array(0=>0) + ($matches[3] ? array(1=>2):array()) as $idx) {
        unset($matches[$idx]);
        $port_ent_to_if[implode('.', $matches)] = ['portIfIndex' => $if_index];
    }
}

What do you think ?

Copy link
Member

@murrant murrant May 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you expect that? Generally the table indexes are fixed. I don't have any sample data to l look at so I can't confirm. (btw you should add test data to this PR)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the loop?
just add two entries into the $port_ent_to_if array

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added tests. I've check with ./lnms dev:check -o iosxe_c9400 , they seem to pass.
Not sure about the 2nd ASA device in the JSON, did snmpsim inject it ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

codeclimate once again complains about "Avoid deeply nested control flow statements". Can't be fixed without drastic rewriting all of the code.

Node analysis timed out "The command produced no output for 180 seconds. You can increase this timeout by defining the "idle_timeout" modifier.". Not something I can fix :)

@murrant
Copy link
Member

murrant commented Jun 5, 2020

Understood, you aren't expected to fix the underlying code issues, just hopefully not make it worse ;)

@murrant murrant removed the Needs Tests 🦄 https://docs.librenms.org/Developing/os/Test-Units/ label Jun 5, 2020
@murrant
Copy link
Member

murrant commented Jun 5, 2020

Also, enable_ports_poe is false by default, so I'm not sure if your code is being tested.

Checking the MIBs...
CISCO-POWER-ETHERNET-EXT-MIB: AUGMENTS { pethPsePortEntry  } 
POWER-ETHERNET-MIB: INDEX { pethPsePortGroupIndex , pethPsePortIndex  }

This means cpeExtPsePortEntry is always indexed by exactly 2 values.  No point in populating slot.subslot.port
@murrant murrant merged commit cd362b7 into librenms:master Jun 5, 2020
Copy link
Contributor Author

@ajsiersema ajsiersema left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The simplified code will also strip subslot != 0.
I currently don't have any devices with e.g. Gi1/1/1, I haven't been able to verify if Cisco always strips the subslot. Hence my reasoning for storing both. You already mentioned you didn't expect any issues.
Thanks again for your effort

@murrant
Copy link
Member

murrant commented Jul 3, 2020

This pull request has been mentioned on LibreNMS Community. There might be relevant details there:

https://community.librenms.org/t/v1-65-release-changelog-june-2020/12687/1

1 similar comment
@murrant
Copy link
Member

murrant commented Jul 3, 2020

This pull request has been mentioned on LibreNMS Community. There might be relevant details there:

https://community.librenms.org/t/v1-65-release-changelog-june-2020/12687/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Device 🖥️ New or added device support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants