infrahub-server 1.2.0b1__py3-none-any.whl → 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- infrahub/api/dependencies.py +6 -6
- infrahub/api/diff/validation_models.py +7 -7
- infrahub/api/schema.py +1 -1
- infrahub/artifacts/models.py +1 -3
- infrahub/artifacts/tasks.py +1 -3
- infrahub/cli/__init__.py +13 -9
- infrahub/cli/constants.py +3 -0
- infrahub/cli/db.py +165 -183
- infrahub/cli/upgrade.py +146 -0
- infrahub/computed_attribute/gather.py +185 -0
- infrahub/computed_attribute/models.py +239 -11
- infrahub/computed_attribute/tasks.py +77 -442
- infrahub/computed_attribute/triggers.py +11 -45
- infrahub/config.py +43 -32
- infrahub/context.py +14 -0
- infrahub/core/account.py +4 -4
- infrahub/core/attribute.py +57 -57
- infrahub/core/branch/tasks.py +12 -9
- infrahub/core/changelog/diff.py +16 -8
- infrahub/core/changelog/models.py +189 -26
- infrahub/core/constants/__init__.py +5 -1
- infrahub/core/constants/infrahubkind.py +2 -0
- infrahub/core/constraint/node/runner.py +9 -8
- infrahub/core/diff/branch_differ.py +10 -10
- infrahub/core/diff/ipam_diff_parser.py +4 -5
- infrahub/core/diff/model/diff.py +27 -27
- infrahub/core/diff/model/path.py +3 -3
- infrahub/core/diff/query/merge.py +20 -17
- infrahub/core/diff/query_parser.py +4 -4
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/initialization.py +1 -10
- infrahub/core/ipam/constants.py +3 -4
- infrahub/core/ipam/reconciler.py +12 -12
- infrahub/core/ipam/utilization.py +10 -13
- infrahub/core/manager.py +34 -34
- infrahub/core/merge.py +7 -7
- infrahub/core/migrations/__init__.py +2 -3
- infrahub/core/migrations/graph/__init__.py +9 -4
- infrahub/core/migrations/graph/m017_add_core_profile.py +1 -5
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +4 -4
- infrahub/core/migrations/graph/m020_duplicate_edges.py +160 -0
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +51 -0
- infrahub/core/migrations/graph/{m020_add_generate_template_attr.py → m022_add_generate_template_attr.py} +3 -3
- infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +96 -0
- infrahub/core/migrations/query/attribute_add.py +2 -2
- infrahub/core/migrations/query/node_duplicate.py +18 -21
- infrahub/core/migrations/query/schema_attribute_update.py +2 -2
- infrahub/core/migrations/schema/models.py +19 -4
- infrahub/core/migrations/schema/tasks.py +2 -2
- infrahub/core/migrations/shared.py +16 -16
- infrahub/core/models.py +15 -6
- infrahub/core/node/__init__.py +29 -28
- infrahub/core/node/base.py +2 -4
- infrahub/core/node/constraints/attribute_uniqueness.py +2 -2
- infrahub/core/node/constraints/grouped_uniqueness.py +99 -47
- infrahub/core/node/constraints/interface.py +1 -2
- infrahub/core/node/delete_validator.py +3 -5
- infrahub/core/node/ipam.py +4 -4
- infrahub/core/node/permissions.py +7 -7
- infrahub/core/node/resource_manager/ip_address_pool.py +6 -6
- infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -6
- infrahub/core/node/resource_manager/number_pool.py +3 -3
- infrahub/core/path.py +12 -12
- infrahub/core/property.py +11 -11
- infrahub/core/protocols.py +5 -0
- infrahub/core/protocols_base.py +21 -21
- infrahub/core/query/__init__.py +33 -33
- infrahub/core/query/attribute.py +6 -4
- infrahub/core/query/diff.py +3 -3
- infrahub/core/query/node.py +82 -32
- infrahub/core/query/relationship.py +24 -24
- infrahub/core/query/resource_manager.py +2 -0
- infrahub/core/query/standard_node.py +3 -3
- infrahub/core/query/subquery.py +9 -9
- infrahub/core/registry.py +13 -15
- infrahub/core/relationship/constraints/count.py +3 -4
- infrahub/core/relationship/constraints/peer_kind.py +3 -4
- infrahub/core/relationship/constraints/profiles_kind.py +2 -2
- infrahub/core/relationship/model.py +40 -46
- infrahub/core/schema/attribute_schema.py +9 -9
- infrahub/core/schema/basenode_schema.py +93 -44
- infrahub/core/schema/computed_attribute.py +3 -3
- infrahub/core/schema/definitions/core/__init__.py +13 -19
- infrahub/core/schema/definitions/core/account.py +151 -148
- infrahub/core/schema/definitions/core/artifact.py +122 -113
- infrahub/core/schema/definitions/core/builtin.py +19 -16
- infrahub/core/schema/definitions/core/check.py +61 -53
- infrahub/core/schema/definitions/core/core.py +17 -0
- infrahub/core/schema/definitions/core/generator.py +89 -85
- infrahub/core/schema/definitions/core/graphql_query.py +72 -70
- infrahub/core/schema/definitions/core/group.py +96 -93
- infrahub/core/schema/definitions/core/ipam.py +176 -235
- infrahub/core/schema/definitions/core/lineage.py +18 -16
- infrahub/core/schema/definitions/core/menu.py +42 -40
- infrahub/core/schema/definitions/core/permission.py +144 -142
- infrahub/core/schema/definitions/core/profile.py +16 -27
- infrahub/core/schema/definitions/core/propose_change.py +88 -79
- infrahub/core/schema/definitions/core/propose_change_comment.py +170 -165
- infrahub/core/schema/definitions/core/propose_change_validator.py +290 -288
- infrahub/core/schema/definitions/core/repository.py +231 -225
- infrahub/core/schema/definitions/core/resource_pool.py +156 -166
- infrahub/core/schema/definitions/core/template.py +27 -12
- infrahub/core/schema/definitions/core/transform.py +85 -76
- infrahub/core/schema/definitions/core/webhook.py +127 -101
- infrahub/core/schema/definitions/internal.py +16 -16
- infrahub/core/schema/dropdown.py +3 -4
- infrahub/core/schema/generated/attribute_schema.py +15 -18
- infrahub/core/schema/generated/base_node_schema.py +12 -14
- infrahub/core/schema/generated/node_schema.py +3 -5
- infrahub/core/schema/generated/relationship_schema.py +9 -11
- infrahub/core/schema/generic_schema.py +2 -2
- infrahub/core/schema/manager.py +20 -9
- infrahub/core/schema/node_schema.py +4 -2
- infrahub/core/schema/relationship_schema.py +7 -7
- infrahub/core/schema/schema_branch.py +276 -138
- infrahub/core/schema/schema_branch_computed.py +41 -4
- infrahub/core/task/task.py +3 -3
- infrahub/core/task/user_task.py +15 -15
- infrahub/core/utils.py +20 -18
- infrahub/core/validators/__init__.py +1 -3
- infrahub/core/validators/aggregated_checker.py +2 -2
- infrahub/core/validators/attribute/choices.py +2 -2
- infrahub/core/validators/attribute/enum.py +2 -2
- infrahub/core/validators/attribute/kind.py +2 -2
- infrahub/core/validators/attribute/length.py +2 -2
- infrahub/core/validators/attribute/optional.py +2 -2
- infrahub/core/validators/attribute/regex.py +2 -2
- infrahub/core/validators/attribute/unique.py +2 -2
- infrahub/core/validators/checks_runner.py +25 -2
- infrahub/core/validators/determiner.py +1 -3
- infrahub/core/validators/interface.py +6 -2
- infrahub/core/validators/model.py +22 -3
- infrahub/core/validators/models/validate_migration.py +17 -4
- infrahub/core/validators/node/attribute.py +2 -2
- infrahub/core/validators/node/generate_profile.py +2 -2
- infrahub/core/validators/node/hierarchy.py +3 -5
- infrahub/core/validators/node/inherit_from.py +27 -5
- infrahub/core/validators/node/relationship.py +2 -2
- infrahub/core/validators/relationship/count.py +4 -4
- infrahub/core/validators/relationship/optional.py +2 -2
- infrahub/core/validators/relationship/peer.py +2 -2
- infrahub/core/validators/shared.py +2 -2
- infrahub/core/validators/tasks.py +8 -0
- infrahub/core/validators/uniqueness/checker.py +22 -21
- infrahub/core/validators/uniqueness/index.py +2 -2
- infrahub/core/validators/uniqueness/model.py +11 -11
- infrahub/database/__init__.py +26 -22
- infrahub/database/metrics.py +7 -1
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +1 -3
- infrahub/dependencies/component/registry.py +2 -2
- infrahub/events/__init__.py +25 -2
- infrahub/events/artifact_action.py +13 -25
- infrahub/events/branch_action.py +26 -18
- infrahub/events/generator.py +71 -0
- infrahub/events/group_action.py +10 -24
- infrahub/events/models.py +10 -16
- infrahub/events/node_action.py +87 -32
- infrahub/events/repository_action.py +5 -18
- infrahub/events/schema_action.py +4 -9
- infrahub/events/utils.py +16 -0
- infrahub/events/validator_action.py +55 -0
- infrahub/exceptions.py +23 -24
- infrahub/generators/models.py +1 -3
- infrahub/git/base.py +7 -7
- infrahub/git/integrator.py +26 -25
- infrahub/git/models.py +22 -9
- infrahub/git/repository.py +3 -3
- infrahub/git/tasks.py +67 -49
- infrahub/git/utils.py +48 -0
- infrahub/git/worktree.py +1 -2
- infrahub/git_credential/askpass.py +1 -2
- infrahub/graphql/analyzer.py +12 -0
- infrahub/graphql/app.py +13 -15
- infrahub/graphql/context.py +6 -0
- infrahub/graphql/initialization.py +3 -0
- infrahub/graphql/loaders/node.py +2 -12
- infrahub/graphql/loaders/peers.py +77 -0
- infrahub/graphql/loaders/shared.py +13 -0
- infrahub/graphql/manager.py +13 -10
- infrahub/graphql/mutations/artifact_definition.py +5 -5
- infrahub/graphql/mutations/computed_attribute.py +4 -5
- infrahub/graphql/mutations/graphql_query.py +5 -5
- infrahub/graphql/mutations/ipam.py +50 -70
- infrahub/graphql/mutations/main.py +164 -141
- infrahub/graphql/mutations/menu.py +5 -5
- infrahub/graphql/mutations/models.py +2 -4
- infrahub/graphql/mutations/node_getter/by_default_filter.py +10 -10
- infrahub/graphql/mutations/node_getter/by_hfid.py +1 -3
- infrahub/graphql/mutations/node_getter/by_id.py +1 -3
- infrahub/graphql/mutations/node_getter/interface.py +1 -2
- infrahub/graphql/mutations/proposed_change.py +7 -7
- infrahub/graphql/mutations/relationship.py +67 -35
- infrahub/graphql/mutations/repository.py +8 -8
- infrahub/graphql/mutations/resource_manager.py +3 -3
- infrahub/graphql/mutations/schema.py +4 -4
- infrahub/graphql/mutations/webhook.py +137 -0
- infrahub/graphql/parser.py +4 -4
- infrahub/graphql/queries/diff/tree.py +4 -4
- infrahub/graphql/queries/ipam.py +2 -2
- infrahub/graphql/queries/relationship.py +2 -2
- infrahub/graphql/queries/search.py +2 -2
- infrahub/graphql/resolvers/many_relationship.py +264 -0
- infrahub/graphql/resolvers/resolver.py +13 -110
- infrahub/graphql/subscription/graphql_query.py +2 -0
- infrahub/graphql/types/event.py +20 -11
- infrahub/graphql/types/node.py +2 -2
- infrahub/graphql/utils.py +2 -2
- infrahub/groups/ancestors.py +29 -0
- infrahub/groups/parsers.py +107 -0
- infrahub/menu/generator.py +7 -7
- infrahub/menu/menu.py +0 -10
- infrahub/menu/models.py +117 -16
- infrahub/menu/repository.py +111 -0
- infrahub/menu/utils.py +5 -8
- infrahub/message_bus/messages/__init__.py +1 -11
- infrahub/message_bus/messages/check_generator_run.py +2 -0
- infrahub/message_bus/messages/finalize_validator_execution.py +3 -0
- infrahub/message_bus/messages/request_generatordefinition_check.py +2 -0
- infrahub/message_bus/operations/__init__.py +0 -2
- infrahub/message_bus/operations/check/generator.py +1 -0
- infrahub/message_bus/operations/event/__init__.py +2 -2
- infrahub/message_bus/operations/finalize/validator.py +51 -1
- infrahub/message_bus/operations/requests/generator_definition.py +19 -19
- infrahub/message_bus/operations/requests/proposed_change.py +3 -1
- infrahub/pools/number.py +2 -4
- infrahub/proposed_change/tasks.py +37 -28
- infrahub/pytest_plugin.py +13 -10
- infrahub/server.py +1 -2
- infrahub/services/adapters/event/__init__.py +1 -1
- infrahub/task_manager/event.py +23 -9
- infrahub/tasks/artifact.py +2 -4
- infrahub/telemetry/__init__.py +0 -0
- infrahub/telemetry/constants.py +9 -0
- infrahub/telemetry/database.py +86 -0
- infrahub/telemetry/models.py +65 -0
- infrahub/telemetry/task_manager.py +77 -0
- infrahub/{tasks/telemetry.py → telemetry/tasks.py} +49 -56
- infrahub/telemetry/utils.py +11 -0
- infrahub/trace.py +4 -4
- infrahub/transformations/tasks.py +2 -2
- infrahub/trigger/catalogue.py +2 -5
- infrahub/trigger/constants.py +0 -8
- infrahub/trigger/models.py +14 -1
- infrahub/trigger/setup.py +90 -0
- infrahub/trigger/tasks.py +35 -90
- infrahub/utils.py +11 -1
- infrahub/validators/__init__.py +0 -0
- infrahub/validators/events.py +42 -0
- infrahub/validators/tasks.py +41 -0
- infrahub/webhook/gather.py +17 -0
- infrahub/webhook/models.py +22 -5
- infrahub/webhook/tasks.py +44 -19
- infrahub/webhook/triggers.py +22 -5
- infrahub/workers/infrahub_async.py +2 -2
- infrahub/workers/utils.py +2 -2
- infrahub/workflows/catalogue.py +28 -20
- infrahub/workflows/initialization.py +1 -3
- infrahub/workflows/models.py +1 -1
- infrahub/workflows/utils.py +10 -1
- infrahub_sdk/client.py +27 -8
- infrahub_sdk/config.py +3 -0
- infrahub_sdk/context.py +13 -0
- infrahub_sdk/exceptions.py +6 -0
- infrahub_sdk/generator.py +4 -1
- infrahub_sdk/graphql.py +45 -13
- infrahub_sdk/node.py +69 -20
- infrahub_sdk/protocols_base.py +32 -11
- infrahub_sdk/query_groups.py +6 -35
- infrahub_sdk/schema/__init__.py +55 -26
- infrahub_sdk/schema/main.py +8 -0
- infrahub_sdk/task/__init__.py +10 -0
- infrahub_sdk/task/manager.py +12 -6
- infrahub_sdk/testing/schemas/animal.py +9 -0
- infrahub_sdk/timestamp.py +12 -4
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/METADATA +3 -2
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/RECORD +289 -260
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/entry_points.txt +1 -0
- infrahub_testcontainers/constants.py +2 -0
- infrahub_testcontainers/container.py +157 -12
- infrahub_testcontainers/docker-compose.test.yml +31 -6
- infrahub_testcontainers/helpers.py +18 -73
- infrahub_testcontainers/host.py +41 -0
- infrahub_testcontainers/measurements.py +93 -0
- infrahub_testcontainers/models.py +38 -0
- infrahub_testcontainers/performance_test.py +166 -0
- infrahub_testcontainers/plugin.py +136 -0
- infrahub_testcontainers/prometheus.yml +30 -0
- infrahub/message_bus/messages/event_branch_create.py +0 -11
- infrahub/message_bus/messages/event_branch_delete.py +0 -11
- infrahub/message_bus/messages/event_branch_rebased.py +0 -9
- infrahub/message_bus/messages/event_node_mutated.py +0 -15
- infrahub/message_bus/messages/event_schema_update.py +0 -9
- infrahub/message_bus/operations/event/node.py +0 -20
- infrahub/message_bus/operations/event/schema.py +0 -17
- infrahub/webhook/constants.py +0 -1
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.0b1.dist-info → infrahub_server-1.2.1.dist-info}/WHEEL +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import shutil
|
|
2
3
|
import uuid
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
+
from dataclasses import dataclass, field
|
|
4
5
|
from functools import cached_property
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
|
|
7
8
|
from testcontainers.compose import DockerCompose
|
|
9
|
+
from testcontainers.core.exceptions import ContainerIsNotRunning
|
|
8
10
|
from typing_extensions import Self
|
|
9
11
|
|
|
10
12
|
from infrahub_testcontainers import __version__ as infrahub_version
|
|
@@ -19,14 +21,21 @@ class ContainerService:
|
|
|
19
21
|
INFRAHUB_SERVICES: dict[str, ContainerService] = {
|
|
20
22
|
"server": ContainerService(container="infrahub-server-lb", port=8000),
|
|
21
23
|
"task-manager": ContainerService(container="task-manager", port=4200),
|
|
24
|
+
"database": ContainerService(container="database", port=7687),
|
|
25
|
+
"scraper": ContainerService(container="scraper", port=8428),
|
|
26
|
+
"cadvisor": ContainerService(container="cadvisor", port=8080),
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
PROJECT_ENV_VARIABLES: dict[str, str] = {
|
|
30
|
+
"NEO4J_DOCKER_IMAGE": "neo4j:5.20.0-community",
|
|
31
|
+
"MESSAGE_QUEUE_DOCKER_IMAGE": "rabbitmq:3.13.7-management",
|
|
32
|
+
"CACHE_DOCKER_IMAGE": "redis:7.2.4",
|
|
25
33
|
"INFRAHUB_TESTING_DOCKER_IMAGE": "registry.opsmill.io/opsmill/infrahub",
|
|
34
|
+
"INFRAHUB_TESTING_DOCKER_ENTRYPOINT": f"gunicorn --config backend/infrahub/serve/gunicorn_config.py -w {os.environ.get('INFRAHUB_TESTING_WEB_CONCURRENCY', 4)} --logger-class infrahub.serve.log.GunicornLogger infrahub.server:app", # noqa: E501
|
|
26
35
|
"INFRAHUB_TESTING_IMAGE_VERSION": infrahub_version,
|
|
27
36
|
"INFRAHUB_TESTING_PRODUCTION": "false",
|
|
28
37
|
"INFRAHUB_TESTING_DB_ADDRESS": "database",
|
|
29
|
-
"INFRAHUB_TESTING_LOG_LEVEL": "
|
|
38
|
+
"INFRAHUB_TESTING_LOG_LEVEL": "INFO",
|
|
30
39
|
"INFRAHUB_TESTING_GIT_REPOSITORIES_DIRECTORY": "/opt/infrahub/git",
|
|
31
40
|
"INFRAHUB_TESTING_API_TOKEN": "44af444d-3b26-410d-9546-b758657e026c",
|
|
32
41
|
"INFRAHUB_TESTING_INITIAL_ADMIN_TOKEN": "06438eb2-8019-4776-878c-0941b1f1d1ec",
|
|
@@ -37,6 +46,7 @@ PROJECT_ENV_VARIABLES: dict[str, str] = {
|
|
|
37
46
|
"INFRAHUB_TESTING_BROKER_ADDRESS": "message-queue",
|
|
38
47
|
"INFRAHUB_TESTING_CACHE_ADDRESS": "cache",
|
|
39
48
|
"INFRAHUB_TESTING_WORKFLOW_ADDRESS": "task-manager",
|
|
49
|
+
"INFRAHUB_TESTING_WORKFLOW_DEFAULT_WORKER_TYPE": "infrahubasync",
|
|
40
50
|
"INFRAHUB_TESTING_TIMEOUT": "60",
|
|
41
51
|
"INFRAHUB_TESTING_PREFECT_API": "http://task-manager:4200/api",
|
|
42
52
|
"INFRAHUB_TESTING_LOCAL_REMOTE_GIT_DIRECTORY": "repos",
|
|
@@ -52,6 +62,7 @@ PROJECT_ENV_VARIABLES: dict[str, str] = {
|
|
|
52
62
|
@dataclass
|
|
53
63
|
class InfrahubDockerCompose(DockerCompose):
|
|
54
64
|
project_name: str | None = None
|
|
65
|
+
env_vars: dict[str, str] = field(default_factory=dict)
|
|
55
66
|
|
|
56
67
|
@classmethod
|
|
57
68
|
def init(cls, directory: Path | None = None, version: str | None = None) -> Self:
|
|
@@ -65,43 +76,111 @@ class InfrahubDockerCompose(DockerCompose):
|
|
|
65
76
|
if version == "local" and infrahub_image_version:
|
|
66
77
|
version = infrahub_image_version
|
|
67
78
|
|
|
68
|
-
cls.
|
|
69
|
-
|
|
79
|
+
compose = cls(project_name=cls.generate_project_name(), context=directory)
|
|
80
|
+
compose.create_docker_file(directory=directory)
|
|
81
|
+
compose.create_env_file(directory=directory, version=version)
|
|
70
82
|
|
|
71
|
-
return
|
|
83
|
+
return compose
|
|
84
|
+
|
|
85
|
+
def get_env_var(self, key: str) -> str:
|
|
86
|
+
if not self.env_vars:
|
|
87
|
+
raise ValueError("env_vars hasn't been initialized yet")
|
|
88
|
+
if key not in self.env_vars:
|
|
89
|
+
raise ValueError(f"{key} is not set in the environment variables")
|
|
90
|
+
return self.env_vars[key]
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def use_neo4j_enterprise(self) -> bool:
|
|
94
|
+
return "enterprise" in self.get_env_var("NEO4J_DOCKER_IMAGE")
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def internal_backup_dir(self) -> Path:
|
|
98
|
+
return Path(self.get_env_var("INFRAHUB_TESTING_INTERNAL_DB_BACKUP_DIRECTORY"))
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def external_backup_dir(self) -> Path:
|
|
102
|
+
return Path(self.context) / Path(self.get_env_var("INFRAHUB_TESTING_LOCAL_DB_BACKUP_DIRECTORY"))
|
|
72
103
|
|
|
73
104
|
@classmethod
|
|
74
105
|
def generate_project_name(cls) -> str:
|
|
75
106
|
project_id = str(uuid.uuid4())[:8]
|
|
76
107
|
return f"infrahub-test-{project_id}"
|
|
77
108
|
|
|
78
|
-
|
|
79
|
-
def create_docker_file(cls, directory: Path) -> Path:
|
|
109
|
+
def create_docker_file(self, directory: Path) -> Path:
|
|
80
110
|
current_directory = Path(__file__).resolve().parent
|
|
81
111
|
compose_file = current_directory / "docker-compose.test.yml"
|
|
82
112
|
|
|
83
113
|
test_compose_file = directory / "docker-compose.yml"
|
|
84
114
|
test_compose_file.write_bytes(compose_file.read_bytes())
|
|
85
115
|
|
|
86
|
-
|
|
116
|
+
for file in ["haproxy.cfg", "prometheus.yml"]:
|
|
117
|
+
config_file = current_directory / file
|
|
87
118
|
|
|
88
|
-
|
|
89
|
-
|
|
119
|
+
test_config_file = directory / file
|
|
120
|
+
test_config_file.write_bytes(config_file.read_bytes())
|
|
90
121
|
|
|
91
122
|
return test_compose_file
|
|
92
123
|
|
|
93
|
-
|
|
94
|
-
def create_env_file(cls, directory: Path, version: str) -> Path:
|
|
124
|
+
def create_env_file(self, directory: Path, version: str) -> Path:
|
|
95
125
|
env_file = directory / ".env"
|
|
96
126
|
|
|
97
127
|
PROJECT_ENV_VARIABLES.update({"INFRAHUB_TESTING_IMAGE_VERSION": version})
|
|
128
|
+
if os.environ.get("INFRAHUB_TESTING_ENTERPRISE"):
|
|
129
|
+
PROJECT_ENV_VARIABLES.update(
|
|
130
|
+
{
|
|
131
|
+
"INFRAHUB_TESTING_DOCKER_IMAGE": "registry.opsmill.io/opsmill/infrahub-enterprise",
|
|
132
|
+
"INFRAHUB_TESTING_DOCKER_ENTRYPOINT": f"gunicorn --config community/backend/infrahub/serve/gunicorn_config.py -w {os.environ.get('INFRAHUB_TESTING_WEB_CONCURRENCY', 4)} --logger-class infrahub.serve.log.GunicornLogger infrahub_enterprise.server:app", # noqa: E501
|
|
133
|
+
"INFRAHUB_TESTING_WORKFLOW_DEFAULT_WORKER_TYPE": "infrahubentasync",
|
|
134
|
+
"NEO4J_DOCKER_IMAGE": "neo4j:5.20.0-enterprise",
|
|
135
|
+
}
|
|
136
|
+
)
|
|
98
137
|
|
|
99
138
|
with env_file.open(mode="w", encoding="utf-8") as file:
|
|
100
139
|
for key, value in PROJECT_ENV_VARIABLES.items():
|
|
101
140
|
env_var_value = os.environ.get(key, value)
|
|
102
141
|
file.write(f"{key}={env_var_value}\n")
|
|
142
|
+
self.env_vars[key] = env_var_value
|
|
143
|
+
|
|
103
144
|
return env_file.absolute()
|
|
104
145
|
|
|
146
|
+
def restart(self) -> None:
|
|
147
|
+
"""
|
|
148
|
+
Restart the docker compose environment.
|
|
149
|
+
|
|
150
|
+
TODO Would be good to contribute this upstream
|
|
151
|
+
"""
|
|
152
|
+
cmd = self.compose_command_property[:]
|
|
153
|
+
cmd += ["restart"]
|
|
154
|
+
|
|
155
|
+
if self.services:
|
|
156
|
+
cmd.extend(self.services)
|
|
157
|
+
self._run_command(cmd=cmd)
|
|
158
|
+
|
|
159
|
+
def start_container(self, service_name: str) -> None:
|
|
160
|
+
"""
|
|
161
|
+
Starts a specific service of the docker compose environment.
|
|
162
|
+
|
|
163
|
+
TODO Would be good to contribute this upstream
|
|
164
|
+
"""
|
|
165
|
+
base_cmd = self.compose_command_property or []
|
|
166
|
+
|
|
167
|
+
# pull means running a separate command before starting
|
|
168
|
+
if self.pull:
|
|
169
|
+
pull_cmd = [*base_cmd, "pull", service_name]
|
|
170
|
+
self._run_command(cmd=pull_cmd)
|
|
171
|
+
|
|
172
|
+
up_cmd = [*base_cmd, "up"]
|
|
173
|
+
|
|
174
|
+
# build means modifying the up command
|
|
175
|
+
if self.wait:
|
|
176
|
+
up_cmd.append("--wait")
|
|
177
|
+
else:
|
|
178
|
+
# we run in detached mode instead of blocking
|
|
179
|
+
up_cmd.append("--detach")
|
|
180
|
+
|
|
181
|
+
up_cmd.append(service_name)
|
|
182
|
+
self._run_command(cmd=up_cmd)
|
|
183
|
+
|
|
105
184
|
# TODO would be good to the support for project_name upstream
|
|
106
185
|
@cached_property
|
|
107
186
|
def compose_command_property(self) -> list[str]:
|
|
@@ -120,3 +199,69 @@ class InfrahubDockerCompose(DockerCompose):
|
|
|
120
199
|
service_name: int(self.get_service_port(service_name=service_data.container, port=service_data.port) or 0)
|
|
121
200
|
for service_name, service_data in INFRAHUB_SERVICES.items()
|
|
122
201
|
}
|
|
202
|
+
|
|
203
|
+
def database_create_backup(self, backup_name: str = "neo4j_database.backup", dest_dir: Path | None = None) -> None:
|
|
204
|
+
assert self.use_neo4j_enterprise
|
|
205
|
+
|
|
206
|
+
self.exec_in_container(
|
|
207
|
+
command=[
|
|
208
|
+
"neo4j-admin",
|
|
209
|
+
"database",
|
|
210
|
+
"backup",
|
|
211
|
+
"--compress=false",
|
|
212
|
+
"--to-path",
|
|
213
|
+
str(self.internal_backup_dir),
|
|
214
|
+
],
|
|
215
|
+
service_name="database",
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
if dest_dir:
|
|
219
|
+
backup_files = list(self.external_backup_dir.glob("*.backup"))
|
|
220
|
+
if not backup_files:
|
|
221
|
+
raise FileNotFoundError(f"No .backup files found in {self.external_backup_dir}")
|
|
222
|
+
|
|
223
|
+
backup_file = backup_files[0]
|
|
224
|
+
shutil.copy(
|
|
225
|
+
backup_file,
|
|
226
|
+
dest_dir / backup_name,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
def database_restore_backup(self, backup_file: Path) -> None:
|
|
230
|
+
assert self.use_neo4j_enterprise
|
|
231
|
+
|
|
232
|
+
shutil.copy(
|
|
233
|
+
str(backup_file),
|
|
234
|
+
str(self.external_backup_dir / backup_file.name),
|
|
235
|
+
)
|
|
236
|
+
service_name = "database"
|
|
237
|
+
|
|
238
|
+
# Ensure the database container is running otherwise start it
|
|
239
|
+
try:
|
|
240
|
+
self.get_container(service_name=service_name)
|
|
241
|
+
except ContainerIsNotRunning:
|
|
242
|
+
self.start_container(service_name=service_name)
|
|
243
|
+
|
|
244
|
+
self.exec_in_container(
|
|
245
|
+
command=["cypher-shell", "-u", "neo4j", "-p", "admin", "STOP DATABASE neo4j;"],
|
|
246
|
+
service_name=service_name,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
self.exec_in_container(
|
|
250
|
+
command=[
|
|
251
|
+
"neo4j-admin",
|
|
252
|
+
"database",
|
|
253
|
+
"restore",
|
|
254
|
+
"--overwrite-destination",
|
|
255
|
+
"--from-path",
|
|
256
|
+
str(self.internal_backup_dir / backup_file.name),
|
|
257
|
+
],
|
|
258
|
+
service_name=service_name,
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
self.exec_in_container(
|
|
262
|
+
command=["cypher-shell", "-d", "system", "-u", "neo4j", "-p", "admin", "START DATABASE neo4j;"],
|
|
263
|
+
service_name=service_name,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
self.stop(down=False)
|
|
267
|
+
self.start()
|
|
@@ -102,11 +102,7 @@ services:
|
|
|
102
102
|
mode: replicated
|
|
103
103
|
replicas: ${INFRAHUB_TESTING_API_SERVER_COUNT}
|
|
104
104
|
image: "${INFRAHUB_TESTING_DOCKER_IMAGE}:${INFRAHUB_TESTING_IMAGE_VERSION}"
|
|
105
|
-
command:
|
|
106
|
-
gunicorn --config backend/infrahub/serve/gunicorn_config.py
|
|
107
|
-
-w ${INFRAHUB_TESTING_WEB_CONCURRENCY}
|
|
108
|
-
--logger-class infrahub.serve.log.GunicornLogger
|
|
109
|
-
infrahub.server:app
|
|
105
|
+
command: ${INFRAHUB_TESTING_DOCKER_ENTRYPOINT}
|
|
110
106
|
environment:
|
|
111
107
|
INFRAHUB_PRODUCTION: ${INFRAHUB_TESTING_PRODUCTION}
|
|
112
108
|
INFRAHUB_LOG_LEVEL: ${INFRAHUB_TESTING_LOG_LEVEL:-INFO}
|
|
@@ -114,6 +110,7 @@ services:
|
|
|
114
110
|
INFRAHUB_CACHE_ADDRESS: ${INFRAHUB_TESTING_CACHE_ADDRESS}
|
|
115
111
|
INFRAHUB_DB_ADDRESS: ${INFRAHUB_TESTING_DB_ADDRESS}
|
|
116
112
|
INFRAHUB_WORKFLOW_ADDRESS: ${INFRAHUB_TESTING_WORKFLOW_ADDRESS}
|
|
113
|
+
INFRAHUB_WORKFLOW_DEFAULT_WORKER_TYPE: ${INFRAHUB_TESTING_WORKFLOW_DEFAULT_WORKER_TYPE}
|
|
117
114
|
INFRAHUB_INITIAL_ADMIN_TOKEN: ${INFRAHUB_TESTING_INITIAL_ADMIN_TOKEN}
|
|
118
115
|
INFRAHUB_INITIAL_AGENT_TOKEN: ${INFRAHUB_TESTING_INITIAL_AGENT_TOKEN}
|
|
119
116
|
INFRAHUB_SECURITY_SECRET_KEY: ${INFRAHUB_TESTING_SECURITY_SECRET_KEY}
|
|
@@ -142,7 +139,7 @@ services:
|
|
|
142
139
|
mode: replicated
|
|
143
140
|
replicas: ${INFRAHUB_TESTING_TASK_WORKER_COUNT}
|
|
144
141
|
image: "${INFRAHUB_TESTING_DOCKER_IMAGE}:${INFRAHUB_TESTING_IMAGE_VERSION}"
|
|
145
|
-
command: prefect worker start --type
|
|
142
|
+
command: prefect worker start --type ${INFRAHUB_TESTING_WORKFLOW_DEFAULT_WORKER_TYPE} --pool infrahub-worker --with-healthcheck
|
|
146
143
|
environment:
|
|
147
144
|
INFRAHUB_PRODUCTION: ${INFRAHUB_TESTING_PRODUCTION}
|
|
148
145
|
INFRAHUB_LOG_LEVEL: ${INFRAHUB_TESTING_LOG_LEVEL}
|
|
@@ -163,8 +160,36 @@ services:
|
|
|
163
160
|
- "./${INFRAHUB_TESTING_LOCAL_REMOTE_GIT_DIRECTORY}:${INFRAHUB_TESTING_INTERNAL_REMOTE_GIT_DIRECTORY}"
|
|
164
161
|
tty: true
|
|
165
162
|
|
|
163
|
+
cadvisor:
|
|
164
|
+
image: "${CADVISOR_DOCKER_IMAGE:-gcr.io/cadvisor/cadvisor:v0.51.0}"
|
|
165
|
+
command:
|
|
166
|
+
- -disable_root_cgroup_stats=true
|
|
167
|
+
- -docker_only=true
|
|
168
|
+
- -store_container_labels=false
|
|
169
|
+
- -whitelisted_container_labels=com.docker.compose.project
|
|
170
|
+
privileged: true
|
|
171
|
+
volumes:
|
|
172
|
+
- /:/rootfs:ro
|
|
173
|
+
- /var/run:/var/run:ro
|
|
174
|
+
- /sys:/sys:ro
|
|
175
|
+
- /var/lib/docker:/var/lib/docker:ro
|
|
176
|
+
- /dev/disk/:/dev/disk:ro
|
|
177
|
+
ports:
|
|
178
|
+
- "${INFRAHUB_TESTING_CADVISOR_PORT:-0}:8080"
|
|
179
|
+
|
|
180
|
+
scraper:
|
|
181
|
+
image: "${SCRAPER_DOCKER_IMAGE:-victoriametrics/victoria-metrics:v1.110.0}"
|
|
182
|
+
volumes:
|
|
183
|
+
- vmdata:/victoria-metrics-data
|
|
184
|
+
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
|
185
|
+
command:
|
|
186
|
+
- "--promscrape.config=/etc/prometheus/prometheus.yml"
|
|
187
|
+
ports:
|
|
188
|
+
- ${INFRAHUB_TESTING_SCRAPER_PORT:-0}:8428
|
|
189
|
+
|
|
166
190
|
volumes:
|
|
167
191
|
database_data:
|
|
168
192
|
database_logs:
|
|
169
193
|
storage_data:
|
|
170
194
|
workflow_db:
|
|
195
|
+
vmdata:
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import os
|
|
2
|
-
import shutil
|
|
3
2
|
import subprocess # noqa: S404
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
|
|
@@ -15,7 +14,8 @@ class TestInfrahubDocker:
|
|
|
15
14
|
def infrahub_version(self) -> str:
|
|
16
15
|
return infrahub_version
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
@staticmethod
|
|
18
|
+
def execute_ctl_run(address: str, script: str) -> str:
|
|
19
19
|
env = os.environ.copy()
|
|
20
20
|
env["INFRAHUB_ADDRESS"] = address
|
|
21
21
|
env["INFRAHUB_API_TOKEN"] = PROJECT_ENV_VARIABLES["INFRAHUB_TESTING_INITIAL_ADMIN_TOKEN"]
|
|
@@ -25,6 +25,17 @@ class TestInfrahubDocker:
|
|
|
25
25
|
)
|
|
26
26
|
return result.stdout
|
|
27
27
|
|
|
28
|
+
@staticmethod
|
|
29
|
+
def execute_command(command: str, address: str, concurrent_execution: int = 10) -> subprocess.CompletedProcess[str]:
|
|
30
|
+
env = os.environ.copy()
|
|
31
|
+
env["INFRAHUB_ADDRESS"] = address
|
|
32
|
+
env["INFRAHUB_API_TOKEN"] = PROJECT_ENV_VARIABLES["INFRAHUB_TESTING_INITIAL_ADMIN_TOKEN"]
|
|
33
|
+
env["INFRAHUB_MAX_CONCURRENT_EXECUTION"] = f"{concurrent_execution}"
|
|
34
|
+
result = subprocess.run( # noqa: S602
|
|
35
|
+
command, shell=True, capture_output=True, text=True, env=env, check=False
|
|
36
|
+
)
|
|
37
|
+
return result
|
|
38
|
+
|
|
28
39
|
@pytest.fixture(scope="class")
|
|
29
40
|
def tmp_directory(self, tmpdir_factory: pytest.TempdirFactory) -> Path:
|
|
30
41
|
directory = Path(str(tmpdir_factory.getbasetemp().strpath))
|
|
@@ -65,7 +76,11 @@ class TestInfrahubDocker:
|
|
|
65
76
|
|
|
66
77
|
request.addfinalizer(cleanup)
|
|
67
78
|
|
|
68
|
-
|
|
79
|
+
try:
|
|
80
|
+
infrahub_compose.start()
|
|
81
|
+
except Exception as exc:
|
|
82
|
+
stdout, stderr = infrahub_compose.get_logs()
|
|
83
|
+
raise Exception(f"Failed to start docker compose:\nStdout:\n{stdout}\nStderr:\n{stderr}") from exc
|
|
69
84
|
|
|
70
85
|
return infrahub_compose.get_services_port()
|
|
71
86
|
|
|
@@ -76,73 +91,3 @@ class TestInfrahubDocker:
|
|
|
76
91
|
@pytest.fixture(scope="class")
|
|
77
92
|
def task_manager_port(self, infrahub_app: dict[str, int]) -> int:
|
|
78
93
|
return infrahub_app["task-manager"]
|
|
79
|
-
|
|
80
|
-
def backup_database(self, request: pytest.FixtureRequest, dest_dir: Path | None = None) -> None:
|
|
81
|
-
assert "enterprise" in os.environ.get("NEO4J_DOCKER_IMAGE", "")
|
|
82
|
-
|
|
83
|
-
backup_dir: Path = request.getfixturevalue("remote_backups_dir")
|
|
84
|
-
infrahub_compose: InfrahubDockerCompose = request.getfixturevalue("infrahub_compose")
|
|
85
|
-
|
|
86
|
-
infrahub_compose.exec_in_container(
|
|
87
|
-
command=[
|
|
88
|
-
"neo4j-admin",
|
|
89
|
-
"database",
|
|
90
|
-
"backup",
|
|
91
|
-
"--to-path",
|
|
92
|
-
os.environ.get(
|
|
93
|
-
"INFRAHUB_TESTING_INTERNAL_DB_BACKUP_DIRECTORY",
|
|
94
|
-
PROJECT_ENV_VARIABLES["INFRAHUB_TESTING_INTERNAL_DB_BACKUP_DIRECTORY"],
|
|
95
|
-
),
|
|
96
|
-
],
|
|
97
|
-
service_name="database",
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
if dest_dir:
|
|
101
|
-
shutil.copytree(
|
|
102
|
-
str(backup_dir),
|
|
103
|
-
str(dest_dir),
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
def restore_database(self, request: pytest.FixtureRequest, backup_file: Path) -> None:
|
|
107
|
-
assert "enterprise" in os.environ.get("NEO4J_DOCKER_IMAGE", "")
|
|
108
|
-
|
|
109
|
-
backup_dir: Path = request.getfixturevalue("remote_backups_dir")
|
|
110
|
-
infrahub_compose: InfrahubDockerCompose = request.getfixturevalue("infrahub_compose")
|
|
111
|
-
|
|
112
|
-
shutil.copy(
|
|
113
|
-
str(backup_file),
|
|
114
|
-
str(backup_dir / backup_file.name),
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
infrahub_compose.exec_in_container(
|
|
118
|
-
command=["cypher-shell", "-u", "neo4j", "-p", "admin", "STOP DATABASE neo4j;"],
|
|
119
|
-
service_name="database",
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
infrahub_compose.exec_in_container(
|
|
123
|
-
command=[
|
|
124
|
-
"neo4j-admin",
|
|
125
|
-
"database",
|
|
126
|
-
"restore",
|
|
127
|
-
"--overwrite-destination",
|
|
128
|
-
"--from-path",
|
|
129
|
-
str(
|
|
130
|
-
Path(
|
|
131
|
-
os.environ.get(
|
|
132
|
-
"INFRAHUB_TESTING_INTERNAL_DB_BACKUP_DIRECTORY",
|
|
133
|
-
PROJECT_ENV_VARIABLES["INFRAHUB_TESTING_INTERNAL_DB_BACKUP_DIRECTORY"],
|
|
134
|
-
)
|
|
135
|
-
)
|
|
136
|
-
/ backup_file.name
|
|
137
|
-
),
|
|
138
|
-
],
|
|
139
|
-
service_name="database",
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
infrahub_compose.exec_in_container(
|
|
143
|
-
command=["cypher-shell", "-d", "system", "-u", "neo4j", "-p", "admin", "START DATABASE neo4j;"],
|
|
144
|
-
service_name="database",
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
infrahub_compose.stop(down=False)
|
|
148
|
-
infrahub_compose.start()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import platform
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import psutil
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_system_stats() -> dict[str, Any]:
|
|
8
|
+
"""
|
|
9
|
+
Gather and return key system statistics about CPU, memory and platform
|
|
10
|
+
Returns a dictionary with system information
|
|
11
|
+
"""
|
|
12
|
+
# CPU information
|
|
13
|
+
cpu_freq = psutil.cpu_freq()
|
|
14
|
+
cpu_stats = {
|
|
15
|
+
"cpu_count_physical": psutil.cpu_count(logical=False),
|
|
16
|
+
"cpu_count_logical": psutil.cpu_count(logical=True),
|
|
17
|
+
"cpu_freq_current": float(f"{cpu_freq.current:.2f}") if cpu_freq else None, # MHz
|
|
18
|
+
"cpu_freq_min": float(f"{cpu_freq.min:.2f}") if cpu_freq else None, # MHz
|
|
19
|
+
"cpu_freq_max": float(f"{cpu_freq.max:.2f}") if cpu_freq else None, # MHz
|
|
20
|
+
"cpu_percent": psutil.cpu_percent(interval=1, percpu=False),
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# Memory information
|
|
24
|
+
memory = psutil.virtual_memory()
|
|
25
|
+
memory_stats = {
|
|
26
|
+
"total_memory": float(f"{memory.total / (1024**3):.2f}"), # GB
|
|
27
|
+
"available_memory": float(f"{memory.available / (1024**3):.2f}"), # GB
|
|
28
|
+
"memory_percent_used": memory.percent,
|
|
29
|
+
"memory_used": float(f"{memory.used / (1024**3):.2f}"), # GB
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Platform information
|
|
33
|
+
platform_stats = {
|
|
34
|
+
"system": platform.system(),
|
|
35
|
+
"platform_release": platform.release(),
|
|
36
|
+
"platform_version": platform.version(),
|
|
37
|
+
"architecture": platform.machine(),
|
|
38
|
+
"processor": platform.processor(),
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {"cpu": cpu_stats, "memory": memory_stats, "platform": platform_stats}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
from .models import ContextUnit, MeasurementDefinition
|
|
2
|
+
|
|
3
|
+
NODE_QUERY_TIME = MeasurementDefinition(
|
|
4
|
+
name="node_query",
|
|
5
|
+
description="Query some nodes",
|
|
6
|
+
dimensions=["kind"],
|
|
7
|
+
unit=ContextUnit.TIME,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
NODE_CREATE_TIME = MeasurementDefinition(
|
|
11
|
+
name="node_mutation_create",
|
|
12
|
+
description="Create a new node",
|
|
13
|
+
dimensions=["kind"],
|
|
14
|
+
unit=ContextUnit.TIME,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
NODE_UPDATE_TIME = MeasurementDefinition(
|
|
18
|
+
name="node_mutation_update",
|
|
19
|
+
description="Update an existing node",
|
|
20
|
+
dimensions=["kind"],
|
|
21
|
+
unit=ContextUnit.TIME,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
NODE_DELETE_TIME = MeasurementDefinition(
|
|
25
|
+
name="node_mutation_delete",
|
|
26
|
+
description="Delete a node",
|
|
27
|
+
dimensions=["kind"],
|
|
28
|
+
unit=ContextUnit.TIME,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
SCHEMA_INITIAL_LOAD_TIME = MeasurementDefinition(
|
|
32
|
+
name="schema_initial_load",
|
|
33
|
+
description="Load the initial schema",
|
|
34
|
+
dimensions=["branch"],
|
|
35
|
+
unit=ContextUnit.TIME,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
SCHEMA_UPDATE_TIME = MeasurementDefinition(
|
|
39
|
+
name="schema_update",
|
|
40
|
+
description="Update the schema",
|
|
41
|
+
dimensions=["branch"],
|
|
42
|
+
unit=ContextUnit.TIME,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
DATABASE_SIZE = MeasurementDefinition(
|
|
46
|
+
name="database_size",
|
|
47
|
+
description="Size of the database",
|
|
48
|
+
unit=ContextUnit.DISK,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
DIFF_CREATE_TIME = MeasurementDefinition(
|
|
52
|
+
name="diff_create",
|
|
53
|
+
description="Create a new diff",
|
|
54
|
+
unit=ContextUnit.TIME,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
DIFF_APPLY_TIME = MeasurementDefinition(
|
|
58
|
+
name="diff_update",
|
|
59
|
+
description="Update an existing diff",
|
|
60
|
+
unit=ContextUnit.TIME,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
BRANCH_CREATE_TIME = MeasurementDefinition(
|
|
64
|
+
name="branch_create",
|
|
65
|
+
description="Create a new branch",
|
|
66
|
+
unit=ContextUnit.TIME,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
BRANCH_MERGE_TIME = MeasurementDefinition(
|
|
70
|
+
name="branch_merge",
|
|
71
|
+
description="Merge a branch",
|
|
72
|
+
unit=ContextUnit.TIME,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
BRANCH_REBASE_TIME = MeasurementDefinition(
|
|
76
|
+
name="branch_rebase",
|
|
77
|
+
description="Rebase a branch",
|
|
78
|
+
unit=ContextUnit.TIME,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
SCRIPT_EXECUTION_TIME = MeasurementDefinition(
|
|
82
|
+
name="script_execution",
|
|
83
|
+
description="Execute a script",
|
|
84
|
+
dimensions=["name"],
|
|
85
|
+
unit=ContextUnit.TIME,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
GENERATOR_EXECUTION_TIME = MeasurementDefinition(
|
|
89
|
+
name="generator_execution",
|
|
90
|
+
description="Execute a generator",
|
|
91
|
+
dimensions=["name"],
|
|
92
|
+
unit=ContextUnit.TIME,
|
|
93
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from datetime import UTC, datetime
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ContextUnit(str, Enum):
|
|
9
|
+
COUNT = "count"
|
|
10
|
+
TIME = "msec" # time in milliseconds
|
|
11
|
+
MEMORY = "memory" # memory in bytes
|
|
12
|
+
DISK = "disk" # disk in bytes
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MeasurementDefinition(BaseModel):
|
|
16
|
+
name: str
|
|
17
|
+
description: str
|
|
18
|
+
dimensions: list[str] = Field(default_factory=dict)
|
|
19
|
+
unit: ContextUnit
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class InfrahubResultContext(BaseModel):
|
|
23
|
+
name: str
|
|
24
|
+
value: int | float | str
|
|
25
|
+
unit: ContextUnit
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class InfrahubActiveMeasurementItem(BaseModel):
|
|
29
|
+
definition: MeasurementDefinition
|
|
30
|
+
start_time: datetime = datetime.now(UTC)
|
|
31
|
+
context: dict[str, Any] = Field(default_factory=dict)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class InfrahubMeasurementItem(BaseModel):
|
|
35
|
+
name: str
|
|
36
|
+
value: int | float | str
|
|
37
|
+
unit: ContextUnit
|
|
38
|
+
context: dict[str, Any] = Field(default_factory=dict)
|