def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open()
class RoutingIntStaticRoute(Screen): #Function to configure a static route on a device def RoutingIntStaticRouteExecute(self): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: destination_address = self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteIPRouteLayout.ids.IPv4AddressTextInput.text + ' ' + self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteIPRouteLayout.ids.SubnetMaskSpinnerLayout.ids.SubnetMaskSpinner.text distance_metric = self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteMetricDistanceLayout.ids.MetricDistanceTextInput.text if self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardIPLayout.ids.IPv4AddressTextInput.text == '': route_egress = self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardInterfaceLayout.ids.InterfaceTypeSpinnerLayout.ids.InterfaceTypeSpinner.text + ' ' + self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardInterfaceLayout.ids.InterfaceNumberTextInput.text else: route_egress = self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardIPLayout.ids.IPv4AddressTextInput.text #Try statement to ensure the IP address entered is valid. If it is an invalid address the ipaddress module will raise a value error, at which point the user is informed that a valid IP address is required using a popup try: device_ip_address = self.ids._IPv4_Target_Device_Layout_.ids.IPv4AddressTextInput.text ipaddress.ip_address(device_ip_address) #ipaddress raises a value error when an invalid IP address is used except ValueError: Factory.InvalidIPAddressPopup().open() return #Exit from the function #If statement to ensure user has entered a username or password if App.get_running_app( ).device_username == '' or App.get_running_app( ).device_password == '': Factory.NoUserOrPassPopup().open() return #Exit from the function else: device_username = App.get_running_app().device_username device_password = App.get_running_app().device_password device = { 'device_type': 'cisco_ios', 'ip': device_ip_address, 'username': device_username, 'password': device_password, } config_commands = [ "ip route " + destination_address + ' ' + route_egress + ' ' + distance_metric ] net_connect = ConnectHandler(**device) net_connect.send_config_set(config_commands) #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' #Create and display a popup to inform the user of the successful configuration popup = Popup( title='', content=Label( markup=True, text="Successfully configured static route to '[b]" + destination_address + "[/b]' on device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint=(0.95, 0.3)) popup.open() #Except error to catch when Credentials are incorrect, informs the user of the error using a popup defined in the MainApplication.kv except AuthenticationException: Factory.NetmikoAuthenticateFailurePopup().open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() #Function to open the credential entry popup def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open() #Function linked to the Interface Egress radio button to modify the various widgets so that they are only visible and useable when the user wishes to use the interface egress def StaticRouteSelectInterfaceEgress(self): self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardIPLayout.disabled = True self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardInterfaceLayout.disabled = False self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardIPLayout.opacity = 0 self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardInterfaceLayout.opacity = 1 self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardIPLayout.ids.IPv4AddressTextInput.text = '' #Function linked to the Forward IP Egress radio button to modify the various widgets so that they are only visible and useable when the user wishes to use the forward ip egress def StaticRouteSelectIPEgress(self): self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardIPLayout.disabled = False self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardInterfaceLayout.disabled = True self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardIPLayout.opacity = 1 self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardInterfaceLayout.opacity = 0 self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardInterfaceLayout.ids.InterfaceTypeSpinnerLayout.text = 'Interface Type' self.ids._Routing_Int_Static_Route_Layout_.ids.RoutingIntStaticRouteForwardInterfaceLayout.ids.InterfaceNumberTextInput.text = ''
class NetMonSpanConf(Screen): #Function to configure SPAN on a switcing device def NetMonSpanConfExecute(self): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: session_ID = self.ids._Net_Mon_Span_Conf_Layout_.ids.NetMonSpanConfSessionNoLayout.ids.SPANSessionIDTextInput.text source_port = self.ids._Net_Mon_Span_Conf_Layout_.ids.NetMonSpanConfSourcePortLayout.ids.InterfaceTypeSpinner.text + ' ' + self.ids._Net_Mon_Span_Conf_Layout_.ids.NetMonSpanConfSourcePortLayout.ids.InterfaceNumberTextInput.text destination_port = self.ids._Net_Mon_Span_Conf_Layout_.ids.NetMonSpanConfDestinationPortLayout.ids.InterfaceTypeSpinner.text + ' ' + self.ids._Net_Mon_Span_Conf_Layout_.ids.NetMonSpanConfDestinationPortLayout.ids.InterfaceNumberTextInput.text source_command = 'monitor session ' + session_ID + ' source interface ' + source_port destionation_command = 'monitor session ' + session_ID + ' destination interface ' + destination_port #Try statement to ensure the IP address entered is valid. If it is an invalid address the ipaddress module will raise a value error, at which point the user is informed that a valid IP address is required using a popup try: device_ip_address = self.ids._IPv4_Target_Device_Layout_.ids.IPv4AddressTextInput.text ipaddress.ip_address(device_ip_address) #ipaddress raises a value error when an invalid IP address is used except ValueError: Factory.InvalidIPAddressPopup().open() return #Exit from the function #If statement to ensure user has entered a username or password if App.get_running_app( ).device_username == '' or App.get_running_app( ).device_password == '': Factory.NoUserOrPassPopup().open() return #Exit from the function else: device_username = App.get_running_app().device_username device_password = App.get_running_app().device_password device = { 'device_type': 'cisco_ios', 'ip': device_ip_address, 'username': device_username, 'password': device_password, } config_commands = [source_command, destionation_command] net_connect = ConnectHandler(**device) net_connect.send_config_set(config_commands) #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' #Create and display a popup to inform the user of the successful configuration popup = Popup( title='', content=Label( markup=True, text="Successfully configured SPAN with session ID '[b]" + session_ID + "[/b]' on device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint=(0.8, 0.3)) popup.open() #Except error to catch when Credentials are incorrect, informs the user of the error using a popup defined in the MainApplication.kv except AuthenticationException: Factory.NetmikoAuthenticateFailurePopup().open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() #Function to open the credential entry popup def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open()
class RoutingIntDefaultGateway(Screen): #Function to configure a default gateway on a device def RoutingIntDefaultGatewayExecute(self): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: default_gateway = self.ids._Routing_Int_Default_Gateway_Layout_.ids.IPv4AddressTextInput.text #Try statement to ensure the IP address entered is valid. If it is an invalid address the ipaddress module will raise a value error, at which point the user is informed that a valid IP address is required using a popup try: device_ip_address = self.ids._IPv4_Target_Device_Layout_.ids.IPv4AddressTextInput.text ipaddress.ip_address(device_ip_address) #ipaddress raises a value error when an invalid IP address is used except ValueError: Factory.InvalidIPAddressPopup().open() return #Exit from the function #If statement to ensure user has entered a username or password if App.get_running_app( ).device_username == '' or App.get_running_app( ).device_password == '': Factory.NoUserOrPassPopup().open() return #Exit from the function else: device_username = App.get_running_app().device_username device_password = App.get_running_app().device_password device = { 'device_type': 'cisco_ios', 'ip': device_ip_address, 'username': device_username, 'password': device_password, } config_commands = ["ip default-gateway " + default_gateway] net_connect = ConnectHandler(**device) net_connect.send_config_set(config_commands) #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' #Create and display a popup to inform the user of the successful configuration popup = Popup( title='', content=Label( markup=True, text="Successfully configured default gateway as '[b]" + default_gateway + "[/b]' on device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint=(0.85, 0.3)) popup.open() #Except error to catch when Credentials are incorrect, informs the user of the error using a popup defined in the MainApplication.kv except AuthenticationException: Factory.NetmikoAuthenticateFailurePopup().open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() #Function to open the credential entry popup def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open()
class SecurityConfLocalUsernameDatabase(Screen): #Function to add a new user account to a device def SecurityConfLocalUsernameDatabaseExecute(self): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: privilege_level = self.ids._Security_Conf_Local_Username_Database_Layout_.ids.SecurityConfLocalUsernameDatabasePrivilegeLayout.ids.PrivilegeLevelSpinner.text new_username = self.ids._Security_Conf_Local_Username_Database_Layout_.ids.SecurityConfLocalUsernameDatabaseUserAndPassLayout.ids.UsernameTextInput.text new_password = self.ids._Security_Conf_Local_Username_Database_Layout_.ids.SecurityConfLocalUsernameDatabaseUserAndPassLayout.ids.PasswordTextInput.text #Try statement to ensure the IP address entered is valid. If it is an invalid address the ipaddress module will raise a value error, at which point the user is informed that a valid IP address is required using a popup try: device_ip_address = self.ids._IPv4_Target_Device_Layout_.ids.IPv4AddressTextInput.text ipaddress.ip_address(device_ip_address) #ipaddress raises a value error when an invalid IP address is used except ValueError: Factory.InvalidIPAddressPopup().open() return #Exit from the function #If statement to ensure user has entered a username or password if App.get_running_app( ).device_username == '' or App.get_running_app( ).device_password == '': Factory.NoUserOrPassPopup().open() return #Exit from the function else: device_username = App.get_running_app().device_username device_password = App.get_running_app().device_password device = { 'device_type': 'cisco_ios', 'ip': device_ip_address, 'username': device_username, 'password': device_password, } priv_check = self.ids._Security_Conf_Local_Username_Database_Layout_.ids.SecurityConfLocalUsernameDatabasePrivilegeLayout.ids.PrivilegeLevelSpinner.text secret_check = self.ids._Security_Conf_Local_Username_Database_Layout_.ids.SecurityConfLocalUsernameDatabaseSecretLayout.ids.SecretPasswordTrue.active if secret_check == True and priv_check != 'No Privilege Required': #Priv and Secret config_commands = [ "username " + new_username + " privilege " + privilege_level + " secret " + new_password ] elif priv_check != 'No Privilege Required': #Priv and password config_commands = [ "username " + new_username + " privilege " + privilege_level + " password " + new_password ] elif secret_check == True: #Secret config_commands = [ "username " + new_username + " secret " + new_password ] else: config_commands = [ "username " + new_username + " password " + new_password ] #Standard net_connect = ConnectHandler(**device) net_connect.send_config_set(config_commands) #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' #Create and display a popup to inform the user of the successful configuration popup = Popup( title='', content=Label(markup=True, text="Successfully added new user '[b]" + new_username + "[/b]' to device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint=(0.8, 0.3)) popup.open() #Except error to catch when Credentials are incorrect, informs the user of the error using a popup defined in the MainApplication.kv except AuthenticationException: Factory.NetmikoAuthenticateFailurePopup().open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() #Function to open the credential entry popup def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open()
class IntConfEthernetInt(Screen): #Function to make configuration changes to a ethernet interface def IntConfEthernetIntExecute(self): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: #Define the three potential commands as empty variables description_command = '' duplex_command = '' bandwidth_command = '' interface = self.ids._Int_Conf_Ethernet_Int_Layout_.ids.InterfaceSelectionLayout.ids.InterfaceTypeSpinnerLayout.ids.InterfaceTypeSpinner.text + ' ' + self.ids._Int_Conf_Ethernet_Int_Layout_.ids.InterfaceSelectionLayout.ids.InterfaceNumberTextInput.text interface_command = "interface " + interface #If statement to check if user has selected Transport Method checkbox, if so the command will be created and inserted into the variable. Else the variable will be left blank if self.ids._Int_Conf_Ethernet_Int_Function_Select_.ids.DescriptionCheckbox.active == True: description_command = 'description ' + self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDescriptionLayout.ids.EthernetIntDescriptionTextInput.text else: pass #If statement to check if user has selected Duplex checkbox, if so the command will be created and inserted into the variable. Else the variable will be left blank if self.ids._Int_Conf_Ethernet_Int_Function_Select_.ids.DuplexCheckbox.active == True: #If statement for handling if a user does not change duplex type or - It will default to Auto if self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDuplexLayout.ids.DuplexTypeSpinner.text == 'Duplex Type': duplex_type = 'Auto' else: duplex_type = self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDuplexLayout.ids.DuplexTypeSpinner.text duplex_command = 'duplex ' + duplex_type #Creates the final duplex command else: pass #If statement to check if user has selected Bandwidth checkbox, if so the command will be created and inserted into the variable. Else the variable will be left blank if self.ids._Int_Conf_Ethernet_Int_Function_Select_.ids.BandwidthCheckbox.active == True: bandwidth_command = 'bandwidth ' + self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntBandwidthLayout.ids.BandwidthTextInput.text else: pass #Try statement to ensure the IP address entered is valid. If it is an invalid address the ipaddress module will raise a value error, at which point the user is informed that a valid IP address is required using a popup try: device_ip_address = self.ids._IPv4_Target_Device_Layout_.ids.IPv4AddressTextInput.text ipaddress.ip_address(device_ip_address) #ipaddress raises a value error when an invalid IP address is used except ValueError: Factory.InvalidIPAddressPopup().open() return #Exit from the function #If statement to ensure user has entered a username or password if App.get_running_app().device_username == '' or App.get_running_app().device_password == '': Factory.NoUserOrPassPopup().open() return #Exit from the function else: device_username = App.get_running_app().device_username device_password = App.get_running_app().device_password device = { 'device_type': 'cisco_ios', 'ip': device_ip_address, 'username': device_username, 'password': device_password, } config_commands = [interface_command, description_command, duplex_command, bandwidth_command] net_connect = ConnectHandler(**device) net_connect.send_config_set(config_commands) #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' #Create and display a popup to inform the user of the successful configuration popup = Popup(title='', content=Label(markup = True, text="Successfully configured interface '[b]" + interface + "[/b]' of device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint =(0.8, 0.3)) popup.open() #Except error to catch when Credentials are incorrect, informs the user of the error using a popup defined in the MainApplication.kv except AuthenticationException: Factory.NetmikoAuthenticateFailurePopup().open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() #Function to open the credential entry popup def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open() #Function linked to the Description checkbox to modify the Description widgets so that they are visible when checked and disabled and hidden from view when unchecked, the text input will have it's value reset def IntConfEthernetIntDescriptionSelect(self): if self.ids._Int_Conf_Ethernet_Int_Function_Select_.ids.DescriptionCheckbox.active == True: self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDescriptionLayout.opacity = 1 self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDescriptionLayout.disabled = False else: self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDescriptionLayout.opacity = 0 self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDescriptionLayout.disabled = True self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDescriptionLayout.ids.EthernetIntDescriptionTextInput.text = '' #Function linked to the Duplex checkbox to modify the Duplex Type widgets so that they are visible when checked and disabled and hidden from view when unchecked, the Spinner input will have it's value reset def IntConfEthernetIntDuplexSelect(self): if self.ids._Int_Conf_Ethernet_Int_Function_Select_.ids.DuplexCheckbox.active == True: self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDuplexLayout.opacity = 1 self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDuplexLayout.disabled = False else: self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDuplexLayout.opacity = 0 self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDuplexLayout.disabled = True self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntDuplexLayout.ids.DuplexTypeSpinner.text = 'Duplex Type' #Function linked to the Bandwidth checkbox to modify the Bandwidth widgets so that they are visible when checked and disabled and hidden from view when unchecked, the text inputs will have it's value reset def IntConfEthernetIntBandwidthSelect(self): if self.ids._Int_Conf_Ethernet_Int_Function_Select_.ids.BandwidthCheckbox.active == True: self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntBandwidthLayout.opacity = 1 self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntBandwidthLayout.disabled = False else: self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntBandwidthLayout.opacity = 0 self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntBandwidthLayout.disabled = True self.ids._Int_Conf_Ethernet_Int_Layout_.ids.IntConfEthernetIntBandwidthLayout.ids.BandwidthTextInput.text = ''
class SecurityConfAuxVtyConLines(Screen): #Function to configure a the Aux, Con or Vty lines on a device def SecurityConfAuxVtyConLinesExecute(self): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: #Define the three potential commands as empty variables transport_command = '' login_command = '' exec_timeout_command = '' #Else if to find out which line the user wishes to configure if self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesSelectLineLayout.ids.ConTrue.active == True: line_to_configure = 'Console' elif self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesSelectLineLayout.ids.AuxTrue.active == True: line_to_configure = 'Aux' else: line_to_configure = 'Vty' #Else if to find out the line_range the user wishes to configure, if console or auxiliary is the line to configure set line to 0 if self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesSelectLineLayout.ids.ConTrue.active == True or self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesSelectLineLayout.ids.AuxTrue.active == True: line_range = '0' else: start_line_range = self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLineRangeLayout.ids.LineRangeStartTextInput.text end_line_range = self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLineRangeLayout.ids.LineRangeEndTextInput.text line_range = start_line_range + ' ' + end_line_range #Define the line_range variable from reading user input from the two text inputs line_command = "line " + line_to_configure + ' ' + line_range #Create a variable to store the command to enter the line to improve ease of reading further down #If statement to check if user has selected Transport Method checkbox, if so the command will be created and inserted into the variable. Else the variable will be left blank if self.ids._Security_Conf_Aux_Vty_Con_Lines_Function_Select_.ids.TransportMethodCheckbox.active == True: #Creates the variable for input/output dependent on user choice transport_type = self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportInputOutputSpinner.text # Defines wheter the user wants to configure input or output transport method #If statement for handling if a user does not change method 1 - It will default to ssh if self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportMethodNo1Spinner.text == 'Method 1': transport_method1 = 'SSH' else: transport_method1 = self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportMethodNo1Spinner.text #If statement for handling if a user does not change method 2 or if N/A was selected. Or if a user has entered 'none' as the value in method 1 - It will default to blank if self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportMethodNo2Spinner.text == 'Method 2' or self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportMethodNo2Spinner.text == 'N/A' or transport_method1 == 'none': transport_method2 = '' else: transport_method2 = self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportMethodNo2Spinner.text #Combines the three variables to create the final command transport_command = 'transport ' + transport_type + ' ' + transport_method1 + ' ' + transport_method2 # Creates the final Transport Command else: pass #If statement to check if user has selected Login Type checkbox, if so the command will be created and inserted into the variable. Else the variable will be left blank if self.ids._Security_Conf_Aux_Vty_Con_Lines_Function_Select_.ids.LoginTypeCheckbox.active == True: #If statement to check if user has selected to login using the local user database or a custom password and set the login_type_command variable accordingly if self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLoginOptionsLayout.ids.LoginLocalTrue.active == True: login_command = 'login local' else: login_command = 'password ' + self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLoginOptionsLayout.ids.LineLoginPasswordTextInput.text else: pass #If statement to check if user has selected Exec Timeout checkbox, if so the command will be created and inserted into the variable. Else the variable will be left blank if self.ids._Security_Conf_Aux_Vty_Con_Lines_Function_Select_.ids.ExecTimeoutCheckbox.active == True: exec_timeout_command = 'exec-timeout ' + self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesExecTimeoutOptionsLayout.ids.LineExecTimeoutMinutesTextInput.text + ' ' + self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesExecTimeoutOptionsLayout.ids.LineExecTimeoutSecondsTextInput.text else: pass #Try statement to ensure the IP address entered is valid. If it is an invalid address the ipaddress module will raise a value error, at which point the user is informed that a valid IP address is required using a popup try: device_ip_address = self.ids._IPv4_Target_Device_Layout_.ids.IPv4AddressTextInput.text ipaddress.ip_address(device_ip_address) #ipaddress raises a value error when an invalid IP address is used except ValueError: Factory.InvalidIPAddressPopup().open() return #Exit from the function #If statement to ensure user has entered a username or password if App.get_running_app( ).device_username == '' or App.get_running_app( ).device_password == '': Factory.NoUserOrPassPopup().open() return #Exit from the function else: device_username = App.get_running_app().device_username device_password = App.get_running_app().device_password device = { 'device_type': 'cisco_ios', 'ip': device_ip_address, 'username': device_username, 'password': device_password, } config_commands = [ line_command, transport_command, login_command, exec_timeout_command ] net_connect = ConnectHandler(**device) net_connect.send_config_set(config_commands) #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' #If statement to check if VTY was the selected function, and then display the text with a line range, else it will display it as line 0 if self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesSelectLineLayout.ids.VtyTrue.active == True: #Create and display a popup to inform the user of the successful configuration popup = Popup( title='', content=Label(markup=True, text="Successfully configured '[b]" + line_to_configure + "[/b]' Lines '[b]" + start_line_range + " - " + end_line_range + "[/b]' on device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint=(0.8, 0.3)) popup.open() else: #Create and display a popup to inform the user of the successful configuration popup = Popup( title='', content=Label(markup=True, text="Successfully configured '[b]" + line_to_configure + "[/b]' Line '[b]" + line_range + "[/b]' on device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint=(0.8, 0.3)) popup.open() #Except error to catch when Credentials are incorrect, informs the user of the error using a popup defined in the MainApplication.kv except AuthenticationException: Factory.NetmikoAuthenticateFailurePopup().open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() #Function to open the credential entry popup def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open() #Function linked to the Console checkbox to modify the various widgets so that only commands that can be performed on the Console line can be set - Remove and reset the Line Range text inputs as Console only allows for line 0 and modifiying which transport methods are available def SecurityConfAuxVtyConLinesConSelect(self): if self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesSelectLineLayout.ids.ConTrue.active == True: self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportInputOutputSpinner.text = 'Output' self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportInputOutputSpinner.values = '' self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportMethodNo1Spinner.values = 'SSH', 'Telnet', 'all', 'none' else: self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportInputOutputSpinner.text = 'Input' self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportInputOutputSpinner.values = 'Output', 'Input' self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportMethodNo1Spinner.values = 'SSH', 'Telnet', 'rlogin', 'all', 'none' #Function linked to the Aux checkbox to modify the various widgets so that only commands that can be performed on the Console line can be set - Remove and reset the Line Range text inputs as Aux only allows for line 0 def SecurityConfAuxVtyConLinesVtySelect(self): if self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesSelectLineLayout.ids.VtyTrue.active == True: self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLineRangeLayout.opacity = 1 self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLineRangeLayout.disabled = False else: self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLineRangeLayout.opacity = 0 self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLineRangeLayout.disabled = True self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLineRangeLayout.ids.LineRangeStartTextInput.text = '' self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLineRangeLayout.ids.LineRangeEndTextInput.text = '' #Function linked to the Transport checkbox to modify the Transport Method widgets so that they are visible when checked and disabled and hidden from view when unchecked, the spinners will have their values reset def SecurityConfAuxVtyConLinesTransportSelect(self): if self.ids._Security_Conf_Aux_Vty_Con_Lines_Function_Select_.ids.TransportMethodCheckbox.active == True: self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.opacity = 1 self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.disabled = False else: self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.opacity = 0 self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.disabled = True self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportInputOutputSpinner.text = 'Output' self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportMethodNo1Spinner.text = 'Method 1' self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesTransportOptionsLayout.ids.TransportMethodNo2Spinner.text = 'Method 2' #Function linked to the Login checkbox to modify the Login Type widgets so that they are visible when checked and disabled and hidden from view when unchecked, the text input will have it's value reset def SecurityConfAuxVtyConLinesLoginTypeSelect(self): if self.ids._Security_Conf_Aux_Vty_Con_Lines_Function_Select_.ids.LoginTypeCheckbox.active == True: self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLoginOptionsLayout.opacity = 1 self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLoginOptionsLayout.disabled = False self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLoginOptionsLayout.ids.LineLoginPasswordTextInput.disabled = True #Specifically disable password text input until user selects that they want to use password entry else: self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLoginOptionsLayout.opacity = 0 self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLoginOptionsLayout.disabled = True self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLoginOptionsLayout.ids.LoginLocalTrue.active = True self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesLoginOptionsLayout.ids.LineLoginPasswordTextInput.text = '' #Function linked to the ExecTimeout checkbox to modify the Exec-Timeout widgets so that they are visible when checked and disabled and hidden from view when unchecked, the text inputs will have their value reset def SecurityConfAuxVtyConLinesExecTimeoutSelect(self): if self.ids._Security_Conf_Aux_Vty_Con_Lines_Function_Select_.ids.ExecTimeoutCheckbox.active == True: self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesExecTimeoutOptionsLayout.opacity = 1 self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesExecTimeoutOptionsLayout.disabled = False else: self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesExecTimeoutOptionsLayout.opacity = 0 self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesExecTimeoutOptionsLayout.disabled = True self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesExecTimeoutOptionsLayout.ids.LineExecTimeoutMinutesTextInput.text = '' self.ids._Security_Conf_Aux_Vty_Con_Lines_Layout_.ids.SecurityConfAuxVtyConLinesExecTimeoutOptionsLayout.ids.LineExecTimeoutSecondsTextInput.text = ''
class DeviceInfoPollAndExtract(Screen): #This function will allow for certain information to be extracted from a device and displayed on screen or saved to a file def DeviceInfoPollAndExtractExecute(self): #Try statement to ensure that any errors connecting and reading the device are handled gracefully and the user is informed of what the potential error was using popups try: selected_storage_directory = App.get_running_app( ).selected_storage_directory #Create a local variable using the value in the global property selected_storage_directory. This will allow the script to create and store files in the directory set by the user #Try statement to ensure the IP address entered is valid. If it is an invalid address the ipaddress module will raise a value error, at which point the user is informed that a valid IP address is required using a popup try: device_ip_address = self.ids._IPv4_Target_Device_Layout_.ids.IPv4AddressTextInput.text ipaddress.ip_address(device_ip_address) #ipaddress raises a value error when an invalid IP address is used except ValueError: Factory.InvalidIPAddressPopup().open() return #Exit from the function #If statement to ensure user has entered a username or password if App.get_running_app( ).device_username == '' or App.get_running_app( ).device_password == '': Factory.NoUserOrPassPopup().open() return #Exit from the function else: device_username = App.get_running_app().device_username device_password = App.get_running_app().device_password device = { 'device_type': 'cisco_ios', 'ip': device_ip_address, 'username': device_username, 'password': device_password, } net_connect = ConnectHandler(**device) #Create variables to store the state of the data information checkboxes, this will allow them to be easily refrenced in the below if statements. This has been done to improve readablity extract_hostname_selection = self.ids._Device_Info_Poll_And_Extract_Info_Select_.ids.HostnameInfoCheckbox.active extract_device_type_selection = self.ids._Device_Info_Poll_And_Extract_Info_Select_.ids.DeviceTypeInfoCheckbox.active extract_ios_version_selection = self.ids._Device_Info_Poll_And_Extract_Info_Select_.ids.IOSVersionInfoCheckbox.active extract_domain_selection = self.ids._Device_Info_Poll_And_Extract_Info_Select_.ids.DomainInfoCheckbox.active extract_uptime_selection = self.ids._Device_Info_Poll_And_Extract_Info_Select_.ids.UptimeInfoCheckbox.active #If statement to see if user selected Hostname checkbox, if so it will call the ExtractHostname function if extract_hostname_selection == True: output = net_connect.send_command( "show version | include (uptime is)") hostname = self.SearchHostname(output) else: #Set hostname to N/A if Hostname is not required hostname = 'N/A' #If statement to see if user selected Device Type checkbox, if so it will call the ExtractHostname function if extract_device_type_selection == True: output = net_connect.send_command( "show version | include (bytes of memory)") device_type = self.SearchDeviceType(output) else: #Set device_type to N/A if Device Type is not required device_type = 'N/A' #If statement to see if user selected IOS Version checkbox, if so it will call the ExtractHostname function if extract_ios_version_selection == True: output = net_connect.send_command( "show version | include (, Version)") ios_version = self.SearchIOSVersion(output) else: #Set ios_version to N/A if IOS Version is not required ios_version = 'N/A' #If statement to see if user selected Domain checkbox, if so it will call the ExtractHostname function if extract_domain_selection == True: output = net_connect.send_command( "show run | include domain name") domain_name = self.SearchDomain(output) else: #Set domain_name to N/A if Domain Name is not required domain_name = 'N/A' #If statement to see if user selected UpTime checkbox, if so it will call the ExtractHostname function if extract_uptime_selection == True: output = net_connect.send_command( "show version | include (uptime is)") uptime = self.SearchUptime(output) else: #Set uptime to N/A if Uptime is not required uptime = 'N/A' #If statement to check if user requested for the output to be stored locally, if so it will store the output in a txt file. If not it is passed and nothing is done if self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.StoreLocalCheckbox.active == True: poll_info_parent_directory = selected_storage_directory + '\\Outputs\\PollDeviceOutput\\' #Create a variable of the absolute path of where the parent directory for output of data capture will be stored poll_info_individual_directory = selected_storage_directory + '\\Outputs\\PollDeviceOutput\\' + device_ip_address #Create a variable of the absolute path of where the all output files for devices with the same hostname will be stored #If statement to check if user has entered an output name, if not the current time and date will be used if self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameTextInput.text == '': file_name = datetime.now().strftime("%Y-%m-%d_%I-%M-%S_%p") else: file_name = self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameTextInput.text #Create a variable for the desired file name poll_info_output_file = poll_info_individual_directory + "/" + file_name + '.txt' #Create a variable for the name and location of the file to be saved. It will be stored as a txt file if not os.path.exists( poll_info_parent_directory ): #Check for existence of the parent poll directory - one to store all individual directories - and if not there create it, this is done using the os.path function os.makedirs(poll_info_parent_directory) else: pass if not os.path.exists( poll_info_individual_directory ): #Check for existence of the individual poll directory - One to store the current output - and if not there create it, this is done using the os.path function os.makedirs(poll_info_individual_directory) else: pass #Create a list variable to store the outputs required requested by the user, this will then be written into the file specified by the user poll_info_output_store_local = [ 'Hostname: ' + hostname, 'Device Type: ' + device_type, 'IOS Version: ' + ios_version, 'Domain: ' + domain_name, 'Uptime: ' + uptime ] with open(poll_info_output_file, 'w') as f: f.write( '\n'.join(poll_info_output_store_local) + '\n' ) #Write each entry of poll_info_output_store_local list in the specified file on a seperate line f.close() else: pass #The following two will update the label to display the IP address of the device that was polled. As well as the text input to display the requested info or input 'N/A' if the user did not request the info self.ids._Device_Info_Poll_And_Extract_Layout_.ids.PolledDeviceInfoLabel.text = 'Device Information for IP Address - [b]' + device_ip_address + '[/b]' self.ids._Device_Info_Poll_And_Extract_Layout_.ids.PolledDeviceInfoOutput.text = 'Hostname: ' + hostname + ' \nDevice Type: ' + device_type + '\nIOS Version: ' + ios_version + '\nDomain: ' + domain_name + '\nUptime: ' + uptime #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' #Except error to catch when Credentials are incorrect, informs the user of the error using a popup defined in the MainApplication.kv except AuthenticationException: Factory.NetmikoAuthenticateFailurePopup().open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() #Function to open the credential entry popup def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open() #Function linked to the Local Store checkbox to modify the various widgets so that they are only visible and useable when the user wishes to store the output from device polling def DeviceInfoPollAndExtractStoreLocalSelect(self): if self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.StoreLocalCheckbox.active == True: self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameLabel.opacity = 1 self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameLabel.disabled = False self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameTextInput.opacity = 1 self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameTextInput.disabled = False else: self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameLabel.opacity = 0 self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameLabel.disabled = True self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameTextInput.opacity = 0 self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameTextInput.disabled = True self.ids._Device_Info_Poll_And_Extract_Layout_.ids.DeviceInfoPollAndExtractStoreLocalLayout.ids.FileNameTextInput.text = '' #Function to search output for the Hostname of a device and return it def SearchHostname(self, output): if re.search( "(.+) uptime is", output ) == None: #If regex search finds no matches in string then set hostname as 'unknown' hostname = "N/" else: #Else if regex search finds any matches then do the following dev_hostname = re.search( "(.+) uptime is", output ) #Set variable dev_hostname as the output of regex search on the output from the device hostname = dev_hostname.group( 1 ) #Set variable hostname as the first match from the regex search hostname = str(hostname) #Convert variable to string return hostname #Return variable hostname to function that called it #Function to search output for the IOS Version of a device and return it def SearchIOSVersion(self, output): if re.search( "\), Version (.+),", output ) == None: #If regex search finds no matches in string then set uptime as 'unknown' ios_version = "N/A" else: #Else if regex search finds any matches then do the following dev_version = re.search( "\), Version (.+),", output ) #Set variable dev_uptime as the output of regex search on the output from the device ios_version = dev_version.group( 1 ) #Set variable uptime as the first match from the regex search ios_version = str(ios_version) #Convert variable to string return ios_version #Return variable ios to function that called it #Function to search output for the Device Type of a device and return it def SearchDeviceType(self, output): if re.search( "(.+?) (.+?) (.+?) (.+) bytes of memory", output ) == None: #If regex search finds no matches in string then set model as 'unknown' device_type = "N/A" else: #Else if regex search finds any matches then do the following dev_model = re.search( "(.+?) (.+?) (.+) bytes of memory", output ) #Set variable dev_model as the output of regex search on the output from the device device_type = dev_model.group(1) + ' ' + dev_model.group( 2 ) #Set variable model as the first match from the regex search device_type = str(device_type) #Convert variable to string return device_type #Return variable model to function that called it #Function to search output for the Domain of a device and return it def SearchDomain(self, output): if re.search( "ip domain name (.+)", output ) == None: #If regex search finds no matches in string then set domain_name as 'unknown' domain_name = "N/A" else: #Else if regex search finds any matches then do the following dev_domain = re.search( "ip domain name (.+)", output ) #Set variable dev_domain as the output of regex search on the output from the device domain_name = dev_domain.group( 1) #Set variable ios as the first match from the regex search domain_name = str(domain_name) #Convert variable to string return domain_name #Return variable domain_name to function that called it #Function to search output for the Uptime of a device and return it def SearchUptime(self, output): if re.search( "uptime is (.+)", output ) == None: #If regex search finds no matches in string then set uptime as 'unknown' uptime = "N/A" else: #Else if regex search finds any matches then do the following dev_uptime = re.search( "uptime is (.+)", output ) #Set variable dev_uptime as the output of regex search on the output from the device uptime = dev_uptime.group( 1 ) #Set variable uptime as the first match from the regex search uptime = str(uptime) #Convert variable to string return uptime #Return variable uptime to function that called it
class DeviceInfoChangeControlUploadConf(Screen): #This function will upload a configuration file to a network device to make a list of configuration changes at once def DeviceInfoChangeControlUploadConfExecute(self): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: #Try statement to ensure the IP address entered is valid. If it is an invalid address the ipaddress module will raise a value error, at which point the user is informed that a valid IP address is required using a popup try: device_ip_address = self.ids._IPv4_Target_Device_Layout_.ids.IPv4AddressTextInput.text ipaddress.ip_address(device_ip_address) #ipaddress raises a value error when an invalid IP address is used except ValueError: Factory.InvalidIPAddressPopup().open() return #Exit from the function #If statement to ensure user has entered a username or password if App.get_running_app( ).device_username == '' or App.get_running_app( ).device_password == '': Factory.NoUserOrPassPopup().open() return #Exit from the function else: device_username = App.get_running_app().device_username device_password = App.get_running_app().device_password device = { 'device_type': 'cisco_ios', 'ip': device_ip_address, 'username': device_username, 'password': device_password, } net_connect = ConnectHandler(**device) selected_conf_file = str( self.ids._Device_Info_Change_Control_Upload_Conf_Layout_.ids. FileChooser.selection[0]) with open( selected_conf_file, 'r' ) as f: #user_path is the variable i defined which takes the path of file(configuration file) as raw input from the user. config_commands = f.readlines() net_connect.send_config_set(config_commands) #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' #Create and display a popup to inform the user of the successful configuration popup = Popup( title='', content=Label( markup=True, text= "Successfully uploaded configuration file to device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint=(0.7, 0.3)) popup.open() #Except error to catch when Credentials are incorrect, informs the user of the error using a popup defined in the MainApplication.kv except AuthenticationException: Factory.NetmikoAuthenticateFailurePopup().open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open()
class DeviceInfoChangeControlSaveConf(Screen): def DeviceInfoChangeControlSaveConfExecute(self): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: #Try statement to ensure the IP address entered is valid. If it is an invalid address the ipaddress module will raise a value error, at which point the user is informed that a valid IP address is required using a popup try: device_ip_address = self.ids._IPv4_Target_Device_Layout_.ids.IPv4AddressTextInput.text ipaddress.ip_address(device_ip_address) #ipaddress raises a value error when an invalid IP address is used except ValueError: Factory.InvalidIPAddressPopup().open() return #Exit from the function #If statement to ensure user has entered a username or password if App.get_running_app( ).device_username == '' or App.get_running_app( ).device_password == '': Factory.NoUserOrPassPopup().open() return #Exit from the function else: device_username = App.get_running_app().device_username device_password = App.get_running_app().device_password device = { 'device_type': 'cisco_ios', 'ip': device_ip_address, 'username': device_username, 'password': device_password, } net_connect = ConnectHandler( **device ) #Connect to the device using the credentials and IP address if self.ids._Device_Info_Change_Control_Save_Conf_Layout_.ids.RunningTrue.active == True: self.SaveDeviceRunConf(net_connect) else: self.SaveDeviceStartupConf(net_connect) #Except error to catch when Credentials are incorrect, informs the user of the error using a popup defined in the MainApplication.kv except AuthenticationException: Factory.NetmikoAuthenticateFailurePopup().open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() #Function to open the credential entry popup def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open() #Function to save a device running configuration to a file def SaveDeviceRunConf(self, net_connect): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: selected_storage_directory = App.get_running_app( ).selected_storage_directory #Create a local variable using the value in the global property selected_storage_directory. This will allow the script to create and store files in the directory set by the user output = net_connect.send_command( "show version | include (uptime is)") hostname = DeviceInfoPollAndExtract.SearchHostname( self, output ) #Sets hostname as output from search_hostname function - This function is designed to find and return the hostname of a device using regex date = datetime.now().strftime("%Y-%m-%d_%I-%M-%S_%p") run_conf_parent_directory = selected_storage_directory + '\\Outputs\\SaveConfOutput\\' #Create a variable of the absolute path of where the parent directory for output of data capture will be stored run_conf_individual_directory = selected_storage_directory + '\\Outputs\\SaveConfOutput\\' + hostname + '\\RunningConf' #Create a variable of the absolute path of where the running configurations files for devices with the same hostname will be stored run_conf_output_file = run_conf_individual_directory + "/" + hostname + '_' + date + '_RunningConfiguration.txt' #Create a variable for the name and location of the file to be saved. It will be stored as a txt file if not os.path.exists( run_conf_parent_directory ): #Check for existence of the parent poll directory - one to store all individual directories - and if not there create it, this is done using the os.path function os.makedirs(run_conf_parent_directory) else: pass if not os.path.exists( run_conf_individual_directory ): #Check for existence of the individual poll directory - One to store the current output - and if not there create it, this is done using the os.path function os.makedirs(run_conf_individual_directory) else: pass #show and save running conf of routing device net_connect.send_command('skip-page-display') output_save_conf = net_connect.send_command('show running-config') file = open( run_conf_output_file, 'w' ) #Set variable file_run to create/Open new/exisitng file and allow it to be written to file.write( output_save_conf ) #Write output from running config from device into the file file.close() #Close file #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' popup = Popup( title='', content=Label( markup=True, text= "Successfully saved the '[b]Running Configuration[/b]' of device with hostname '[b]" + hostname + "[/b]'"), size_hint=(0.8, 0.3)) popup.open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() #Function to save a device startup configuration to a file def SaveDeviceStartupConf(self, net_connect): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: selected_storage_directory = App.get_running_app( ).selected_storage_directory #Create a local variable using the value in the global property selected_storage_directory. This will allow the script to create and store files in the directory set by the user output = net_connect.send_command( "show version | include (uptime is)") hostname = DeviceInfoPollAndExtract.SearchHostname( self, output ) #Sets hostname as output from search_hostname function - This function is designed to find and return the hostname of a device using regex date = datetime.now().strftime("%Y-%m-%d_%I-%M-%S_%p") start_conf_parent_directory = selected_storage_directory + '\\Outputs\\SaveConfOutput\\' #Create a variable of the absolute path of where the parent directory for output of data capture will be stored start_conf_individual_directory = selected_storage_directory + '\\Outputs\\SaveConfOutput\\' + hostname + '\\StartupConf' #Create a variable of the absolute path of where the running configurations files for devices with the same hostname will be stored start_conf_output_file = start_conf_individual_directory + "/" + hostname + '_' + date + '_StartupConfiguration.txt' #Create a variable for the name and location of the file to be saved. It will be stored as a txt file if not os.path.exists( start_conf_parent_directory ): #Check for existence of the parent poll directory - one to store all individual directories - and if not there create it, this is done using the os.path function os.makedirs(start_conf_parent_directory) else: pass if not os.path.exists( start_conf_individual_directory ): #Check for existence of the individual poll directory - One to store the current output - and if not there create it, this is done using the os.path function os.makedirs(start_conf_individual_directory) else: pass #show and save running conf of routing device net_connect.send_command('skip-page-display') output_save_conf = net_connect.send_command('show startup-config') file = open( start_conf_output_file, 'w' ) #Set variable file_run to create/Open new/exisitng file and allow it to be written to file.write( output_save_conf ) #Write output from running config from device into the file file.close() #Close file #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' popup = Popup( title='', content=Label( markup=True, text= "Successfully saved the '[b]Startup Configuration[/b]' of device with hostname '[b]" + hostname + "[/b]'"), size_hint=(0.8, 0.3)) popup.open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open()
class BasicConfReload(Screen): #Creates the function to execute the reload function def BasicConfReloadExecute(self): #Try statement to ensure that any errors connecting and configuring the device are handled gracefully and the user is informed of what the potential error was using popups try: #Try statement to ensure the IP address entered is valid. If it is an invalid address the ipaddress module will raise a value error, at which point the user is informed that a valid IP address is required using a popup try: device_ip_address = self.ids._Basic_Conf_Reload_Layout_.ids.IPv4AddressTextInput.text ipaddress.ip_address(device_ip_address) #ipaddress raises a value error when an invalid IP address is used except ValueError: Factory.InvalidIPAddressPopup().open() return #Exit from the function #If statement to ensure user has entered a username or password if App.get_running_app( ).device_username == '' or App.get_running_app( ).device_password == '': Factory.NoUserOrPassPopup().open() return #Exit from the function else: device_username = App.get_running_app().device_username device_password = App.get_running_app().device_password device = { 'device_type': 'cisco_ios', 'ip': device_ip_address, 'username': device_username, 'password': device_password, } net_connect = ConnectHandler(**device) output = net_connect.send_command_timing('reload') #If statements that check the output for various strings to ensure that the correct commands are sent if 'Proceed with reload' in output: #If this string is detected the tool will send a newline, which will start the reload output += net_connect.send_command_timing('\n') #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' #Creates and displays a popup to inform user that reload was successful popup = Popup( title='', content=Label( markup=True, text="Succesful reload of device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint=(0.5, 0.3)) popup.open() if 'System configuration has been modified' in output: #If this string is detected the tool will send the below commands to start the reload output += net_connect.send_command_timing('yes') output += net_connect.send_command_timing('\n') #print(output) #Set the password and username back to empty after completion of configuration App.get_running_app().device_username = '' App.get_running_app().device_password = '' #Creates and displays a popup to inform user that reload was successful popup = Popup( title='', content=Label( markup=True, text="Succesful reload of device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint=(0.5, 0.3)) popup.open() else: #If neither set of strings are detected the tool will display a failed configuration popup #Creates and displays a popup to inform user that reload has failed popup = Popup( title='', content=Label( markup=True, text="Failed to reload device with IP address '[b]" + device_ip_address + "[/b]'"), size_hint=(0.5, 0.3)) popup.open() #Except error to catch when Credentials are incorrect, informs the user of the error using a popup defined in the MainApplication.kv except AuthenticationException: Factory.NetmikoAuthenticateFailurePopup().open() #Except error to catch when Netmiko timeouts and is unable to connect to device, informs the user of the error using a popup defined in the MainApplication.kv except NetMikoTimeoutException: Factory.NetmikoTimeoutPopup().open() #Function to open the credential entry popup def OpenCredentialPopup(self): self.the_popup = DeviceUsernameAndPasswordPopup() self.the_popup.open()