예제 #1
0
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
예제 #2
0
    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 ""
예제 #3
0
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"]
예제 #4
0
 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
예제 #5
0
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)
예제 #6
0
 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')]))
예제 #7
0
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()
예제 #8
0
 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'
예제 #9
0
 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
예제 #10
0
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
예제 #11
0
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)
예제 #12
0
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
예제 #13
0
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
예제 #14
0
 def getChild(self, name, request):
     LOGGER.info('Rendering child of TimelineView: %s' % name)
     if name == '':
         return self
     return resource.Resource.getChild(self, name, request)
예제 #15
0
 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.')
예제 #16
0
    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 ""
예제 #17
0
 def reboot(self) -> HTMLResponse:
     """Send command to reboot router"""
     LOGGER.info('Rebooting....')
     response: HTMLResponse = self.post()
     LOGGER.info('Reboot command completed.')
     return response
예제 #18
0
 async def on_ready():
     LOGGER.info("Logged in as %s: %d", bot.user.name, bot.user.id)
예제 #19
0
        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()