Repository: networktocode/ntc-templates

Issue:
arista_eos_show_port-channel_summary.textfsm
Suggest making a new module for Arista
show port-channel dense

```
7010T-48-02#7010T-48-02#show port-channel summary
% Invalid input
7010T-48-02#% Unavailable command (This command is deprecated by 'show port-channel dense')
% Invalid input
```
I tested arista_eos_show_port-channel_summary.textfsm on that new command and it works on that command But does fail if the device has no port channels:
```
Flags                                                              
--------------------------- -------------------------------- -------------------------
   a - LACP Active             p - LACP Passive              * - static fallback      
   F - Fallback enabled        f - Fallback configured       ^ - individual fallback  
   U - In Use                  D - Down                                               
   + - In-Sync                 - - Out-of-Sync               i - incompatible with agg
   P - bundled in Po           s - suspended                 G - Aggregable           
   I - Individual              S - ShortTimeout              w - wait for agg         
   C - Transmit disabled       M - Exceeds maximum weight                             
  E - Inactive. The number of configured port channels exceeds the config limit

Number of channels in use: 0
Number of aggregators: 0

   Port-Channel       Protocol    Ports
------------------ -------------- -----
```

State Error raised. Rule Line: 16. Input Line:    Port-Channel       Protocol    Ports


Discussion:
> I tested arista_eos_show_port-channel_summary.textfsm on that new command and it works on that command But does fail if the device has no port channels:

Thank you for the testing you've done!

It's possible the former command's output with no port channels may have failed, but the contributor (and thus this project just didn't have test data for that) so it wasn't caught.

Based on your feedback, since the existing template mostly works we could leverage the existing template and just add in the other conditions. Then it's a matter of adding to the index.

:dart: I'd be glad to take this one on.

And there's a bug regarding multi-line port-channel members.

[yml - lines 312 to 316](https://github.com/networktocode/ntc-templates/blob/fedc878e1370fd7d55630216e3506dfeed5c9ff6/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary.yml#L312)
[raw - lines 53 to 54](https://github.com/networktocode/ntc-templates/blob/fedc878e1370fd7d55630216e3506dfeed5c9ff6/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary.raw#L53)

**Edit:** Updated links with commit (point in time view) and not master branch.
I've addressed the bug and added `dense` to the index.
(PR #2143 is a draft for now as I review it further.)

~I decided to create a new tests directory for this one so we have at least one use of the index for `show port-channel dense`. I don't necessarily like the sprawl, but so others don't miss it in the future~ I'll put a note in the template that it is used for `dense` as well.

Looks like `sh[[ow]] port-c[[hannel]] d[[ense]]` should be the correct "resulting" command regex per [Arista port-channel docs](https://www.arista.com/en/um-eos/eos-port-channels-and-lacp). (_It has to be combined with the other use of the template though._)



Patch:
diff --git a/ntc_templates/templates/arista_eos_show_port-channel_summary.textfsm b/ntc_templates/templates/arista_eos_show_port-channel_summary.textfsm
index 4d711a81f9..ad81c043d4 100644
--- a/ntc_templates/templates/arista_eos_show_port-channel_summary.textfsm
+++ b/ntc_templates/templates/arista_eos_show_port-channel_summary.textfsm
@@ -5,28 +5,26 @@ Value BUNDLE_PROTOCOL_STATE (\S+)
 Value List MEMBER_INTERFACE (Et\S+)
 Value List MEMBER_INTERFACE_STATUS (\S+)
 
+# template also used for `show port-channel dense`
 
 Start
   ^\s*Flags
   ^-+
   ^\s+\S\s+-
   ^Number
-  ^\s+Port-Channel\s+Protocol\s+Ports\s+$$ -> PCS
+  ^\s+Port-Channel\s+Protocol\s+Ports\s*$$ -> PCS
   ^\s*$$
   ^. -> Error
 
 
-
 PCS
   ^\s*Po\d+ -> Continue.Record
   ^\s*${BUNDLE_NAME}\(${BUNDLE_STATUS}\)\s+${BUNDLE_PROTOCOL}\(${BUNDLE_PROTOCOL_STATE}\)\s+${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
-  ^\s*Po\d+.+(Et.+?\(.+?\)\s){1}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
-  ^\s*Po\d+.+(Et.+?\(.+?\)\s){2}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
-  ^\s*Po\d+.+(Et.+?\(.+?\)\s){3}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
-  ^\s*Po\d+.+(Et.+?\(.+?\)\s){4}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
+  ^\s*Po\d+.+?(Et.+?\(.+?\)\s){1}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
+  ^\s*Po\d+.+?(Et.+?\(.+?\)\s){2}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
+  ^\s*Po\d+.+?(Et.+?\(.+?\)\s){3}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)\s*$$ -> Continue
   ^\s+${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
   ^\s+(Et.+?\(.+?\)\s){1}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
   ^\s+(Et.+?\(.+?\)\s){2}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
-  ^\s+(Et.+?\(.+?\)\s){3}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
-  ^\s+(Et.+?\(.+?\)\s){4}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)(\s|$$) -> Continue
-
+  ^\s+(Et.+?\(.+?\)\s){3}${MEMBER_INTERFACE}\(${MEMBER_INTERFACE_STATUS}\)\s*$$ -> Continue
+  ^-+
diff --git a/ntc_templates/templates/index b/ntc_templates/templates/index
index 6573e8b2bf..55ce99260a 100644
--- a/ntc_templates/templates/index
+++ b/ntc_templates/templates/index
@@ -72,7 +72,7 @@ arista_eos_show_interfaces_description.textfsm, .*, arista_eos, sh[[ow]] int[[er
 arista_eos_show_interfaces_transceiver.textfsm, .*, arista_eos, sh[[ow]] inte[[rfaces]] tr[[ansceiver]]
 arista_eos_show_mac_security_interface.textfsm, .*, arista_eos, sh[[ow]] ma[[c]] secu[[rity]] int[[erface]]
 arista_eos_show_lldp_neighbors_detail.textfsm, .*, arista_eos, sh[[ow]] ll[[dp]] nei[[ghbors]] d[[etail]]
-arista_eos_show_port-channel_summary.textfsm, .*, arista_eos, sh[[ow]] port-c[[hannel]] s[[ummary]]
+arista_eos_show_port-channel_summary.textfsm, .*, arista_eos, sh[[ow]] port-c[[hannel]] (s[[ummary]]|d[[ense]])
 arista_eos_show_environment_cooling.textfsm, .*, arista_eos, sh[[ow]] en[[vironment]] c[[ooling]]
 arista_eos_show_ip_interface_brief.textfsm, .*, arista_eos, sh[[ow]] i[[p]] int[[erface]] br[[ief]]
 arista_eos_show_pim_ipv4_interface.textfsm, .*, arista_eos, sh[[ow]] pim ipv4 int[[erface]]


Test patch:
diff --git a/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary.raw b/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary.raw
index ce4d3a1697..62e8103ef2 100644
--- a/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary.raw
+++ b/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary.raw
@@ -23,33 +23,15 @@ Number of aggregators: 1
    Po113(D)           LACP(aF*)    Et13(D)                          
    Po114(D)           LACP(aF*)    Et14(D)                          
    Po115(D)           LACP(aF*)    Et15(D)                          
-   Po116(D)           LACP(aF*)    Et16(D)                          
-   Po117(D)           LACP(aF*)    Et17(D)                          
-   Po118(D)           LACP(aF*)    Et18(D)                          
-   Po119(D)           LACP(aF*)    Et19(D)                          
-   Po120(D)           LACP(aF*)    Et20(D)                          
-   Po121(D)           LACP(aF*)    Et21(D)                          
-   Po122(D)           LACP(aF*)    Et22(D)                          
-   Po123(D)           LACP(aF*)    Et23(D)                          
-   Po124(D)           LACP(aF*)    Et24(D)                          
-   Po125(D)           LACP(aF*)    Et25(D)                          
-   Po126(D)           LACP(aF*)    Et26(D)                          
-   Po127(D)           LACP(aF*)    Et27(D)                          
-   Po128(D)           LACP(aF*)    Et28(D)                          
-   Po129(D)           LACP(aF*)    Et29(D)                          
-   Po130(D)           LACP(aF*)    Et30(D)                          
-   Po131(D)           LACP(aF*)    Et31(D)                          
-   Po132(D)           LACP(aF*)    Et32(D)                          
-   Po133(D)           LACP(aF*)    Et33(D)                          
-   Po134(D)           LACP(aF*)    Et34(D)                          
-   Po135(D)           LACP(aF*)    Et35(D)                          
-   Po136(D)           LACP(aF*)    Et36(D)                          
-   Po137(D)           LACP(aF*)    Et37(D)                          
-   Po138(D)           LACP(aF*)    Et38(D)                          
-   Po139(D)           LACP(aF*)    Et39(D)                          
-   Po140(D)           LACP(aF*)    Et40(D)                          
-   Po141(D)           LACP(aF*)    Et41(D)                          
-   Po142(D)           LACP(aF*)    Et42(D)                          
+   Po116(D)           LACP(aF*)    Et16(D) Et17(D)                  
+   Po118(D)           LACP(aF*)    Et18(D) Et19(D) Et20(D)          
+   Po121(D)           LACP(aF*)    Et21(D) Et22(D) Et23(D) Et24(D)  
+   Po125(D)           LACP(aF*)    Et25(D) Et26(D) Et27(D) Et28(D)  
+                                   Et29(D)                          
+   Po130(D)           LACP(aF*)    Et30(D) Et31(D) Et32(D) Et33(D)  
+                                   Et34(D) Et35(D)                  
+   Po136(D)           LACP(aF*)    Et36(D) Et37(D) Et38(D) Et39(D)  
+                                   Et40(D) Et41(D) Et42(D)          
    Po146(D)           LACP(aF*)    Et43(D) Et44(D) Et45(D) Et46(D)  
-                                   Et47(D)                          
+                                   Et47(D) Et48(D) Et49(D) Et50(D)  
    Po2000(U)          LACP(a)      Et54/1(PG+)   
\ No newline at end of file
diff --git a/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary.yml b/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary.yml
index 1454c35898..cfc2f21d7b 100644
--- a/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary.yml
+++ b/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary.yml
@@ -94,232 +94,112 @@ parsed_sample:
     bundle_status: "D"
     member_interface:
       - "Et16"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po117"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et17"
     member_interface_status:
       - "D"
+      - "D"
   - bundle_name: "Po118"
     bundle_protocol: "LACP"
     bundle_protocol_state: "aF*"
     bundle_status: "D"
     member_interface:
       - "Et18"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po119"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et19"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po120"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et20"
     member_interface_status:
       - "D"
+      - "D"
+      - "D"
   - bundle_name: "Po121"
     bundle_protocol: "LACP"
     bundle_protocol_state: "aF*"
     bundle_status: "D"
     member_interface:
       - "Et21"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po122"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et22"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po123"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et23"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po124"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et24"
     member_interface_status:
       - "D"
+      - "D"
+      - "D"
+      - "D"
   - bundle_name: "Po125"
     bundle_protocol: "LACP"
     bundle_protocol_state: "aF*"
     bundle_status: "D"
     member_interface:
       - "Et25"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po126"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et26"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po127"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et27"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po128"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et28"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po129"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et29"
     member_interface_status:
       - "D"
+      - "D"
+      - "D"
+      - "D"
+      - "D"
   - bundle_name: "Po130"
     bundle_protocol: "LACP"
     bundle_protocol_state: "aF*"
     bundle_status: "D"
     member_interface:
       - "Et30"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po131"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et31"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po132"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et32"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po133"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et33"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po134"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et34"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po135"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et35"
     member_interface_status:
       - "D"
+      - "D"
+      - "D"
+      - "D"
+      - "D"
+      - "D"
   - bundle_name: "Po136"
     bundle_protocol: "LACP"
     bundle_protocol_state: "aF*"
     bundle_status: "D"
     member_interface:
       - "Et36"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po137"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et37"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po138"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et38"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po139"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et39"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po140"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et40"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po141"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et41"
-    member_interface_status:
-      - "D"
-  - bundle_name: "Po142"
-    bundle_protocol: "LACP"
-    bundle_protocol_state: "aF*"
-    bundle_status: "D"
-    member_interface:
       - "Et42"
     member_interface_status:
       - "D"
+      - "D"
+      - "D"
+      - "D"
+      - "D"
+      - "D"
+      - "D"
   - bundle_name: "Po146"
     bundle_protocol: "LACP"
     bundle_protocol_state: "aF*"
     bundle_status: "D"
     member_interface:
       - "Et43"
-      - "Et46"
-      - "Et46"
+      - "Et44"
+      - "Et45"
       - "Et46"
       - "Et47"
+      - "Et48"
+      - "Et49"
+      - "Et50"
     member_interface_status:
       - "D"
       - "D"
       - "D"
       - "D"
       - "D"
+      - "D"
+      - "D"
+      - "D"
   - bundle_name: "Po2000"
     bundle_protocol: "LACP"
     bundle_protocol_state: "a"
diff --git a/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary_none.raw b/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary_none.raw
new file mode 100644
index 0000000000..b8d329794f
--- /dev/null
+++ b/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary_none.raw
@@ -0,0 +1,16 @@
+Flags                                                              
+--------------------------- -------------------------------- -------------------------
+   a - LACP Active             p - LACP Passive              * - static fallback      
+   F - Fallback enabled        f - Fallback configured       ^ - individual fallback  
+   U - In Use                  D - Down                                               
+   + - In-Sync                 - - Out-of-Sync               i - incompatible with agg
+   P - bundled in Po           s - suspended                 G - Aggregable           
+   I - Individual              S - ShortTimeout              w - wait for agg         
+   C - Transmit disabled       M - Exceeds maximum weight                             
+  E - Inactive. The number of configured port channels exceeds the config limit
+
+Number of channels in use: 0
+Number of aggregators: 0
+
+   Port-Channel       Protocol    Ports
+------------------ -------------- -----
\ No newline at end of file
diff --git a/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary_none.yml b/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary_none.yml
new file mode 100644
index 0000000000..e77add67ed
--- /dev/null
+++ b/tests/arista_eos/show_port-channel_summary/arista_eos_show_port-channel_summary_none.yml
@@ -0,0 +1,2 @@
+---
+parsed_sample: []