def modalSpecificInterfaceOnHost(x, y): """Show specific interface details from device. x = device id y = interface name """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) # Removes dashes from interface in URL, replacing '_' with '/' interface = interfaceReplaceSlash(y) # Replace's '=' with '.' host.interface = interface.replace('=', '.') intConfig, intMacAddr, intStats = host.pull_interface_info(activeSession) macToIP = '' logger.write_log('viewed interface %s on host %s' % (host.interface, host.hostname)) return render_template("/viewspecificinterfaceonhost.html", host=host, interface=interface, intConfig=intConfig, intMacAddr=intMacAddr, macToIP=macToIP, intStats=intStats)
def resultsMultipleHostDelete(x): """Display results from deleting multiple devices in local databse. x = each host id to be deleted, separated by an '&' symbol """ initialChecks() hostList = [] for x in x.split('&'): if x: host = datahandler.getHostByID(x) hostList.append(host) datahandler.deleteHostInDB(x) try: sshhandler.disconnectSpecificSSHSession(host) logger.write_log( 'disconnected any remaining active sessions for host %s' % (host.hostname)) except: logger.write_log( 'unable to attempt to disconnect host %s active sessions' % (host.hostname)) overallResult = True return render_template("results/resultsmultiplehostdeleted.html", overallResult=overallResult, hostList=hostList)
def logout(): """Disconnect all SSH sessions by user.""" sshhandler.disconnectAllSSHSessions() try: currentUser = session['USER'] deleteUserInRedis() logger.write_log('deleted user %s data stored in Redis' % (currentUser)) session.pop('USER', None) logger.write_log('deleted user %s as stored in session variable' % (currentUser), user=currentUser) u = session['UUID'] session.pop('UUID', None) logger.write_log( 'deleted UUID %s for user %s as stored in session variable' % (u, currentUser), user=currentUser) u = None except KeyError: logger.write_log('Exception thrown on logout.') return redirect(url_for('index')) logger.write_log('logged out') return redirect(url_for('index'))
def resultsAddHost(): """Confirm new host details prior to saving in local database.""" initialChecks() hostname = request.form['hostname'] ipv4_addr = request.form['ipv4_addr'] hosttype = request.form['hosttype'] ios_type = request.form['ios_type'] # If checkbox is unchecked, this fails as the request.form['local_creds'] value returned is False try: if request.form['local_creds']: local_creds = True except: local_creds = False response, hostid, e = datahandler.addHostToDB(hostname, ipv4_addr, hosttype, ios_type, local_creds) if response: return render_template("/results/resultsaddhost.html", title='Add host result', hostname=hostname, ipv4_addr=ipv4_addr, hosttype=hosttype, ios_type=ios_type, local_creds=local_creds, hostid=hostid) else: logger.write_log( 'exception thrown when adding new host to database: %s' % (e)) # TO-DO Add popup error message here return redirect(url_for('addHosts'))
def resultsMultiIntEdit(x, y): """Display results from editing multiple device interfaces. WIP. x = device id y = interfaces separated by '&' in front of each interface name """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) result = [] # Split by interfaces, separated by '&' for a in y.split('&'): if a: # Removes dashes from interface in URL a = interfaceReplaceSlash(a) result.append(host.save_config_on_device(activeSession)) logger.write_log('edited multiple interfaces on host %s' % (host.hostname)) return render_template("results/resultsmultipleintedit.html", host=host, interfaces=y, result=result)
def deviceUptime(x): """Get uptime of selected device. x = host id. """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) logger.write_log('retrieved uptime on host %s' % (host.hostname)) return jsonify(host.pull_device_uptime(activeSession))
def viewHosts(): """Display all devices.""" logger.write_log('viewed all hosts') hosts = datahandler.getHosts() # TODO this should happen not during the view render # status = ph.reachable(hosts) return render_template('/db/viewhosts.html', hosts=hosts, title='View hosts in database')
def devicePoeStatus(x): """Get PoE status of all interfaces on device. x = host id. """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) logger.write_log('retrieved PoE status for interfaces on host %s' % (host.hostname)) return json.dumps(host.pull_device_poe_status(activeSession))
def hostShellOutput(x, m, y): """Display iShell output fields. x = device id m = config or enable mode y = encoded commands from javascript """ initialChecks() configError = False host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) # Replace '___' with '/' x = unquote_plus(y).decode('utf-8') command = x.replace('___', '/') # command = interfaceReplaceSlash(unquote_plus(y).decode('utf-8')) # Append prompt and command executed to beginning of output # output.append(host.find_prompt_in_session(activeSession) + command) # Check if last character is a '?' if command[-1] == '?': if m == 'c': # Get command output as a list. # Insert list contents into 'output' list. configError = True output = '' else: # Run command on provided existing SSH session and returns output. # Since we set normalize to False, we need to do this. # The normalize() function in NetMiko does rstrip and adds a CR to the end of the command. output = activeSession.send_command(command.strip(), normalize=False).splitlines() else: if m == 'c': # Get configuration command output from network device, split output by newline output = activeSession.send_config_set( command, exit_config_mode=False).splitlines() # Remove first item in list, as Netmiko returns the command ran only in the output output.pop(0) else: output = host.get_cmd_output(command, activeSession) logger.write_log('ran command on host %s - %s' % (host.hostname, command)) return render_template("hostshelloutput.html", output=output, command=command, mode=m, configError=configError)
def modalCmdSaveConfig(x): """Save device configuration to memory and display result in modal. x = device id """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) host.save_config_on_device(activeSession) logger.write_log('saved config via button on host %s' % (host.hostname)) return render_template("/cmdsaveconfig.html", host=host)
def modalCmdShowCDPNeigh(x): """Display modal with CDP/LLDP neighbors info for device. x = device id """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) neigh = host.pull_cdp_neighbor(activeSession) logger.write_log('viewed CDP neighbors via button on host %s' % (host.hostname)) return render_template("/cmdshowcdpneigh.html", host=host, neigh=neigh)
def enterConfigMode(x): """Enter device configuration mode. x = device id """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) # Enter configuration mode on device using existing SSH session activeSession.config_mode() logger.write_log('entered config mode via iShell on host %s' % (host.hostname)) return ('', 204)
def hostShell(x): """Display iShell input fields. x = device id """ initialChecks() host = datahandler.getHostByID(x) # Exit config mode if currently in it on page refresh/load exitConfigMode(host.id) logger.write_log('accessed interactive shell on host %s' % (host.hostname)) return render_template("hostshell.html", host=host)
def modalCmdShowVersion(x): """Display modal with device version information. x = device id """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) result = host.pull_version(activeSession) logger.write_log('viewed version info via button on host %s' % (host.hostname)) return render_template("/cmdshowversion.html", host=host, result=result)
def callDisconnectSpecificSSHSession(x): """Disconnect any SSH sessions for a specific host from all users. x = ID of host to disconnect. """ host = datahandler.getHostByID(x) # Disconnect device. try: sshhandler.disconnectSpecificSSHSession(host) except: # Log error if unable to disconnect specific SSH session logger.write_log( 'unable to disconnect SSH session to provided host %s from user %s' % (host.hostname, session['USER'])) return redirect(url_for('viewHosts'))
def modalCmdShowStartConfig(x): """Display modal with saved/stored configuration settings on device. x = device id """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) hostConfig = host.pull_start_config(activeSession) logger.write_log('viewed startup-config via button on host %s' % (host.hostname)) return render_template("/cmdshowstartconfig.html", host=host, hostConfig=hostConfig)
def modalLocalCredentials(x): """Get local credentials from user. x is host ID """ initialChecks() host = datahandler.getHostByID(x) if sshhandler.checkHostActiveSSHSession(host): return redirect('/db/viewhosts/%s' % (host.id)) form = LocalCredentialsForm() logger.write_log('saved local credentials for host %s' % (host.hostname)) return render_template('localcredentials.html', title='Login with local SSH credentials', form=form, host=host)
def index(): """Return index page for user. Requires user to be logged in to display index page. Else attempts to retrieve user credentials from login form. If successful, stores them in server-side Redis server, with timer set to automatically clear information after a set time, or clear when user logs out. Else, redirect user to login form. """ if 'USER' in session: return redirect(url_for('viewHosts')) else: try: if storeUserInRedis(request.form['user'], request.form['pw']): logger.write_log('logged in') return redirect(url_for('viewHosts')) else: return render_template("index.html", title='Home') except: return render_template("index.html", title='Home')
def resultsIntDisabled(x, y): """Display results for disabling specific interface. x = device id y = interface name """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) # Removes dashes from interface in URL and disable interface result = host.run_disable_interface_cmd(interfaceReplaceSlash(y), activeSession) logger.write_log('disabled interface %s on host %s' % (y, host.hostname)) return render_template("results/resultsinterfacedisabled.html", host=host, interface=y, result=result)
def resultsCmdCustom(): """Display results from bulk command execution on device.""" initialChecks() host = datahandler.getHostByID(session['HOSTID']) activeSession = sshhandler.retrieveSSHSession(host) command = session['COMMAND'] result = host.run_multiple_commands(command, activeSession) session.pop('HOSTNAME', None) session.pop('COMMAND', None) session.pop('HOSTID', None) logger.write_log('ran custom commands on host %s' % (host.hostname)) return render_template("results/resultscmdcustom.html", host=host, command=command, result=result)
def resultsIntEdit(x, datavlan, voicevlan, other): """Display results for editing specific interface config settings. x = device id d = data vlan v = voice vlan o = other """ initialChecks() host = datahandler.getHostByID(x) activeSession = sshhandler.retrieveSSHSession(host) # Get interface from passed variable in URL hostinterface = request.args.get('int', '') # Decode 'other' string other = unquote_plus(other).decode('utf-8') # Replace '___' with '/' other = other.replace('___', '/') # Replace '\r\n' with '\n' other = other.replace('\r\n', '\n') # Remove dashes from interface in URL and edit interface config result = host.run_edit_interface_cmd(hostinterface, datavlan, voicevlan, other, activeSession) logger.write_log('edited interface %s on host %s' % (hostinterface, host.hostname)) return render_template("results/resultsinterfaceedit.html", host=host, interface=hostinterface, datavlan=datavlan, voicevlan=voicevlan, other=other, result=result)
def viewSpecificHost(x): """Display specific device page. x is host.id """ initialChecks() # This fixes page refresh issue when clicking on a Modal # that breaks DataTables if 'modal' in x: # Return empty response, as the page is loaded from the Modal JS # However this breaks the Loading modal JS function. # Unsure why, need to research return ('', 204) host = datahandler.getHostByID(x) logger.write_log('accessed host %s using IPv4 address %s' % (host.hostname, host.ipv4_addr)) # Try statement as if this page was accessed directly and not via the Local Credentials form it will fail and we want to operate normally # Variable to determine if successfully connected o host use local credentials varFormSet = False try: if storeUserInRedis(request.form['user'], request.form['pw'], privpw=request.form['privpw'], host=host): # Set to True if variables are set correctly from local credentials form varFormSet = True logger.write_log( 'local credentials saved to REDIS for accessing host %s' % (host.hostname)) except: # If no form submitted (not using local credentials), get SSH session # Don't go in if form was used (local credentials) but SSH session failed in above 'try' statement if not varFormSet: logger.write_log( 'credentials used of currently logged in user for accessing host %s' % (host.hostname)) # Get any existing SSH sessions activeSession = sshhandler.retrieveSSHSession(host) result = host.pull_host_interfaces(activeSession) if result: interfaces = host.count_interface_status(result) return render_template("/db/viewspecifichost.html", host=host, interfaces=interfaces, result=result) else: # If interfaces is x.x.x.x skipped - connection timeout, # throw error page redirect sshhandler.disconnectSpecificSSHSession(host) return redirect(url_for('noHostConnectError', host=host))
def login(): """Login page for user to save credentials.""" form = LoginForm() if request.method == 'POST': # If page is accessed via form POST submission if form.validate_on_submit(): # Validate form if 'USER' in session: # If user already stored in session variable, return home page return redirect(url_for('viewHosts')) else: # Try to save user credentials in Redis. Return index if fails try: if storeUserInRedis(request.form['user'], request.form['pw']): logger.write_log('logged in') return redirect(url_for('viewHosts')) except: logger.write_log( 'failed to store user data in Redis when logging in') # Return login page if accessed via GET request return render_template('auth/login.html', title='Login with SSH credentials', form=form)
def resultsHostEdit(x): """Confirm settings to edit host with in local database. x = original host ID """ if 'modal' in x: return ('', 204) storedHost = datahandler.getHostByID(x) # Save all existing host variables, as the class stores get updated later in the function origHostname = storedHost.hostname origIpv4_addr = storedHost.ipv4_addr origHosttype = storedHost.type origIos_type = storedHost.ios_type origLocal_creds = storedHost.local_creds # Save form user inputs into new variables hostname = request.form['hostname'] ipv4_addr = request.form['ipv4_addr'] hosttype = request.form['hosttype'] ios_type = request.form['ios_type'] if request.form['local_creds'] == 'True': local_creds = True local_creds_updated = True elif request.form['local_creds'] == 'False': local_creds = False local_creds_updated = True else: local_creds = '' local_creds_updated = False # If exists, disconnect any existing SSH sessions # and clear them from the SSH dict try: sshhandler.disconnectSpecificSSHSession(storedHost) logger.write_log( 'disconnected and cleared saved SSH session information for edited host %s' % (storedHost.hostname)) except (socket.error, EOFError): logger.write_log('no existing SSH sessions for edited host %s' % (storedHost.hostname)) except: logger.write_log('could not clear SSH session for edited host %s' % (storedHost.hostname)) result = datahandler.editHostInDatabase(storedHost.id, hostname, ipv4_addr, hosttype, ios_type, local_creds, local_creds_updated) if result: logger.write_log('edited host %s in database' % (storedHost.hostname)) return render_template("results/resultshostedit.html", title='Edit host confirm', storedHost=storedHost, hostname=hostname, ipv4_addr=ipv4_addr, hosttype=hosttype, ios_type=ios_type, local_creds=local_creds, local_creds_updated=local_creds_updated, origHostname=origHostname, origIpv4_addr=origIpv4_addr, origHosttype=origHosttype, origIos_type=origIos_type, origLocal_creds=origLocal_creds) else: return redirect(url_for('confirmHostEdit', x=storedHost))
def disconnectAllSSH(): """Disconnect all SSH sessions for all users.""" sshhandler.disconnectAllSSHSessions() logger.write_log('disconnected all active SSH sessions') return redirect(url_for('index'))