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,55 @@
|
|
|
1
|
+
from typing import ClassVar
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from .constants import EVENT_NAMESPACE
|
|
6
|
+
from .models import InfrahubEvent
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ValidatorEvent(InfrahubEvent):
|
|
10
|
+
"""Event generated when an validator within a pipeline has started."""
|
|
11
|
+
|
|
12
|
+
node_id: str = Field(..., description="The ID of the validator")
|
|
13
|
+
kind: str = Field(..., description="The kind of the validator")
|
|
14
|
+
proposed_change_id: str = Field(..., description="The ID of the proposed change")
|
|
15
|
+
|
|
16
|
+
def get_resource(self) -> dict[str, str]:
|
|
17
|
+
return {
|
|
18
|
+
"prefect.resource.id": self.node_id,
|
|
19
|
+
"infrahub.node.kind": self.kind,
|
|
20
|
+
"infrahub.node.id": self.node_id,
|
|
21
|
+
"infrahub.branch.name": self.meta.context.branch.name,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
def get_related(self) -> list[dict[str, str]]:
|
|
25
|
+
related = super().get_related()
|
|
26
|
+
related.append(
|
|
27
|
+
{
|
|
28
|
+
"prefect.resource.id": self.proposed_change_id,
|
|
29
|
+
"prefect.resource.role": "infrahub.related.node",
|
|
30
|
+
"infrahub.node.kind": "CoreProposedChange",
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
return related
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ValidatorStartedEvent(ValidatorEvent):
|
|
38
|
+
"""Event generated when an validator within a pipeline has started."""
|
|
39
|
+
|
|
40
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.validator.started"
|
|
41
|
+
infrahub_node_kind_event: ClassVar[bool] = True
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ValidatorPassedEvent(ValidatorEvent):
|
|
45
|
+
"""Event generated when an validator within a pipeline has completed successfully."""
|
|
46
|
+
|
|
47
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.validator.passed"
|
|
48
|
+
infrahub_node_kind_event: ClassVar[bool] = True
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ValidatorFailedEvent(ValidatorEvent):
|
|
52
|
+
"""Event generated when an validator within a pipeline has completed successfully."""
|
|
53
|
+
|
|
54
|
+
event_name: ClassVar[str] = f"{EVENT_NAMESPACE}.validator.failed"
|
|
55
|
+
infrahub_node_kind_event: ClassVar[bool] = True
|
infrahub/exceptions.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class Error(Exception):
|
|
6
6
|
HTTP_CODE: int = 500
|
|
7
7
|
DESCRIPTION: str = "Unknown Error"
|
|
8
8
|
message: str = ""
|
|
9
|
-
errors:
|
|
9
|
+
errors: list | None = None
|
|
10
10
|
|
|
11
11
|
def api_response(self) -> dict[str, Any]:
|
|
12
12
|
"""Return error response."""
|
|
@@ -291,35 +291,26 @@ class MigrationError(Error):
|
|
|
291
291
|
class ValidationError(Error):
|
|
292
292
|
HTTP_CODE = 422
|
|
293
293
|
|
|
294
|
-
def __init__(self, input_value:
|
|
294
|
+
def __init__(self, input_value: str | dict | list) -> None:
|
|
295
295
|
self.message = ""
|
|
296
|
-
self.location = None
|
|
297
|
-
self.messages = {}
|
|
298
296
|
|
|
299
297
|
if isinstance(input_value, str):
|
|
300
298
|
self.message = input_value
|
|
301
|
-
elif isinstance(input_value, dict)
|
|
302
|
-
self.message =
|
|
303
|
-
self.location = list(input_value.keys())[0]
|
|
304
|
-
elif isinstance(input_value, dict) and len(input_value) > 1:
|
|
305
|
-
for key, value in input_value.items():
|
|
306
|
-
self.messages[key] = value
|
|
307
|
-
|
|
299
|
+
elif isinstance(input_value, dict):
|
|
300
|
+
self.message = ", ".join([f"{message} at {location}" for location, message in input_value.items()])
|
|
308
301
|
elif isinstance(input_value, list):
|
|
309
|
-
for item in input_value:
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
super().__init__(self.message)
|
|
302
|
+
if all(isinstance(item, ValidationError) for item in input_value):
|
|
303
|
+
self.message = ", ".join([validation_error.message for validation_error in input_value])
|
|
304
|
+
if all(isinstance(item, dict) for item in input_value):
|
|
305
|
+
messages = []
|
|
306
|
+
for item in input_value:
|
|
307
|
+
messages.append(", ".join([f"{message} at {location}" for location, message in item.items()]))
|
|
308
|
+
self.message = ", ".join(messages)
|
|
317
309
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
return ", ".join([f"{message} at {location}" for location, message in self.messages.items()])
|
|
310
|
+
if not self.message:
|
|
311
|
+
raise ValueError("Could not build validation error message")
|
|
321
312
|
|
|
322
|
-
|
|
313
|
+
super().__init__(self.message)
|
|
323
314
|
|
|
324
315
|
|
|
325
316
|
class DiffError(Error):
|
|
@@ -329,6 +320,14 @@ class DiffError(Error):
|
|
|
329
320
|
self.message = message
|
|
330
321
|
|
|
331
322
|
|
|
323
|
+
class HFIDViolatedError(ValidationError):
|
|
324
|
+
matching_nodes_ids: set[str]
|
|
325
|
+
|
|
326
|
+
def __init__(self, input_value: str | dict | list, matching_nodes_ids: set[str]) -> None:
|
|
327
|
+
self.matching_nodes_ids = matching_nodes_ids
|
|
328
|
+
super().__init__(input_value)
|
|
329
|
+
|
|
330
|
+
|
|
332
331
|
class DiffRangeValidationError(DiffError): ...
|
|
333
332
|
|
|
334
333
|
|
infrahub/generators/models.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
3
|
from pydantic import BaseModel, ConfigDict, Field
|
|
6
4
|
|
|
7
5
|
|
|
@@ -9,7 +7,7 @@ class RequestGeneratorRun(BaseModel):
|
|
|
9
7
|
"""Runs a generator."""
|
|
10
8
|
|
|
11
9
|
generator_definition: ProposedChangeGeneratorDefinition = Field(..., description="The Generator definition")
|
|
12
|
-
generator_instance:
|
|
10
|
+
generator_instance: str | None = Field(
|
|
13
11
|
default=None, description="The id of the generator instance if it previously existed"
|
|
14
12
|
)
|
|
15
13
|
commit: str = Field(..., description="The commit to target")
|
infrahub/git/base.py
CHANGED
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import shutil
|
|
4
4
|
from abc import ABC, abstractmethod
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import TYPE_CHECKING, NoReturn
|
|
6
|
+
from typing import TYPE_CHECKING, NoReturn
|
|
7
7
|
from uuid import UUID # noqa: TC003
|
|
8
8
|
|
|
9
9
|
import git
|
|
@@ -144,12 +144,12 @@ class InfrahubRepositoryBase(BaseModel, ABC):
|
|
|
144
144
|
False, description="Flag to indicate if a remote repository (named origin) is present in the config."
|
|
145
145
|
)
|
|
146
146
|
|
|
147
|
-
client:
|
|
147
|
+
client: InfrahubClient | None = Field(
|
|
148
148
|
default=None,
|
|
149
149
|
description="Infrahub Client, used to query the Repository and Branch information in the graph and to update the commit.",
|
|
150
150
|
)
|
|
151
151
|
|
|
152
|
-
cache_repo:
|
|
152
|
+
cache_repo: Repo | None = Field(None, description="Internal cache of the GitPython Repo object")
|
|
153
153
|
service: InfrahubServices = Field(
|
|
154
154
|
..., description="Service object with access to the message queue, the database etc.."
|
|
155
155
|
)
|
|
@@ -584,7 +584,7 @@ class InfrahubRepositoryBase(BaseModel, ABC):
|
|
|
584
584
|
|
|
585
585
|
return True
|
|
586
586
|
|
|
587
|
-
def create_commit_worktree(self, commit: str) ->
|
|
587
|
+
def create_commit_worktree(self, commit: str) -> bool | Worktree:
|
|
588
588
|
"""Create a new worktree for a given commit."""
|
|
589
589
|
|
|
590
590
|
# Check of the worktree already exist
|
|
@@ -744,7 +744,7 @@ class InfrahubRepositoryBase(BaseModel, ABC):
|
|
|
744
744
|
branch_id: str | None = None,
|
|
745
745
|
create_if_missing: bool = False,
|
|
746
746
|
update_commit_value: bool = True,
|
|
747
|
-
) ->
|
|
747
|
+
) -> bool | str:
|
|
748
748
|
"""Pull the latest update from the remote repository on a given branch."""
|
|
749
749
|
|
|
750
750
|
if not self.has_origin:
|
|
@@ -812,10 +812,10 @@ class InfrahubRepositoryBase(BaseModel, ABC):
|
|
|
812
812
|
|
|
813
813
|
async def find_files(
|
|
814
814
|
self,
|
|
815
|
-
extension:
|
|
815
|
+
extension: str | list[str],
|
|
816
816
|
branch_name: str | None = None,
|
|
817
817
|
commit: str | None = None,
|
|
818
|
-
directory:
|
|
818
|
+
directory: Path | None = None,
|
|
819
819
|
) -> list[Path]:
|
|
820
820
|
"""Return the path of all files matching a specific extension in a given Branch or Commit."""
|
|
821
821
|
if not branch_name and not commit:
|
infrahub/git/integrator.py
CHANGED
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import hashlib
|
|
4
4
|
import importlib
|
|
5
5
|
import sys
|
|
6
|
-
from typing import TYPE_CHECKING, Any
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
7
|
|
|
8
8
|
import jinja2
|
|
9
9
|
import ujson
|
|
@@ -39,7 +39,7 @@ from typing_extensions import Self
|
|
|
39
39
|
|
|
40
40
|
from infrahub.core.constants import ArtifactStatus, ContentType, InfrahubKind, RepositorySyncStatus
|
|
41
41
|
from infrahub.core.registry import registry
|
|
42
|
-
from infrahub.events.artifact_action import
|
|
42
|
+
from infrahub.events.artifact_action import ArtifactCreatedEvent, ArtifactUpdatedEvent
|
|
43
43
|
from infrahub.events.models import EventMeta
|
|
44
44
|
from infrahub.events.repository_action import CommitUpdatedEvent
|
|
45
45
|
from infrahub.exceptions import CheckError, RepositoryInvalidFileSystemError, TransformError
|
|
@@ -93,10 +93,10 @@ class CheckDefinitionInformation(BaseModel):
|
|
|
93
93
|
timeout: int
|
|
94
94
|
"""Timeout for the Check."""
|
|
95
95
|
|
|
96
|
-
parameters:
|
|
96
|
+
parameters: dict | None = None
|
|
97
97
|
"""Additional Parameters to extract from each target (if targets is provided)"""
|
|
98
98
|
|
|
99
|
-
targets:
|
|
99
|
+
targets: str | None = Field(default=None, description="Targets if not a global check")
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
class TransformPythonInformation(BaseModel):
|
|
@@ -161,7 +161,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
161
161
|
|
|
162
162
|
@flow(name="import-object-from-file", flow_run_name="Import objects")
|
|
163
163
|
async def import_objects_from_files(
|
|
164
|
-
self, infrahub_branch_name: str, git_branch_name:
|
|
164
|
+
self, infrahub_branch_name: str, git_branch_name: str | None = None, commit: str | None = None
|
|
165
165
|
) -> None:
|
|
166
166
|
if not commit:
|
|
167
167
|
commit = self.get_commit_value(branch_name=git_branch_name or infrahub_branch_name)
|
|
@@ -171,27 +171,27 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
171
171
|
self.create_commit_worktree(commit)
|
|
172
172
|
await self._update_sync_status(branch_name=infrahub_branch_name, status=RepositorySyncStatus.SYNCING)
|
|
173
173
|
|
|
174
|
-
config_file = await self.get_repository_config(branch_name=infrahub_branch_name, commit=commit)
|
|
174
|
+
config_file = await self.get_repository_config(branch_name=infrahub_branch_name, commit=commit) # type: ignore[misc]
|
|
175
175
|
sync_status = RepositorySyncStatus.IN_SYNC if config_file else RepositorySyncStatus.ERROR_IMPORT
|
|
176
176
|
error: Exception | None = None
|
|
177
177
|
|
|
178
178
|
try:
|
|
179
179
|
if config_file:
|
|
180
|
-
await self.import_schema_files(branch_name=infrahub_branch_name, commit=commit, config_file=config_file)
|
|
180
|
+
await self.import_schema_files(branch_name=infrahub_branch_name, commit=commit, config_file=config_file) # type: ignore[misc]
|
|
181
181
|
|
|
182
182
|
await self.import_all_graphql_query(
|
|
183
183
|
branch_name=infrahub_branch_name, commit=commit, config_file=config_file
|
|
184
|
-
)
|
|
184
|
+
) # type: ignore[misc]
|
|
185
185
|
|
|
186
186
|
await self.import_all_python_files( # type: ignore[call-overload]
|
|
187
187
|
branch_name=infrahub_branch_name, commit=commit, config_file=config_file
|
|
188
|
-
)
|
|
188
|
+
) # type: ignore[misc]
|
|
189
189
|
await self.import_jinja2_transforms(
|
|
190
190
|
branch_name=infrahub_branch_name, commit=commit, config_file=config_file
|
|
191
|
-
)
|
|
191
|
+
) # type: ignore[misc]
|
|
192
192
|
await self.import_artifact_definitions(
|
|
193
193
|
branch_name=infrahub_branch_name, commit=commit, config_file=config_file
|
|
194
|
-
)
|
|
194
|
+
) # type: ignore[misc]
|
|
195
195
|
|
|
196
196
|
except Exception as exc:
|
|
197
197
|
sync_status = RepositorySyncStatus.ERROR_IMPORT
|
|
@@ -443,7 +443,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
443
443
|
await existing_artifact_definition.save()
|
|
444
444
|
|
|
445
445
|
@task(name="repository-get-config", task_run_name="get repository config", cache_policy=NONE) # type: ignore[arg-type]
|
|
446
|
-
async def get_repository_config(self, branch_name: str, commit: str) ->
|
|
446
|
+
async def get_repository_config(self, branch_name: str, commit: str) -> InfrahubRepositoryConfig | None:
|
|
447
447
|
branch_wt = self.get_worktree(identifier=commit or branch_name)
|
|
448
448
|
log = get_run_logger()
|
|
449
449
|
|
|
@@ -636,7 +636,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
636
636
|
module=module,
|
|
637
637
|
file_path=file_info.relative_path_file,
|
|
638
638
|
check_definition=check,
|
|
639
|
-
)
|
|
639
|
+
) # type: ignore[misc]
|
|
640
640
|
)
|
|
641
641
|
|
|
642
642
|
local_check_definitions = {check.name: check for check in checks}
|
|
@@ -797,7 +797,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
797
797
|
module=module,
|
|
798
798
|
file_path=file_info.relative_path_file,
|
|
799
799
|
transform=transform,
|
|
800
|
-
)
|
|
800
|
+
) # type: ignore[misc]
|
|
801
801
|
)
|
|
802
802
|
|
|
803
803
|
local_transform_definitions = {transform.name: transform for transform in transforms}
|
|
@@ -1070,9 +1070,9 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1070
1070
|
) -> None:
|
|
1071
1071
|
await add_tags(branches=[branch_name], nodes=[str(self.id)])
|
|
1072
1072
|
|
|
1073
|
-
await self.import_python_check_definitions(branch_name=branch_name, commit=commit, config_file=config_file)
|
|
1074
|
-
await self.import_python_transforms(branch_name=branch_name, commit=commit, config_file=config_file)
|
|
1075
|
-
await self.import_generator_definitions(branch_name=branch_name, commit=commit, config_file=config_file)
|
|
1073
|
+
await self.import_python_check_definitions(branch_name=branch_name, commit=commit, config_file=config_file) # type: ignore[misc]
|
|
1074
|
+
await self.import_python_transforms(branch_name=branch_name, commit=commit, config_file=config_file) # type: ignore[misc]
|
|
1075
|
+
await self.import_generator_definitions(branch_name=branch_name, commit=commit, config_file=config_file) # type: ignore[misc]
|
|
1076
1076
|
|
|
1077
1077
|
@task(name="jinja2-template-render", task_run_name="Render Jinja2 template", cache_policy=NONE) # type: ignore[arg-type]
|
|
1078
1078
|
async def render_jinja2_template(self, commit: str, location: str, data: dict) -> str:
|
|
@@ -1098,7 +1098,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1098
1098
|
location: str,
|
|
1099
1099
|
class_name: str,
|
|
1100
1100
|
client: InfrahubClient,
|
|
1101
|
-
params:
|
|
1101
|
+
params: dict | None = None,
|
|
1102
1102
|
) -> InfrahubCheck:
|
|
1103
1103
|
"""Execute A Python Check stored in the repository."""
|
|
1104
1104
|
log = get_run_logger()
|
|
@@ -1227,7 +1227,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1227
1227
|
if transformation.typename == InfrahubKind.TRANSFORMJINJA2:
|
|
1228
1228
|
artifact_content = await self.render_jinja2_template.with_options(
|
|
1229
1229
|
timeout_seconds=transformation.timeout.value
|
|
1230
|
-
)(commit=commit, location=transformation.template_path.value, data=response)
|
|
1230
|
+
)(commit=commit, location=transformation.template_path.value, data=response) # type: ignore[misc]
|
|
1231
1231
|
elif transformation.typename == InfrahubKind.TRANSFORMPYTHON:
|
|
1232
1232
|
transformation_location = f"{transformation.file_path.value}::{transformation.class_name.value}"
|
|
1233
1233
|
artifact_content = await self.execute_python_transform.with_options(
|
|
@@ -1238,7 +1238,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1238
1238
|
location=transformation_location,
|
|
1239
1239
|
data=response,
|
|
1240
1240
|
client=self.sdk,
|
|
1241
|
-
)
|
|
1241
|
+
) # type: ignore[misc]
|
|
1242
1242
|
|
|
1243
1243
|
if definition.content_type.value == ContentType.APPLICATION_JSON.value and isinstance(artifact_content, dict):
|
|
1244
1244
|
artifact_content_str = ujson.dumps(artifact_content, indent=2)
|
|
@@ -1270,7 +1270,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1270
1270
|
self,
|
|
1271
1271
|
artifact: CoreArtifact,
|
|
1272
1272
|
artifact_created: bool,
|
|
1273
|
-
message:
|
|
1273
|
+
message: CheckArtifactCreate | RequestArtifactGenerate,
|
|
1274
1274
|
) -> ArtifactGenerateResult:
|
|
1275
1275
|
response = await self.sdk.query_gql_query(
|
|
1276
1276
|
name=message.query,
|
|
@@ -1289,7 +1289,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1289
1289
|
if message.transform_type == InfrahubKind.TRANSFORMJINJA2:
|
|
1290
1290
|
artifact_content = await self.render_jinja2_template.with_options(timeout_seconds=message.timeout)(
|
|
1291
1291
|
commit=message.commit, location=message.transform_location, data=response
|
|
1292
|
-
)
|
|
1292
|
+
) # type: ignore[misc]
|
|
1293
1293
|
elif message.transform_type == InfrahubKind.TRANSFORMPYTHON:
|
|
1294
1294
|
artifact_content = await self.execute_python_transform.with_options(timeout_seconds=message.timeout)(
|
|
1295
1295
|
branch_name=message.branch_name,
|
|
@@ -1297,7 +1297,7 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1297
1297
|
location=message.transform_location,
|
|
1298
1298
|
data=response,
|
|
1299
1299
|
client=self.sdk,
|
|
1300
|
-
)
|
|
1300
|
+
) # type: ignore[misc]
|
|
1301
1301
|
|
|
1302
1302
|
if message.content_type == ContentType.APPLICATION_JSON.value and isinstance(artifact_content, dict):
|
|
1303
1303
|
artifact_content_str = ujson.dumps(artifact_content, indent=2)
|
|
@@ -1324,7 +1324,9 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1324
1324
|
artifact.name.value = message.artifact_name
|
|
1325
1325
|
await artifact.save()
|
|
1326
1326
|
|
|
1327
|
-
|
|
1327
|
+
event_class = ArtifactCreatedEvent if artifact_created else ArtifactUpdatedEvent
|
|
1328
|
+
|
|
1329
|
+
event = event_class(
|
|
1328
1330
|
node_id=artifact.id,
|
|
1329
1331
|
target_id=message.target_id,
|
|
1330
1332
|
target_kind=message.target_kind,
|
|
@@ -1334,7 +1336,6 @@ class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
|
|
|
1334
1336
|
checksum_previous=previous_checksum,
|
|
1335
1337
|
storage_id=storage_id,
|
|
1336
1338
|
storage_id_previous=previous_storage_id,
|
|
1337
|
-
created=artifact_created,
|
|
1338
1339
|
)
|
|
1339
1340
|
|
|
1340
1341
|
await self.service.event.send(event=event)
|
infrahub/git/models.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
1
|
from pydantic import BaseModel, ConfigDict, Field
|
|
4
2
|
|
|
5
3
|
from infrahub.context import InfrahubContext
|
|
@@ -34,7 +32,7 @@ class RequestArtifactGenerate(BaseModel):
|
|
|
34
32
|
target_id: str = Field(..., description="The ID of the target object for this artifact")
|
|
35
33
|
target_kind: str = Field(..., description="The kind of the target object for this artifact")
|
|
36
34
|
target_name: str = Field(..., description="Name of the artifact target")
|
|
37
|
-
artifact_id:
|
|
35
|
+
artifact_id: str | None = Field(default=None, description="The id of the artifact if it previously existed")
|
|
38
36
|
query: str = Field(..., description="The name of the query to use when collecting data")
|
|
39
37
|
timeout: int = Field(..., description="Timeout for requests used to generate this artifact")
|
|
40
38
|
variables: dict = Field(..., description="Input variables when generating the artifact")
|
|
@@ -47,8 +45,8 @@ class GitRepositoryAdd(BaseModel):
|
|
|
47
45
|
location: str = Field(..., description="The external URL of the repository")
|
|
48
46
|
repository_id: str = Field(..., description="The unique ID of the Repository")
|
|
49
47
|
repository_name: str = Field(..., description="The name of the repository")
|
|
50
|
-
created_by:
|
|
51
|
-
default_branch_name:
|
|
48
|
+
created_by: str | None = Field(default=None, description="The user ID of the user that created the repository")
|
|
49
|
+
default_branch_name: str | None = Field(None, description="Default branch for this repository")
|
|
52
50
|
infrahub_branch_name: str = Field(..., description="Infrahub branch on which to sync the remote repository")
|
|
53
51
|
infrahub_branch_id: str = Field(..., description="Id of the Infrahub branch on which to sync the remote repository")
|
|
54
52
|
internal_status: str = Field(..., description="Administrative status of the repository")
|
|
@@ -61,7 +59,7 @@ class GitRepositoryAddReadOnly(BaseModel):
|
|
|
61
59
|
repository_id: str = Field(..., description="The unique ID of the Repository")
|
|
62
60
|
repository_name: str = Field(..., description="The name of the repository")
|
|
63
61
|
ref: str = Field(..., description="Ref to track on the external repository")
|
|
64
|
-
created_by:
|
|
62
|
+
created_by: str | None = Field(default=None, description="The user ID of the user that created the repository")
|
|
65
63
|
infrahub_branch_name: str = Field(..., description="Infrahub branch on which to sync the remote repository")
|
|
66
64
|
infrahub_branch_id: str = Field(..., description="Id of the Infrahub branch on which to sync the remote repository")
|
|
67
65
|
internal_status: str = Field(..., description="Internal status of the repository")
|
|
@@ -73,8 +71,8 @@ class GitRepositoryPullReadOnly(BaseModel):
|
|
|
73
71
|
location: str = Field(..., description="The external URL of the repository")
|
|
74
72
|
repository_id: str = Field(..., description="The unique ID of the Repository")
|
|
75
73
|
repository_name: str = Field(..., description="The name of the repository")
|
|
76
|
-
ref:
|
|
77
|
-
commit:
|
|
74
|
+
ref: str | None = Field(None, description="Ref to track on the external repository")
|
|
75
|
+
commit: str | None = Field(None, description="Specific commit to pull")
|
|
78
76
|
infrahub_branch_name: str = Field(..., description="Infrahub branch on which to sync the remote repository")
|
|
79
77
|
infrahub_branch_id: str = Field(..., description="Infrahub branch on which to sync the remote repository")
|
|
80
78
|
|
|
@@ -108,7 +106,7 @@ class GitDiffNamesOnly(BaseModel):
|
|
|
108
106
|
repository_name: str = Field(..., description="The name of the repository")
|
|
109
107
|
repository_kind: str = Field(..., description="The kind of the repository")
|
|
110
108
|
first_commit: str = Field(..., description="The first commit")
|
|
111
|
-
second_commit:
|
|
109
|
+
second_commit: str | None = Field(None, description="The second commit")
|
|
112
110
|
|
|
113
111
|
|
|
114
112
|
class GitDiffNamesOnlyResponse(BaseModel):
|
|
@@ -189,3 +187,18 @@ class CheckRepositoryMergeConflicts(BaseModel):
|
|
|
189
187
|
repository_name: str = Field(..., description="The name of the Repository")
|
|
190
188
|
source_branch: str = Field(..., description="The source branch")
|
|
191
189
|
target_branch: str = Field(..., description="The target branch")
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class RepositoryBranchInfo(BaseModel):
|
|
193
|
+
internal_status: str
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
class RepositoryData(BaseModel):
|
|
197
|
+
repository_id: str = Field(..., description="Id of the repository")
|
|
198
|
+
repository_name: str = Field(..., description="Name of the repository")
|
|
199
|
+
branches: dict[str, str] = Field(
|
|
200
|
+
...,
|
|
201
|
+
description="Dictionary with the name of the branch as the key and the active commit id as the value",
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
branch_info: dict[str, RepositoryBranchInfo] = Field(default_factory=dict)
|
infrahub/git/repository.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Any
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
4
|
|
|
5
5
|
from git.exc import BadName, GitCommandError
|
|
6
6
|
from infrahub_sdk.exceptions import GraphQLError
|
|
@@ -250,7 +250,7 @@ class InfrahubReadOnlyRepository(InfrahubRepositoryIntegrator):
|
|
|
250
250
|
|
|
251
251
|
async def get_initialized_repo(
|
|
252
252
|
repository_id: str, name: str, service: InfrahubServices, repository_kind: str, commit: str | None = None
|
|
253
|
-
) ->
|
|
253
|
+
) -> InfrahubReadOnlyRepository | InfrahubRepository:
|
|
254
254
|
if repository_kind == InfrahubKind.REPOSITORY:
|
|
255
255
|
return await InfrahubRepository.init(
|
|
256
256
|
id=repository_id, name=name, commit=commit, client=service._client, service=service
|
|
@@ -266,7 +266,7 @@ async def get_initialized_repo(
|
|
|
266
266
|
|
|
267
267
|
async def initialize_repo(
|
|
268
268
|
location: str, repository_id: str, name: str, service: InfrahubServices, repository_kind: str
|
|
269
|
-
) ->
|
|
269
|
+
) -> InfrahubReadOnlyRepository | InfrahubRepository:
|
|
270
270
|
if repository_kind == InfrahubKind.REPOSITORY:
|
|
271
271
|
return await InfrahubRepository.new(
|
|
272
272
|
location=location, id=repository_id, name=name, client=service._client, service=service
|