Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -589,32 +589,6 @@ jobs:
- name: "Install Package"
run: "poetry install"

- name: Install NodeJS
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: ./schema/package-lock.json
- name: "Install format-graphql"
working-directory: schema
run: npm install

- name: Select infrahub db port
run: echo "INFRAHUB_DB_PORT=$(shuf -n 1 -i 10000-60000)" >> $GITHUB_ENV

- name: "Set environment variables"
run: echo INFRAHUB_BUILD_NAME=infrahub-${{ runner.name }} >> $GITHUB_ENV
- name: "Set environment variables"
run: echo INFRAHUB_IMAGE_VER=local-${{ runner.name }}-${{ github.sha }} >> $GITHUB_ENV
- name: "Clear docker environment"
run: docker compose -p $INFRAHUB_BUILD_NAME down -v --remove-orphans --rmi local

- name: Create docker compose override
run: mv development/docker-compose.dev-override-benchmark.yml development/docker-compose.dev-override.yml

- name: Start dependencies
run: poetry run invoke dev.build dev.deps

- name: Run validation
run: poetry run invoke schema.validate-graphqlschema

Expand Down
3 changes: 1 addition & 2 deletions .vale/styles/Infrahub/branded-terms-case-swap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ swap:
(?<![\.|/|#])[Gg]itlab[\.!]?\s: GitLab
(?:gitpod): GitPod
(?:grafana): Grafana
(?:[^/][Gg]raphql): GraphQL
(?:[^/.][Gg]raphql): GraphQL
(?:[Ii]nflux[Dd]b): InfluxDB
(?<![\.|/|#])infrahub[\.!]?\s: Infrahub
(?<![\.|/|#])InfraHub[\.!]?\s: Infrahub
(?:jinja2): Jinja2
(?:k3s): K3s
(?<![\.|/|#])k8s[\.!]?\s: K8s
Expand Down
2 changes: 2 additions & 0 deletions backend/infrahub/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from ..workers.dependencies import get_database
from .context import CliContext
from .db import app as db_app
from .dev import app as dev_app
from .events import app as events_app
from .git_agent import app as git_app
from .server import app as server_app
Expand All @@ -27,6 +28,7 @@ def common(ctx: typer.Context) -> None:
app.add_typer(db_app, name="db")
app.add_typer(events_app, name="events", help="Interact with the events system.", hidden=True)
app.add_typer(tasks_app, name="tasks", hidden=True)
app.add_typer(dev_app, name="dev", help="Internal development commands.")
app.command(name="upgrade")(upgrade_cmd)


Expand Down
67 changes: 0 additions & 67 deletions backend/infrahub/cli/db.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import importlib
import logging
import os
from collections import defaultdict
Expand All @@ -16,7 +15,6 @@
from prefect.testing.utilities import prefect_test_harness
from rich import print as rprint
from rich.console import Console
from rich.logging import RichHandler
from rich.table import Table

from infrahub import config
Expand All @@ -33,9 +31,7 @@
GraphRelationshipProperties,
)
from infrahub.core.initialization import (
first_time_initialization,
get_root_node,
initialization,
initialize_registry,
)
from infrahub.core.migrations.graph import get_graph_migrations, get_migration_by_number
Expand All @@ -44,13 +40,11 @@
from infrahub.core.schema import SchemaRoot, core_models, internal_schema
from infrahub.core.schema.definitions.deprecated import deprecated_models
from infrahub.core.schema.manager import SchemaManager
from infrahub.core.utils import delete_all_nodes
from infrahub.core.validators.models.validate_migration import SchemaValidateMigrationData
from infrahub.core.validators.tasks import schema_validate_migrations
from infrahub.database import DatabaseType
from infrahub.database.memgraph import IndexManagerMemgraph
from infrahub.database.neo4j import IndexManagerNeo4j
from infrahub.log import get_logger

from .constants import ERROR_BADGE, FAILED_BADGE, SUCCESS_BADGE
from .db_commands.check_inheritance import check_inheritance
Expand Down Expand Up @@ -94,67 +88,6 @@ def callback() -> None:
"""


@app.command()
async def init(
ctx: typer.Context,
config_file: str = typer.Option(
"infrahub.toml", envvar="INFRAHUB_CONFIG", help="Location of the configuration file to use for Infrahub"
),
) -> None:
"""Erase the content of the database and initialize it with the core schema."""

log = get_logger()

# --------------------------------------------------
# CLEANUP
# - For now we delete everything in the database
# TODO, if possible try to implement this in an idempotent way
# --------------------------------------------------

logging.getLogger("neo4j").setLevel(logging.ERROR)
config.load_and_exit(config_file_name=config_file)

context: CliContext = ctx.obj
dbdriver = await context.init_db(retry=1)
async with dbdriver.start_transaction() as db:
log.info("Delete All Nodes")
await delete_all_nodes(db=db)
await first_time_initialization(db=db)

await dbdriver.close()


@app.command()
async def load_test_data(
ctx: typer.Context,
config_file: str = typer.Option(
"infrahub.toml", envvar="INFRAHUB_CONFIG", help="Location of the configuration file to use for Infrahub"
),
dataset: str = "dataset01",
) -> None:
"""Load test data into the database from the `test_data` directory."""

logging.getLogger("neo4j").setLevel(logging.ERROR)
config.load_and_exit(config_file_name=config_file)

context: CliContext = ctx.obj
dbdriver = await context.init_db(retry=1)

async with dbdriver.start_session() as db:
await initialization(db=db)

log_level = "DEBUG"

FORMAT = "%(message)s"
logging.basicConfig(level=log_level, format=FORMAT, datefmt="[%X]", handlers=[RichHandler()])
logging.getLogger("infrahub")

dataset_module = importlib.import_module(f"infrahub.test_data.{dataset}")
await dataset_module.load_data(db=db)

await dbdriver.close()


@app.command(name="migrate")
async def migrate_cmd(
ctx: typer.Context,
Expand Down
118 changes: 118 additions & 0 deletions backend/infrahub/cli/dev.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
from __future__ import annotations

import importlib
import logging
from pathlib import Path # noqa: TC003
from typing import TYPE_CHECKING

import typer
from graphql import parse, print_ast, print_schema
from infrahub_sdk.async_typer import AsyncTyper
from rich.logging import RichHandler

from infrahub import config
from infrahub.core.initialization import (
first_time_initialization,
initialization,
)
from infrahub.core.schema import SchemaRoot, core_models, internal_schema
from infrahub.core.schema.schema_branch import SchemaBranch
from infrahub.core.utils import delete_all_nodes
from infrahub.graphql.manager import GraphQLSchemaManager
from infrahub.graphql.schema_sort import sort_schema_ast
from infrahub.log import get_logger

if TYPE_CHECKING:
from infrahub.cli.context import CliContext

app = AsyncTyper()


@app.command(name="export-graphql-schema")
async def export_graphql_schema(
ctx: typer.Context, # noqa: ARG001
config_file: str = typer.Option("infrahub.toml", envvar="INFRAHUB_CONFIG"),
out: Path = typer.Option("schema.graphql"), # noqa: B008
) -> None:
"""Export the GraphQL schema to a file."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity I think we should still say "Export the core GraphQL schema to a file."


config.load_and_exit(config_file_name=config_file)

schema = SchemaRoot(**internal_schema)
full_schema = schema.merge(schema=SchemaRoot(**core_models))

schema_branch = SchemaBranch(cache={}, name="default")
schema_branch.load_schema(schema=full_schema)

schema_branch.process()

gqlm = GraphQLSchemaManager(schema=schema_branch)
gql_schema = gqlm.generate()

schema_str = print_schema(gql_schema)
schema_ast = parse(schema_str)
sorted_schema_ast = sort_schema_ast(schema_ast)
sorted_schema_str = print_ast(sorted_schema_ast)

out.write_text(sorted_schema_str)


@app.command(name="db-init")
async def database_init(
ctx: typer.Context,
config_file: str = typer.Option(
"infrahub.toml", envvar="INFRAHUB_CONFIG", help="Location of the configuration file to use for Infrahub"
),
) -> None:
"""Erase the content of the database and initialize it with the core schema."""

log = get_logger()

# --------------------------------------------------
# CLEANUP
# - For now we delete everything in the database
# TODO, if possible try to implement this in an idempotent way
# --------------------------------------------------

logging.getLogger("neo4j").setLevel(logging.ERROR)
config.load_and_exit(config_file_name=config_file)

context: CliContext = ctx.obj
dbdriver = await context.init_db(retry=1)
async with dbdriver.start_transaction() as db:
log.info("Delete All Nodes")
await delete_all_nodes(db=db)
await first_time_initialization(db=db)

await dbdriver.close()


@app.command(name="load-test-data")
async def load_test_data(
ctx: typer.Context,
config_file: str = typer.Option(
"infrahub.toml", envvar="INFRAHUB_CONFIG", help="Location of the configuration file to use for Infrahub"
),
dataset: str = "dataset01",
) -> None:
"""Load test data into the database from the `test_data` directory."""

logging.getLogger("neo4j").setLevel(logging.ERROR)
config.load_and_exit(config_file_name=config_file)

context: CliContext = ctx.obj
dbdriver = await context.init_db(retry=1)

async with dbdriver.start_session() as db:
await initialization(db=db)

log_level = "DEBUG"

FORMAT = "%(message)s"
logging.basicConfig(level=log_level, format=FORMAT, datefmt="[%X]", handlers=[RichHandler()])
logging.getLogger("infrahub")

dataset_module = importlib.import_module(f"infrahub.test_data.{dataset}")
await dataset_module.load_data(db=db)

await dbdriver.close()
2 changes: 1 addition & 1 deletion backend/infrahub/core/initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ async def get_root_node(db: InfrahubDatabase, initialize: bool = False) -> Root:
roots = await Root.get_list(db=db)
if len(roots) == 0 and not initialize:
raise DatabaseError(
"The Database hasn't been initialized for Infrahub, please run 'infrahub db init' or 'infrahub server start' to initialize the database."
"The Database hasn't been initialized for Infrahub, please 'infrahub server start' to initialize the database."
)

if len(roots) == 0:
Expand Down
18 changes: 14 additions & 4 deletions backend/infrahub/graphql/api/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

from typing import TYPE_CHECKING

from fastapi import APIRouter, Depends
from fastapi import APIRouter, Depends, Query
from fastapi.responses import PlainTextResponse
from graphql import print_schema
from graphql import parse, print_ast, print_schema
from starlette.routing import Route, WebSocketRoute

from infrahub.api.dependencies import get_branch_dep, get_current_user
from infrahub.core import registry
from infrahub.graphql.registry import registry as graphql_registry
from infrahub.graphql.schema_sort import sort_schema_ast

from .dependencies import build_graphql_app

Expand All @@ -27,11 +28,20 @@
router.routes.append(WebSocketRoute(path="/graphql/{branch_name:str}", endpoint=graphql_app))


@router.get("/schema.graphql", include_in_schema=False)
@router.get("/schema.graphql")
async def get_graphql_schema(
branch: Branch = Depends(get_branch_dep), _: AccountSession = Depends(get_current_user)
branch: Branch = Depends(get_branch_dep),
_: AccountSession = Depends(get_current_user),
sort_schema: bool = Query(default=False, alias="sorted", description="Whether to sort the schema alphabetically."),
) -> PlainTextResponse:
schema_branch = registry.schema.get_schema_branch(name=branch.name)
gqlm = graphql_registry.get_manager_for_branch(branch=branch, schema_branch=schema_branch)
graphql_schema = gqlm.get_graphql_schema()

if sort_schema:
schema_str = print_schema(graphql_schema)
schema_ast = parse(schema_str)
sorted_schema_ast = sort_schema_ast(schema_ast)
return PlainTextResponse(content=print_ast(sorted_schema_ast))

return PlainTextResponse(content=print_schema(graphql_schema))
Loading