Skip to content

Commit

Permalink
Enhancements: Cisco IOS show mac and show module (#1006)
Browse files Browse the repository at this point in the history
  • Loading branch information
armartirosyan authored Oct 27, 2021
1 parent 9362ca2 commit ec76c69
Show file tree
Hide file tree
Showing 13 changed files with 532 additions and 47 deletions.
51 changes: 29 additions & 22 deletions ntc_templates/templates/cisco_ios_show_mac-address-table.textfsm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Value DESTINATION_ADDRESS ([0-9a-fA-F]{4}\.[0-9a-fA-F]{4}\.[0-9a-fA-F]{4})
Value TYPE (\S+)
Value VLAN (\S+)
Value List DESTINATION_PORT (\S+?)
Value List DESTINATION_PORT ([^,\s]+)

Start
^Destination\s+Address\s+Address\s+Type\s+VLAN\s+Destination\s+Port -> TYPE1
Expand All @@ -23,30 +23,37 @@ TYPE1

TYPE2
# Order of the group in brackets here matters
^\s*(?:\*\s+R|\*|R|\s)\s*(?:\d+|-+) -> Continue.Record
^\s*(?:\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s*$$ -> Continue
^\s*(?:\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+(?!\S+?,)${DESTINATION_PORT}\s*$$ -> Continue
^\s*(?:\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+${DESTINATION_PORT}, -> Continue
^\s*(?:\*\s+R|\*|R|\s)\s*(?:\d+|-+)\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+\S+?,${DESTINATION_PORT}, -> Continue
^\s*(?:\*\s+R|\*|R|\s)\s*(?:\d+|-+)\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+(?:\S+?,){2}${DESTINATION_PORT}, -> Continue
^\s*(?:\*\s+R|\*|R|\s)\s*(?:\d+|-+)\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+(?:\S+?,){3}${DESTINATION_PORT}(?:,|$$) -> Continue
^\s*(?:\*\s+R|\*|R|\s)\s*(?:\d+|-+)\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+(?:\S+?,){4}${DESTINATION_PORT}(?:,|$$) -> Continue
^\s*(?:\*\s+R|\*|R|\s)\s*(?:\d+|-+)\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+(?:\S+?,){5}${DESTINATION_PORT}(?:,|$$) -> Continue
^\s*(?:\*\s+R|\*|R|\s)\s*(?:\d+|-+)\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+(?:\S+?,){6}${DESTINATION_PORT}(?:,|$$) -> Continue
^\s*(?:\*\s+R|\*|R|\s)\s*(?:\d+|-+)\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+(?:\S+?,){7}${DESTINATION_PORT}(?:,|$$) -> Continue
^\s{20}\s+${DESTINATION_PORT}, -> Continue
^\s{20}\s+(?:\S+?,)${DESTINATION_PORT}, -> Continue
^\s{20}\s+(?:\S+?,){2}${DESTINATION_PORT}, -> Continue
^\s{20}\s+(?:\S+?,){3}${DESTINATION_PORT}(?:,|$$) -> Continue
^\s{20}\s+(?:\S+?,){4}${DESTINATION_PORT}(?:,|$$) -> Continue
^\s{20}\s+(?:\S+?,){5}${DESTINATION_PORT}(?:,|$$) -> Continue
^\s{20}\s+(?:\S+?,){6}${DESTINATION_PORT}(?:,|$$) -> Continue
^\s{20}\s+(?:\S+?,){7}${DESTINATION_PORT}(?:,|$$) -> Continue
^\s*(\*\s+R|\*|R|\s)\s*(\d+|-+|[Nn]/[Aa]) -> Continue.Record
# using 20 spaces should ensure that lines only match destination port flowing to next line
^\s{20}\s+${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s{20}\s+${DESTINATION_PORT},*\s*$$
^\s{20}\s+[^,\s]+(\s+|,\s*)${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s{20}\s+[^,\s]+(\s+|,\s*)${DESTINATION_PORT},*\s*$$
^\s{20}\s+([^,\s]+(\s+|,\s*)){2}${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s{20}\s+([^,\s]+(\s+|,\s*)){2}${DESTINATION_PORT},*\s*$$
^\s{20}\s+([^,\s]+(\s+|,\s*)){3}${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s{20}\s+([^,\s]+(\s+|,\s*)){3}${DESTINATION_PORT},*\s*$$
^\s{20}\s+([^,\s]+(\s+|,\s*)){4}${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s{20}\s+([^,\s]+(\s+|,\s*)){4}${DESTINATION_PORT},*\s*$$
^\s{20}\s+([^,\s]+(\s+|,\s*)){5}${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s{20}\s+([^,\s]+(\s+|,\s*)){5}${DESTINATION_PORT},*\s*$$
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s*$$
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+${DESTINATION_PORT},*\s*$$
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+[^,\s]+(\s+|,\s*)${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+[^,\s]+?(\s+|,\s*)${DESTINATION_PORT},*\s*$$
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+([^,\s]+(\s+|,\s*)){2}${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+([^,\s]+(\s+|,\s*)){2}${DESTINATION_PORT},*\s*$$
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+([^,\s]+(\s+|,\s*)){3}${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+([^,\s]+(\s+|,\s*)){3}${DESTINATION_PORT},*\s*$$
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+([^,\s]+(\s+|,\s*)){4}${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+([^,\s]+(\s+|,\s*)){4}${DESTINATION_PORT},*\s*$$
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+([^,\s]+(\s+|,\s*)){5}${DESTINATION_PORT}(\s+|,\s*)\S -> Continue
^\s*(\*\s+R|\*|R|\s)\s*${VLAN}\s+${DESTINATION_ADDRESS}\s+${TYPE}\s+\S+\s+\S+\s+([^,\s]+(\s+|,\s*)){5}${DESTINATION_PORT},*\s*$$
^-+\+-+
^Displaying\s+entries
^\s+vlan\s+mac address\s+type\s+learn\s+age\s+ports
^\s*$$
^\s*\S+
^Multicast\s+Entries -> End
^. -> Error

Expand All @@ -67,4 +74,4 @@ TYPE4
^\s*$$
^Total\s+Mac\s+Addresses
^MultiCast\s+Entries -> End
^. -> Error
^. -> Error
8 changes: 5 additions & 3 deletions ntc_templates/templates/cisco_ios_show_module.textfsm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Value Key MODULE (\d+)
Value PORT (\d+)
Value CARDTYPE (.+?)
Value CARDTYPE (\S.+?)
Value MODEL (\S+)
Value SERIAL (\w+)

Expand All @@ -10,9 +10,11 @@ Start

Status
^-+
^\s*${MODULE}\s+${PORT}\s+${CARDTYPE}\s+${MODEL}\s+${SERIAL}\s*$$ -> Record
^Mod\s+MAC\s+addresses\s+Hw\s+Fw\s+Sw\s+Status -> End
^\s*${MODULE}\s+(${PORT}\s+)?${CARDTYPE}(\s+${MODEL})?(\s+${SERIAL})?\s*$$ -> Record
^(?:Mod|\s+M)\s+MAC\s+addresses\s+Hw\s+Fw\s+Sw\s+Status -> End
^Mod\s+Sub-Module\s+Model\s+Serial\s+Hw\s+Status -> End
^Mod\s+Redundancy\s+Role\s+Operating\s+Redundancy\s+Mode\s+Configured\s+Redundancy\s+Mode -> End
^Mod\s+Redundancy\s+Role\s+Operating\s+Mode\s+Configured\s+Mode\s+Redundancy\s+Status -> End
^Mod\s+Online\s+Diag\s+Status -> End
^\s*$$
^. -> Error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ Value Key MODULE (\d+)
Value ONLINE_DIAG (\w+)

Start
^Mod\s+Online\s+Diag\s+Status -> Diag
^Mod\s+Online\s+Diag\s+Status -> Diag

Diag
^-+
^\s*${MODULE}\s+${ONLINE_DIAG} -> Record
^\s*${MODULE}\s+${ONLINE_DIAG} -> Record
^Mod\s+Ports\s+Card\s+Type\s+Model\s+Serial -> End
^Mod\s+MAC\s+addresses\s+Hw\s+Fw\s+Sw\s+Status -> End
^(?:Mod|\s+M)\s+MAC\s+addresses\s+Hw\s+Fw\s+Sw\s+Status -> End
^Mod\s+Sub-Module\s+Model\s+Serial\s+Hw\s+Status -> End
^Mod\s+Redundancy\s+Role\s+Operating\s+Redundancy\s+Mode\s+Configured\s+Redundancy\s+Mode -> End
^Mod\s+Redundancy\s+Role\s+Operating\s+Mode\s+Configured\s+Mode\s+Redundancy\s+Status -> End
^Mod\s+Online\s+Diag\s+Status -> End
^\s*$$
^. -> Error

Expand Down
10 changes: 6 additions & 4 deletions ntc_templates/templates/cisco_ios_show_module_status.textfsm
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
Value Key MODULE (\d+)
Value MAC_ADDR (\S+\s+to\s+\S+)
Value MOD_HW (\S+)
Value FW (\S+)
Value SW (\S+)
Value MOD_FW (\S+)
Value MOD_SW (\S+)
Value STATUS (\w+)


Start
^\s*Mod\s+MAC\saddresses\s+Hw\s+Fw\s+Sw\s+Status\s*$$ -> ModStatus
^\s*Mod\s+MAC\s+addresses\s+Hw\s+Fw\s+Sw\s+Status\s*$$ -> ModStatus

ModStatus
^-+
^\s*${MODULE}\s+${MAC_ADDR}\s+${MOD_HW}\s+${FW}\s+${SW}\s+${STATUS}\s*$$ -> Record
^\s*${MODULE}\s+${MAC_ADDR}\s+${MOD_HW}\s+${MOD_FW}\s+${MOD_SW}\s+${STATUS}\s*$$ -> Record
^Mod\s+Ports\s+Card\s+Type\s+Model\s+Serial -> End
^\s*Mod\s+Sub-Module\s+Model\s+Serial\s+Hw\s+Status\s*$$ -> End
^Mod\s+Online\s+Diag\s+Status -> End
^Mod\s+Redundancy\s+Role\s+Operating\s+Redundancy\s+Mode\s+Configured\s+Redundancy\s+Mode -> End
^Mod\s+Redundancy\s+Role\s+Operating\s+Mode\s+Configured\s+Mode\s+Redundancy\s+Status -> End
^\s*$$
^. -> Error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ Value SUBMODULE_STATUS (\w+)


Start
^\s*Mod\s+Sub-Module\s+Model\s+Serial\s+Hw\s+Status\s*$$ -> SubModule
^\s*Mod\s+Sub-Module\s+Model\s+Serial\s+Hw\s+Status\s*$$ -> SubModule

SubModule
^-+
^\s*${MODULE}\s+${SUBMODULE}\s+${SUBMODULE_MODEL}\s+${SUBMODULE_SERIAL}\s+${SUBMODULE_HW}\s+${SUBMODULE_STATUS}\s*$$ -> Record
^\s*${MODULE}\s+${SUBMODULE}\s+${SUBMODULE_MODEL}\s+${SUBMODULE_SERIAL}\s+${SUBMODULE_HW}\s+${SUBMODULE_STATUS}\s*$$ -> Record
^Mod\s+Ports\s+Card\s+Type\s+Model\s+Serial -> End
^Mod\s+MAC\s+addresses\s+Hw\s+Fw\s+Sw\s+Status -> End
^(?:Mod|\s+M)\s+MAC\s+addresses\s+Hw\s+Fw\s+Sw\s+Status -> End
^Mod\s+Online\s+Diag\s+Status -> End
^Mod\s+Redundancy\s+Role\s+Operating\s+Redundancy\s+Mode\s+Configured\s+Redundancy\s+Mode -> End
^Mod\s+Redundancy\s+Role\s+Operating\s+Mode\s+Configured\s+Mode\s+Redundancy\s+Status -> End
^\s*$$
^. -> Error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ parsed_sample:
- "Gi9/48"
- "Router"
- "Switch"
- "Stby-Switch"
type: "static"
vlan: "345"
- destination_address: "3333.0000.000d"
Expand Down Expand Up @@ -103,6 +104,7 @@ parsed_sample:
- "Gi9/48"
- "Router"
- "Switch"
- "Stby-Switch"
type: "static"
vlan: "344"
- destination_address: "b4b5.2fef.dd44"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Legend: * - primary entry
age - seconds since last seen
n/a - not available
S - secure entry
R - router's gateway mac address entry
D - Duplicate mac address entry
# - Fabric mac address entry. Clear mac cli doesn't clear this entry

Displaying entries from active supervisor::

vlan mac address type learn age ports
-----+----+---------------+-------+-----+----------+-----------------------------
50 5ca0.1545.f407 dynamic Yes 20 Po50
50 f4ea.6748.92ad dynamic Yes 5 Po50
20 5ca0.15a8.682e dynamic Yes 0 Po80
* 38 b4e9.b0c8.0340 dynamic Yes 0 Po5
R N/A b4e9.b0c8.01c0 static No - Router
* 115 6064.05fa.cadd dynamic Yes 50 Gi3/35
5 a4ff.6d0d.dcf5 dynamic Yes 0 Po10
40 c8f9.f9d7.a87b dynamic Yes 15 Po40
1 0100.0ccc.ccce static No - Gi1/14 Po5 Po10 Po20
Po30 Po40 Po50 Po60
Po70 Po80 Po90
50 5ca0.15a9.103e dynamic Yes 15 Po50



Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
parsed_sample:
- destination_address: "5ca0.1545.f407"
type: "dynamic"
vlan: "50"
destination_port:
- "Po50"
- destination_address: "f4ea.6748.92ad"
type: "dynamic"
vlan: "50"
destination_port:
- "Po50"
- destination_address: "5ca0.15a8.682e"
type: "dynamic"
vlan: "20"
destination_port:
- "Po80"
- destination_address: "b4e9.b0c8.0340"
type: "dynamic"
vlan: "38"
destination_port:
- "Po5"
- destination_address: "b4e9.b0c8.01c0"
type: "static"
vlan: "N/A"
destination_port:
- "Router"
- destination_address: "6064.05fa.cadd"
type: "dynamic"
vlan: "115"
destination_port:
- "Gi3/35"
- destination_address: "a4ff.6d0d.dcf5"
type: "dynamic"
vlan: "5"
destination_port:
- "Po10"
- destination_address: "c8f9.f9d7.a87b"
type: "dynamic"
vlan: "40"
destination_port:
- "Po40"
- destination_address: "0100.0ccc.ccce"
type: "static"
vlan: "1"
destination_port:
- "Gi1/14"
- "Po5"
- "Po10"
- "Po20"
- "Po30"
- "Po40"
- "Po50"
- "Po60"
- "Po70"
- "Po80"
- "Po90"
- destination_address: "5ca0.15a9.103e"
type: "dynamic"
vlan: "50"
destination_port:
- "Po50"
24 changes: 12 additions & 12 deletions tests/cisco_ios/show_module/cisco_ios_show_module1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ parsed_sample:
serial: "SAL11111111"
mac_addr: "aaaa.aaaa.0000 to aaaa.aaaa.ffff"
mod_hw: "2.1"
fw: "12.2(18r)S1"
sw: "15.2(1)SY5"
mod_fw: "12.2(18r)S1"
mod_sw: "15.2(1)SY5"
status: "Ok"
submodule: "Distributed Forwarding Card"
submodule_model: "WS-F6K-DFC4-E"
Expand All @@ -23,8 +23,8 @@ parsed_sample:
serial: "SAL22222222"
mac_addr: "bbbb.bbbb.0000 to bbbb.bbbb.ffff"
mod_hw: "2.5"
fw: "12.2(14r)S5"
sw: "15.2(1)SY5"
mod_fw: "12.2(14r)S5"
mod_sw: "15.2(1)SY5"
status: "Ok"
submodule: "Centralized Forwarding Card"
submodule_model: "WS-F6700-CFC"
Expand All @@ -39,8 +39,8 @@ parsed_sample:
serial: "SAL33333333"
mac_addr: "cccc.cccc.0000 to cccc.cccc.ffff"
mod_hw: "2.5"
fw: "12.2(14r)S5"
sw: "15.2(1)SY5"
mod_fw: "12.2(14r)S5"
mod_sw: "15.2(1)SY5"
status: "Ok"
submodule: "Centralized Forwarding Card"
submodule_model: "WS-F6700-CFC"
Expand All @@ -55,8 +55,8 @@ parsed_sample:
serial: "SAL44444444"
mac_addr: "dddd.dddd.0000 to dddd.dddd.ffff"
mod_hw: "2.3"
fw: "12.2(18r)S1"
sw: "15.2(1)SY5"
mod_fw: "12.2(18r)S1"
mod_sw: "15.2(1)SY5"
status: "Ok"
submodule: "Distributed Forwarding Card"
submodule_model: "WS-F6K-DFC4-E"
Expand All @@ -71,8 +71,8 @@ parsed_sample:
serial: "SAL55555555"
mac_addr: "eeee.eeee.0000 to eeee.eeee.ffff"
mod_hw: "1.5"
fw: "12.2(50r)SYS"
sw: "15.2(1)SY5"
mod_fw: "12.2(50r)SYS"
mod_sw: "15.2(1)SY5"
status: "Ok"
submodule: "Policy Feature Card 4"
submodule_model: "VS-F6K-PFC4"
Expand All @@ -87,8 +87,8 @@ parsed_sample:
serial: "SAL66666666"
mac_addr: "ffff.ffff.0000 to ffff.ffff.ffff"
mod_hw: "1.5"
fw: "12.2(50r)SYS"
sw: "15.2(1)SY5"
mod_fw: "12.2(50r)SYS"
mod_sw: "15.2(1)SY5"
status: "Ok"
submodule: "Policy Feature Card 4"
submodule_model: "VS-F6K-PFC4"
Expand Down
32 changes: 32 additions & 0 deletions tests/cisco_ios/show_module/cisco_ios_show_module2.raw
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Chassis Type : WS-C4510R+E

Power consumed by backplane : 40 Watts

Mod Ports Card Type Model Serial No.
---+-----+--------------------------------------+------------------+-----------
1 48 10/100/1000BaseT UPOE E Series AS-T4748-UPOE+E ABC1234L0X3
2 48 10/100/1000BaseT UPOE E Series AS-T4748-UPOE+E ABC1234L15S
3 48 10/100/1000BaseT UPOE E Series AS-T4748-UPOE+E ABC1234L0WR
4 48 10/100/1000BaseT UPOE E Series AS-T4748-UPOE+E ABC1234L15B
5 4 Sup 7-E 10GE (SFP+), 1000BaseX (SFP) AS-T45-SUP7-E ABC1234L46Z
6 4 Sup 7-E 10GE (SFP+), 1000BaseX (SFP) AS-T45-SUP7-E ABC1234L0MU
8 48 10/100/1000BaseT UPOE E Series AS-T4748-UPOE+E ABC1234L4XM
9 48 10/100/1000BaseT UPOE E Series AS-T4748-UPOE+E ABC1234L17Y
10 12 1000BaseX (SFP) AS-T4612-SFP-E ABC1234021X

M MAC addresses Hw Fw Sw Status
--+--------------------------------+---+------------+----------------+---------
1 ffff.ca83.ffff to ffff.ca83.ffff 1.2 Ok
2 ffff.89a3.ffff to ffff.89a3.ffff 1.2 Ok
3 ffff.ac5c.ffff to ffff.ac5c.ffff 1.2 Ok
4 ffff.ca83.ffff to ffff.ca83.ffff 1.2 Ok
5 ffff.aca5.ffff to ffff.aca5.ffff 2.1 15.0(1r)SG5 03.11.03a.E Ok
6 ffff.aca5.ffff to ffff.aca5.ffff 2.1 15.0(1r)SG5 03.11.03a.E Ok
8 ffff.2894.ffff to ffff.2894.ffff 1.2 Ok
9 ffff.a78f.ffff to ffff.a78f.ffff 1.1 Ok
10 ffff.0671.ffff to ffff.0671.ffff 2.0 Ok

Mod Redundancy role Operating mode Redundancy status
----+-------------------+-------------------+----------------------------------
5 Active Supervisor SSO Active
6 Standby Supervisor SSO Standby hot
Loading

0 comments on commit ec76c69

Please sign in to comment.