예제 #1
0
def test_build_conf_with_conf_file(conf_file_conf):
    default_conf_copy = deepcopy(DEFAULT_CONF)

    conf_loader = ConfigLoader(data_dir, conf_file_name, default_conf_copy, {})
    config = conf_loader.build_config()

    for k, v in config.items():
        # Check that we have only loaded parameters that were already in the default conf. Additional params are not
        # loaded
        assert k in DEFAULT_CONF
        assert isinstance(v, DEFAULT_CONF[k].get("type"))

        # If a value is in the conf file, it will overwrite the one in the default conf
        if k in conf_file_conf:
            comp_v = conf_file_conf[k]

            # Check that we have kept track of what's overwritten
            assert k in conf_loader.overwritten_fields

        else:
            comp_v = DEFAULT_CONF[k].get("value")

        if DEFAULT_CONF[k].get("path"):
            assert v == data_dir + comp_v
        else:
            assert v == comp_v
예제 #2
0
def test_build_conf_with_command_line():
    foo_data_dir = "foo/"
    default_conf_copy = deepcopy(DEFAULT_CONF)

    conf_loader = ConfigLoader(foo_data_dir, conf_file_name, default_conf_copy,
                               cmd_data)
    config = conf_loader.build_config()

    assert foo_data_dir == config.pop("DATA_DIR")

    for k, v in config.items():
        # Check that we have only loaded parameters that were already in the default conf. Additional params are not
        # loaded
        assert k in DEFAULT_CONF
        assert isinstance(v, DEFAULT_CONF[k].get("type"))

        # If a value is in the command line conf, it will overwrite the one in the default conf
        if k in COMMAND_LINE_CONF:
            comp_v = cmd_data[k]

            # Check that we have kept track of what's overwritten
            assert k in conf_loader.overwritten_fields

        else:
            comp_v = DEFAULT_CONF[k].get("value")

        if DEFAULT_CONF[k].get("path"):
            assert v == foo_data_dir + comp_v
        else:
            assert v == comp_v
예제 #3
0
def get_config(command_line_conf, data_dir):
    """
    Combines the command line config with the config loaded from the file and the default config in order to construct
    the final config object.

    Args:
        command_line_conf (:obj:`dict`): a collection of the command line parameters.

    Returns:
        :obj:`dict`: A dictionary containing all the system's configuration parameters.

    Raises:
        UnknownConfigParam: if an unknown configuration parameter is found in the configuration file.
    """

    config_loader = ConfigLoader(data_dir, CONF_FILE_NAME, DEFAULT_CONF,
                                 command_line_conf)
    config = config_loader.build_config()

    # Set default RPC port if not overwritten by the user.
    if "BTC_RPC_PORT" not in config_loader.overwritten_fields:
        config["BTC_RPC_PORT"] = get_default_rpc_port(
            config.get("BTC_NETWORK"))

    return config
예제 #4
0
def test_build_conf_with_all(conf_file_conf):
    default_conf_copy = deepcopy(DEFAULT_CONF)

    conf_loader = ConfigLoader(data_dir, conf_file_name, default_conf_copy,
                               cmd_data)
    config = conf_loader.build_config()

    assert data_dir == config.pop("DATA_DIR")

    for k, v in config.items():
        # Check that we have only loaded parameters that were already in the default conf. Additional params are not
        # loaded
        assert k in DEFAULT_CONF
        assert isinstance(v, DEFAULT_CONF[k].get("type"))

        # The priority is: cmd, conf file, default
        if k in cmd_data:
            comp_v = cmd_data[k]
        elif k in conf_file_conf:
            comp_v = conf_file_conf[k]
        else:
            comp_v = DEFAULT_CONF[k].get("value")

        if DEFAULT_CONF[k].get("path"):
            assert v == data_dir + comp_v
        else:
            assert v == comp_v

        if k in cmd_data or k in conf_file_conf:
            # Check that we have kept track of what's overwritten
            assert k in conf_loader.overwritten_fields
예제 #5
0
    def __init__(self, data_dir, command_line_conf):
        # Loads config and sets up the data folder and log file
        config_loader = ConfigLoader(data_dir, CONF_FILE_NAME, DEFAULT_CONF,
                                     command_line_conf)
        config = config_loader.build_config()

        setup_data_folder(data_dir)

        teos_rpc_host = config.get("RPC_BIND")
        teos_rpc_port = config.get("RPC_PORT")

        self.rpc_client = RPCClient(teos_rpc_host, teos_rpc_port)
예제 #6
0
def test_create_config_dict():
    # create_config_dict should create a dictionary with the config fields in ConfigLoader.config_fields as long as
    # the type of the field "value" matches the type in "type". The conf source does not matter here.
    foo_data_dir = "foo/"
    default_conf_copy = deepcopy(DEFAULT_CONF)
    conf_loader = ConfigLoader(foo_data_dir, conf_file_name, default_conf_copy,
                               {})
    config = conf_loader.create_config_dict()

    assert isinstance(config, dict)
    for k, v in config.items():
        assert k in config
        assert isinstance(v, default_conf_copy[k].get("type"))
예제 #7
0
def test_create_config_dict_invalid_type():
    # If any type does not match the expected one, we should get a ValueError
    foo_data_dir = "foo/"
    default_conf_copy = deepcopy(DEFAULT_CONF)

    # Modify a field so the type does not match
    default_conf_copy["FOO_STR_2"]["value"] = 1234

    conf_loader = ConfigLoader(foo_data_dir, conf_file_name, default_conf_copy,
                               {})

    with pytest.raises(ValueError):
        conf_loader.create_config_dict()
예제 #8
0
def test_build_conf_only_default():
    foo_data_dir = "foo/"
    default_conf_copy = deepcopy(DEFAULT_CONF)

    conf_loader = ConfigLoader(foo_data_dir, conf_file_name, default_conf_copy,
                               {})
    config = conf_loader.build_config()

    for k, v in config.items():
        assert k in DEFAULT_CONF
        assert isinstance(v, DEFAULT_CONF[k].get("type"))

        if DEFAULT_CONF[k].get("path"):
            assert v == foo_data_dir + DEFAULT_CONF[k].get("value")
        else:
            assert v == DEFAULT_CONF[k].get("value")
예제 #9
0
def test_init():
    conf_loader = ConfigLoader(data_dir, conf_file_name, DEFAULT_CONF,
                               COMMAND_LINE_CONF)
    assert conf_loader.data_dir == data_dir
    assert conf_loader.conf_file_path == data_dir + conf_file_name
    assert conf_loader.conf_fields == DEFAULT_CONF
    assert conf_loader.command_line_conf == COMMAND_LINE_CONF
예제 #10
0
def test_extend_paths():
    # Test that only items with the path flag are extended
    foo_data_dir = "foo/"
    default_conf_copy = deepcopy(DEFAULT_CONF)

    conf_loader = ConfigLoader(foo_data_dir, conf_file_name, default_conf_copy,
                               {})
    conf_loader.extend_paths()

    for k, field in conf_loader.conf_fields.items():
        if isinstance(field.get("value"), str):
            if field.get("path") is True:
                assert conf_loader.data_dir in field.get("value")
            else:
                assert conf_loader.data_dir not in field.get("value")

    # Check that absolute paths are not extended
    absolute_path = "/foo/var"
    conf_loader.conf_fields["ABSOLUTE_PATH"] = {
        "value": absolute_path,
        "type": str,
        "path": True
    }
    conf_loader.extend_paths()

    assert conf_loader.conf_fields["ABSOLUTE_PATH"]["value"] == absolute_path
예제 #11
0
def test_unknown_params():
    # Test that the configuration dict won't be built if unknown data if found in the config file
    aux_conf = deepcopy(CONF_FILE_CONF)
    aux_conf["ADDITIONAL_FOO"] = {"value": "additional_var", "type": str}
    aux_conf_file_data = {k: v["value"] for k, v in aux_conf.items()}
    aux_conf_file_name = f"aux_{conf_file_name}"

    # Save config file to disk (we don't need to delete it, the fixture cleanup will)
    config_parser = ConfigParser()
    config_parser["foo_section"] = aux_conf_file_data
    with open(data_dir + aux_conf_file_name, "w") as fout:
        config_parser.write(fout)

    with pytest.raises(UnknownConfigParam):
        default_conf_copy = deepcopy(DEFAULT_CONF)

        conf_loader = ConfigLoader(data_dir, aux_conf_file_name,
                                   default_conf_copy, {})
        conf_loader.build_config()
예제 #12
0
def init(options, configuration, plugin):
    """Initializes the plugin"""

    try:
        user_sk, user_id = generate_keys(DATA_DIR)
        plugin.log(f"Generating a new key pair for the watchtower client. Keys stored at {DATA_DIR}")

    except FileExistsError:
        plugin.log("A key file for the watchtower client already exists. Loading it")
        user_sk, user_id = load_keys(DATA_DIR)

    plugin.log(f"Plugin watchtower client initialized. User id = {user_id}")
    config_loader = ConfigLoader(DATA_DIR, CONF_FILE_NAME, DEFAULT_CONF, {})

    try:
        plugin.wt_client = WTClient(user_sk, user_id, config_loader.build_config())
    except plyvel.IOError:
        error = "Cannot load towers db. Resource temporarily unavailable"
        plugin.log("Cannot load towers db. Resource temporarily unavailable")
        raise IOError(error)
예제 #13
0
def test_build_conf_only_default():
    foo_data_dir = "foo/"
    default_conf_copy = deepcopy(DEFAULT_CONF)

    conf_loader = ConfigLoader(foo_data_dir, conf_file_name, default_conf_copy,
                               {})
    config = conf_loader.build_config()

    assert foo_data_dir == config.pop("DATA_DIR")

    for k, v in config.items():
        assert k in DEFAULT_CONF
        assert isinstance(v, DEFAULT_CONF[k].get("type"))

        if DEFAULT_CONF[k].get("path"):
            assert v == foo_data_dir + DEFAULT_CONF[k].get("value")
        else:
            assert v == DEFAULT_CONF[k].get("value")

    # No field should have been overwritten
    assert not conf_loader.overwritten_fields
예제 #14
0
def run():
    command_line_conf = {}
    commands = [
        "register", "add_appointment", "get_appointment",
        "get_subscription_info", "help"
    ]

    try:
        opts, args = getopt(argv[1:], "h", ["apiconnect=", "apiport=", "help"])

        for opt, arg in opts:
            if opt in ["--apiconnect"]:
                if arg:
                    command_line_conf["API_CONNECT"] = arg

            if opt in ["--apiport"]:
                if arg:
                    try:
                        command_line_conf["API_PORT"] = int(arg)
                    except ValueError:
                        sys.exit("port must be an integer")

            if opt in ["-h", "--help"]:
                sys.exit(show_usage())

        command = args.pop(0) if args else None
        if command in commands:
            config_loader = ConfigLoader(DATA_DIR, CONF_FILE_NAME,
                                         DEFAULT_CONF, command_line_conf)
            config = config_loader.build_config()
            main(command, args, config)
        elif not command:
            sys.exit(f"No command provided.\n\n{show_usage()}")
        else:
            sys.exit(f"Unknown command.\n\n{show_usage()}")

    except GetoptError as e:
        sys.exit(f"{e}\n\n{show_usage()}")
    except UnknownConfigParam as e:
        exit(f"{e}. Check your teos_client.conf file")
예제 #15
0
def init(options, configuration, plugin):
    """Initializes the plugin"""

    clightning_conf = {}
    for k, v in options.items():
        # c-lightning config options are lower case, hyphened prefixed by `watchtower_`. Internal options are upper
        # case, underscored with no prefix
        key = k[11:].replace("-", "_").upper()
        value = DEFAULT_CONF.get(key).get("value")

        # Avoid setting the key in clightning_conf if it matches with the defaults, since otherwise it'll rewrite the
        # standalone conf with defaults.
        if key in DEFAULT_CONF and v != value:
            clightning_conf[key] = v

    try:
        user_sk, user_id = generate_keys(DATA_DIR)
        plugin.log(f"Generating a new key pair for the watchtower client. Keys stored at {DATA_DIR}")

    except FileExistsError:
        plugin.log("A key file for the watchtower client already exists. Loading it")
        user_sk, user_id = load_keys(DATA_DIR)

    # Loads plugin config. priority is clightning conf, plugin conf, default.
    plugin.log(f"Plugin watchtower client initialized. User id = {user_id}")
    config_loader = ConfigLoader(DATA_DIR, CONF_FILE_NAME, DEFAULT_CONF, clightning_conf)

    try:
        conf = config_loader.build_config()
        plugin.wt_client = WTClient(user_sk, user_id, conf)
    except plyvel.IOError:
        error = "Cannot load towers db. Resource temporarily unavailable"
        plugin.log("Cannot load towers db. Resource temporarily unavailable")
        raise IOError(error)
    except UnknownConfigParam as e:
        plugin.log(str(e), level="error")
        exit(1)
예제 #16
0
def main(command, args, command_line_conf):
    # Loads config and sets up the data folder and log file
    config_loader = ConfigLoader(DATA_DIR, CONF_FILE_NAME, DEFAULT_CONF, command_line_conf)
    config = config_loader.build_config()

    setup_data_folder(config.get("DATA_DIR"))

    # Set the teos url
    teos_url = "{}:{}".format(config.get("API_CONNECT"), config.get("API_PORT"))
    # If an http or https prefix if found, leaves the server as is. Otherwise defaults to http.
    if not teos_url.startswith("http"):
        teos_url = "http://" + teos_url

    try:
        if os.path.exists(config.get("USER_PRIVATE_KEY")):
            logger.debug("Client id found. Loading keys")
            user_sk, user_id = load_keys(config.get("USER_PRIVATE_KEY"))

        else:
            logger.info("Client id not found. Generating new keys")
            user_sk = Cryptographer.generate_key()
            Cryptographer.save_key_file(user_sk.to_der(), "user_sk", config.get("DATA_DIR"))
            user_id = Cryptographer.get_compressed_pk(user_sk.public_key)

        if command == "register":
            if not args:
                raise InvalidParameter("Cannot register. No tower id was given")
            else:
                teos_id = args.pop(0)
                if not is_compressed_pk(teos_id):
                    raise InvalidParameter("Cannot register. Tower id has invalid format")

                available_slots, subscription_expiry = register(user_id, teos_id, teos_url)
                logger.info("Registration succeeded. Available slots: {}".format(available_slots))
                logger.info("Subscription expires at block {}".format(subscription_expiry))

                teos_id_file = os.path.join(config.get("DATA_DIR"), "teos_pk")
                Cryptographer.save_key_file(bytes.fromhex(teos_id), teos_id_file, config.get("DATA_DIR"))

        if command == "add_appointment":
            teos_id = load_teos_id(config.get("TEOS_PUBLIC_KEY"))
            appointment_data = parse_add_appointment_args(args)
            appointment = create_appointment(appointment_data)
            start_block, signature = add_appointment(appointment, user_sk, teos_id, teos_url)
            save_appointment_receipt(
                appointment.to_dict(), start_block, signature, config.get("APPOINTMENTS_FOLDER_NAME")
            )

        elif command == "get_appointment":
            if not args:
                logger.error("No arguments were given")

            else:
                arg_opt = args.pop(0)

                if arg_opt in ["-h", "--help"]:
                    sys.exit(help_get_appointment())

                teos_id = load_teos_id(config.get("TEOS_PUBLIC_KEY"))
                appointment_data = get_appointment(arg_opt, user_sk, teos_id, teos_url)
                if appointment_data:
                    logger.info(json.dumps(appointment_data, indent=4))

        elif command == "get_subscription_info":
            if args:
                arg_opt = args.pop(0)

                if arg_opt in ["-h", "--help"]:
                    sys.exit(help_get_subscription_info())

            teos_id = load_teos_id(config.get("TEOS_PUBLIC_KEY"))
            subscription_info = get_subscription_info(user_sk, teos_id, teos_url)
            if subscription_info:
                logger.info(json.dumps(subscription_info, indent=4))

        elif command == "help":
            if args:
                command = args.pop(0)

                if command == "register":
                    sys.exit(help_register())

                if command == "add_appointment":
                    sys.exit(help_add_appointment())

                if command == "get_subscription_info":
                    sys.exit(help_get_subscription_info())

                elif command == "get_appointment":
                    sys.exit(help_get_appointment())

                else:
                    logger.error("Unknown command. Use help to check the list of available commands")

            else:
                sys.exit(show_usage())

    except (FileNotFoundError, IOError, ConnectionError, ValueError, BasicException,) as e:
        logger.error(str(e))
    except Exception as e:
        logger.error("Unknown error occurred", error=str(e))
예제 #17
0
def main(command_line_conf):
    global db_manager, chain_monitor

    signal(SIGINT, handle_signals)
    signal(SIGTERM, handle_signals)
    signal(SIGQUIT, handle_signals)

    # Loads config and sets up the data folder and log file
    config_loader = ConfigLoader(DATA_DIR, CONF_FILE_NAME, DEFAULT_CONF,
                                 command_line_conf)
    config = config_loader.build_config()
    setup_data_folder(DATA_DIR)
    setup_logging(config.get("LOG_FILE"), LOG_PREFIX)

    logger.info("Starting TEOS")
    db_manager = DBManager(config.get("DB_PATH"))

    bitcoind_connect_params = {
        k: v
        for k, v in config.items() if k.startswith("BTC")
    }
    bitcoind_feed_params = {
        k: v
        for k, v in config.items() if k.startswith("FEED")
    }

    if not can_connect_to_bitcoind(bitcoind_connect_params):
        logger.error("Can't connect to bitcoind. Shutting down")

    elif not in_correct_network(bitcoind_connect_params,
                                config.get("BTC_NETWORK")):
        logger.error(
            "bitcoind is running on a different network, check conf.py and bitcoin.conf. Shutting down"
        )

    else:
        try:
            secret_key_der = Cryptographer.load_key_file(
                config.get("TEOS_SECRET_KEY"))
            if not secret_key_der:
                raise IOError("TEOS private key can't be loaded")

            block_processor = BlockProcessor(bitcoind_connect_params)
            carrier = Carrier(bitcoind_connect_params)

            responder = Responder(db_manager, carrier, block_processor)
            watcher = Watcher(
                db_manager,
                block_processor,
                responder,
                secret_key_der,
                config.get("MAX_APPOINTMENTS"),
                config.get("EXPIRY_DELTA"),
            )

            # Create the chain monitor and start monitoring the chain
            chain_monitor = ChainMonitor(watcher.block_queue,
                                         watcher.responder.block_queue,
                                         block_processor, bitcoind_feed_params)

            watcher_appointments_data = db_manager.load_watcher_appointments()
            responder_trackers_data = db_manager.load_responder_trackers()

            if len(watcher_appointments_data) == 0 and len(
                    responder_trackers_data) == 0:
                logger.info("Fresh bootstrap")

                watcher.awake()
                watcher.responder.awake()

            else:
                logger.info("Bootstrapping from backed up data")

                # Update the Watcher backed up data if found.
                if len(watcher_appointments_data) != 0:
                    watcher.appointments, watcher.locator_uuid_map = Builder.build_appointments(
                        watcher_appointments_data)

                # Update the Responder with backed up data if found.
                if len(responder_trackers_data) != 0:
                    watcher.responder.trackers, watcher.responder.tx_tracker_map = Builder.build_trackers(
                        responder_trackers_data)

                # Awaking components so the states can be updated.
                watcher.awake()
                watcher.responder.awake()

                last_block_watcher = db_manager.load_last_block_hash_watcher()
                last_block_responder = db_manager.load_last_block_hash_responder(
                )

                # Populate the block queues with data if they've missed some while offline. If the blocks of both match
                # we don't perform the search twice.

                # FIXME: 32-reorgs-offline dropped txs are not used at this point.
                last_common_ancestor_watcher, dropped_txs_watcher = block_processor.find_last_common_ancestor(
                    last_block_watcher)
                missed_blocks_watcher = block_processor.get_missed_blocks(
                    last_common_ancestor_watcher)

                if last_block_watcher == last_block_responder:
                    dropped_txs_responder = dropped_txs_watcher
                    missed_blocks_responder = missed_blocks_watcher

                else:
                    last_common_ancestor_responder, dropped_txs_responder = block_processor.find_last_common_ancestor(
                        last_block_responder)
                    missed_blocks_responder = block_processor.get_missed_blocks(
                        last_common_ancestor_responder)

                # If only one of the instances needs to be updated, it can be done separately.
                if len(missed_blocks_watcher
                       ) == 0 and len(missed_blocks_responder) != 0:
                    Builder.populate_block_queue(watcher.responder.block_queue,
                                                 missed_blocks_responder)
                    watcher.responder.block_queue.join()

                elif len(missed_blocks_responder
                         ) == 0 and len(missed_blocks_watcher) != 0:
                    Builder.populate_block_queue(watcher.block_queue,
                                                 missed_blocks_watcher)
                    watcher.block_queue.join()

                # Otherwise they need to be updated at the same time, block by block
                elif len(missed_blocks_responder) != 0 and len(
                        missed_blocks_watcher) != 0:
                    Builder.update_states(watcher, missed_blocks_watcher,
                                          missed_blocks_responder)

            # Fire the API and the ChainMonitor
            # FIXME: 92-block-data-during-bootstrap-db
            chain_monitor.monitor_chain()
            API(Inspector(block_processor, config.get("MIN_TO_SELF_DELAY")),
                watcher).start()
        except Exception as e:
            logger.error("An error occurred: {}. Shutting down".format(e))
            exit(1)
예제 #18
0
def get_config(data_folder, conf_file_name, default_conf):
    config_loader = ConfigLoader(data_folder, conf_file_name, default_conf, {})
    config = config_loader.build_config()

    return config
예제 #19
0
def run():
    # Split the command line as follows: global options, command, command args,
    # where command is the first argument not starting with "-".

    try:
        command_index = next(i for i in range(len(argv))
                             if i > 0 and not argv[i].startswith("-"))
    except StopIteration:
        sys.exit(f"No command found\n\n{show_usage()}")

    command = argv[command_index]
    global_options = argv[1:command_index]
    command_args = argv[command_index + 1:]

    command_line_conf = {}

    # Process global options
    try:
        opts, args = getopt(global_options, "h",
                            ["rpcbind=", "rpcport=", "datadir=", "help"])

        data_dir = DATA_DIR

        for opt, arg in opts:
            if opt in ["--rpcbind"]:
                if arg:
                    command_line_conf["RPC_BIND"] = arg

            if opt in ["--rpcport"]:
                if arg:
                    try:
                        command_line_conf["RPC_PORT"] = int(arg)
                    except ValueError:
                        sys.exit("port must be an integer")

            if opt in ["--datadir"]:
                data_dir = os.path.expanduser(arg)

            if opt in ["-h", "--help"]:
                sys.exit(show_usage())

        config_loader = ConfigLoader(data_dir, CONF_FILE_NAME, DEFAULT_CONF,
                                     command_line_conf)
        config = config_loader.build_config()

        if command in CLI.COMMANDS:
            cli = CLI(data_dir, config)
            result = cli.run(command, command_args)
            if result:
                print(result)

        elif not command:
            sys.exit(
                "No command provided. Use help to check the list of available commands"
            )
        else:
            sys.exit(
                "Unknown command. Use help to check the list of available commands"
            )

    except GetoptError as e:
        sys.exit(f"{e}\n\n{show_usage()}")
    except UnknownConfigParam as e:
        exit(f"{e}. Check your teos.conf file")
예제 #20
0
def main(command, args, command_line_conf):
    # Loads config and sets up the data folder and log file
    config_loader = ConfigLoader(DATA_DIR, CONF_FILE_NAME, DEFAULT_CONF,
                                 command_line_conf)
    config = config_loader.build_config()

    setup_data_folder(DATA_DIR)
    setup_logging(config.get("LOG_FILE"), LOG_PREFIX)

    # Set the teos url
    teos_url = "{}:{}".format(config.get("API_CONNECT"),
                              config.get("API_PORT"))
    # If an http or https prefix if found, leaves the server as is. Otherwise defaults to http.
    if not teos_url.startswith("http"):
        teos_url = "http://" + teos_url

    try:
        teos_id, user_sk, user_id = load_keys(config.get("TEOS_PUBLIC_KEY"),
                                              config.get("CLI_PRIVATE_KEY"))

        if command == "register":
            register_data = register(user_id, teos_url)
            logger.info("Registration succeeded. Available slots: {}".format(
                register_data.get("available_slots")))

        if command == "add_appointment":
            appointment_data = parse_add_appointment_args(args)
            appointment, signature = add_appointment(appointment_data, user_sk,
                                                     teos_id, teos_url)
            save_appointment_receipt(appointment.to_dict(), signature,
                                     config.get("APPOINTMENTS_FOLDER_NAME"))

        elif command == "get_appointment":
            if not args:
                logger.error("No arguments were given")

            else:
                arg_opt = args.pop(0)

                if arg_opt in ["-h", "--help"]:
                    sys.exit(help_get_appointment())

                appointment_data = get_appointment(arg_opt, user_sk, teos_id,
                                                   teos_url)
                if appointment_data:
                    print(appointment_data)

        elif command == "get_all_appointments":
            appointment_data = get_all_appointments(teos_url)
            if appointment_data:
                print(appointment_data)

        elif command == "help":
            if args:
                command = args.pop(0)

                if command == "register":
                    sys.exit(help_register())

                if command == "add_appointment":
                    sys.exit(help_add_appointment())

                elif command == "get_appointment":
                    sys.exit(help_get_appointment())

                elif command == "get_all_appointments":
                    sys.exit(help_get_all_appointments())

                else:
                    logger.error(
                        "Unknown command. Use help to check the list of available commands"
                    )

            else:
                sys.exit(show_usage())

    except (FileNotFoundError, IOError, ConnectionError, ValueError) as e:
        logger.error(str(e))
    except (InvalidKey, InvalidParameter, TowerResponseError,
            SignatureError) as e:
        logger.error(e.msg, **e.kwargs)
    except Exception as e:
        logger.error("Unknown error occurred", error=str(e))
예제 #21
0
def get_config():
    config_loader = ConfigLoader(".", "teos_cli.conf", DEFAULT_CONF, {})
    config = config_loader.build_config()

    return config
예제 #22
0
def main(args, command_line_conf):
    # Loads config and sets up the data folder and log file
    config_loader = ConfigLoader(DATA_DIR, CONF_FILE_NAME, DEFAULT_CONF,
                                 command_line_conf)
    config = config_loader.build_config()

    setup_data_folder(DATA_DIR)
    setup_logging(config.get("LOG_FILE"), LOG_PREFIX)

    # Set the teos url
    teos_url = "{}:{}".format(config.get("TEOS_SERVER"),
                              config.get("TEOS_PORT"))
    # If an http or https prefix if found, leaves the server as is. Otherwise defaults to http.
    if not teos_url.startswith("http"):
        teos_url = "http://" + teos_url

    try:
        if args:
            command = args.pop(0)

            if command in commands:
                if command == "add_appointment":
                    add_appointment(args, teos_url, config)

                elif command == "get_appointment":
                    if not args:
                        logger.error("No arguments were given")

                    else:
                        arg_opt = args.pop(0)

                        if arg_opt in ["-h", "--help"]:
                            sys.exit(help_get_appointment())

                        get_appointment_endpoint = "{}/get_appointment".format(
                            teos_url)
                        appointment_data = get_appointment(
                            arg_opt, get_appointment_endpoint)
                        if appointment_data:
                            print(appointment_data)

                elif command == "help":
                    if args:
                        command = args.pop(0)

                        if command == "add_appointment":
                            sys.exit(help_add_appointment())

                        elif command == "get_appointment":
                            sys.exit(help_get_appointment())

                        else:
                            logger.error(
                                "Unknown command. Use help to check the list of available commands"
                            )

                    else:
                        sys.exit(show_usage())

            else:
                logger.error(
                    "Unknown command. Use help to check the list of available commands"
                )

        else:
            logger.error(
                "No command provided. Use help to check the list of available commands"
            )

    except json.JSONDecodeError:
        logger.error("Non-JSON encoded appointment passed as parameter")
예제 #23
0
def test_build_invalid_data(conf_file_conf):
    # Lets first try with only default
    foo_data_dir = "foo/"
    default_conf_copy = deepcopy(DEFAULT_CONF)
    default_conf_copy["FOO_INT"]["value"] = "foo"

    conf_loader = ConfigLoader(foo_data_dir, conf_file_name, default_conf_copy,
                               {})

    with pytest.raises(ValueError):
        conf_loader.build_config()

    # Set back the default value
    default_conf_copy["FOO_INT"]["value"] = DEFAULT_CONF["FOO_INT"]["value"]

    # Only conf file now
    conf_file_conf["FOO_INT2"] = "foo"
    # Save the wrong data
    config_parser = ConfigParser()
    config_parser["foo_section"] = conf_file_data
    with open(data_dir + conf_file_name, "w") as fout:
        config_parser.write(fout)

    conf_loader = ConfigLoader(data_dir, conf_file_name, default_conf_copy, {})

    with pytest.raises(ValueError):
        conf_loader.build_config()

    # Only command line now
    cmd_data["FOO_INT"] = "foo"
    conf_loader = ConfigLoader(foo_data_dir, conf_file_name, default_conf_copy,
                               cmd_data)

    with pytest.raises(ValueError):
        conf_loader.build_config()

    # All together
    # Set back a wrong default
    default_conf_copy["FOO_STR"]["value"] = 1234
    conf_loader = ConfigLoader(data_dir, conf_file_name, default_conf_copy,
                               cmd_data)

    with pytest.raises(ValueError):
        conf_loader.build_config()