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
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import json
|
|
3
|
+
from datetime import UTC, datetime
|
|
4
|
+
from types import TracebackType
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
import pytest
|
|
9
|
+
from typing_extensions import Self
|
|
10
|
+
|
|
11
|
+
from .constants import PERFORMANCE_TEST_KIND, PERFORMANCE_TEST_VERSION
|
|
12
|
+
from .helpers import InfrahubDockerCompose
|
|
13
|
+
from .host import get_system_stats
|
|
14
|
+
from .models import (
|
|
15
|
+
ContextUnit,
|
|
16
|
+
InfrahubActiveMeasurementItem,
|
|
17
|
+
InfrahubMeasurementItem,
|
|
18
|
+
InfrahubResultContext,
|
|
19
|
+
MeasurementDefinition,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class InfrahubPerformanceTest:
|
|
24
|
+
context: dict[str, InfrahubResultContext]
|
|
25
|
+
measurements: list[InfrahubMeasurementItem]
|
|
26
|
+
active_measurements: InfrahubActiveMeasurementItem | None = None
|
|
27
|
+
|
|
28
|
+
def __init__(self, results_url: str) -> None:
|
|
29
|
+
self.name: str | None = None
|
|
30
|
+
self.infrahub_version: str | None = None
|
|
31
|
+
self.context = {}
|
|
32
|
+
self.measurements = []
|
|
33
|
+
self.metrics = {}
|
|
34
|
+
self.host = get_system_stats()
|
|
35
|
+
self.env_vars = {}
|
|
36
|
+
self.project_name = ""
|
|
37
|
+
self.test_info = {}
|
|
38
|
+
self.start_time = datetime.now(UTC)
|
|
39
|
+
self.end_time: datetime | None = None
|
|
40
|
+
self.results_url = results_url
|
|
41
|
+
self.scraper_endpoint = ""
|
|
42
|
+
self.initialized = False
|
|
43
|
+
|
|
44
|
+
def initialize(
|
|
45
|
+
self,
|
|
46
|
+
name: str,
|
|
47
|
+
compose: InfrahubDockerCompose | None = None,
|
|
48
|
+
client: Any | None = None, # noqa: ANN401
|
|
49
|
+
) -> None:
|
|
50
|
+
self.name = name
|
|
51
|
+
if client:
|
|
52
|
+
self.infrahub_version = client.get_version()
|
|
53
|
+
if compose:
|
|
54
|
+
self.extract_compose_information(compose)
|
|
55
|
+
|
|
56
|
+
self.initialized = True
|
|
57
|
+
|
|
58
|
+
def finalize(self, session: pytest.Session) -> None:
|
|
59
|
+
if self.initialized:
|
|
60
|
+
self.end_time = datetime.now(UTC)
|
|
61
|
+
self.extract_test_session_information(session)
|
|
62
|
+
self.send_results()
|
|
63
|
+
|
|
64
|
+
def extract_compose_information(self, compose: InfrahubDockerCompose) -> None:
|
|
65
|
+
self.env_vars = compose.env_vars
|
|
66
|
+
self.project_name = compose.project_name
|
|
67
|
+
self.scraper_endpoint = (
|
|
68
|
+
f"http://127.0.0.1:{compose.get_service_host_and_port(service_name='scraper')[1]}/api/v1/export"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def extract_test_session_information(self, session: pytest.Session) -> None:
|
|
72
|
+
self.test_info = {
|
|
73
|
+
"summary": {
|
|
74
|
+
"exitstatus": session.exitstatus,
|
|
75
|
+
"nbr_tests": session.testscollected,
|
|
76
|
+
"nbr_errors": session.testsfailed,
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
def add_context(self, name: str, value: float | str = 0, unit: ContextUnit = ContextUnit.COUNT) -> None:
|
|
81
|
+
self.context[name] = InfrahubResultContext(name=name, value=value, unit=unit)
|
|
82
|
+
|
|
83
|
+
def add_measurement(
|
|
84
|
+
self,
|
|
85
|
+
definition: MeasurementDefinition,
|
|
86
|
+
value: float | str,
|
|
87
|
+
**kwargs: str | float,
|
|
88
|
+
) -> None:
|
|
89
|
+
self.measurements.append(
|
|
90
|
+
InfrahubMeasurementItem(
|
|
91
|
+
name=definition.name,
|
|
92
|
+
value=value,
|
|
93
|
+
unit=definition.unit,
|
|
94
|
+
context=kwargs or {},
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def start_measurement(self, definition: MeasurementDefinition, **kwargs: str | float) -> Self:
|
|
99
|
+
self.active_measurements = InfrahubActiveMeasurementItem(definition=definition, context=kwargs or {})
|
|
100
|
+
return self
|
|
101
|
+
|
|
102
|
+
def fetch_metrics(self) -> None:
|
|
103
|
+
with httpx.Client() as client:
|
|
104
|
+
# Get Infrahub metrics
|
|
105
|
+
response = client.post(
|
|
106
|
+
url=self.scraper_endpoint,
|
|
107
|
+
content='match[]={__name__=~"infrahub.*"}',
|
|
108
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
109
|
+
)
|
|
110
|
+
self.metrics = [json.loads(line) for line in response.text.splitlines()]
|
|
111
|
+
|
|
112
|
+
# Get system metrics, filter by docker project name
|
|
113
|
+
response = client.post(
|
|
114
|
+
url=self.scraper_endpoint,
|
|
115
|
+
content=f'match[]={{__name__=~"container.*", container_label_com_docker_compose_project="{self.project_name}"}}',
|
|
116
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
117
|
+
)
|
|
118
|
+
self.metrics += [json.loads(line) for line in response.text.splitlines()]
|
|
119
|
+
|
|
120
|
+
def __enter__(self) -> Self:
|
|
121
|
+
return self
|
|
122
|
+
|
|
123
|
+
def __exit__(
|
|
124
|
+
self,
|
|
125
|
+
exc_type: type[BaseException] | None,
|
|
126
|
+
exc_value: BaseException | None,
|
|
127
|
+
traceback: TracebackType | None,
|
|
128
|
+
) -> None:
|
|
129
|
+
if not exc_type and self.active_measurements:
|
|
130
|
+
self.add_measurement(
|
|
131
|
+
definition=self.active_measurements.definition,
|
|
132
|
+
value=(datetime.now(UTC) - self.active_measurements.start_time).total_seconds() * 1000,
|
|
133
|
+
context=self.active_measurements.context,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Don't record the measurement if the test failed
|
|
137
|
+
self.active_measurements = None
|
|
138
|
+
|
|
139
|
+
def _get_payload(self) -> dict[str, Any]:
|
|
140
|
+
return {
|
|
141
|
+
"name": self.name,
|
|
142
|
+
"infrahub_version": self.infrahub_version,
|
|
143
|
+
"start_time": self.start_time.isoformat(),
|
|
144
|
+
"end_time": self.end_time.isoformat() if self.end_time else None,
|
|
145
|
+
"duration": (self.end_time - self.start_time).total_seconds() * 1000 if self.end_time else None,
|
|
146
|
+
"context": [item.model_dump() for item in self.context.values()],
|
|
147
|
+
"measurements": [item.model_dump() for item in self.measurements],
|
|
148
|
+
"metrics": self.metrics,
|
|
149
|
+
"host": self.host,
|
|
150
|
+
"env_vars": self.env_vars,
|
|
151
|
+
"test_info": self.test_info,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
def send_results(self) -> None:
|
|
155
|
+
data = self._get_payload()
|
|
156
|
+
|
|
157
|
+
payload = {
|
|
158
|
+
"kind": PERFORMANCE_TEST_KIND,
|
|
159
|
+
"payload_format": PERFORMANCE_TEST_VERSION,
|
|
160
|
+
"data": data,
|
|
161
|
+
"checksum": hashlib.sha256(json.dumps(data).encode()).hexdigest(),
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
with httpx.Client() as client:
|
|
165
|
+
response = client.post(self.results_url, json=payload)
|
|
166
|
+
response.raise_for_status()
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from .performance_test import InfrahubPerformanceTest
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
import _pytest
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def pytest_addoption(parser: pytest.Parser) -> None:
|
|
14
|
+
group = parser.getgroup("infrahub-performance-test")
|
|
15
|
+
|
|
16
|
+
group.addoption(
|
|
17
|
+
"--performance-result-address",
|
|
18
|
+
action="store",
|
|
19
|
+
dest="infrahub_performance_test_result_address",
|
|
20
|
+
default="https://webhook.site/25802839-4b34-433e-9dc4-59623cd73c80",
|
|
21
|
+
metavar="INFRAHUB_PERFORMANCE_TEST_RESULT_ADDRESS",
|
|
22
|
+
help="Address to send the results of the performance test (default: %(default)s)",
|
|
23
|
+
)
|
|
24
|
+
group.addoption(
|
|
25
|
+
"--performance-backup",
|
|
26
|
+
action="store",
|
|
27
|
+
dest="infrahub_performance_backup",
|
|
28
|
+
default="neo4j_database.db",
|
|
29
|
+
metavar="INFRAHUB_PERFORMANCE_BACKUP",
|
|
30
|
+
help="Name of the backup to use (default: %(default)s)",
|
|
31
|
+
)
|
|
32
|
+
group.addoption(
|
|
33
|
+
"--performance-backup-location",
|
|
34
|
+
action="store",
|
|
35
|
+
dest="infrahub_performance_backup_location",
|
|
36
|
+
metavar="INFRAHUB_PERFORMANCE_BACKUP_LOCATION",
|
|
37
|
+
help="Location of the backup to use (default: %(default)s)",
|
|
38
|
+
)
|
|
39
|
+
group.addoption(
|
|
40
|
+
"--performance-create-backup",
|
|
41
|
+
action="store_true",
|
|
42
|
+
default=False,
|
|
43
|
+
dest="infrahub_performance_create_backup",
|
|
44
|
+
help="Generate a backup of the database (default: %(default)s)",
|
|
45
|
+
)
|
|
46
|
+
group.addoption(
|
|
47
|
+
"--performance-use-backup",
|
|
48
|
+
action="store_true",
|
|
49
|
+
default=False,
|
|
50
|
+
dest="infrahub_performance_use_backup",
|
|
51
|
+
help="Use a backup of the database and skip all tests that creates data (default: %(default)s)",
|
|
52
|
+
)
|
|
53
|
+
group.addoption(
|
|
54
|
+
"--performance-report",
|
|
55
|
+
action="store_true",
|
|
56
|
+
dest="infrahub_performance_report",
|
|
57
|
+
default=False,
|
|
58
|
+
help="Display performance report at the end of the test run",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None:
|
|
63
|
+
use_backup_skip = pytest.mark.skip(reason="load data from backup")
|
|
64
|
+
no_create_backup_skip = pytest.mark.skip(reason="no need to create a backup")
|
|
65
|
+
no_load_backup_skip = pytest.mark.skip(reason="no need to load a backup")
|
|
66
|
+
|
|
67
|
+
use_backup = config.getoption("infrahub_performance_use_backup")
|
|
68
|
+
create_backup = config.getoption("infrahub_performance_create_backup")
|
|
69
|
+
|
|
70
|
+
for item in items:
|
|
71
|
+
has_create_backup_marker = bool(
|
|
72
|
+
[True for marker in item.own_markers if marker.name == "performance_create_backup"]
|
|
73
|
+
)
|
|
74
|
+
has_load_backup_marker = bool([True for marker in item.own_markers if marker.name == "performance_load_backup"])
|
|
75
|
+
has_load_data_marker = bool([True for marker in item.own_markers if marker.name == "performance_load_data"])
|
|
76
|
+
|
|
77
|
+
if has_create_backup_marker and not create_backup:
|
|
78
|
+
item.add_marker(no_create_backup_skip)
|
|
79
|
+
if has_load_backup_marker and not use_backup:
|
|
80
|
+
item.add_marker(no_load_backup_skip)
|
|
81
|
+
if has_load_data_marker and use_backup:
|
|
82
|
+
item.add_marker(use_backup_skip)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def pytest_sessionstart(session: pytest.Session) -> None:
|
|
86
|
+
session.infrahub_performance_test = InfrahubPerformanceTest(
|
|
87
|
+
results_url=session.config.getoption("infrahub_performance_test_result_address")
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def pytest_sessionfinish(session: pytest.Session, exitstatus: int) -> None: # noqa: ARG001
|
|
92
|
+
"""whole test run finishes."""
|
|
93
|
+
if not session.config.getoption("infrahub_performance_report"):
|
|
94
|
+
return
|
|
95
|
+
|
|
96
|
+
session.infrahub_performance_test.finalize(session=session)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def pytest_runtest_teardown(item: pytest.Item, nextitem: pytest.Item | None) -> None: # noqa: ARG001
|
|
100
|
+
"""Fetch metrics at each test teardown because there's no better hook...
|
|
101
|
+
pytest_sessionfinish() is executed after fixtures has been finalized and pytest_fixture_post_finalizer() is too late"""
|
|
102
|
+
if not item.config.getoption("infrahub_performance_report"):
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
item.session.infrahub_performance_test.fetch_metrics()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def pytest_configure(config: pytest.Config) -> None:
|
|
109
|
+
if config.getoption("infrahub_performance_use_backup") and config.getoption("infrahub_performance_create_backup"):
|
|
110
|
+
raise pytest.UsageError("--performance-use-backup and --performance-create-backup are mutually exclusive")
|
|
111
|
+
|
|
112
|
+
config.addinivalue_line("markers", "performance_create_backup: Create a backup of the database")
|
|
113
|
+
config.addinivalue_line("markers", "performance_load_backup: Load the backup of the database")
|
|
114
|
+
config.addinivalue_line("markers", "performance_load_data: Load initial data into the database")
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def pytest_terminal_summary(
|
|
118
|
+
terminalreporter: _pytest.terminal.TerminalReporter,
|
|
119
|
+
exitstatus: int, # noqa: ARG001
|
|
120
|
+
config: pytest.Config,
|
|
121
|
+
) -> None:
|
|
122
|
+
if not config.getoption("infrahub_performance_report"):
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
performance_test = terminalreporter._session.infrahub_performance_test
|
|
126
|
+
|
|
127
|
+
report = [
|
|
128
|
+
f"{measurement.name}: {measurement.value} {measurement.unit.value}"
|
|
129
|
+
for measurement in performance_test.measurements
|
|
130
|
+
]
|
|
131
|
+
terminalreporter.write("\n" + "\n".join(report) + "\n")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@pytest.fixture(scope="session")
|
|
135
|
+
def perf_test(request: pytest.FixtureRequest) -> InfrahubPerformanceTest:
|
|
136
|
+
return request.session.infrahub_performance_test
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
global:
|
|
3
|
+
scrape_interval: 15s
|
|
4
|
+
|
|
5
|
+
scrape_configs:
|
|
6
|
+
- job_name: 'infrahub-server'
|
|
7
|
+
dns_sd_configs:
|
|
8
|
+
- names:
|
|
9
|
+
- server
|
|
10
|
+
type: A
|
|
11
|
+
port: 8000
|
|
12
|
+
|
|
13
|
+
- job_name: 'infrahub-worker'
|
|
14
|
+
dns_sd_configs:
|
|
15
|
+
- names:
|
|
16
|
+
- task-worker
|
|
17
|
+
type: A
|
|
18
|
+
port: 8000
|
|
19
|
+
|
|
20
|
+
- job_name: 'cadvisor'
|
|
21
|
+
dns_sd_configs:
|
|
22
|
+
- names:
|
|
23
|
+
- cadvisor
|
|
24
|
+
type: A
|
|
25
|
+
port: 8080
|
|
26
|
+
metric_relabel_configs:
|
|
27
|
+
- source_labels: [container_label_namespace]
|
|
28
|
+
target_label: namespace
|
|
29
|
+
- source_labels: [container_label_pod]
|
|
30
|
+
target_label: pod
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from pydantic import Field
|
|
2
|
-
|
|
3
|
-
from infrahub.message_bus import InfrahubMessage
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class EventBranchCreate(InfrahubMessage):
|
|
7
|
-
"""Sent a new branch is created."""
|
|
8
|
-
|
|
9
|
-
branch: str = Field(..., description="The branch that was created")
|
|
10
|
-
branch_id: str = Field(..., description="The unique ID of the branch")
|
|
11
|
-
sync_with_git: bool = Field(..., description="Indicates if Infrahub should extend this branch to git.")
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from pydantic import Field
|
|
2
|
-
|
|
3
|
-
from infrahub.message_bus import InfrahubMessage
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class EventBranchDelete(InfrahubMessage):
|
|
7
|
-
"""Sent when a branch has been deleted."""
|
|
8
|
-
|
|
9
|
-
branch: str = Field(..., description="The branch that was deleted")
|
|
10
|
-
branch_id: str = Field(..., description="The unique ID of the branch")
|
|
11
|
-
sync_with_git: bool = Field(..., description="Indicates if the branch was extended to Git")
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
|
|
3
|
-
from pydantic import Field
|
|
4
|
-
|
|
5
|
-
from infrahub.message_bus import InfrahubMessage
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class EventNodeMutated(InfrahubMessage):
|
|
9
|
-
"""Sent when a node has been mutated"""
|
|
10
|
-
|
|
11
|
-
branch: str = Field(..., description="The branch that was created")
|
|
12
|
-
kind: str = Field(..., description="The type of object modified")
|
|
13
|
-
node_id: str = Field(..., description="The ID of the mutated node")
|
|
14
|
-
action: str = Field(..., description="The action taken on the node")
|
|
15
|
-
data: dict[str, Any] = Field(..., description="Data on modified object")
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
from pydantic import Field
|
|
2
|
-
|
|
3
|
-
from infrahub.message_bus import InfrahubMessage
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class EventSchemaUpdate(InfrahubMessage):
|
|
7
|
-
"""Sent when the schema on a branch has been updated."""
|
|
8
|
-
|
|
9
|
-
branch: str = Field(..., description="The branch where the update occurred")
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from infrahub.message_bus import messages
|
|
2
|
-
from infrahub.services import InfrahubServices
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
async def mutated(
|
|
6
|
-
message: messages.EventNodeMutated,
|
|
7
|
-
service: InfrahubServices,
|
|
8
|
-
) -> None:
|
|
9
|
-
"""Event posted when a node is mutated"""
|
|
10
|
-
# Note for now this is only kept to facilitate publishing to other queues in the future
|
|
11
|
-
# This operation doesn't have a flow defined to avoid having the workers need to register
|
|
12
|
-
# the results in Prefect when they don't actually do anything aside from add noise.
|
|
13
|
-
service.log.debug(
|
|
14
|
-
"Mutation on node",
|
|
15
|
-
branch=message.branch,
|
|
16
|
-
node_id=message.node_id,
|
|
17
|
-
action=message.action,
|
|
18
|
-
kind=message.kind,
|
|
19
|
-
data=message.data,
|
|
20
|
-
)
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
from prefect import flow
|
|
2
|
-
|
|
3
|
-
from infrahub.log import get_logger
|
|
4
|
-
from infrahub.message_bus import messages
|
|
5
|
-
from infrahub.services import InfrahubServices
|
|
6
|
-
|
|
7
|
-
log = get_logger()
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@flow(name="event-schema-update")
|
|
11
|
-
async def update(message: messages.EventSchemaUpdate, service: InfrahubServices) -> None:
|
|
12
|
-
log.info("run_message", branch=message.branch)
|
|
13
|
-
|
|
14
|
-
msg = messages.RefreshRegistryBranches()
|
|
15
|
-
|
|
16
|
-
msg.assign_meta(parent=message)
|
|
17
|
-
await service.message_bus.send(message=msg)
|
infrahub/webhook/constants.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
AUTOMATION_NAME_RUN = "Trigger-webhook-execution"
|
|
File without changes
|
|
File without changes
|