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,65 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
from .constants import InfrahubType
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TelemetryWorkerData(BaseModel):
|
|
7
|
+
total: int
|
|
8
|
+
active: int
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TelemetryBranchData(BaseModel):
|
|
12
|
+
total: int
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TelemetrySchemaData(BaseModel):
|
|
16
|
+
node_count: int
|
|
17
|
+
generic_count: int
|
|
18
|
+
last_update: str
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TelemetryDatabaseServerData(BaseModel):
|
|
22
|
+
name: str
|
|
23
|
+
version: str
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TelemetryDatabaseSystemInfoData(BaseModel):
|
|
27
|
+
memory_total: int
|
|
28
|
+
memory_available: int
|
|
29
|
+
processor_available: int
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TelemetryDatabaseData(BaseModel):
|
|
33
|
+
database_type: str
|
|
34
|
+
relationship_count: dict[str, int]
|
|
35
|
+
node_count: dict[str, int]
|
|
36
|
+
servers: list[TelemetryDatabaseServerData]
|
|
37
|
+
system_info: TelemetryDatabaseSystemInfoData | None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class TelemetryWorkPoolData(BaseModel):
|
|
41
|
+
name: str
|
|
42
|
+
type: str
|
|
43
|
+
total_workers: int
|
|
44
|
+
active_workers: int
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class TelemetryPrefectData(BaseModel):
|
|
48
|
+
events: dict[str, int]
|
|
49
|
+
automations: dict[str, int]
|
|
50
|
+
work_pools: list[TelemetryWorkPoolData]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class TelemetryData(BaseModel):
|
|
54
|
+
deployment_id: str | None
|
|
55
|
+
execution_time: float | None
|
|
56
|
+
infrahub_version: str
|
|
57
|
+
infrahub_type: InfrahubType
|
|
58
|
+
python_version: str
|
|
59
|
+
platform: str
|
|
60
|
+
workers: TelemetryWorkerData
|
|
61
|
+
branches: TelemetryBranchData
|
|
62
|
+
features: dict[str, int]
|
|
63
|
+
schema_info: TelemetrySchemaData
|
|
64
|
+
database: TelemetryDatabaseData
|
|
65
|
+
prefect: TelemetryPrefectData
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from prefect import task
|
|
4
|
+
from prefect.cache_policies import NONE
|
|
5
|
+
from prefect.client.orchestration import PrefectClient, get_client
|
|
6
|
+
from prefect.client.schemas.objects import WorkerStatus
|
|
7
|
+
|
|
8
|
+
from infrahub.events.utils import get_all_events
|
|
9
|
+
from infrahub.trigger.constants import NAME_SEPARATOR
|
|
10
|
+
from infrahub.trigger.models import TriggerType
|
|
11
|
+
|
|
12
|
+
from .models import TelemetryPrefectData, TelemetryWorkPoolData
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@task(name="telemetry-gather-work-pools", task_run_name="Gather Work Pools", cache_policy=NONE)
|
|
16
|
+
async def gather_prefect_work_pools(client: PrefectClient) -> list[TelemetryWorkPoolData]:
|
|
17
|
+
work_pools = await client.read_work_pools()
|
|
18
|
+
data: list[TelemetryWorkPoolData] = []
|
|
19
|
+
|
|
20
|
+
for pool in work_pools:
|
|
21
|
+
workers = await client.read_workers_for_work_pool(work_pool_name=pool.name)
|
|
22
|
+
data.append(
|
|
23
|
+
TelemetryWorkPoolData(
|
|
24
|
+
name=pool.name,
|
|
25
|
+
type=pool.type,
|
|
26
|
+
total_workers=len(workers),
|
|
27
|
+
active_workers=len([item for item in workers if item.status == WorkerStatus.ONLINE]),
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
return data
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@task(name="telemetry-gather-events", task_run_name="Gather Events", cache_policy=NONE)
|
|
35
|
+
async def gather_prefect_events(client: PrefectClient) -> dict[str, Any]:
|
|
36
|
+
infrahub_events = get_all_events()
|
|
37
|
+
events: dict[str, int] = {}
|
|
38
|
+
|
|
39
|
+
async def count_events(event_name: str) -> int:
|
|
40
|
+
payload = {"filter": {"event": {"name": [event_name]}}}
|
|
41
|
+
response = await client._client.post("/events/count-by/event", json=payload)
|
|
42
|
+
response.raise_for_status()
|
|
43
|
+
data = response.json()
|
|
44
|
+
if not isinstance(data, list) or len(data) == 0:
|
|
45
|
+
return 0
|
|
46
|
+
return data[0]["count"]
|
|
47
|
+
|
|
48
|
+
for event in infrahub_events:
|
|
49
|
+
events[event.event_name] = await count_events(event_name=event.event_name)
|
|
50
|
+
|
|
51
|
+
return events
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@task(name="telemetry-gather-automations", task_run_name="Gather Automations", cache_policy=NONE)
|
|
55
|
+
async def gather_prefect_automations(client: PrefectClient) -> dict[str, Any]:
|
|
56
|
+
automations = await client.read_automations()
|
|
57
|
+
|
|
58
|
+
data: dict[str, Any] = {}
|
|
59
|
+
|
|
60
|
+
for trigger_type in TriggerType:
|
|
61
|
+
data[trigger_type.value] = len(
|
|
62
|
+
[item for item in automations if item.name.startswith(f"{trigger_type.value}{NAME_SEPARATOR}")]
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
return data
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@task(name="telemetry-gather-prefect-information", task_run_name="Gather Prefect Information", cache_policy=NONE)
|
|
69
|
+
async def gather_prefect_information() -> TelemetryPrefectData:
|
|
70
|
+
async with get_client(sync_client=False) as client:
|
|
71
|
+
data = TelemetryPrefectData(
|
|
72
|
+
work_pools=await gather_prefect_work_pools(client=client),
|
|
73
|
+
events=await gather_prefect_events(client=client),
|
|
74
|
+
automations=await gather_prefect_automations(client=client),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
return data
|
|
@@ -12,44 +12,32 @@ from infrahub import __version__, config
|
|
|
12
12
|
from infrahub.core import registry, utils
|
|
13
13
|
from infrahub.core.branch import Branch
|
|
14
14
|
from infrahub.core.constants import InfrahubKind
|
|
15
|
-
from infrahub.core.graph.schema import GRAPH_SCHEMA
|
|
16
15
|
from infrahub.services import InfrahubServices
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
from .constants import TELEMETRY_KIND, TELEMETRY_VERSION
|
|
18
|
+
from .database import gather_database_information
|
|
19
|
+
from .models import (
|
|
20
|
+
TelemetryBranchData,
|
|
21
|
+
TelemetryData,
|
|
22
|
+
TelemetrySchemaData,
|
|
23
|
+
TelemetryWorkerData,
|
|
24
|
+
)
|
|
25
|
+
from .task_manager import gather_prefect_information
|
|
26
|
+
from .utils import determine_infrahub_type
|
|
20
27
|
|
|
21
28
|
|
|
22
|
-
@task(name="telemetry-
|
|
23
|
-
async def
|
|
24
|
-
async with service.database.start_session() as db:
|
|
25
|
-
data: dict[str, Any] = {
|
|
26
|
-
"database_type": db.db_type.value,
|
|
27
|
-
"relationship_count": {"total": await utils.count_relationships(db=db)},
|
|
28
|
-
"node_count": {"total": await utils.count_nodes(db=db)},
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
for name in GRAPH_SCHEMA["relationships"]:
|
|
32
|
-
data["relationship_count"][name] = await utils.count_relationships(db=db, label=name)
|
|
33
|
-
|
|
34
|
-
for name in GRAPH_SCHEMA["nodes"]:
|
|
35
|
-
data["node_count"][name] = await utils.count_nodes(db=db, label=name)
|
|
36
|
-
|
|
37
|
-
return data
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@task(name="telemetry-schema-information", task_run_name="Gather Schema Information", cache_policy=NONE) # type: ignore[arg-type]
|
|
41
|
-
async def gather_schema_information(branch: Branch) -> dict:
|
|
42
|
-
data: dict[str, Any] = {}
|
|
29
|
+
@task(name="telemetry-schema-information", task_run_name="Gather Schema Information", cache_policy=NONE)
|
|
30
|
+
async def gather_schema_information(branch: Branch) -> TelemetrySchemaData:
|
|
43
31
|
main_schema = registry.schema.get_schema_branch(name=branch.name)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
32
|
+
return TelemetrySchemaData(
|
|
33
|
+
node_count=len(main_schema.node_names),
|
|
34
|
+
generic_count=len(main_schema.generic_names),
|
|
35
|
+
last_update=branch.schema_changed_at or "",
|
|
36
|
+
)
|
|
49
37
|
|
|
50
38
|
|
|
51
|
-
@task(name="telemetry-feature-information", task_run_name="Gather Feature Information", cache_policy=NONE)
|
|
52
|
-
async def gather_feature_information(service: InfrahubServices) -> dict:
|
|
39
|
+
@task(name="telemetry-feature-information", task_run_name="Gather Feature Information", cache_policy=NONE)
|
|
40
|
+
async def gather_feature_information(service: InfrahubServices) -> dict[str, int]:
|
|
53
41
|
async with service.database.start_session() as db:
|
|
54
42
|
data = {}
|
|
55
43
|
features_to_count = [
|
|
@@ -59,7 +47,9 @@ async def gather_feature_information(service: InfrahubServices) -> dict:
|
|
|
59
47
|
InfrahubKind.GENERICGROUP,
|
|
60
48
|
InfrahubKind.PROFILE,
|
|
61
49
|
InfrahubKind.PROPOSEDCHANGE,
|
|
50
|
+
InfrahubKind.OBJECTTEMPLATE,
|
|
62
51
|
InfrahubKind.TRANSFORM,
|
|
52
|
+
InfrahubKind.WEBHOOK,
|
|
63
53
|
]
|
|
64
54
|
for kind in features_to_count:
|
|
65
55
|
data[kind] = await utils.count_nodes(db=db, label=kind)
|
|
@@ -67,37 +57,39 @@ async def gather_feature_information(service: InfrahubServices) -> dict:
|
|
|
67
57
|
return data
|
|
68
58
|
|
|
69
59
|
|
|
70
|
-
@task(name="telemetry-gather-data", task_run_name="Gather Anonynous Data", cache_policy=NONE)
|
|
71
|
-
async def gather_anonymous_telemetry_data(service: InfrahubServices) ->
|
|
60
|
+
@task(name="telemetry-gather-data", task_run_name="Gather Anonynous Data", cache_policy=NONE)
|
|
61
|
+
async def gather_anonymous_telemetry_data(service: InfrahubServices) -> TelemetryData:
|
|
72
62
|
start_time = time.time()
|
|
73
63
|
|
|
74
64
|
default_branch = registry.get_branch_from_registry()
|
|
75
65
|
workers = await service.component.list_workers(branch=default_branch.name, schema_hash=False)
|
|
76
66
|
|
|
77
|
-
data
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
67
|
+
data = TelemetryData(
|
|
68
|
+
deployment_id=registry.id,
|
|
69
|
+
execution_time=None,
|
|
70
|
+
infrahub_version=__version__,
|
|
71
|
+
infrahub_type=determine_infrahub_type(),
|
|
72
|
+
python_version=platform.python_version(),
|
|
73
|
+
platform=platform.machine(),
|
|
74
|
+
workers=TelemetryWorkerData(
|
|
75
|
+
total=len(workers),
|
|
76
|
+
active=len([w for w in workers if w.active]),
|
|
77
|
+
),
|
|
78
|
+
branches=TelemetryBranchData(
|
|
79
|
+
total=len(registry.branch),
|
|
80
|
+
),
|
|
81
|
+
features=await gather_feature_information(service=service),
|
|
82
|
+
schema_info=await gather_schema_information(branch=default_branch),
|
|
83
|
+
database=await gather_database_information(db=service.database),
|
|
84
|
+
prefect=await gather_prefect_information(),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
data.execution_time = time.time() - start_time
|
|
96
88
|
|
|
97
89
|
return data
|
|
98
90
|
|
|
99
91
|
|
|
100
|
-
@task(name="telemetry-post-data", task_run_name="Upload data", retries=5, cache_policy=NONE)
|
|
92
|
+
@task(name="telemetry-post-data", task_run_name="Upload data", retries=5, cache_policy=NONE)
|
|
101
93
|
async def post_telemetry_data(service: InfrahubServices, url: str, payload: dict[str, Any]) -> None:
|
|
102
94
|
"""Send the telemetry data to the specified URL, using HTTP POST."""
|
|
103
95
|
response = await service.http.post(url=url, json=payload)
|
|
@@ -114,13 +106,14 @@ async def send_telemetry_push(service: InfrahubServices) -> None:
|
|
|
114
106
|
log.info(f"Pushing anonymous telemetry data to {config.SETTINGS.main.telemetry_endpoint}...")
|
|
115
107
|
|
|
116
108
|
data = await gather_anonymous_telemetry_data(service=service)
|
|
117
|
-
|
|
109
|
+
data_dict = data.model_dump(mode="json")
|
|
110
|
+
log.info(f"Anonymous usage telemetry gathered in {data.execution_time} seconds. | {data_dict}")
|
|
118
111
|
|
|
119
112
|
payload = {
|
|
120
113
|
"kind": TELEMETRY_KIND,
|
|
121
114
|
"payload_format": TELEMETRY_VERSION,
|
|
122
|
-
"data":
|
|
123
|
-
"checksum": hashlib.sha256(json.dumps(
|
|
115
|
+
"data": data_dict,
|
|
116
|
+
"checksum": hashlib.sha256(json.dumps(data_dict).encode()).hexdigest(),
|
|
124
117
|
}
|
|
125
118
|
|
|
126
119
|
await post_telemetry_data(service=service, url=config.SETTINGS.main.telemetry_endpoint, payload=payload)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import importlib.metadata
|
|
2
|
+
|
|
3
|
+
from .constants import InfrahubType
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def determine_infrahub_type() -> InfrahubType:
|
|
7
|
+
try:
|
|
8
|
+
importlib.metadata.version("infrahub-enterprise")
|
|
9
|
+
return InfrahubType.ENTERPRISE
|
|
10
|
+
except importlib.metadata.PackageNotFoundError:
|
|
11
|
+
return InfrahubType.COMMUNITY
|
infrahub/trace.py
CHANGED
|
@@ -9,7 +9,7 @@ from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
|
|
|
9
9
|
)
|
|
10
10
|
from opentelemetry.sdk.resources import Resource
|
|
11
11
|
from opentelemetry.sdk.trace import TracerProvider
|
|
12
|
-
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
|
|
12
|
+
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter, SpanExporter
|
|
13
13
|
from opentelemetry.trace import StatusCode
|
|
14
14
|
|
|
15
15
|
from infrahub.worker import WORKER_IDENTITY
|
|
@@ -19,7 +19,7 @@ def get_current_span_with_context() -> trace.Span:
|
|
|
19
19
|
return trace.get_current_span()
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def get_traceid() -> str:
|
|
22
|
+
def get_traceid() -> str | None:
|
|
23
23
|
current_span = get_current_span_with_context()
|
|
24
24
|
trace_id = current_span.get_span_context().trace_id
|
|
25
25
|
if trace_id == 0:
|
|
@@ -63,7 +63,7 @@ def create_tracer_provider(
|
|
|
63
63
|
) -> TracerProvider:
|
|
64
64
|
# Create a BatchSpanProcessor exporter based on the type
|
|
65
65
|
if exporter_type == "console":
|
|
66
|
-
exporter = ConsoleSpanExporter()
|
|
66
|
+
exporter: SpanExporter = ConsoleSpanExporter()
|
|
67
67
|
elif exporter_type == "otlp":
|
|
68
68
|
if not exporter_endpoint:
|
|
69
69
|
raise ValueError("Exporter type is set to otlp but endpoint is not set")
|
|
@@ -76,7 +76,7 @@ def create_tracer_provider(
|
|
|
76
76
|
|
|
77
77
|
extra_attributes = {}
|
|
78
78
|
if os.getenv("OTEL_RESOURCE_ATTRIBUTES"):
|
|
79
|
-
extra_attributes = dict(attr.split("=") for attr in os.getenv("OTEL_RESOURCE_ATTRIBUTES").split(","))
|
|
79
|
+
extra_attributes = dict(attr.split("=") for attr in os.getenv("OTEL_RESOURCE_ATTRIBUTES", "").split(","))
|
|
80
80
|
|
|
81
81
|
# Resource can be required for some backends, e.g. Jaeger
|
|
82
82
|
resource = Resource(
|
|
@@ -30,7 +30,7 @@ async def transform_python(message: TransformPythonData, service: InfrahubServic
|
|
|
30
30
|
location=message.transform_location,
|
|
31
31
|
data=message.data,
|
|
32
32
|
client=service.client,
|
|
33
|
-
)
|
|
33
|
+
) # type: ignore[misc]
|
|
34
34
|
|
|
35
35
|
return transformed_data
|
|
36
36
|
|
|
@@ -49,6 +49,6 @@ async def transform_render_jinja2_template(message: TransformJinjaTemplateData,
|
|
|
49
49
|
|
|
50
50
|
rendered_template = await repo.render_jinja2_template.with_options(timeout_seconds=message.timeout)(
|
|
51
51
|
commit=message.commit, location=message.template_location, data={"data": message.data}
|
|
52
|
-
)
|
|
52
|
+
) # type: ignore[misc]
|
|
53
53
|
|
|
54
54
|
return rendered_template
|
infrahub/trigger/catalogue.py
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
from infrahub.computed_attribute.triggers import (
|
|
2
2
|
TRIGGER_COMPUTED_ATTRIBUTE_ALL_SCHEMA,
|
|
3
|
-
TRIGGER_COMPUTED_ATTRIBUTE_PYTHON_CLEAN_BRANCH,
|
|
4
|
-
TRIGGER_COMPUTED_ATTRIBUTE_PYTHON_SETUP_BRANCH,
|
|
5
3
|
TRIGGER_COMPUTED_ATTRIBUTE_PYTHON_SETUP_COMMIT,
|
|
6
4
|
)
|
|
7
5
|
from infrahub.trigger.models import TriggerDefinition
|
|
8
|
-
from infrahub.webhook.triggers import TRIGGER_WEBHOOK_SETUP_UPDATE
|
|
6
|
+
from infrahub.webhook.triggers import TRIGGER_WEBHOOK_DELETE, TRIGGER_WEBHOOK_SETUP_UPDATE
|
|
9
7
|
|
|
10
8
|
builtin_triggers: list[TriggerDefinition] = [
|
|
11
9
|
TRIGGER_COMPUTED_ATTRIBUTE_ALL_SCHEMA,
|
|
12
|
-
TRIGGER_COMPUTED_ATTRIBUTE_PYTHON_CLEAN_BRANCH,
|
|
13
|
-
TRIGGER_COMPUTED_ATTRIBUTE_PYTHON_SETUP_BRANCH,
|
|
14
10
|
TRIGGER_COMPUTED_ATTRIBUTE_PYTHON_SETUP_COMMIT,
|
|
11
|
+
TRIGGER_WEBHOOK_DELETE,
|
|
15
12
|
TRIGGER_WEBHOOK_SETUP_UPDATE,
|
|
16
13
|
]
|
infrahub/trigger/constants.py
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
DEPRECATED_STATIC_TRIGGER_NAMES = [
|
|
2
|
-
"Trigger-branch-create-events", # used in 1.1.x
|
|
3
|
-
"Trigger-branch-remove-events", # used in 1.1.x
|
|
4
|
-
"Trigger-webhook-update-configuration", # used in 1.1.x
|
|
5
|
-
"Trigger-repository-commit-update-event", # used in 1.1.x
|
|
6
|
-
"Trigger-schema-update-event", # used in 1.1.x
|
|
7
|
-
]
|
|
8
|
-
|
|
9
1
|
NAME_SEPARATOR = "::"
|
infrahub/trigger/models.py
CHANGED
|
@@ -10,6 +10,7 @@ from prefect.events.schemas.automations import Posture
|
|
|
10
10
|
from prefect.events.schemas.events import ResourceSpecification
|
|
11
11
|
from pydantic import BaseModel, Field
|
|
12
12
|
|
|
13
|
+
from infrahub import __version__
|
|
13
14
|
from infrahub.workflows.models import WorkflowDefinition # noqa: TC001
|
|
14
15
|
|
|
15
16
|
from .constants import NAME_SEPARATOR
|
|
@@ -21,8 +22,10 @@ if TYPE_CHECKING:
|
|
|
21
22
|
class TriggerType(str, Enum):
|
|
22
23
|
BUILTIN = "builtin"
|
|
23
24
|
WEBHOOK = "webhook"
|
|
25
|
+
COMPUTED_ATTR_JINJA2 = "computed_attr_jinja2"
|
|
26
|
+
COMPUTED_ATTR_PYTHON = "computed_attr_python"
|
|
27
|
+
COMPUTED_ATTR_PYTHON_QUERY = "computed_attr_python_query"
|
|
24
28
|
# OBJECT = "object"
|
|
25
|
-
# COMPUTED_ATTR = "computed_attr"
|
|
26
29
|
|
|
27
30
|
|
|
28
31
|
class EventTrigger(BaseModel):
|
|
@@ -93,6 +96,9 @@ class TriggerDefinition(BaseModel):
|
|
|
93
96
|
"""Return the name of all deployments used by this trigger"""
|
|
94
97
|
return [action.name for action in self.actions]
|
|
95
98
|
|
|
99
|
+
def get_description(self) -> str:
|
|
100
|
+
return f"Automation for Trigger {self.name} of type {self.type.value} (v{__version__})"
|
|
101
|
+
|
|
96
102
|
def generate_name(self) -> str:
|
|
97
103
|
return f"{self.type.value}{NAME_SEPARATOR}{self.name}"
|
|
98
104
|
|
|
@@ -101,5 +107,12 @@ class TriggerDefinition(BaseModel):
|
|
|
101
107
|
action.validate_parameters()
|
|
102
108
|
|
|
103
109
|
|
|
110
|
+
class TriggerBranchDefinition(TriggerDefinition):
|
|
111
|
+
branch: str
|
|
112
|
+
|
|
113
|
+
def generate_name(self) -> str:
|
|
114
|
+
return f"{self.type.value}{NAME_SEPARATOR}{self.branch}{NAME_SEPARATOR}{self.name}"
|
|
115
|
+
|
|
116
|
+
|
|
104
117
|
class BuiltinTriggerDefinition(TriggerDefinition):
|
|
105
118
|
type: TriggerType = TriggerType.BUILTIN
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from prefect import get_run_logger, task
|
|
4
|
+
from prefect.automations import AutomationCore
|
|
5
|
+
from prefect.cache_policies import NONE
|
|
6
|
+
from prefect.client.orchestration import PrefectClient
|
|
7
|
+
from prefect.client.schemas.filters import DeploymentFilter, DeploymentFilterName
|
|
8
|
+
|
|
9
|
+
from infrahub.trigger.models import TriggerDefinition
|
|
10
|
+
|
|
11
|
+
from .models import TriggerType
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from uuid import UUID
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@task(name="trigger-setup", task_run_name="Setup triggers", cache_policy=NONE) # type: ignore[arg-type]
|
|
18
|
+
async def setup_triggers(
|
|
19
|
+
client: PrefectClient,
|
|
20
|
+
triggers: list[TriggerDefinition],
|
|
21
|
+
trigger_type: TriggerType | None = None,
|
|
22
|
+
) -> None:
|
|
23
|
+
log = get_run_logger()
|
|
24
|
+
|
|
25
|
+
if trigger_type:
|
|
26
|
+
log.info(f"Setting up triggers of type {trigger_type.value}")
|
|
27
|
+
else:
|
|
28
|
+
log.info("Setting up all triggers")
|
|
29
|
+
|
|
30
|
+
# -------------------------------------------------------------
|
|
31
|
+
# Retrieve existing Deployments and Automation from the server
|
|
32
|
+
# -------------------------------------------------------------
|
|
33
|
+
deployment_names = list({name for trigger in triggers for name in trigger.get_deployment_names()})
|
|
34
|
+
deployments = {
|
|
35
|
+
item.name: item
|
|
36
|
+
for item in await client.read_deployments(
|
|
37
|
+
deployment_filter=DeploymentFilter(name=DeploymentFilterName(any_=deployment_names))
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
deployments_mapping: dict[str, UUID] = {name: item.id for name, item in deployments.items()}
|
|
41
|
+
existing_automations = {item.name: item for item in await client.read_automations()}
|
|
42
|
+
|
|
43
|
+
# If a trigger type is provided, narrow down the list of existing triggers to know which one to delete
|
|
44
|
+
if trigger_type:
|
|
45
|
+
trigger_automations = [
|
|
46
|
+
item.name for item in await client.read_automations() if item.name.startswith(trigger_type.value)
|
|
47
|
+
]
|
|
48
|
+
else:
|
|
49
|
+
trigger_automations = [item.name for item in await client.read_automations()]
|
|
50
|
+
|
|
51
|
+
trigger_names = [trigger.generate_name() for trigger in triggers]
|
|
52
|
+
|
|
53
|
+
log.debug(f"{len(trigger_automations)} existing triggers ({trigger_automations})")
|
|
54
|
+
log.debug(f"{len(trigger_names)} triggers to configure ({trigger_names})")
|
|
55
|
+
|
|
56
|
+
to_delete = set(trigger_automations) - set(trigger_names)
|
|
57
|
+
log.debug(f"{len(trigger_names)} triggers to delete ({to_delete})")
|
|
58
|
+
|
|
59
|
+
# -------------------------------------------------------------
|
|
60
|
+
# Create or Update all triggers
|
|
61
|
+
# -------------------------------------------------------------
|
|
62
|
+
for trigger in triggers:
|
|
63
|
+
automation = AutomationCore(
|
|
64
|
+
name=trigger.generate_name(),
|
|
65
|
+
description=trigger.get_description(),
|
|
66
|
+
enabled=True,
|
|
67
|
+
trigger=trigger.trigger.get_prefect(),
|
|
68
|
+
actions=[action.get_prefect(mapping=deployments_mapping) for action in trigger.actions],
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
existing_automation = existing_automations.get(trigger.generate_name(), None)
|
|
72
|
+
|
|
73
|
+
if existing_automation:
|
|
74
|
+
await client.update_automation(automation_id=existing_automation.id, automation=automation)
|
|
75
|
+
log.info(f"{trigger.generate_name()} Updated")
|
|
76
|
+
else:
|
|
77
|
+
await client.create_automation(automation=automation)
|
|
78
|
+
log.info(f"{trigger.generate_name()} Created")
|
|
79
|
+
|
|
80
|
+
# -------------------------------------------------------------
|
|
81
|
+
# Delete Triggers that shouldn't be there
|
|
82
|
+
# -------------------------------------------------------------
|
|
83
|
+
for item_to_delete in to_delete:
|
|
84
|
+
existing_automation = existing_automations.get(item_to_delete)
|
|
85
|
+
|
|
86
|
+
if not existing_automation:
|
|
87
|
+
continue
|
|
88
|
+
|
|
89
|
+
await client.delete_automation(automation_id=existing_automation.id)
|
|
90
|
+
log.info(f"{item_to_delete} Deleted")
|
infrahub/trigger/tasks.py
CHANGED
|
@@ -1,91 +1,36 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from infrahub.trigger.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
from .
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
1
|
+
from prefect import flow
|
|
2
|
+
from prefect.client.orchestration import get_client
|
|
3
|
+
|
|
4
|
+
from infrahub.computed_attribute.gather import (
|
|
5
|
+
gather_trigger_computed_attribute_jinja2,
|
|
6
|
+
gather_trigger_computed_attribute_python,
|
|
7
|
+
)
|
|
8
|
+
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
|
|
9
|
+
from infrahub.trigger.catalogue import builtin_triggers
|
|
10
|
+
from infrahub.webhook.gather import gather_trigger_webhook
|
|
11
|
+
|
|
12
|
+
from .setup import setup_triggers
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@flow(name="trigger-configure-all", flow_run_name="Configure all triggers")
|
|
16
|
+
async def trigger_configure_all(service: InfrahubServices) -> None:
|
|
17
|
+
webhook_trigger = await gather_trigger_webhook(db=service.database)
|
|
18
|
+
computed_attribute_j2_triggers = await gather_trigger_computed_attribute_jinja2()
|
|
19
|
+
(
|
|
20
|
+
computed_attribute_python_triggers,
|
|
21
|
+
computed_attribute_python_query_triggers,
|
|
22
|
+
) = await gather_trigger_computed_attribute_python(db=service.database)
|
|
23
|
+
|
|
24
|
+
triggers = (
|
|
25
|
+
computed_attribute_j2_triggers
|
|
26
|
+
+ computed_attribute_python_triggers
|
|
27
|
+
+ computed_attribute_python_query_triggers
|
|
28
|
+
+ builtin_triggers
|
|
29
|
+
+ webhook_trigger
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
async with get_client(sync_client=False) as prefect_client:
|
|
33
|
+
await setup_triggers(
|
|
34
|
+
client=prefect_client,
|
|
35
|
+
triggers=triggers,
|
|
35
36
|
)
|
|
36
|
-
}
|
|
37
|
-
deployments_mapping: dict[str, UUID] = {name: item.id for name, item in deployments.items()}
|
|
38
|
-
existing_automations = {item.name: item for item in await client.read_automations()}
|
|
39
|
-
|
|
40
|
-
trigger_automations = [
|
|
41
|
-
item.name for item in await client.read_automations() if item.name.startswith(trigger_type.value)
|
|
42
|
-
]
|
|
43
|
-
trigger_names = [trigger.generate_name() for trigger in triggers]
|
|
44
|
-
|
|
45
|
-
to_delete = set(trigger_automations) - set(trigger_names)
|
|
46
|
-
|
|
47
|
-
# -------------------------------------------------------------
|
|
48
|
-
# Create or Update all triggers
|
|
49
|
-
# -------------------------------------------------------------
|
|
50
|
-
for trigger in triggers:
|
|
51
|
-
automation = AutomationCore(
|
|
52
|
-
name=trigger.generate_name(),
|
|
53
|
-
description=trigger.description,
|
|
54
|
-
enabled=True,
|
|
55
|
-
trigger=trigger.trigger.get_prefect(),
|
|
56
|
-
actions=[action.get_prefect(mapping=deployments_mapping) for action in trigger.actions],
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
existing_automation = existing_automations.get(trigger.name, None)
|
|
60
|
-
|
|
61
|
-
if existing_automation:
|
|
62
|
-
await client.update_automation(automation_id=existing_automation.id, automation=automation)
|
|
63
|
-
log.info(f"{trigger.name} Updated")
|
|
64
|
-
else:
|
|
65
|
-
await client.create_automation(automation=automation)
|
|
66
|
-
log.info(f"{trigger.name} Created")
|
|
67
|
-
|
|
68
|
-
# -------------------------------------------------------------
|
|
69
|
-
# Delete Triggers that shouldn't be there
|
|
70
|
-
# -------------------------------------------------------------
|
|
71
|
-
for item_to_delete in to_delete:
|
|
72
|
-
existing_automation = existing_automations.get(item_to_delete)
|
|
73
|
-
|
|
74
|
-
if not existing_automation:
|
|
75
|
-
continue
|
|
76
|
-
|
|
77
|
-
await client.delete_automation(automation_id=existing_automation.id)
|
|
78
|
-
log.info(f"{item_to_delete} Deleted")
|
|
79
|
-
|
|
80
|
-
# -------------------------------------------------------------
|
|
81
|
-
# Delete Deprecated triggers
|
|
82
|
-
# -------------------------------------------------------------
|
|
83
|
-
if deprecated_triggers:
|
|
84
|
-
for trigger_name in deprecated_triggers:
|
|
85
|
-
existing_automation = existing_automations.get(trigger_name)
|
|
86
|
-
|
|
87
|
-
if not existing_automation:
|
|
88
|
-
continue
|
|
89
|
-
|
|
90
|
-
await client.delete_automation(automation_id=existing_automation.id)
|
|
91
|
-
log.info(f"{trigger_name} Deleted")
|