def component_tests_config(): config_file = os.getenv("COMPONENT_TESTS_CONFIG") if config_file is None: raise Exception( "Need to provide path to config file in COMPONENT_TESTS_CONFIG") with open(config_file, 'r') as stream: config = yaml.safe_load(stream) LOGGER.info(f"component tests base config {config}") def _component_tests_config(additional_config={}, named_tunnel=True): # Regression test for TUN-4177, running with proxy-dns should not prevent tunnels from running additional_config["proxy-dns"] = True additional_config["proxy-dns-port"] = 9053 if named_tunnel: return NamedTunnelConfig(additional_config=additional_config, cloudflared_binary=config['cloudflared_binary'], tunnel=config['tunnel'], credentials_file=config['credentials_file'], ingress=config['ingress']) return ClassicTunnelConfig( additional_config=additional_config, cloudflared_binary=config['cloudflared_binary'], hostname=config['classic_hostname'], origincert=config['origincert']) return _component_tests_config
def render_GET(self, request): LOGGER.info('Rendering TimelineView %s' % request.path) request.setHeader('content-type', 'text/html') processes = [] # This array will hold all of the data for the timeline view. data = [['Timestamp']] # Add the list of processes to the timeline table. for row in self.db.get_process_cmdlines(name=self.process_name_filter): processes.append(row[0]) data[0].append(row[1].strip()) LOGGER.debug('got process data: %s' % data) # Now add the top-level PSS values for the processes to the table. for row in self.db.get_process_stats(name=self.process_name_filter): timestamp = row[0] if timestamp != data[-1][0]: # Moved onto a new snapshot data.append([0] * (len(processes) + 1)) data[-1][0] = timestamp # Add process for this snapshot pos = 1 + processes.index(row[2]) data[-1][pos] = int(row[4]) flattenString(None, TimelineElement('static/timeline.html', data)).addCallback(self.renderOutput) request.write(self.output) return ""
def create_tunnel(config, origincert_path, random_uuid): # Delete any previous existing credentials file. If the agent keeps files around (that's the case in Windows) then # cloudflared tunnel create will refuse to create the tunnel because it does not want to overwrite credentials # files. credentials_path = config["credentials_file"] try: os.remove(credentials_path) except OSError: pass tunnel_name = "cfd_component_test-" + random_uuid create_cmd = [ config["cloudflared_binary"], "tunnel", "--origincert", origincert_path, "create", "--credentials-file", credentials_path, tunnel_name ] LOGGER.info(f"Creating tunnel with {create_cmd}") subprocess.run(create_cmd, check=True) list_cmd = [ config["cloudflared_binary"], "tunnel", "--origincert", origincert_path, "list", "--name", tunnel_name, "--output", "json" ] LOGGER.info(f"Listing tunnel with {list_cmd}") cloudflared = subprocess.run(list_cmd, check=True, capture_output=True) return json.loads(cloudflared.stdout)[0]["id"]
def logout(self) -> HTMLResponse: """Login in to router admin""" LOGGER.info('LOGGING OUT...') response: HTMLResponse = self.get() assert response.html.search('You are {} logged out.'), ( f'Failed to logout. HTML: {response.html.html}') LOGGER.info('LOGGED OUT...') return response
def delete_tunnel(config): credentials_path = config["credentials_file"] delete_cmd = [ config["cloudflared_binary"], "tunnel", "--origincert", config["origincert"], "delete", "--credentials-file", credentials_path, "-f", config["tunnel"] ] LOGGER.info(f"Deleting tunnel with {delete_cmd}") subprocess.run(delete_cmd, check=True)
def list_devices(self): """List devices & statuses of the internal DHCP server for the LAN""" LOGGER.info('Getting list of devices on network.') header_row: Element = self.html.find(self.TABLE_HEADER, first=True) rows: List[Element] = self.html.find(self.TABLE_ROWS) table_header_map: dict = { str(i): x.text for i, x in enumerate(header_row.find('td')) } print(' '.join(table_header_map.values())) for row in rows: print(' '.join([e.text for e in row.find('td')]))
def main(args): import logging if args.verbose: LOGGER.setLevel(logging.DEBUG) else: LOGGER.setLevel(logging.INFO) db = Database(args.db) root = RootView(db, args.filter) root.putChild('static', static.File("./static")) site = server.Site(root) LOGGER.info("Listening on http://localhost:%d" % args.port) reactor.listenTCP(args.port, site) reactor.run()
def enable_wifi(self): """Disable WiFi""" LOGGER.info('DISABLING WIFI...') wireless_url = f'{self.url}/wlanRadio.asp' wireless_form = f'{self.url}/goform/wlanRadio' response: HTMLResponse = self.session.get(wireless_url) html = response.html current_params = get_page_selected_selects_as_dict(html=html) current_params.update({'WirelessEnable': '1'}) response: HTMLResponse = self.session.post( url=wireless_form, data=current_params ) next_page = response.html current_params = get_page_selected_selects_as_dict(html=next_page) assert current_params['WirelessEnable'] == '1'
def login(self) -> HTMLResponse: """Login in to router admin""" LOGGER.info('LOGGING IN...') response: HTMLResponse = self.post() rows: List[Element] = response.html.find(self.TABLE_ROWS) try: assert rows except AssertionError: error_element = response.html.find('font[style="color: red"]', first=True) if error_element.text == self.USER_OR_PASSWORD_ERROR: raise PermissionError(self.USER_OR_PASSWORD_ERROR) else: raise Exception( f"Table rows but none found. HTML: \n{response.html.html}") LOGGER.info('LOGGED IN...') return response
def component_tests_config(): config_file = os.getenv("COMPONENT_TESTS_CONFIG") if config_file is None: raise Exception( "Need to provide path to config file in COMPONENT_TESTS_CONFIG") with open(config_file, 'r') as stream: config = yaml.safe_load(stream) LOGGER.info(f"component tests base config {config}") def _component_tests_config(additional_config={}, cfd_mode=CfdModes.NAMED, run_proxy_dns=True): if run_proxy_dns: # Regression test for TUN-4177, running with proxy-dns should not prevent tunnels from running. # So we run all tests with it. additional_config["proxy-dns"] = True additional_config["proxy-dns-port"] = PROXY_DNS_PORT else: additional_config.pop("proxy-dns", None) additional_config.pop("proxy-dns-port", None) if cfd_mode is CfdModes.NAMED: return NamedTunnelConfig( additional_config=additional_config, cloudflared_binary=config['cloudflared_binary'], tunnel=config['tunnel'], credentials_file=config['credentials_file'], ingress=config['ingress']) elif cfd_mode is CfdModes.CLASSIC: return ClassicTunnelConfig( additional_config=additional_config, cloudflared_binary=config['cloudflared_binary'], hostname=config['classic_hostname'], origincert=config['origincert']) elif cfd_mode is CfdModes.PROXY_DNS: return ProxyDnsConfig( cloudflared_binary=config['cloudflared_binary']) else: raise Exception(f"Unknown cloudflared mode {cfd_mode}") return _component_tests_config
def main(args): import logging if args.verbose: LOGGER.setLevel(logging.DEBUG) else: LOGGER.setLevel(logging.INFO) # Get the database handle db = Database(args.db, args.overwrite) for i in range(args.count): if i > 0: time.sleep(args.period) # Read all the data we need system_stats, processes, memory_stats = read_stats(args) LOGGER.info('Found {} process(es) and {} used memory fragments'.format( len(processes), len(memory_stats))) LOGGER.info('Regions: %s' % memory_stats) db.add(args.host if len(args.host) else '[local]', system_stats, memory_stats, processes)
def create_bot(env: Env, session: aiohttp.ClientSession) -> Bot: """ Setup the Bot """ intents = Intents.default() intents.members = True bot = Rollo(("!", "?", "->"), intents=intents) async def on_ready(): LOGGER.info("Logged in as %s: %d", bot.user.name, bot.user.id) async def on_command_error(_, error): LOGGER.warning("Command error: %s", error) bot.add_listener(on_ready, "on_ready") bot.add_listener(on_command_error, "on_command_error") bot.add_cog(General(bot)) bot.add_cog(Meiern()) if env.str("TENOR_TOKEN", None) is not None: LOGGER.info("Tenor API Key found. Enabling GIF posting!") bot.add_cog(Memes(session, env.str("TENOR_TOKEN"))) return bot
def read_stats(args): # This is the command to grab all of the necessary info. # Note that -v is passed to tail - this is so we always the filename # given to us, which is needed for parsing. # As processes can be transient, we can get errors here about # non-existent files, so ignore them, this is expected. cmd = 'nice tail -v -n +1 '\ '/proc/%s/{cmdline,smaps} '\ '/proc/meminfo '\ '/proc/loadavg '\ '/proc/uptime '\ '/proc/vmstat '\ '2>/dev/null; ' \ 'nice find /proc/%s -type f -name stat '\ '-exec tail -v -n +1 {} \; 2>/dev/null | '\ 'awk \''\ '/==>/ {print} '\ '/^[0-9]/ {print \$2, \$10, \$12, \$14, \$15, \$22}\';' # Accept a space-separated list of pids as that is what pidof(8) returns and # it's quite likely you'll want to invoke this script with something like: # # --pid "`pidof foobar`" # # at some point. if args.pid.isdigit() or args.pid == '*': pids = args.pid else: pids = '{%s}' % args.pid.replace(' ', ',') # root can see all of /proc, another user is likely not going to be able # to read all of it. This isn't a hard error, but won't give a full view # of the system. if (args.host == '' and getpass.getuser() != "root") or\ (args.host != '' and args.user != 'root'): LOGGER.warning("If not running as root you may not see all info.") if args.host == '': LOGGER.info('Loading local procfs files') cmd = "bash -c \"%s\"" % (cmd % (pids, pids)) elif args.host != '': ssh = ( "ssh %s@%s" " -o UserKnownHostsFile=/dev/null" " -o StrictHostKeyChecking=no" " -o LogLevel=error" % (args.user, args.host) ) if args.password: ssh = "sshpass -p %s %s" % (args.password, ssh) else: ssh = "%s -o PasswordAuthentication=no" % ssh cmd = """%s "%s" """ % (ssh, cmd % (pids, pids)) LOGGER.info('Reading procfs with cmd: %s' % cmd) p = Popen(cmd, shell=True, bufsize=-1, stdout=PIPE, stderr=PIPE) stats = read_tailed_files(p.stdout) if p.poll() != 0: LOGGER.error("Command failed with: %r" % p.stderr.read().strip()) sys.exit(1) return stats
def getChild(self, name, request): LOGGER.info('Rendering child of TimelineView: %s' % name) if name == '': return self return resource.Resource.getChild(self, name, request)
def reboot(self): """Send command to reboot router""" LOGGER.info('Rebooting....') config_page = Configuration(base_url=self.url, session=self.session) config_page.reboot() LOGGER.info('Reboot command completed.')
def render_GET(self, request): LOGGER.info('Rendering SnapshotView %s' % request.path) self.numberRequests += 1 request.setHeader('content-type', 'text/html') if 'snapshot' in request.args: snapshot = int(request.args.get('snapshot', ['1'])[0]) elif 'snapshot_date' in request.args: snapshot = self.db.get_snapshot_id(request.args['snapshot_date'][0]) data = [ ['Process', 'Parent', 'Size (Kb)'], ['machine', None, 0], ] processes = [] fields = [ "heap", "stack", "ro_shared", "ro_shared_file", "ro_private", "ro_private_file", "rw_shared", "rw_shared_file", "rw_private", "rw_private_file", "rx_shared", "rx_shared_file", "rx_private", "rx_private_file", "rwx_shared", "rwx_shared_file", "rwx_private", "rwx_private_file", ] extra_data = [] units = 1024 * 1024 # Units in MB for row in self.db.get_process_info(snapshot_id=snapshot, name=self.process_name_filter): # Unfortunately we need to make every entry unique, so add # the pid into the description of the entries. pid = int(row[0]) process = '%s (%0.2fMb, frags:%d, pid:%d)' % \ (row[1].split('/')[-1], # process name float(row[2]) / units, # pss in MB int(row[3]), # number of memory fragments pid) data.append([str(process), 'machine', 0]) for i, field in enumerate(row[4:]): extra_data.append(['%s (%0.2fMb, pid:%d)' % \ (fields[i], float(field) / units, pid), process, int(field)]) data += extra_data flattenString( None, SnapshotElement('static/snapshot-tree.html', data, snapshot) ).addCallback(self.renderOutput) request.write(self.output) return ""
def reboot(self) -> HTMLResponse: """Send command to reboot router""" LOGGER.info('Rebooting....') response: HTMLResponse = self.post() LOGGER.info('Reboot command completed.') return response
async def on_ready(): LOGGER.info("Logged in as %s: %d", bot.user.name, bot.user.id)
html = response.html current_params = get_page_selected_selects_as_dict(html=html) current_params.update({'WirelessEnable': '1'}) response: HTMLResponse = self.session.post( url=wireless_form, data=current_params ) next_page = response.html current_params = get_page_selected_selects_as_dict(html=next_page) assert current_params['WirelessEnable'] == '1' def list_devices(self): """List devices & statuses of the internal DHCP server for the LAN""" dhcp = DHCP(base_url=self.url, session=self.session) dhcp.list_devices() if __name__ == '__main__': command_line_args = parse_args() with Router( user=ROUTER_USERNAME, password=ROUTER_PASSWORD, url=ROUTER_URL ) as r: if command_line_args.reboot_switch: LOGGER.info('REBOOTING.....') r.reboot() # r.disable_wifi() else: r.list_devices()