Ejemplo n.º 1
0
async def cli_deps(
    filled_graph_db: ArangoGraphDB,
    message_bus: MessageBus,
    event_sender: InMemoryEventSender,
    foo_model: Model,
    task_queue: WorkerTaskQueue,
    worker: Tuple[WorkerTaskDescription, WorkerTaskDescription, WorkerTaskDescription],
    expander: TemplateExpander,
    config_handler: ConfigHandler,
    cert_handler: CertificateHandler,
) -> AsyncIterator[CLIDependencies]:
    db_access = DbAccess(filled_graph_db.db.db, event_sender, NoAdjust(), empty_config())
    model_handler = ModelHandlerStatic(foo_model)
    config = empty_config(["--graphdb-database", "test", "--graphdb-username", "test", "--graphdb-password", "test"])
    deps = CLIDependencies(
        message_bus=message_bus,
        event_sender=event_sender,
        db_access=db_access,
        model_handler=model_handler,
        worker_task_queue=task_queue,
        config=config,
        template_expander=expander,
        forked_tasks=Queue(),
        config_handler=config_handler,
        cert_handler=cert_handler,
    )
    yield deps
    await deps.stop()
Ejemplo n.º 2
0
    async def __update_config(self) -> None:
        # in case the internal configuration holds new properties, we update the existing config always.
        try:
            existing = await self.config_handler.get_config(ResotoCoreConfigId)
            empty = empty_config().json()
            updated = deep_merge(empty, existing.config) if existing else empty
            updated = migrate_config(updated)
            if existing is None or updated != existing.config:
                await self.config_handler.put_config(
                    ConfigEntity(ResotoCoreConfigId, updated), False)
                log.info("Default resoto config updated.")
        except Exception as ex:
            log.error(f"Could not update resoto default configuration: {ex}",
                      exc_info=ex)

        # make sure there is a default command configuration
        # note: this configuration is only created one time and never updated
        try:
            existing_commands = await self.config_handler.get_config(
                ResotoCoreCommandsConfigId)
            if existing_commands is None:
                await self.config_handler.put_config(
                    ConfigEntity(ResotoCoreCommandsConfigId,
                                 CustomCommandsConfig().json()), False)
                log.info("Default resoto commands config updated.")
        except Exception as ex:
            log.error(f"Could not update resoto command configuration: {ex}",
                      exc_info=ex)
async def test_validation() -> None:
    validate = CoreConfigHandler.validate_config_entry

    # empty config is valid
    assert validate({"config": {ResotoCoreRoot: {}}}) is None
    # expected json object but got 23
    assert validate({"config": {ResotoCoreRoot: 23}}) is not None
    # validation fails, since ui-path does not exist
    assert validate({"config": {
        ResotoCoreRoot: {
            "api": {
                "ui_path": "n/a"
            }
        }
    }}) is not None
    # default configuration is valid
    assert validate({"config": {
        ResotoCoreRoot: empty_config().json()
    }}) is None

    # empty command config is fine
    assert validate({"config": {ResotoCoreCommandsRoot: {}}}) is None
    # 23 can not be parsed as command list
    pytest.raises(DeserializationError, validate,
                  {"config": {
                      ResotoCoreCommandsRoot: {
                          "commands": 23
                      }
                  }})
    # valid entry can be read
    assert validate(
        {"config": {
            ResotoCoreCommandsRoot: CustomCommandsConfig().json()
        }}) is None
def core_config_handler(message_bus: MessageBus, task_queue: WorkerTaskQueue,
                        config_handler: ConfigHandler) -> CoreConfigHandler:
    def on_exit() -> None:
        config_handler_exits.append(True)

    config = empty_config()
    return CoreConfigHandler(config, message_bus, task_queue, config_handler,
                             on_exit)
Ejemplo n.º 5
0
async def test_default_workflow_triggers() -> None:
    workflows = {wf.name: wf for wf in TaskHandlerService.known_workflows(empty_config())}
    assert workflows["collect"].triggers == [EventTrigger("start_collect_workflow")]
    assert workflows["cleanup"].triggers == [EventTrigger("start_cleanup_workflow")]
    assert workflows["metrics"].triggers == [EventTrigger("start_metrics_workflow")]
    assert workflows["collect_and_cleanup"].triggers == [
        EventTrigger("start_collect_and_cleanup_workflow"),
        TimeTrigger("0 * * * *"),
    ]
Ejemplo n.º 6
0
async def test_merge_process(event_sender: AnalyticsEventSender,
                             graph_db: ArangoGraphDB,
                             foo_kinds: List[Kind]) -> None:
    # set explicitly (is done in main explicitly as well)
    set_start_method("spawn")

    # wipe any existing data
    await graph_db.wipe()
    # store the model in db, so it can be loaded by the sub process
    graph_db.db.collection("model").insert_many([to_js(a) for a in foo_kinds])
    # define args to parse for the sub process
    config = empty_config([
        "--graphdb-username", "test", "--graphdb-password", "test",
        "--graphdb-database", "test"
    ])
    # create sample graph data to insert
    graph = create_graph("test")

    await outer_edge_db(graph_db.db,
                        "deferred_outer_edges").create_update_schema()

    async def iterator() -> AsyncGenerator[bytes, None]:
        for node in graph.nodes():
            yield bytes(json.dumps(graph.nodes[node]), "utf-8")
        for from_node, to_node, data in graph.edges(data=True):
            yield bytes(
                json.dumps({
                    "from": from_node,
                    "to": to_node,
                    "edge_type": data["edge_type"]
                }), "utf-8")
        yield bytes(
            json.dumps({
                "from_selector": {
                    "node_id": "id_123"
                },
                "to_selector": {
                    "node_id": "id_456"
                },
                "edge_type": "delete"
            }),
            "utf-8",
        )

    result = await merge_graph_process(graph_db, event_sender, config,
                                       iterator(), timedelta(seconds=30), None,
                                       TaskId("test_task_123"))
    assert result == GraphUpdate(112, 1, 0, 212, 0, 0)
    elem = graph_db.db.collection("deferred_outer_edges").all().next()
    assert elem["_key"] == "test_task_123"
    assert elem["task_id"] == "test_task_123"
    assert elem["edges"][0] == {
        "from_node": "id_123",
        "to_node": "id_456",
        "edge_type": "delete"
    }
Ejemplo n.º 7
0
def test_not_existing(system_db: StandardDatabase, test_db: StandardDatabase) -> None:
    access = DbAccess(test_db, NoEventSender(), NoAdjust(), empty_config())

    # foo db and pass does not exist
    foodb = ["--graphdb-username", "foo", "--graphdb-password", "test", "--graphdb-database", "foo"]
    system_db.delete_user("foo", ignore_missing=True)
    system_db.delete_database("foo", ignore_missing=True)
    access.connect(parse_args(foodb), timedelta(seconds=5), sleep_time=0.1)
    assert system_db.has_user("foo")
    assert system_db.has_database("foo")
Ejemplo n.º 8
0
 def handler() -> TaskHandlerService:
     th = TaskHandlerService(
         running_task_db,
         job_db,
         message_bus,
         event_sender,
         subscription_handler,
         Scheduler(),
         cli,
         empty_config(),
     )
     th.task_descriptions = [test_workflow]
     return th
Ejemplo n.º 9
0
def test_not_existing_and_default_root_account(
    local_client: ArangoClient, system_db: StandardDatabase, test_db: StandardDatabase
) -> None:
    access = DbAccess(test_db, NoEventSender(), NoAdjust(), empty_config())
    # foo db and pass does not exist
    foodb = ["--graphdb-username", "foo", "--graphdb-password", "bombproof", "--graphdb-database", "foo"]
    system_db.delete_user("foo", ignore_missing=True)
    system_db.delete_database("foo", ignore_missing=True)
    access.connect(parse_args(foodb), timedelta(seconds=5), sleep_time=0.1)

    # The default root account is used and a valid password is given -> also the root account uses this password
    changed_root = local_client.db(username="******", password="******")
    # Rest the password to the default one, to reset the state before the test
    changed_root.replace_user("root", "", True)
Ejemplo n.º 10
0
async def task_handler(
    running_task_db: RunningTaskDb,
    job_db: JobDb,
    message_bus: MessageBus,
    event_sender: AnalyticsEventSender,
    subscription_handler: SubscriptionHandler,
    cli: CLI,
    test_workflow: Workflow,
) -> AsyncGenerator[TaskHandlerService, None]:
    config = empty_config()
    task_handler = TaskHandlerService(
        running_task_db, job_db, message_bus, event_sender, subscription_handler, Scheduler(), cli, config
    )
    task_handler.task_descriptions = [test_workflow]
    cli.dependencies.lookup["task_handler"] = task_handler
    async with task_handler:
        yield task_handler
Ejemplo n.º 11
0
def test_bootstrap(test_db: StandardDatabase) -> None:
    with TemporaryDirectory() as tmpdir:
        tmp = Path(tmpdir)
        sd = test_db.collection("system_data")
        config = empty_config()
        # Delete any existing entry, so a new certificate needs to be created
        sd.delete("ca", ignore_missing=True)
        handler = CertificateHandler.lookup(config, test_db, tmp)
        ca = sd.get("ca")
        assert ca is not None
        # ensure the certificate in the database is the same as exposed by the handler
        ca_bytes, fingerprint = handler.authority_certificate
        assert ca_bytes == ca["certificate"].encode("utf-8")
        # a new handler will use the existing certificate
        handler2 = CertificateHandler.lookup(config, test_db, tmp)
        assert handler.authority_certificate == handler2.authority_certificate
        # but the host certificate will be different
        assert handler.host_certificate != handler2.host_certificate
Ejemplo n.º 12
0
def cert_handler() -> Iterator[CertificateHandler]:
    config = empty_config()
    key, certificate = bootstrap_ca()
    temp = TemporaryDirectory()
    yield CertificateHandler(config, key, certificate, Path(temp.name))
    temp.cleanup()
Ejemplo n.º 13
0
def test_already_existing(test_db: StandardDatabase) -> None:
    access = DbAccess(test_db, NoEventSender(), NoAdjust(), empty_config())

    # test db and user already exist
    testdb = ["--graphdb-username", "test", "--graphdb-password", "test", "--graphdb-database", "test"]
    access.connect(parse_args(testdb), timedelta(seconds=0.01), sleep_time=0.01)