From 399597949a749d6ecf90f907a29d720029364f64 Mon Sep 17 00:00:00 2001
From: "rick.mollard" <rick.mollard@nebraska.edu>
Date: Mon, 21 Aug 2023 16:13:15 -0500
Subject: [PATCH] 	new file:   CampusSelector.py 	new file:  
 ConfigChecker.py 	new file:   SwitchCommands.py 	new file:  
 __pycache__/CampusSelector.cpython-310.pyc 	new file:  
 __pycache__/ConfigChecker.cpython-310.pyc 	new file:  
 __pycache__/FindLinkTransitions.cpython-310.pyc 	new file:  
 __pycache__/PortFlipper.cpython-310.pyc 	new file:  
 __pycache__/SwitchCommands.cpython-310.pyc 	modified:   findfails.py 
 new file:   greaterNebraska.txt 	modified:   highTransitions.py 	new
 file:   highTransitions.txt 	new file:   main.py 	modified:  
 unkSwitches-cx.txt 	new file:   unlCitySwitches-cx.txt 	new file:  
 unoSwitches-cx.txt

---
 CampusSelector.py                             |  39 ++++
 ConfigChecker.py                              | 168 ++++++++++++++++
 SwitchCommands.py                             |  32 ++++
 __pycache__/CampusSelector.cpython-310.pyc    | Bin 0 -> 1256 bytes
 __pycache__/ConfigChecker.cpython-310.pyc     | Bin 0 -> 3314 bytes
 .../FindLinkTransitions.cpython-310.pyc       | Bin 0 -> 1822 bytes
 __pycache__/PortFlipper.cpython-310.pyc       | Bin 0 -> 2142 bytes
 __pycache__/SwitchCommands.cpython-310.pyc    | Bin 0 -> 1338 bytes
 findfails.py                                  |   5 +-
 greaterNebraska.txt                           |   2 +
 highTransitions.py                            |   2 +-
 highTransitions.txt                           |  15 ++
 main.py                                       |  39 ++++
 unkSwitches-cx.txt                            |  65 ++++++-
 unlCitySwitches-cx.txt                        |  50 +++++
 unoSwitches-cx.txt                            | 180 ++++++++++++++++++
 16 files changed, 594 insertions(+), 3 deletions(-)
 create mode 100644 CampusSelector.py
 create mode 100644 ConfigChecker.py
 create mode 100644 SwitchCommands.py
 create mode 100644 __pycache__/CampusSelector.cpython-310.pyc
 create mode 100644 __pycache__/ConfigChecker.cpython-310.pyc
 create mode 100644 __pycache__/FindLinkTransitions.cpython-310.pyc
 create mode 100644 __pycache__/PortFlipper.cpython-310.pyc
 create mode 100644 __pycache__/SwitchCommands.cpython-310.pyc
 create mode 100644 greaterNebraska.txt
 create mode 100644 highTransitions.txt
 create mode 100644 main.py
 create mode 100644 unlCitySwitches-cx.txt
 create mode 100644 unoSwitches-cx.txt

diff --git a/CampusSelector.py b/CampusSelector.py
new file mode 100644
index 0000000..2f6afa2
--- /dev/null
+++ b/CampusSelector.py
@@ -0,0 +1,39 @@
+def Campus_Selector():
+    print("Please select the switch scope: ")
+    print(" 1: City Campus \n 2: East Campus \n 3: Omaha \n 4: Kearney \n 5: Custom File \n 6: Single Switch")
+    ip = "0.0.0.0"
+    campus = ""
+    campus_selection = input()
+    if campus_selection == "1":
+        campus = "unlCitySwitches-cx.txt"
+    if campus_selection == "2":
+        campus = "unlEastSwitches-cx.txt"
+    if campus_selection == "3":
+        campus = "unoSwitches-cx.txt"
+    if campus_selection == "4":
+        campus = "unkSwitches-cx.txt"
+    if campus_selection == "5":
+        print("Type the name of your file:")
+        campus = input()
+    if campus_selection == "6":
+        print("Enter Switch IP Address:")
+        ip = input()
+    return campus, ip, campus_selection
+
+
+def Role_Selector():
+    print("What role would you like to reboot:")
+    print(" 1: CCTV \n 2: Doors \n 3: Printers \n 4: Failed Ports \n 5: Custom")
+    role = input()
+    if role == "1":
+        role = "wired_cctv_dur-3107-8"
+    if role == "2":
+        role = "wired_door_tunneled-3112-4"
+    if role == "3":
+        role = "wired_l2_print_dur-3134-6"
+    if role == "4":
+        role = "Fail"
+    if role == "5":
+        print("Please type your role:")
+        role = input()
+    return role
diff --git a/ConfigChecker.py b/ConfigChecker.py
new file mode 100644
index 0000000..cb2d865
--- /dev/null
+++ b/ConfigChecker.py
@@ -0,0 +1,168 @@
+from urllib3 import exceptions  # Prevent SSL Self-Signed Certificate Error
+import requests  # Creation Of New Object
+import urllib3
+from netmiko import (ConnectHandler,NetmikoTimeoutException)  # SSH Connection
+import socket  # DNS Lookup
+import time  # For Waiting
+import CampusSelector
+import SwitchCommands
+
+
+def main(ArubaUsername, ArubaPassword):
+    # Preparatory Work for SSH Connection
+    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)  # Disable Certificate Warning
+    interfaces = {}  # Initialize the interface variable
+    current_interface = ""  # Initialize Current Interface to make sure it isn't null
+    port_configuration = ['vlan access 1', 'enable', 'enable']
+    exception = ['trunk allowed 2000', 'trunk allowed 1999']
+    int_changes = []
+
+    # Get the Campus or Switch IP Address
+    campus = CampusSelector.Campus_Selector()
+    ip = campus[1]
+    campus_selection = campus[2]
+    campus_file = campus[0]
+
+    # Single Switch Only
+    if campus_selection == "6":
+        hostname = socket.getfqdn(ip)
+        print('Current Switch:', hostname, ":", ip)
+        missing = []
+
+        # Create Session Object
+        #session = requests.session()
+
+        # Create SSH Connection
+
+        ssh = ConnectHandler(
+            device_type="aruba_procurve",
+            host=ip,
+            username=ArubaUsername,
+            password=ArubaPassword,
+        )
+
+        # Find The Ports With Deviations
+        try:
+            cli = ssh.send_command(f"show run int")
+            parse = cli.split("\n")
+            for line in parse:
+                for x in exception:
+                    if x in line:
+                        print("An Exception has been found, skipping port:", current_interface,
+                              "Either exception VLAN or trunk port")
+                        missing.clear()
+                        continue
+                if line.split()[0].strip() == "interface":
+                    if len(missing) > 0:
+                        print("The following Config Was Missing From Interface:", current_interface, missing)
+                        print(
+                            "Would you like to reset this interface back to normal configuration? \n 1) Yes "
+                            "\n 2) No")
+                        missing.clear()
+                        reset = input()
+                        if reset == "1":  # Reset the Interface
+                            print('Resetting Port to Default: ', current_interface)
+                            SwitchCommands.defaultport(ssh, current_interface)  # Reset Port
+                            int_changes.append(current_interface)
+                        if reset == "2":  # Skip Resetting the Interface
+                            print("Skipping Interface Reset")
+
+                    # Set some Variables
+                    current_interface = line.split()[1].strip()
+                    port = current_interface.split("/")[-1]
+
+                    # Global Ignore Conditions
+                    if port == '49' or port == '50' or port == '51' or port == '52':  # Ignore SFP Ports
+                        continue
+                    if port == 'vlan1' or port == "vlan1999" or "lag" in port:  # Ignore Local Interfaces
+                        print("Local Interface, Skipping.", current_interface)
+                        continue
+                    for m in missing:
+                        interfaces[current_interface].append(m)
+                    for x in port_configuration:
+                        missing.append(x)
+                else:
+                    for command in missing:
+                        if line.strip() == command.strip():
+                            missing.pop(missing.index(command.strip()))
+
+        finally:
+            print("Logging Out From Switch", hostname, ip)
+            ssh.disconnect()
+            time.sleep(1)
+
+    # Read from File
+    if campus_selection != "6":
+        with open(campus_file) as file:
+            while line := file.readline().rstrip():
+                ip = line
+                hostname = socket.getfqdn(ip)
+                print('Current Switch:', hostname, ":", ip)
+
+                missing = []
+                # Create Session Object
+                session = requests.session()
+
+                # Create SSH Connection
+                try:
+                    ssh = ConnectHandler(
+                        device_type="aruba_procurve",
+                        host=ip,
+                        username=ArubaUsername,
+                        password=ArubaPassword,
+                    )
+
+                    # Find The Ports With Deviations
+                    try:
+                        cli = ssh.send_command(f"show run int")
+                        parse = cli.split("\n")
+                        for line in parse:
+                            for x in exception:
+                                if x in line or "trunk allowed" in line:
+                                    print("An Exception has been found, skipping port:", current_interface, "Either exception VLAN or trunk port")
+                                    missing.clear()
+                                    continue
+                            if line.split()[0].strip() == "interface":
+                                if len(missing) > 0:
+                                    print("The following Config Was Missing From Interface:", current_interface, missing)
+                                    print(
+                                        "Would you like to reset this interface back to normal configuration? \n 1) Yes "
+                                        "\n 2) No")
+                                    missing.clear()
+                                    reset = input()
+                                    if reset == "1":  # Reset the Interface
+                                        print('Resetting Port to Default: ', current_interface)
+                                        SwitchCommands.defaultport(ssh, current_interface)  # Reset Port
+                                        int_changes.append(current_interface)
+                                    if reset == "2":  # Skip Resetting the Interface
+                                        print("Skipping Interface Reset")
+
+                                # Set some Variables
+                                current_interface = line.split()[1].strip()
+                                port = current_interface.split("/")[-1]
+
+                                # Global Ignore Conditions
+                                if port == '49' or port == '50' or port == '51' or port == '52':  # Ignore SFP Ports
+                                    continue
+                                if port == 'vlan1' or port == "vlan1999" or "lag" in port:  # Ignore Local Interfaces
+                                    print("Local Interface, Skipping.", current_interface)
+                                    continue
+                                for m in missing:
+                                    interfaces[current_interface].append(m)
+                                for x in port_configuration:
+                                    missing.append(x)
+                            else:
+                                for command in missing:
+                                    if line.strip() == command.strip():
+                                        missing.pop(missing.index(command.strip()))
+
+                    finally:
+                        print("Interfaces that changed:", int_changes)  # Print Interface Change Summary
+                        int_changes.clear()  # Clear the List For Next Switch
+                        print("Logging Out From Switch", hostname, ip)
+                        ssh.disconnect()
+                        time.sleep(1)
+                except (NetmikoTimeoutException) as error:
+                    print("Switch is not responding----->  " + ip)
+                    print("Switch is not responding----->  " + ip)
+                    print("Switch is not responding----->  " + ip)
diff --git a/SwitchCommands.py b/SwitchCommands.py
new file mode 100644
index 0000000..5fd4231
--- /dev/null
+++ b/SwitchCommands.py
@@ -0,0 +1,32 @@
+import netmiko
+import ConfigChecker
+import time
+
+
+# File to hold switch commands
+
+def defaultport(ssh, current_interface):
+    interface_configuration = [f'interface {current_interface}', 'shutdown'
+                               'no routing',
+                               'vlan access 1', 'spanning-tree bpdu-guard',
+                               'spanning-tree port-type admin-edge',
+                               'aaa authentication port-access auth-precedence mac-auth dot1x',
+                               'aaa authentication port-access auth-priority dot1x mac-auth',
+                               'aaa authentication port-access client-limit 15',
+                               'aaa authentication port-access dot1x authenticator max-eapol-requests 1',
+                               'aaa authentication port-access dot1x authenticator max-retries 3',
+                               'aaa authentication port-access dot1x authenticator enable',
+                               'aaa authentication port-access mac-auth enable',
+                               'loop-protect', 'no shutdown']
+    ssh.send_config_set(interface_configuration)  # Send the Command To Reset The Interface
+    print("Interface:", current_interface, "has been reset.")
+
+
+def shutport(ssh, current_interface):
+    interface_configuration = [f'interface {current_interface}', 'shut']
+    ssh.send_config_set(interface_configuration)  # Send a Shutdown Command
+
+
+def noshutport(ssh, current_interface):
+    interface_configuration = [f'interface {current_interface}', 'no shut']
+    ssh.send_config_set(interface_configuration)  # Send a No Shutdown Command
diff --git a/__pycache__/CampusSelector.cpython-310.pyc b/__pycache__/CampusSelector.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e52340b7c7ac5042170d0be72db8257947aef46a
GIT binary patch
literal 1256
zcmd1j<>g{vU|_i4yeCPPm4V?gh=Yuo7#J8F7#J9eMHm<uQW#PgTNt7kQkYVhTNt7k
zQ&@r-G+C38)iX0NFo3W#NKXp`149Wz3S%=PBZy`K(J9Qe3@I$Nj3tcC47E%(Oew6{
zOhuw8Y_*IvOeyTyOhwWu9AGwQHdB#e3Ky8ooy}CFp27oW^JX&@8I>@k@PSMNn*!3w
zpUqTcTf&ec02gJbVXR@OVM=2TX3!M$t5OKaNlh$HRVYr)Nlh+MD9K1wC@#+|NzPCx
zPR=h#wNj{xQ82VpaLz2LRB%qrEhsHk;8HNMQgBTyE<p$wTPgVGCT1ima4DErDR`$Q
z7UiW@DsU;7S}8b}7MJAbD!66lq$+SJm{}<VXXd5nq$&i1ZK+~6&;!F;47V5!tHet4
zazIu=BvXrZlPmN}DoSoK8iA!imSRX5R|%Eo<zon&fP}L#giWiYLn;eW!5+;^%uQ9u
zPgAJOFD+6?%gjl&y2WT#CE=P^l3E0HpMqzAf@4ZbQEG9q)k>yYtOZ4xc_p`4GxG{c
zOEj5pF=ZCqVoL@G%Pj#29S;e~%>2BS3`Kkl3=F>_oULL)i&Kk=V{-FzauSPDieg;y
z%ky&b6H|&~0xC-~^79mQ72I+%3lswKi%Jyo^K|pm(qf8obqm0f#mPmP1trBXkl+sn
zM^t{1UP0w8euz*!OpFnfx-=LV7&sU?7+Dxu7}>xyh>gG;U{Mgs#aJZ3z`%f#P(en3
z5;r)ZCSXaZ;H1S+!;r$9%~T|q!cq%jgA%KF3LBUWO02Re9AGvmu_~u<f!UzMs#n60
z!h@6)8G;!!dHt%C!!r^~6pHe5QWeVcOLI~{F`|%@nVqUolCMydnv|bkVpU}iPKVAR
zVUPsqlAm7$N{hx;3IU)<Nd@yvtQ6c5Gjmc?z(EO;hbO@zkhiKt%QK5oQ{t18OUmL?
zN{e)j4Gqk7Es8*Svq}mgmy(}f6kk%BmzSE8nxboLXlSHsQpCc*z)&R#QIKO44^9VA
z1B^{{&5BqV7#N~hKz0|gfs~3t^Hm8bv4Im9$a_{r91IK$nv78_ARah*KnQ*Y28LU_
zLHRkU@W_+^MW!4yGI2#D3uBQW0|SGfCKEU+!5oN*pri+3fz9Ty$<0qG%}KQbMQ}05
JHyjK+;sC*pLEr!Y

literal 0
HcmV?d00001

diff --git a/__pycache__/ConfigChecker.cpython-310.pyc b/__pycache__/ConfigChecker.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1240ce09b6eef00aad0cf6f4e855fe67c2bb4069
GIT binary patch
literal 3314
zcmd1j<>g{vU|=}Lw=YRefq~&Mh=Yuo7#J8F7#J9eBN!MMQW#Pga~N_NqZk=MY^EHh
zD5eyK6s8=8C=j1HhdGxeiY1pdiWMr)7R3gZXOChB(;QJ8V45?EGleCEwS^&yD}^bT
zL6hwz$WBehTU@CX$*Bb;nfZCeews|T_?+|e@=}vaJQDL#a#D+KiTkCN<Ys2)hh*la
z=9iYZ!W1WioCz`lge4gm7`Pc27@R@QPGDtVC}CK@Si+FSl*PP|k&z*jp_VCyv6eZV
zA%$rXV=YSxa|%m3Q!Q&cLoHhg%L3Mg47Kbv>?y3047D6J>?v%L47Hp!>?!P$47FS}
zoGBdHOcNN3luFnZu-9-bWUS>b;Yi`E;ZEVI;b>-IWJqVI<tgDz;jZDRVW?qD;pt_m
z<*m9{!@Gbhg?AxiEnf}a0`3&Pg^acQHT*6Nv72iJYFJ$uVg+jjYXoZq${320N;p#Z
zYnW36nwc3HYIqj#EM#D0C=4tNtPxniy^sOqjs?668BzqZnTlSP@YV1%Gp4X-vlJ~T
z;YbmxVXol;=_}z#5pHHg=r7@KW~dda5lRusW-6Ld!jU3c!`#fo$WS7%K(L0lhIt_q
zBSQ__0-+jk2-OIsh-EW@O%w;40<oD@k^y9MEprX?0`3%vg^VeZk_@%NHNq)U*-XXz
zYlKszp|lK?md$1=I#B3aBb*|a%~X7*MmR+tM5id!2$wMwT`J*7QG~do(6@%ig&~%+
zR-}fhhFOwffl!SID6R^x)UdcP#In~4*6=J4su2W>J%FkfsTHje0J*3}6hvk-75%T_
zSs+})vp@tQvXBw1{&k^mI710Xic$@C4F@Q6YIqljf<m=KY=L+RD@aYA0Dk#$25`(X
zPhcuqS0Yiv)yz17vA?`ltVV2s<U)o8QVSVa7-|J3Fcr<N5vb+Bn>M5u$Sh>26`#OZ
zC5e$vzT!+L=b-6C5|&OTFcuf4D1%bW1jeFTY-wf!V__-?W2T!4OhuxIlrw>`=m4>4
zX98o<cH&YG)KsF=&jiNe$B+~RWyyf@8CXmf#436^fw3?Vl9DDc7Jq@HB@hdenkFz7
z{YIoGuv$=x;zCbR6BrBsg3}ZSa+;dJRLBL_BZi)?CNLH0U`tsOm<q)~y1=PRrG^cZ
zqiWb7ITn9<%9AYNNFhl_IYT%@o+=ANiR=WX%1%axS_wvmDv1(~6xA9IaRyK>#l;S1
zh-64%sFkRb$YX`j<&5PFXepPm*eskOg@J{Eg#na9QW%06(D{Z86PSvZmoqXlfM6s8
zsE7|{0IAee^Si~M$y~)-mXnyLkeHmDT3oDPc#ADHFEJ@6wTO*@fuTyMq^LA6TOlzg
zC%-&3MZw6xzyMv$(9+WKB_jg^!%I+UUIb#@Vl=DbcP=d|O3f=#2rkboNzSnP#b_19
zmsnJqlo(%7l%HH$RF<mA62+a8T9%od8edXbkQ&93kzZUA#Zg+ET9lWVn;OMYkXT$?
zo?nzw#Z#P-U#?J8nx~MNS8|Jyt4iB3PXS(yC}boSD<q|+<|(A*m*%DDC=_RB78GRW
zr7INV7nN95DZ6HtWTX};z$+<*Fds)hh5RA~i0?qEqBt}2N>Yo`5|dM_3_>ze71HuS
zeg+xhoS&DLnXV9?SghciSzHVfax2QuRq%vqu&N3T&o9kMQK-x>RmjQAPE{z$S13v?
zPAyR=$;d1Qxfx=zLQ-OKHb^orzbH2`M<E$(a%oW_sOGd+;8HNuRESJ1R^U=F(p2!v
zzr|=+B^?AZrvzkaKz>mPNV7|7T4HHViIu`FMx!c;V3=Rw&QSns`NgRJ^8f$;|D%{p
zETfoA4WgJ#4WpP$jiOjV(QO#T0j4Z1Eu)xo64R@seDaeMa}a*gQGgk&S0(O~pPmkK
zfq!X<0@&-2IIZG^gda3@R7t>{P^?grkyxUToROH9o|<A+1x*ABnZ*iu`6ZyRDag-D
z$;?aF1pzw+1x>kI?4?CHIhjeuQ35HM#h?@zU!GW$mzkGdTm(v3QDUBX#i_}qMX5ol
zg{7&*CE*a+TYS!mxdo-g!Kpc^$tC$kQTz~oJWSvgTXBAJc4|o!dwOa~T474wE!Kjf
z%)F8!W(Ed^D4ycfyp;Il{M_8cyp&t4#RWN;CAV0Ub5awFZm|}Z6lE6NV$Mm;yTzKB
zS5R7Vix1*+XNdY@Q2GT&1}F*LVoNM2NX<*R#axhI0Md|>S`o#Sl3AP#X${?CDap)D
zy~SFblbTv^izUAxHSZQjQEFmJPG(-}Ew&<vZ5%}q?-k!-FHS8k&dkp%Vqsul(3HHz
z>j=s{q0rm`<pw~rNE8=5{T4?FCPVUGJX|bF2;{<elmr*W3C|Ew+?jbL@sQ{$j$%s&
zhiDX2W<itygdJZD4&KcCyeMv{NLpr2Y7_@3%Yrj2doCnzL@^f^XGAe4=VV5)79<uG
zr`}=#`;W2W7ArVUM6rOJa*HuHiX9g0EFiOrlo=QpZn35o73CMLWGK>MU|{$a?raqU
z@^EoXZhlTqVo^#_j7xrbUQT{uN^wj;Wl2VUo`SA|TTW(y0yuZ%=jrCBrNtEG>K1?{
zi<65o3rdP(AX(TsBQ-fYwMeg^@)k>OVrCwwwOOpe$iTqI#KOqJ$ic_~BAG!n2O}3V
z7b71d3nLRd6C(t&{bAzZV&np=<6vZCWMX9b&%wmR$n-~qm4}fBtcvA72QwQZ2O}3F
z4^*W9GasV@GZUi(BNrnRBL|}ZBL_(Be-35=MiEA)2Bv>Zw|TTcVm$vqBo{LeqYxtt
zBiME(4ki|6i0vQ}*##nuJYe^-{1s#21DObM4>KDh$c-S|K`sT^uEEU0D96YJ@*ATN
zBL~P=|2de27)2Oa8d&}@-Qm&%*$cv4e?TP2jRK4yA4xEBG%)=Y*~9mriBaW0%l{%h
zP)g)35@29p0B6b~B~Tt>&x17Y!8r<?T8o50Dr7-~Acz39?ZKMC(TYUqg5sRRCO1E&
aG$+*#RCg4EwDK^3A^{XsAew`bhZz7z?vLpJ

literal 0
HcmV?d00001

diff --git a/__pycache__/FindLinkTransitions.cpython-310.pyc b/__pycache__/FindLinkTransitions.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ce4d417ab65ab047d4157e00a93ea8478adaeb1a
GIT binary patch
literal 1822
zcmd1j<>g{vU|?|aKc4iKgMr~Oh=Yuo7#J8F7#J9eBN!MMQW#Pga~N_NqZk=MY^EHh
zD5eyK6s8=8C<vc9iaCWLg*k^Mmo<ttmo177s*XL19juNciUUk@MscRFq_DOyL~*4s
z1v6-}y#(2*$#{z^wIVsSpd>Rtuh>tM=@y@JeqLT`a*0P`UP?}C(JgVm)RNrH?EH|-
z+|>Ni5?7ewWRNpKMu4z50|NudQ_dh~Phn(WC}CK@Si+FSl*PP|k&z*jp_VCyv6eZV
zA%$rXV=YSxa|%m3Q!Q&cLoHhg%L3Mg47Kbv>?y3047D6J>?v%L47Hp!>?!P$47FS-
z9JSmjthGETthKx~oGF~y%ta?k*lM_%8T)l=`D*wUurFj-z_E~lg`t+eD58eHmZOAo
z0ap#jLdIHw67CeP8i5q<8jfZbMuv2TTEP;Y1-uIxYK2hs72AX}q%g2BurM?;Gcx3H
z7%~(ml`}FjfM6s8BSTd{3113N4Mz<_4Py##FH5a(33my9Gb1BIjZl_A3SSM!Y=#v6
zxy&W}C4y;8DFP{iz09>DH9`x7pmIVrJhK^6gll+bGo*;jWnaixD_X)`A`CHM0n7x^
zxy%b0YsE^qQ^ab-vP5Px%w+<p2xlnaP7$vWsNn#)u10u)=t2fYh7z#_;wh}4&`n_o
zCZM960i;G#!tWM?CUX^USx#b}LSk}qYH_iG;Vrh*yu_rO)FL(p28Jr3lA_YQY=y*}
zoc!|C6a^y#0|Rt1LrY7`my8Sy3@<?`pa{ge#R5`zi_xr#-?_A?C^fG{A-FuVBss(C
z7o*iJzQm%^q{R4wqWt92qOw#?mRsB@sb!hTsqrP11*x}KGV+T{ZgG?rrxxWU=BD1_
zC`c?WF3&GYsp7~eDJdwn($}xz(=SRbF3~SD)X&LJ&&+evWV*$Yl30>>i>)lRC^N0H
zN*<=bK+nKLzqqovBsEt*Gp{7IC@nELwOGH3UDe3VP}Rt-%Gf@!q@*Y_sk9`u*fu9K
zFFU>{wK%n;SS=;Bpd`cANUb<ECpEbwzsR<@B(Ws3xFj>VxQZWUJjnk1(vm6(pZxUv
z(h>#d{FGFMw4(f6n1`#xee%=OGxO3F{7Xv|+z>LF61Uh(i*j-@lZ<Z(q+}L@!aTk_
zu_!MyFTJ=36qL8bJoAcElS_+IgHj7iQ;SQ&A+oploD*{kN{fS`4!gw<;m5-TSn>-}
z^KNkzr6#82Wag#bVk;^xDatIk#a5i3oSj;7i#<KHB&{$d?-px8QD$BVNF~^U;#=&+
zsl~;a`FTam3=9lK{0s~Xw^$1Di%W_GKuqTJ)RHKU^wg60oc#3STil=!DJ_mq&QD3b
z#g&p-oD3-{Zn2bP=BD0aEzU_zEzlId#p?))@K9KULbw6YSiQxCh?ZM|$&lm{4;Q;7
zRFGd(5}%x(mzJ4cT9gPXmu_*wi>O=NnRzAg$r*`x>8ZuH*pk5kbBign;FbV{9S@1V
z%>2At+)$CU%$(FH?vkR!yy8rdam7(=kklE)1)&4-i%M>>fRx>00f!$4C`p17BYSRU
zadBo|dXYRhJc^4mZn1)sU=%1!LBVp1EeD(wRx%V>FfcIuigmV%0eQVRCO1DPC$T7{
zD8?nfJTE6dF{L;rpt2+*KTknd!7V4VKmla0LVliZep*^gQLb(QSh6^|D6^oXIL0kA
zFU2P_FFOR`ZoPuaTP(SWnR(oxVir_8@G-G4vM_Qma)3x?5Dj91#hADl1sGWvxfuBv
zS(rGO1b#9#$oyyGW@3avwm%$fGE8!e9E?JYLX14j9E^O7JpVWtc^Fw96<IMbFlcfY
z34>AvC~X$Wf&9-@lzNLj4^kgMQVa`7fi#Fv0TE&#0;Crl7D$98NIQp3ZhlH>PO2TK
W%qSLOU|`^3fVf!z><11;9%cZ@<`#MY

literal 0
HcmV?d00001

diff --git a/__pycache__/PortFlipper.cpython-310.pyc b/__pycache__/PortFlipper.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..af9bb1f73413539ce4009f8994e9432278edd557
GIT binary patch
literal 2142
zcmd1j<>g{vU|>iT+?V7a%)sy%#6iYP3=9ko3=9m#5ey6rDGVu$ISjdsQH+crHd78$
z6jKUA3R4b46o}89!<@?!#gfY!#R`>Yi(&)Ivq!OmX^tokFwGgonZlC7+QJaUmBJLv
zpvm?UWTz(MEw0px<kW(a%>2A!KTW1ve9rlKd8x@I9*KD=IjKdr#QjoBax=5@Lo#zy
z^Gi!yVTzMM&IB0&!u$*j4BQM149*~D3o$b=lrSt{EMdrE%3@x~$jDH_vVe6VLoHJc
zQwpObLoIU+QwozLLoG`UQwp;rLoHJY%L2BA47IE^EGaD6OhwB}*cWirFfU}RWh>!K
zVXa|HVXI+oW?^I~;ab4GkfD~ngeQf)hPj5JhB1Ysm!+1YD!zte0dETDLdIIo8qNiL
zDO?K~Yq@H;To_^<Yq@K<7w|7+sO7F<t>G?XC~B?YUci^ay^s-XH%|>u3QsmuQ5swn
z<U*bj&J^Ano@ORShC&y(49KlKB?1csYdC6n7BVq1lyIi-)$pY7H#0Lbln5*kLK7DN
zi5I$rgVYJufc(JB$WX(vKzJboBSVSE0?`ykQ0U|dlyIitkuPTehYRxr#-jETu^Ogk
z#{M(4yfwTF#1}FwkXXpT!cfaSfw8EhhP#%TP{>skVT4@_&aiVv54#DBMXIQw0SUbc
zj74m4arE$e1eYN%{2pNszdUYip;pci&XA|d!cZbPfw3}~k)f84k)cYWgfm5`hFP4U
z8I%@ru)`T58B!Q(`Re%cSRr&dV>ttAC>QSvXGmdSVPIhZ#cT>gFatW@kYNI2aYH#H
zBLfIVGJrB=Fat=Xrm){jMg|6km!N!81Y+G{G^^rwE-flb%_~s|F3&7U&anE$XmyJ(
zv8XgDF}|QEKe@E1ELD@`7I#W&S!Qx-d`V?N>MfRx{Nj>Z9HqsnMR|$2skb-^5{rw=
z^NUidB#JZg%M}Xpi%N78lao`6ixrY{GE?(Pif=J;{bE$O#h6kh<(HqQ8&aB=mztBB
zqTm8HR!1Q?JF~#5N-#JzFC{ZCUBNj&H#ada#Y&+{nM)xczo<kZIHR;ACBHmRL02I>
zF|!1u$VeeLH90>orMOCqOTjHCv!Ea~1xeZvDy`s_U!>rdT2TTvs7l-?KRq3!-M_R%
z!L2Ai7wYjUD6NoLtdN&qqEM7tT#yfTjV=h-DJW=4-C{2-%E`%0GQK5{l3ARXl#?1?
zo>-KZnU`K%#KgeBa7)ZHuQ)Ziv?w(wwXig`xFj4RdyCIGF}I+!I5;&YHMu0e=oUYO
z9}gGc4a(0+MR3`Q^OLhvOK!2Jr<SA@rsUmXEhx&&E4jr{1TnYx7JG4OadBpTUJ*0M
zUY_FAyp;H4NT}UnEiTB(EV;#&Q(RJ%S#XOF60^`SExyH3oKac=ilbXxdHD!-N@j5~
zq~N{9Qj(dQdW*F<CpER;7E69XY97eu#FU)OywqE4MPOr#SQr=>H2H7wI)c(lC@d{N
zxB<`vaf>Y(?D1PnnFY55Anf>Ja42Nv=iOo{%Fju?#Q{oApoCN;4e|?fadE~i=H#5r
zTdW0%Ma8MNSishDX6BWo7NsR7r`}>o%gjl=#hO}FlwY)xp~#GZf#FxEvsDbp5ydgN
z`8hd>MJYuwF8SqoIr)hx#W4YuB^mjkqytJN;AEhXpQoFjmKIZ#t6Kn;EKV-UEGQ|C
z0VOt&s)E!ay@JYHEV+r9d7yfwcohQ!10N#?GY2CWGIKC-F@pF^%uI|B$o7Ycor{qR
zA`g;d<YVMv<YVH2LZ$|$4?IE~j694y|3D-c6BnZpBMT$g943T0OpI)QnAl(@fn-4#
z!z5uYMxOtCi~=C@7$q1v8kqhH-Q@ev#HjM0<$sX{D0aAu1Q{3@z)7=63KX{Nd8y#4
z6r5_nF<2xHQlShYL_mZ*hyZB@2P+a`4${wIlbfGXnv-e=Dm{vY7#J9M7(l@x0QEEn
HBM&nGK{7!I

literal 0
HcmV?d00001

diff --git a/__pycache__/SwitchCommands.cpython-310.pyc b/__pycache__/SwitchCommands.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ba2ac58f9170a3306e2f741939cb8b63eea82856
GIT binary patch
literal 1338
zcmd1j<>g{vU|_i4yeFxHje+4Yh=Yuo7#J8F7#J9eO&Ay$QW#Pga~Pr^G-DJan9mf&
zl){w4+`<sWoWhdA+QJaUlERk4-og;Yn!*^&pvmzPWS(C#$RrR8gqax_82A_%7@R>S
zgN#pMtYMtZFc)kR$P|zXDI6)BDO@SsDLg5>DSYXCwM;b(3m9sc7BVt2lrX07*D$6C
zG&3_Yq%Z_CXbSrM;>ye`Ni9lCOiop(5-QFpElJ5Q&&$hKD9SG_$;?Zy;w{Tb%u`5A
zPEIW@RxqrRC@x6M%gfA5*DWbZO;t!LNGa7#FHI~;sZv6fDabD>(JiSgNL5Ho$<55u
zO-)Hpt+Gu_OjJlLEy+mDE6GewEXmBzQvfT3nh%oFEhtJ&PEAS8OHNhDO-$AWi7BMy
zml#%5Srex{GruUaq!OYBZbX$H0nN!dnW=dtx;dG-nI#H_rd93))PtRb?3w%`h1|pn
z-PFW_{2bk))WXu#;u27hIgn{kQEEw1W@@p5ag`+*CZy&iCgr3O^ff$$q3U^Z^79LH
z3yShfQj<%nxbyNAU}>U?%M+GTtg84k5{ng*Qd9F3ic*VHOY}6EZt)kV=B30Z=jWwm
zrpFhjmfT`3D9X$$S;>5hxwtsvmSA#eQBi7MNjyBgMTx_iP;I3};3Tn<p@@Tlf#Fw#
zvsFxJacWU<Om2QoPGV6?QH)D|d0tL_VoGsLKxIirex8D^f?G~zfkHrjQHer+o^F0x
zT1-){ZUI=bIJqdZprkk^xID8YIm0<WH#adarC6_^@)mbWYFc7xP6;UOfvhT)VPIh3
zVq{@rVnl^3j4WTdcmx=WK=~abGlDWCC^LQrX-8znbSC6X2hM2Benp_19K`|(&6SKr
zAe}|53=9yTg1uYB$-uyHivy$p<Sa=B28Pcppd8Q0$5_P6z`%gh`XX)y1_n*26;<re
zI4j}-8IR2luDpDhEpi|=pfaV1A7lpGE%v<BlHAPf{9C-v;FxsINKMX8ExN^0l9`(d
t4h67Vz{(-c28ADl1@VAQZhlH>PO2RvsFVV^frEjAk%N(gl|zt+6#xTTe{BE&

literal 0
HcmV?d00001

diff --git a/findfails.py b/findfails.py
index d5f3270..02b291e 100644
--- a/findfails.py
+++ b/findfails.py
@@ -14,7 +14,7 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
 #  
 
 ###########################################################################
-print(" 1 = UNL-City \n 2 = UNL-East \n 3 = UNO \n 4 = UNK \n Select Campus:")
+print(" 1 = UNL-City \n 2 = UNL-East \n 3 = UNO \n 4 = UNK \n 5 = Greater NE \n Select Campus:")
 campus = input()
 print(f"Campus Selected: {campus}")
 print("----------------------------------")
@@ -29,6 +29,8 @@ if campus == "3":
     file = [line.strip() for line in open("unoSwitches-cx.txt", 'r')]
 if campus == "4":
     file = [line.strip() for line in open("unkSwitches-cx.txt", 'r')]
+if campus == "5":
+    file = [line.strip() for line in open("greaterNebraska.txt", 'r')]
     #print(file[])
     #file.close()
 
@@ -65,6 +67,7 @@ for selectIP in file:
             if policyrole in to:
                 print(to)
                 to3 = to.split(" ")[0]
+                output3 = net_connect.send_command(f"aruba-central support-mode")
                 output2 = net_connect.send_command(f"port-access reauthenticate interface {to3}")
                 print(f"{to3} Reauthentication initiated.")
 
diff --git a/greaterNebraska.txt b/greaterNebraska.txt
new file mode 100644
index 0000000..4951d1b
--- /dev/null
+++ b/greaterNebraska.txt
@@ -0,0 +1,2 @@
+10.162.139.1
+10.162.139.2
\ No newline at end of file
diff --git a/highTransitions.py b/highTransitions.py
index 480017a..a237b5d 100644
--- a/highTransitions.py
+++ b/highTransitions.py
@@ -47,7 +47,7 @@ for selectIP in file:
         try:
             # Login to API and set initial Variables
             login = session.post(f"https://{self}/rest/v1/login", data=creds, verify=False)
-            transitions = 10000
+            transitions = 5000
             vsfMember = 1
             Switch = 1
             SwitchPort = 1
diff --git a/highTransitions.txt b/highTransitions.txt
new file mode 100644
index 0000000..ca4a80a
--- /dev/null
+++ b/highTransitions.txt
@@ -0,0 +1,15 @@
+Login  from: kmsab00m1s1a01.nebraska.edu 10.171.0.10
+Port: 2/1/41 6845
+Logout from: kmsab00m1s1a01.nebraska.edu 10.171.0.10
+Login  from: kcpst0310s1a01.nebraska.edu 10.171.0.12
+Logout from: kcpst0310s1a01.nebraska.edu 10.171.0.12
+Login  from: k0fac0002s1a01.nebraska.edu 10.171.0.15
+Logout from: k0fac0002s1a01.nebraska.edu 10.171.0.15
+Login  from: k0gsb0002s1a01.nebraska.edu 10.171.0.16
+Logout from: k0gsb0002s1a01.nebraska.edu 10.171.0.16
+Login  from: klibr0028s1a01.nebraska.edu 10.171.0.19
+Logout from: klibr0028s1a01.nebraska.edu 10.171.0.19
+Login  from: kthmh0001s1a01.nebraska.edu 10.171.0.20
+Port: 1/1/48 7251
+Port: 2/1/3 7283
+Logout from: kthmh0001s1a01.nebraska.edu 10.171.0.20
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..ab3ff23
--- /dev/null
+++ b/main.py
@@ -0,0 +1,39 @@
+# Primary Network Script For University of Nebraska
+import ConfigChecker
+import PortFlipper  # PortFlipper Script
+import FindLinkTransitions
+import getpass  # Password Handler
+
+# Get User Information
+print("Please enter your NUID:")
+ArubaUsername = input()
+print("Please enter your password:")
+ArubaPassword = getpass.getpass()
+
+# Get Choice
+print("Please Select From the Following Choices: \n 1: Port Flipper \n 2: Configuration Checker 48 Port "
+      "\n 3: Configuration Checker 24 Port \n 4: Link Transitions")
+selection = input()
+
+# Call The Port Flipper Script
+if selection == '1':
+    PortFlipper.main(ArubaUsername, ArubaPassword)
+# Call the VLAN Flipper Script
+if selection == '2':
+    ConfigChecker.main(ArubaUsername, ArubaPassword)
+# Call The MAC Address Flipper
+if selection == '3':
+    print("Not Implemented Yet, on ToDo List")
+    # Idea behind this is if a specific device on the network needs re-authenticated, it will find the device and flip
+    # the port.
+if selection == '4':
+    print("Find Excecive Link Transitions")
+    FindLinkTransitions.main(ArubaUsername, ArubaPassword)
+
+
+# Sample code for personal reference
+# def print_hi(name):
+# print(f'Hi, {name}')
+
+# if __name__ == '__main__':
+# print_hi('PyCharm')
diff --git a/unkSwitches-cx.txt b/unkSwitches-cx.txt
index 242c593..a4f7d5c 100644
--- a/unkSwitches-cx.txt
+++ b/unkSwitches-cx.txt
@@ -1,2 +1,65 @@
+10.171.0.10
+10.171.0.12
+10.171.0.15
+10.171.0.16
+10.171.0.19
+10.171.0.20
+10.171.0.21
+10.171.0.23
+10.171.0.24
+10.171.0.26
+10.171.0.27
+10.171.0.28
+10.171.0.29
+10.171.0.30
+10.171.0.31
+10.171.0.32
+10.171.0.33
+10.171.0.34
+10.171.0.35
+10.171.0.37
+10.171.0.38
+10.171.0.39
+10.171.0.40
+10.171.0.41
+10.171.0.42
+10.171.0.43
+10.171.0.44
+10.171.0.45
+10.171.0.47
+10.171.0.48
+10.171.0.49
+10.171.0.50
+10.171.0.51
+10.171.0.52
 10.171.0.53
-10.171.0.28
\ No newline at end of file
+10.171.0.54
+10.171.0.55
+10.171.0.56
+10.171.0.57
+10.171.0.58
+10.171.0.59
+10.171.0.60
+10.171.0.61
+10.171.0.62
+10.171.0.63
+10.171.0.64
+10.171.0.65
+10.171.0.66
+10.171.0.67
+10.171.0.68
+10.171.0.69
+10.171.0.70
+10.171.0.71
+10.171.0.72
+10.171.0.73
+10.171.0.74
+10.171.0.11
+10.171.0.13
+10.171.0.14
+10.171.0.17
+10.171.0.18
+10.171.0.25
+10.171.0.36
+10.171.0.46
+10.171.0.75
\ No newline at end of file
diff --git a/unlCitySwitches-cx.txt b/unlCitySwitches-cx.txt
new file mode 100644
index 0000000..ca5887f
--- /dev/null
+++ b/unlCitySwitches-cx.txt
@@ -0,0 +1,50 @@
+10.163.0.1
+10.163.0.2
+10.163.0.3
+10.163.0.4
+10.163.0.5
+10.163.0.6
+10.163.0.7
+10.163.0.8
+10.163.0.9
+10.163.0.10
+10.163.0.11
+10.163.0.12
+10.163.0.13
+10.163.0.14
+10.163.0.15
+10.163.0.16
+10.163.0.17
+10.163.0.18
+10.163.0.19
+10.163.0.20
+10.163.0.21
+10.163.0.22
+10.163.0.23
+10.163.0.24
+10.163.0.25
+10.163.0.26
+10.163.0.27
+10.163.0.28
+10.163.0.29
+10.163.0.30
+10.163.0.31
+10.163.0.32
+10.163.0.33
+10.163.0.34
+10.163.0.35
+10.163.0.36
+10.163.0.37
+10.163.0.38
+10.163.0.39
+10.163.0.40
+10.163.0.41
+10.163.0.42
+10.163.0.43
+10.163.0.44
+10.163.0.45
+10.163.0.46
+10.163.0.47
+10.163.0.48
+10.163.0.49
+10.163.0.50
\ No newline at end of file
diff --git a/unoSwitches-cx.txt b/unoSwitches-cx.txt
new file mode 100644
index 0000000..65ed43c
--- /dev/null
+++ b/unoSwitches-cx.txt
@@ -0,0 +1,180 @@
+10.175.0.1
+10.175.0.2
+10.175.0.3
+10.175.0.4
+10.175.0.5
+10.175.0.6
+10.175.0.7
+10.175.0.8
+10.175.0.9
+10.175.0.10
+10.175.0.11
+10.175.0.12
+10.175.0.13
+10.175.0.14
+10.175.0.15
+10.175.0.16
+10.175.0.17
+10.175.0.18
+10.175.0.19
+10.175.0.20
+10.175.0.21
+10.175.0.22
+10.175.0.23
+10.175.0.24
+10.175.0.25
+10.175.0.26
+10.175.0.27
+10.175.0.28
+10.175.0.29
+10.175.0.30
+10.175.0.31
+10.175.0.32
+10.175.0.33
+10.175.0.34
+10.175.0.35
+10.175.0.36
+10.175.0.37
+10.175.0.38
+10.175.0.39
+10.175.0.40
+10.175.0.41
+10.175.0.42
+10.175.0.43
+10.175.0.44
+10.175.0.45
+10.175.0.46
+10.175.0.47
+10.175.0.48
+10.175.0.49
+10.175.0.50
+10.175.0.51
+10.175.0.52
+10.175.0.53
+10.175.0.54
+10.175.0.55
+10.175.0.56
+10.175.0.57
+10.175.0.58
+10.175.0.59
+10.175.0.60
+10.175.0.61
+10.175.0.62
+10.175.0.63
+10.175.0.64
+10.175.0.65
+10.175.0.66
+10.175.0.67
+10.175.0.68
+10.175.0.69
+10.175.0.70
+10.175.0.71
+10.175.0.72
+10.175.0.73
+10.175.0.74
+10.175.0.75
+10.175.0.76
+10.175.0.77
+10.175.0.78
+10.175.0.79
+10.175.0.80
+10.175.0.81
+10.175.0.82
+10.175.0.83
+10.175.0.84
+10.175.0.85
+10.175.0.86
+10.175.0.87
+10.175.0.88
+10.175.0.89
+10.175.0.90
+10.175.0.91
+10.175.0.92
+10.175.0.93
+10.175.0.94
+10.175.0.95
+10.175.0.96
+10.175.0.97
+10.175.0.98
+10.175.0.99
+10.175.0.100
+10.175.0.101
+10.175.0.102
+10.175.0.103
+10.175.0.104
+10.175.0.105
+10.175.0.106
+10.175.0.107
+10.175.0.108
+10.175.0.109
+10.175.0.110
+10.175.0.111
+10.175.0.112
+10.175.0.113
+10.175.0.114
+10.175.0.115
+10.175.0.116
+10.175.0.117
+10.175.0.118
+10.175.0.119
+10.175.0.120
+10.175.0.121
+10.175.0.122
+10.175.0.123
+10.175.0.124
+10.175.0.125
+10.175.0.126
+10.175.0.127
+10.175.0.128
+10.175.0.129
+10.175.0.130
+10.175.0.131
+10.175.0.132
+10.175.0.133
+10.175.0.134
+10.175.0.135
+10.175.0.136
+10.175.0.137
+10.175.0.138
+10.175.0.139
+10.175.0.140
+10.175.0.141
+10.175.0.142
+10.175.0.143
+10.175.0.144
+10.175.0.145
+10.175.0.146
+10.175.0.147
+10.175.0.148
+10.175.0.149
+10.175.0.150
+10.175.0.151
+10.175.0.152
+10.175.0.153
+10.175.0.154
+10.175.0.155
+10.175.0.156
+10.175.0.157
+10.175.0.158
+10.175.0.159
+10.175.0.160
+10.175.0.161
+10.175.0.162
+10.175.0.163
+10.175.0.164
+10.175.0.165
+10.175.0.166
+10.175.0.167
+10.175.0.168
+10.175.0.169
+10.175.0.170
+10.175.0.171
+10.175.0.172
+10.175.0.173
+10.175.0.174
+10.175.0.175
+10.175.0.176
+10.175.0.177
+10.175.0.178
+10.175.0.179
+10.175.0.180
\ No newline at end of file
-- 
GitLab