Example #1
0
def test_parse_config_file_valid(mocker):
    # Patch config file read
    mocker.patch('os.path.exists', return_value=True)
    mocker.patch(builtin('open'), lambda *_: io.StringIO(CONFIG_FILE_VALID))

    parsed_config = settings.parse_config_file('/configdir/config_rel.yaml')

    assert len(parsed_config['services']) == 1
    assert len(parsed_config['services'][0]['instances']) == 2

    # Test key with absolute path
    assert os.path.dirname(parsed_config['services'][0]['key']) == '/configdir'

    # Test key with absolute path
    mocker.patch(builtin('open'), lambda *_: io.StringIO(CONFIG_FILE_ABSOLUTE))
    parsed_config = settings.parse_config_file('/configdir/config_abs.yaml')
    assert os.path.dirname(parsed_config['services'][0]['key']) == '/absdir'
Example #2
0
def test_parse_config_file_valid(mocker):
    # Patch config file read
    mocker.patch('os.path.exists', return_value=True)
    mocker.patch(builtin('open'),
                 lambda *_: io.StringIO(CONFIG_FILE_VALID))

    parsed_config = settings.parse_config_file('/configdir/config_rel.yaml')

    assert len(parsed_config['services']) == 1
    assert len(parsed_config['services'][0]['instances']) == 2

    # Test key with absolute path
    assert os.path.dirname(parsed_config['services'][0]['key']) == '/configdir'

    # Test key with absolute path
    mocker.patch(builtin('open'),
                 lambda *_: io.StringIO(CONFIG_FILE_ABSOLUTE))
    parsed_config = settings.parse_config_file('/configdir/config_abs.yaml')
    assert os.path.dirname(parsed_config['services'][0]['key']) == '/absdir'
Example #3
0
def main():
    """
    Entry point when invoked over the command line.
    """
    args = parse_cmd_args().parse_args()
    config_file_options = settings.parse_config_file(args.config)

    # Update global configuration with options specified in the config file
    for setting in dir(config):
        if setting.isupper() and config_file_options.get(setting):
            setattr(config, setting, config_file_options.get(setting))

    # Override the log level if specified on the command line.
    if args.verbosity:
        config.LOG_LEVEL = args.verbosity.upper()

    # Write log file if configured in environment variable or config file
    if config.LOG_LOCATION:
        log.setup_file_logger(config.LOG_LOCATION)

    logger.setLevel(logging.__dict__[config.LOG_LEVEL.upper()])

    # Create a connection to the Tor control port
    try:
        controller = Controller.from_port(address=args.ip, port=args.port)
    except stem.SocketError as exc:
        logger.error("Unable to connect to Tor control port: %s", exc)
        sys.exit(1)
    else:
        logger.debug("Successfully connected to the Tor control port.")

    try:
        controller.authenticate()
    except stem.connection.AuthenticationFailure as exc:
        logger.error("Unable to authenticate to Tor control port: %s", exc)
        sys.exit(1)
    else:
        logger.debug("Successfully authenticated to the Tor control port.")

    # Disable no-member due to bug with "Instance of 'Enum' has no * member"
    # pylint: disable=no-member

    # Check that the Tor client supports the HSPOST control port command
    if not controller.get_version() >= stem.version.Requirement.HSPOST:
        logger.error(
            "A Tor version >= %s is required. You may need to "
            "compile Tor from source or install a package from "
            "the experimental Tor repository.",
            stem.version.Requirement.HSPOST)
        sys.exit(1)

    # Load the keys and config for each onion service
    settings.initialize_services(controller,
                                 config_file_options.get('services'))

    # Finished parsing all the config file.

    handler = eventhandler.EventHandler()
    controller.add_event_listener(handler.new_desc, EventType.HS_DESC)
    controller.add_event_listener(handler.new_desc_content,
                                  EventType.HS_DESC_CONTENT)

    # Schedule descriptor fetch and upload events
    schedule.every(config.REFRESH_INTERVAL).seconds.do(
        onionbalance.instance.fetch_instance_descriptors, controller)
    schedule.every(config.PUBLISH_CHECK_INTERVAL).seconds.do(
        onionbalance.service.publish_all_descriptors)

    try:
        # Run initial fetch of HS instance descriptors
        schedule.run_all(delay_seconds=30)

        # Begin main loop to poll for HS descriptors
        while True:
            schedule.run_pending()
            time.sleep(1)
    except KeyboardInterrupt:
        logger.info("Keyboard interrupt received. Stopping the "
                    "management server.")
    return 0
Example #4
0
def main():
    """
    Entry point when invoked over the command line.
    """
    args = parse_cmd_args().parse_args()
    config_file_options = settings.parse_config_file(args.config)

    # Update global configuration with options specified in the config file
    for setting in dir(config):
        if setting.isupper() and config_file_options.get(setting):
            setattr(config, setting, config_file_options.get(setting))

    # Override the log level if specified on the command line.
    if args.verbosity:
        config.LOG_LEVEL = args.verbosity.upper()

    # Write log file if configured in environment variable or config file
    if config.LOG_LOCATION:
        log.setup_file_logger(config.LOG_LOCATION)

    logger.setLevel(logging.__dict__[config.LOG_LEVEL.upper()])

    # Create a connection to the Tor control port
    try:
        controller = Controller.from_port(address=args.ip, port=args.port)
    except stem.SocketError as exc:
        logger.error("Unable to connect to Tor control port: %s", exc)
        sys.exit(1)
    else:
        logger.debug("Successfully connected to the Tor control port.")

    try:
        controller.authenticate()
    except stem.connection.AuthenticationFailure as exc:
        logger.error("Unable to authenticate to Tor control port: %s", exc)
        sys.exit(1)
    else:
        logger.debug("Successfully authenticated to the Tor control port.")

    # Disable no-member due to bug with "Instance of 'Enum' has no * member"
    # pylint: disable=no-member

    # Check that the Tor client supports the HSPOST control port command
    if not controller.get_version() >= stem.version.Requirement.HSPOST:
        logger.error("A Tor version >= %s is required. You may need to "
                     "compile Tor from source or install a package from "
                     "the experimental Tor repository.",
                     stem.version.Requirement.HSPOST)
        sys.exit(1)

    # Load the keys and config for each onion service
    settings.initialize_services(controller,
                                 config_file_options.get('services'))

    # Finished parsing all the config file.

    handler = eventhandler.EventHandler()
    controller.add_event_listener(handler.new_desc,
                                  EventType.HS_DESC)
    controller.add_event_listener(handler.new_desc_content,
                                  EventType.HS_DESC_CONTENT)

    # Schedule descriptor fetch and upload events
    schedule.every(config.REFRESH_INTERVAL).seconds.do(
        onionbalance.instance.fetch_instance_descriptors, controller)
    schedule.every(config.PUBLISH_CHECK_INTERVAL).seconds.do(
        onionbalance.service.publish_all_descriptors)

    try:
        # Run initial fetch of HS instance descriptors
        schedule.run_all(delay_seconds=30)

        # Begin main loop to poll for HS descriptors
        while True:
            schedule.run_pending()
            time.sleep(1)
    except KeyboardInterrupt:
        logger.info("Keyboard interrupt received. Stopping the "
                    "management server.")
    return 0
Example #5
0
def test_parse_config_file_does_not_exist(mocker):
    with pytest.raises(SystemExit):
        settings.parse_config_file('doesnotexist/config.yaml')
Example #6
0
def main():
    """
    Entry point when invoked over the command line.
    """
    setproctitle('onionbalance')
    args = parse_cmd_args().parse_args()
    config_file_options = settings.parse_config_file(args.config)

    # Update global configuration with options specified in the config file
    for setting in dir(config):
        if setting.isupper() and config_file_options.get(setting):
            setattr(config, setting, config_file_options.get(setting))

    # Override the log level if specified on the command line.
    if args.verbosity:
        config.LOG_LEVEL = args.verbosity.upper()

    # Write log file if configured in environment variable or config file
    if config.LOG_LOCATION:
        log.setup_file_logger(config.LOG_LOCATION)

    logger.setLevel(logging.__dict__[config.LOG_LEVEL.upper()])

    # Create a connection to the Tor unix domain control socket or control port
    try:
        tor_socket = (args.socket or config.TOR_CONTROL_SOCKET)
        tor_address = (args.ip or config.TOR_ADDRESS)
        tor_port = (args.port or config.TOR_PORT)
        try:
            controller = Controller.from_socket_file(path=tor_socket)
            logger.debug(
                "Successfully connected to the Tor control socket "
                "%s.", tor_socket)
        except stem.SocketError:
            logger.debug("Unable to connect to the Tor control socket %s.",
                         tor_socket)
            controller = Controller.from_port(address=tor_address,
                                              port=tor_port)
            logger.debug("Successfully connected to the Tor control port.")
    except stem.SocketError as exc:
        logger.error("Unable to connect to Tor control socket or port: %s",
                     exc)
        sys.exit(1)

    try:
        controller.authenticate(password=config.TOR_CONTROL_PASSWORD)
    except stem.connection.AuthenticationFailure as exc:
        logger.error(
            "Unable to authenticate on the Tor control connection: "
            "%s", exc)
        sys.exit(1)
    else:
        logger.debug("Successfully authenticated on the Tor control "
                     "connection.")

    status_socket = status.StatusSocket(config.STATUS_SOCKET_LOCATION)
    eventhandler.SignalHandler(controller, status_socket)

    # Disable no-member due to bug with "Instance of 'Enum' has no * member"
    # pylint: disable=no-member

    # Check that the Tor client supports the HSPOST control port command
    if not controller.get_version() >= stem.version.Requirement.HSPOST:
        logger.error(
            "A Tor version >= %s is required. You may need to "
            "compile Tor from source or install a package from "
            "the experimental Tor repository.",
            stem.version.Requirement.HSPOST)
        sys.exit(1)

    # Load the keys and config for each onion service
    settings.initialize_services(controller,
                                 config_file_options.get('services'))

    # Finished parsing all the config file.

    handler = eventhandler.EventHandler()
    controller.add_event_listener(handler.new_status, EventType.STATUS_GENERAL)
    controller.add_event_listener(handler.new_desc, EventType.HS_DESC)
    controller.add_event_listener(handler.new_desc_content,
                                  EventType.HS_DESC_CONTENT)

    # Schedule descriptor fetch and upload events
    scheduler.add_job(config.REFRESH_INTERVAL, fetch_instance_descriptors,
                      controller)
    scheduler.add_job(config.PUBLISH_CHECK_INTERVAL, publish_all_descriptors)

    # Run initial fetch of HS instance descriptors
    scheduler.run_all(delay_seconds=config.INITIAL_DELAY)

    # Begin main loop to poll for HS descriptors
    scheduler.run_forever()

    return 0
Example #7
0
def test_parse_config_file_does_not_exist(mocker):
    with pytest.raises(SystemExit):
        settings.parse_config_file('doesnotexist/config.yaml')
Example #8
0
def main():
    """
    Entry point when invoked over the command line.
    """
    setproctitle('onionbalance')
    args = parse_cmd_args().parse_args()
    config_file_options = settings.parse_config_file(args.config)

    # Update global configuration with options specified in the config file
    for setting in dir(config):
        if setting.isupper() and config_file_options.get(setting):
            setattr(config, setting, config_file_options.get(setting))

    # Override the log level if specified on the command line.
    if args.verbosity:
        config.LOG_LEVEL = args.verbosity.upper()

    # Write log file if configured in environment variable or config file
    if config.LOG_LOCATION:
        log.setup_file_logger(config.LOG_LOCATION)

    logger.setLevel(logging.__dict__[config.LOG_LEVEL.upper()])

    # Create a connection to the Tor unix domain control socket or control port
    try:
        tor_socket = (args.socket or config.TOR_CONTROL_SOCKET)
        tor_address = (args.ip or config.TOR_ADDRESS)
        tor_port = (args.port or config.TOR_PORT)
        try:
            controller = Controller.from_socket_file(path=tor_socket)
            logger.debug("Successfully connected to the Tor control socket "
                         "%s.", tor_socket)
        except stem.SocketError:
            logger.debug("Unable to connect to the Tor control socket %s.",
                         tor_socket)
            controller = Controller.from_port(address=tor_address,
                                              port=tor_port)
            logger.debug("Successfully connected to the Tor control port.")
    except stem.SocketError as exc:
        logger.error("Unable to connect to Tor control socket or port: %s",
                     exc)
        sys.exit(1)

    try:
        controller.authenticate(password=config.TOR_CONTROL_PASSWORD)
    except stem.connection.AuthenticationFailure as exc:
        logger.error("Unable to authenticate on the Tor control connection: "
                     "%s", exc)
        sys.exit(1)
    else:
        logger.debug("Successfully authenticated on the Tor control "
                     "connection.")

    status_socket = status.StatusSocket(config.STATUS_SOCKET_LOCATION)
    eventhandler.SignalHandler(controller, status_socket)

    # Disable no-member due to bug with "Instance of 'Enum' has no * member"
    # pylint: disable=no-member

    # Check that the Tor client supports the HSPOST control port command
    if not controller.get_version() >= stem.version.Requirement.HSPOST:
        logger.error("A Tor version >= %s is required. You may need to "
                     "compile Tor from source or install a package from "
                     "the experimental Tor repository.",
                     stem.version.Requirement.HSPOST)
        sys.exit(1)

    # Load the keys and config for each onion service
    settings.initialize_services(controller,
                                 config_file_options.get('services'))

    # Finished parsing all the config file.

    handler = eventhandler.EventHandler()
    controller.add_event_listener(handler.new_status,
                                  EventType.STATUS_GENERAL)
    controller.add_event_listener(handler.new_desc,
                                  EventType.HS_DESC)
    controller.add_event_listener(handler.new_desc_content,
                                  EventType.HS_DESC_CONTENT)

    # Schedule descriptor fetch and upload events
    scheduler.add_job(config.REFRESH_INTERVAL, fetch_instance_descriptors,
                      controller)
    scheduler.add_job(config.PUBLISH_CHECK_INTERVAL, publish_all_descriptors)

    # Run initial fetch of HS instance descriptors
    scheduler.run_all(delay_seconds=config.INITIAL_DELAY)

    # Begin main loop to poll for HS descriptors
    scheduler.run_forever()

    return 0