infrahub-server 1.2.11__py3-none-any.whl → 1.3.0__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/actions/constants.py +130 -0
- infrahub/actions/gather.py +114 -0
- infrahub/actions/models.py +243 -0
- infrahub/actions/parsers.py +104 -0
- infrahub/actions/schema.py +393 -0
- infrahub/actions/tasks.py +119 -0
- infrahub/actions/triggers.py +21 -0
- infrahub/branch/__init__.py +0 -0
- infrahub/branch/tasks.py +29 -0
- infrahub/branch/triggers.py +22 -0
- infrahub/cli/db.py +3 -4
- infrahub/computed_attribute/gather.py +3 -1
- infrahub/computed_attribute/tasks.py +23 -29
- infrahub/core/account.py +24 -47
- infrahub/core/attribute.py +13 -15
- infrahub/core/constants/__init__.py +10 -0
- infrahub/core/constants/database.py +1 -0
- infrahub/core/constants/infrahubkind.py +9 -0
- infrahub/core/constraint/node/runner.py +3 -1
- infrahub/core/convert_object_type/__init__.py +0 -0
- infrahub/core/convert_object_type/conversion.py +124 -0
- infrahub/core/convert_object_type/schema_mapping.py +56 -0
- infrahub/core/diff/coordinator.py +8 -1
- infrahub/core/diff/query/all_conflicts.py +1 -5
- infrahub/core/diff/query/artifact.py +10 -20
- infrahub/core/diff/query/delete_query.py +8 -4
- infrahub/core/diff/query/diff_get.py +3 -6
- infrahub/core/diff/query/field_specifiers.py +1 -1
- infrahub/core/diff/query/field_summary.py +2 -4
- infrahub/core/diff/query/merge.py +72 -125
- infrahub/core/diff/query/save.py +83 -68
- infrahub/core/diff/query/summary_counts_enricher.py +34 -54
- infrahub/core/diff/query/time_range_query.py +0 -1
- infrahub/core/diff/repository/repository.py +4 -0
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/manager.py +14 -11
- infrahub/core/migrations/graph/__init__.py +6 -0
- infrahub/core/migrations/graph/m003_relationship_parent_optional.py +1 -2
- infrahub/core/migrations/graph/m012_convert_account_generic.py +1 -1
- infrahub/core/migrations/graph/m013_convert_git_password_credential.py +2 -6
- infrahub/core/migrations/graph/m015_diff_format_update.py +1 -2
- infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -2
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +11 -22
- infrahub/core/migrations/graph/m020_duplicate_edges.py +3 -6
- infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +1 -2
- infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +2 -2
- infrahub/core/migrations/graph/m024_missing_hierarchy_backfill.py +1 -2
- infrahub/core/migrations/graph/m028_delete_diffs.py +1 -2
- infrahub/core/migrations/graph/m029_duplicates_cleanup.py +662 -0
- infrahub/core/migrations/graph/m030_illegal_edges.py +82 -0
- infrahub/core/migrations/query/attribute_add.py +14 -11
- infrahub/core/migrations/query/attribute_rename.py +6 -11
- infrahub/core/migrations/query/delete_element_in_schema.py +19 -17
- infrahub/core/migrations/query/node_duplicate.py +19 -21
- infrahub/core/migrations/query/relationship_duplicate.py +19 -18
- infrahub/core/migrations/schema/node_attribute_remove.py +4 -8
- infrahub/core/migrations/schema/node_remove.py +19 -20
- infrahub/core/models.py +29 -2
- infrahub/core/node/__init__.py +131 -28
- infrahub/core/node/base.py +1 -1
- infrahub/core/node/create.py +211 -0
- infrahub/core/node/resource_manager/number_pool.py +31 -5
- infrahub/core/node/standard.py +6 -1
- infrahub/core/path.py +15 -1
- infrahub/core/protocols.py +57 -0
- infrahub/core/protocols_base.py +3 -0
- infrahub/core/query/__init__.py +2 -2
- infrahub/core/query/delete.py +3 -3
- infrahub/core/query/diff.py +19 -32
- infrahub/core/query/ipam.py +10 -20
- infrahub/core/query/node.py +29 -47
- infrahub/core/query/relationship.py +55 -34
- infrahub/core/query/resource_manager.py +1 -2
- infrahub/core/query/standard_node.py +19 -5
- infrahub/core/query/subquery.py +2 -4
- infrahub/core/relationship/constraints/count.py +10 -9
- infrahub/core/relationship/constraints/interface.py +2 -1
- infrahub/core/relationship/constraints/peer_kind.py +2 -1
- infrahub/core/relationship/constraints/peer_parent.py +56 -0
- infrahub/core/relationship/constraints/peer_relatives.py +72 -0
- infrahub/core/relationship/constraints/profiles_kind.py +1 -1
- infrahub/core/relationship/model.py +4 -1
- infrahub/core/schema/__init__.py +2 -1
- infrahub/core/schema/attribute_parameters.py +160 -0
- infrahub/core/schema/attribute_schema.py +130 -7
- infrahub/core/schema/basenode_schema.py +27 -3
- infrahub/core/schema/definitions/core/__init__.py +29 -1
- infrahub/core/schema/definitions/core/group.py +45 -0
- infrahub/core/schema/definitions/core/resource_pool.py +9 -0
- infrahub/core/schema/definitions/internal.py +43 -5
- infrahub/core/schema/generated/attribute_schema.py +16 -3
- infrahub/core/schema/generated/relationship_schema.py +11 -1
- infrahub/core/schema/manager.py +7 -2
- infrahub/core/schema/schema_branch.py +109 -12
- infrahub/core/validators/__init__.py +15 -2
- infrahub/core/validators/attribute/choices.py +1 -3
- infrahub/core/validators/attribute/enum.py +1 -3
- infrahub/core/validators/attribute/kind.py +1 -3
- infrahub/core/validators/attribute/length.py +13 -7
- infrahub/core/validators/attribute/min_max.py +118 -0
- infrahub/core/validators/attribute/number_pool.py +106 -0
- infrahub/core/validators/attribute/optional.py +1 -4
- infrahub/core/validators/attribute/regex.py +5 -6
- infrahub/core/validators/attribute/unique.py +1 -3
- infrahub/core/validators/determiner.py +18 -2
- infrahub/core/validators/enum.py +12 -0
- infrahub/core/validators/node/hierarchy.py +3 -6
- infrahub/core/validators/query.py +1 -3
- infrahub/core/validators/relationship/count.py +6 -12
- infrahub/core/validators/relationship/optional.py +2 -4
- infrahub/core/validators/relationship/peer.py +177 -12
- infrahub/core/validators/tasks.py +1 -1
- infrahub/core/validators/uniqueness/query.py +5 -9
- infrahub/database/__init__.py +12 -4
- infrahub/database/validation.py +100 -0
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +4 -0
- infrahub/dependencies/builder/constraint/relationship_manager/peer_parent.py +8 -0
- infrahub/dependencies/builder/constraint/relationship_manager/peer_relatives.py +8 -0
- infrahub/dependencies/builder/constraint/schema/aggregated.py +2 -0
- infrahub/dependencies/builder/constraint/schema/relationship_peer.py +8 -0
- infrahub/dependencies/builder/diff/deserializer.py +1 -1
- infrahub/dependencies/registry.py +4 -0
- infrahub/events/group_action.py +1 -0
- infrahub/events/models.py +1 -1
- infrahub/git/base.py +5 -3
- infrahub/git/integrator.py +96 -5
- infrahub/git/tasks.py +1 -0
- infrahub/graphql/analyzer.py +139 -18
- infrahub/graphql/manager.py +4 -0
- infrahub/graphql/mutations/action.py +164 -0
- infrahub/graphql/mutations/convert_object_type.py +71 -0
- infrahub/graphql/mutations/main.py +25 -176
- infrahub/graphql/mutations/proposed_change.py +20 -17
- infrahub/graphql/mutations/relationship.py +32 -0
- infrahub/graphql/mutations/resource_manager.py +63 -7
- infrahub/graphql/queries/convert_object_type_mapping.py +34 -0
- infrahub/graphql/queries/resource_manager.py +7 -1
- infrahub/graphql/resolvers/many_relationship.py +1 -1
- infrahub/graphql/resolvers/resolver.py +2 -2
- infrahub/graphql/resolvers/single_relationship.py +1 -1
- infrahub/graphql/schema.py +6 -0
- infrahub/menu/menu.py +34 -2
- infrahub/message_bus/messages/__init__.py +0 -10
- infrahub/message_bus/operations/__init__.py +0 -8
- infrahub/message_bus/operations/refresh/registry.py +4 -7
- infrahub/patch/queries/delete_duplicated_edges.py +45 -39
- infrahub/pools/models.py +14 -0
- infrahub/pools/number.py +5 -3
- infrahub/pools/registration.py +22 -0
- infrahub/pools/tasks.py +126 -0
- infrahub/prefect_server/models.py +1 -19
- infrahub/proposed_change/models.py +68 -3
- infrahub/proposed_change/tasks.py +911 -34
- infrahub/schema/__init__.py +0 -0
- infrahub/schema/tasks.py +27 -0
- infrahub/schema/triggers.py +23 -0
- infrahub/task_manager/models.py +10 -6
- infrahub/trigger/catalogue.py +6 -0
- infrahub/trigger/models.py +23 -6
- infrahub/trigger/setup.py +26 -2
- infrahub/trigger/tasks.py +4 -2
- infrahub/types.py +6 -0
- infrahub/webhook/tasks.py +6 -9
- infrahub/workflows/catalogue.py +103 -1
- infrahub_sdk/client.py +43 -10
- infrahub_sdk/ctl/generator.py +4 -4
- infrahub_sdk/ctl/repository.py +1 -1
- infrahub_sdk/node/__init__.py +39 -0
- infrahub_sdk/node/attribute.py +122 -0
- infrahub_sdk/node/constants.py +21 -0
- infrahub_sdk/{node.py → node/node.py} +158 -803
- infrahub_sdk/node/parsers.py +15 -0
- infrahub_sdk/node/property.py +24 -0
- infrahub_sdk/node/related_node.py +266 -0
- infrahub_sdk/node/relationship.py +302 -0
- infrahub_sdk/protocols.py +112 -0
- infrahub_sdk/protocols_base.py +34 -2
- infrahub_sdk/pytest_plugin/items/python_transform.py +2 -1
- infrahub_sdk/query_groups.py +17 -5
- infrahub_sdk/schema/main.py +1 -0
- infrahub_sdk/schema/repository.py +16 -0
- infrahub_sdk/spec/object.py +1 -1
- infrahub_sdk/store.py +1 -1
- infrahub_sdk/testing/schemas/car_person.py +1 -0
- infrahub_sdk/utils.py +7 -20
- infrahub_sdk/yaml.py +6 -5
- {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/METADATA +5 -5
- {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/RECORD +197 -168
- {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/WHEEL +1 -1
- infrahub_testcontainers/container.py +239 -65
- infrahub_testcontainers/docker-compose-cluster.test.yml +321 -0
- infrahub_testcontainers/docker-compose.test.yml +2 -1
- infrahub_testcontainers/helpers.py +23 -3
- infrahub_testcontainers/plugin.py +9 -0
- infrahub/message_bus/messages/check_generator_run.py +0 -26
- infrahub/message_bus/messages/finalize_validator_execution.py +0 -15
- infrahub/message_bus/messages/proposed_change/base_with_diff.py +0 -16
- infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +0 -11
- infrahub/message_bus/messages/request_generatordefinition_check.py +0 -20
- infrahub/message_bus/messages/request_proposedchange_pipeline.py +0 -23
- infrahub/message_bus/operations/check/__init__.py +0 -3
- infrahub/message_bus/operations/check/generator.py +0 -156
- infrahub/message_bus/operations/finalize/__init__.py +0 -3
- infrahub/message_bus/operations/finalize/validator.py +0 -133
- infrahub/message_bus/operations/requests/__init__.py +0 -9
- infrahub/message_bus/operations/requests/generator_definition.py +0 -140
- infrahub/message_bus/operations/requests/proposed_change.py +0 -629
- infrahub/patch/queries/consolidate_duplicated_nodes.py +0 -109
- /infrahub/{message_bus/messages/proposed_change → actions}/__init__.py +0 -0
- {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/LICENSE.txt +0 -0
- {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
from infrahub_sdk.exceptions import ModuleImportError
|
|
2
|
-
from infrahub_sdk.node import InfrahubNode
|
|
3
|
-
from infrahub_sdk.schema.repository import InfrahubGeneratorDefinitionConfig
|
|
4
|
-
from prefect import flow
|
|
5
|
-
from prefect.logging import get_run_logger
|
|
6
|
-
|
|
7
|
-
from infrahub import lock
|
|
8
|
-
from infrahub.core.constants import GeneratorInstanceStatus, InfrahubKind, ValidatorConclusion
|
|
9
|
-
from infrahub.core.timestamp import Timestamp
|
|
10
|
-
from infrahub.git.base import extract_repo_file_information
|
|
11
|
-
from infrahub.git.repository import get_initialized_repo
|
|
12
|
-
from infrahub.message_bus import messages
|
|
13
|
-
from infrahub.services import InfrahubServices
|
|
14
|
-
from infrahub.tasks.check import set_check_status
|
|
15
|
-
from infrahub.workflows.utils import add_tags
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@flow(
|
|
19
|
-
name="git-repository-check-generator-run",
|
|
20
|
-
flow_run_name="Execute Generator {message.generator_definition.definition_name} for {message.target_name}",
|
|
21
|
-
)
|
|
22
|
-
async def run(message: messages.CheckGeneratorRun, service: InfrahubServices) -> None:
|
|
23
|
-
if message.proposed_change:
|
|
24
|
-
await add_tags(branches=[message.branch_name], nodes=[message.proposed_change], db_change=True)
|
|
25
|
-
else:
|
|
26
|
-
await add_tags(branches=[message.branch_name], nodes=[message.repository_id], db_change=True)
|
|
27
|
-
|
|
28
|
-
log = get_run_logger()
|
|
29
|
-
|
|
30
|
-
repository = await get_initialized_repo(
|
|
31
|
-
repository_id=message.repository_id,
|
|
32
|
-
name=message.repository_name,
|
|
33
|
-
service=service,
|
|
34
|
-
repository_kind=message.repository_kind,
|
|
35
|
-
commit=message.commit,
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
conclusion = ValidatorConclusion.SUCCESS
|
|
39
|
-
|
|
40
|
-
generator_definition = InfrahubGeneratorDefinitionConfig(
|
|
41
|
-
name=message.generator_definition.definition_name,
|
|
42
|
-
class_name=message.generator_definition.class_name,
|
|
43
|
-
file_path=message.generator_definition.file_path,
|
|
44
|
-
query=message.generator_definition.query_name,
|
|
45
|
-
targets=message.generator_definition.group_id,
|
|
46
|
-
convert_query_response=message.generator_definition.convert_query_response,
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
commit_worktree = repository.get_commit_worktree(commit=message.commit)
|
|
50
|
-
|
|
51
|
-
file_info = extract_repo_file_information(
|
|
52
|
-
full_filename=commit_worktree.directory / generator_definition.file_path,
|
|
53
|
-
repo_directory=repository.directory_root,
|
|
54
|
-
worktree_directory=commit_worktree.directory,
|
|
55
|
-
)
|
|
56
|
-
generator_instance = await _define_instance(message=message, service=service)
|
|
57
|
-
|
|
58
|
-
check_message = "Instance successfully generated"
|
|
59
|
-
try:
|
|
60
|
-
log.debug(f"repo information {file_info}")
|
|
61
|
-
log.debug(f"Root directory : {repository.directory_root}")
|
|
62
|
-
generator_class = generator_definition.load_class(
|
|
63
|
-
import_root=repository.directory_root, relative_path=file_info.relative_repo_path_dir
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
generator = generator_class(
|
|
67
|
-
query=generator_definition.query,
|
|
68
|
-
client=service.client,
|
|
69
|
-
branch=message.branch_name,
|
|
70
|
-
params=message.variables,
|
|
71
|
-
generator_instance=generator_instance.id,
|
|
72
|
-
convert_query_response=generator_definition.convert_query_response,
|
|
73
|
-
infrahub_node=InfrahubNode,
|
|
74
|
-
)
|
|
75
|
-
generator._init_client.request_context = message.context.to_request_context()
|
|
76
|
-
await generator.run(identifier=generator_definition.name)
|
|
77
|
-
generator_instance.status.value = GeneratorInstanceStatus.READY.value
|
|
78
|
-
except ModuleImportError as exc:
|
|
79
|
-
conclusion = ValidatorConclusion.FAILURE
|
|
80
|
-
generator_instance.status.value = GeneratorInstanceStatus.ERROR.value
|
|
81
|
-
check_message = f"Failed to import generator: {exc.message}"
|
|
82
|
-
log.exception(check_message, exc_info=exc)
|
|
83
|
-
except Exception as exc:
|
|
84
|
-
conclusion = ValidatorConclusion.FAILURE
|
|
85
|
-
generator_instance.status.value = GeneratorInstanceStatus.ERROR.value
|
|
86
|
-
check_message = f"Failed to execute generator: {str(exc)}"
|
|
87
|
-
log.exception(check_message, exc_info=exc)
|
|
88
|
-
|
|
89
|
-
log.info("Generator run completed, starting update")
|
|
90
|
-
await generator_instance.update(do_full_update=True)
|
|
91
|
-
|
|
92
|
-
check = None
|
|
93
|
-
existing_check = await service.client.filters(
|
|
94
|
-
kind=InfrahubKind.GENERATORCHECK, validator__ids=message.validator_id, instance__value=generator_instance.id
|
|
95
|
-
)
|
|
96
|
-
if existing_check:
|
|
97
|
-
check = existing_check[0]
|
|
98
|
-
|
|
99
|
-
if check:
|
|
100
|
-
check.created_at.value = Timestamp().to_string()
|
|
101
|
-
check.conclusion.value = conclusion.value
|
|
102
|
-
await check.save()
|
|
103
|
-
else:
|
|
104
|
-
check = await service.client.create(
|
|
105
|
-
kind=InfrahubKind.GENERATORCHECK,
|
|
106
|
-
data={
|
|
107
|
-
"name": message.target_name,
|
|
108
|
-
"origin": message.repository_id,
|
|
109
|
-
"kind": "GeneratorDefinition",
|
|
110
|
-
"validator": message.validator_id,
|
|
111
|
-
"created_at": Timestamp().to_string(),
|
|
112
|
-
"message": check_message,
|
|
113
|
-
"conclusion": conclusion.value,
|
|
114
|
-
"instance": generator_instance.id,
|
|
115
|
-
},
|
|
116
|
-
)
|
|
117
|
-
await check.save()
|
|
118
|
-
|
|
119
|
-
await set_check_status(message=message, conclusion=conclusion.value, service=service)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
async def _define_instance(message: messages.CheckGeneratorRun, service: InfrahubServices) -> InfrahubNode:
|
|
123
|
-
if message.generator_instance:
|
|
124
|
-
instance = await service.client.get(
|
|
125
|
-
kind=InfrahubKind.GENERATORINSTANCE, id=message.generator_instance, branch=message.branch_name
|
|
126
|
-
)
|
|
127
|
-
instance.status.value = GeneratorInstanceStatus.PENDING.value
|
|
128
|
-
await instance.update(do_full_update=True)
|
|
129
|
-
|
|
130
|
-
else:
|
|
131
|
-
async with lock.registry.get(
|
|
132
|
-
f"{message.target_id}-{message.generator_definition.definition_id}", namespace="generator"
|
|
133
|
-
):
|
|
134
|
-
instances = await service.client.filters(
|
|
135
|
-
kind=InfrahubKind.GENERATORINSTANCE,
|
|
136
|
-
definition__ids=[message.generator_definition.definition_id],
|
|
137
|
-
object__ids=[message.target_id],
|
|
138
|
-
branch=message.branch_name,
|
|
139
|
-
)
|
|
140
|
-
if instances:
|
|
141
|
-
instance = instances[0]
|
|
142
|
-
instance.status.value = GeneratorInstanceStatus.PENDING.value
|
|
143
|
-
await instance.update(do_full_update=True)
|
|
144
|
-
else:
|
|
145
|
-
instance = await service.client.create(
|
|
146
|
-
kind=InfrahubKind.GENERATORINSTANCE,
|
|
147
|
-
branch=message.branch_name,
|
|
148
|
-
data={
|
|
149
|
-
"name": f"{message.generator_definition.definition_name}: {message.target_name}",
|
|
150
|
-
"status": GeneratorInstanceStatus.PENDING.value,
|
|
151
|
-
"object": message.target_id,
|
|
152
|
-
"definition": message.generator_definition.definition_id,
|
|
153
|
-
},
|
|
154
|
-
)
|
|
155
|
-
await instance.save()
|
|
156
|
-
return instance
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
from infrahub_sdk.protocols import (
|
|
2
|
-
CoreArtifactValidator,
|
|
3
|
-
CoreDataValidator,
|
|
4
|
-
CoreGeneratorValidator,
|
|
5
|
-
CoreRepositoryValidator,
|
|
6
|
-
CoreSchemaValidator,
|
|
7
|
-
CoreUserValidator,
|
|
8
|
-
CoreValidator,
|
|
9
|
-
)
|
|
10
|
-
from prefect import flow
|
|
11
|
-
|
|
12
|
-
from infrahub import config
|
|
13
|
-
from infrahub.core.constants import InfrahubKind, ValidatorConclusion
|
|
14
|
-
from infrahub.core.timestamp import Timestamp
|
|
15
|
-
from infrahub.log import get_logger
|
|
16
|
-
from infrahub.message_bus import messages
|
|
17
|
-
from infrahub.message_bus.types import KVTTL, MessageTTL
|
|
18
|
-
from infrahub.services import InfrahubServices
|
|
19
|
-
from infrahub.validators.events import send_failed_validator, send_passed_validator
|
|
20
|
-
|
|
21
|
-
log = get_logger()
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@flow(name="validator-finalize-execution")
|
|
25
|
-
async def execution(message: messages.FinalizeValidatorExecution, service: InfrahubServices) -> None:
|
|
26
|
-
"""Monitors the status of checks associated with a validator and finalizes the conclusion of the validator
|
|
27
|
-
|
|
28
|
-
Based on the unique execution_id this function looks expects to see an entry in the cache for each check
|
|
29
|
-
associated with this validator. Upon seeing the result of a check the function will exclude it from further
|
|
30
|
-
checks and update the current conclusion of the validator if any of the checks failed.
|
|
31
|
-
|
|
32
|
-
The message will get rescheduled until the timeout has exceeded or until all checks are accounted for.
|
|
33
|
-
"""
|
|
34
|
-
validator_type = get_validator_type(validator_type=message.validator_type)
|
|
35
|
-
validator = await service.client.get(kind=validator_type, id=message.validator_id)
|
|
36
|
-
checks_key = f"validator_execution_id:{message.validator_execution_id}:checks"
|
|
37
|
-
current_conclusion = validator.conclusion.value
|
|
38
|
-
if validator.state.value != "in_progress":
|
|
39
|
-
validator.state.value = "in_progress"
|
|
40
|
-
validator.started_at.value = Timestamp().to_string()
|
|
41
|
-
validator.completed_at.value = ""
|
|
42
|
-
await validator.save()
|
|
43
|
-
|
|
44
|
-
required_checks_data = await service.cache.get(key=checks_key) or ""
|
|
45
|
-
# Remove instances of empty checks
|
|
46
|
-
required_checks = [required_check for required_check in required_checks_data.split(",") if required_check]
|
|
47
|
-
|
|
48
|
-
completed_checks_data = await service.cache.list_keys(
|
|
49
|
-
filter_pattern=f"validator_execution_id:{message.validator_execution_id}:check_execution_id:*"
|
|
50
|
-
)
|
|
51
|
-
completed_checks = [check.split(":")[-1] for check in completed_checks_data]
|
|
52
|
-
|
|
53
|
-
missing_checks = [check for check in required_checks if check not in completed_checks]
|
|
54
|
-
checks_to_verify = [check for check in completed_checks if check in required_checks]
|
|
55
|
-
failed_check = False
|
|
56
|
-
|
|
57
|
-
for check in checks_to_verify:
|
|
58
|
-
conclusion = await service.cache.get(
|
|
59
|
-
f"validator_execution_id:{message.validator_execution_id}:check_execution_id:{check}"
|
|
60
|
-
)
|
|
61
|
-
if conclusion != "success":
|
|
62
|
-
failed_check = True
|
|
63
|
-
|
|
64
|
-
conclusion = "failure" if failed_check else "success"
|
|
65
|
-
if failed_check and current_conclusion != "failure":
|
|
66
|
-
validator.conclusion.value = "failure"
|
|
67
|
-
await validator.save()
|
|
68
|
-
|
|
69
|
-
if missing_checks:
|
|
70
|
-
remaining_checks = ",".join(missing_checks)
|
|
71
|
-
await service.cache.set(key=checks_key, value=remaining_checks, expires=KVTTL.TWO_HOURS)
|
|
72
|
-
current_time = Timestamp()
|
|
73
|
-
starting_time = Timestamp(message.start_time)
|
|
74
|
-
deadline = starting_time.add_delta(seconds=config.SETTINGS.miscellaneous.maximum_validator_execution_time)
|
|
75
|
-
if current_time < deadline:
|
|
76
|
-
log.debug(
|
|
77
|
-
"Still waiting for checks to complete",
|
|
78
|
-
missing_checks=missing_checks,
|
|
79
|
-
validator_id=message.validator_id,
|
|
80
|
-
validator_execution_id=message.validator_execution_id,
|
|
81
|
-
)
|
|
82
|
-
await service.message_bus.send(message=message, delay=MessageTTL.FIVE)
|
|
83
|
-
return
|
|
84
|
-
|
|
85
|
-
log.info(
|
|
86
|
-
"Timeout reached",
|
|
87
|
-
validator_id=message.validator_id,
|
|
88
|
-
validator_execution_id=message.validator_execution_id,
|
|
89
|
-
)
|
|
90
|
-
conclusion = "failure"
|
|
91
|
-
|
|
92
|
-
validator.state.value = "completed"
|
|
93
|
-
validator.completed_at.value = Timestamp().to_string()
|
|
94
|
-
validator.conclusion.value = conclusion
|
|
95
|
-
await validator.save()
|
|
96
|
-
if validator.conclusion.value == ValidatorConclusion.SUCCESS.value:
|
|
97
|
-
await send_passed_validator(
|
|
98
|
-
service=service, validator=validator, proposed_change_id=message.proposed_change, context=message.context
|
|
99
|
-
)
|
|
100
|
-
else:
|
|
101
|
-
await send_failed_validator(
|
|
102
|
-
service=service, validator=validator, proposed_change_id=message.proposed_change, context=message.context
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def get_validator_type(
|
|
107
|
-
validator_type: str,
|
|
108
|
-
) -> (
|
|
109
|
-
type[CoreArtifactValidator]
|
|
110
|
-
| type[CoreDataValidator]
|
|
111
|
-
| type[CoreGeneratorValidator]
|
|
112
|
-
| type[CoreRepositoryValidator]
|
|
113
|
-
| type[CoreSchemaValidator]
|
|
114
|
-
| type[CoreUserValidator]
|
|
115
|
-
| type[CoreValidator]
|
|
116
|
-
):
|
|
117
|
-
match validator_type:
|
|
118
|
-
case InfrahubKind.USERVALIDATOR:
|
|
119
|
-
validator_kind = CoreUserValidator
|
|
120
|
-
case InfrahubKind.SCHEMAVALIDATOR:
|
|
121
|
-
validator_kind = CoreSchemaValidator
|
|
122
|
-
case InfrahubKind.GENERATORVALIDATOR:
|
|
123
|
-
validator_kind = CoreGeneratorValidator
|
|
124
|
-
case InfrahubKind.REPOSITORYVALIDATOR:
|
|
125
|
-
validator_kind = CoreRepositoryValidator
|
|
126
|
-
case InfrahubKind.DATAVALIDATOR:
|
|
127
|
-
validator_kind = CoreDataValidator
|
|
128
|
-
case InfrahubKind.ARTIFACTVALIDATOR:
|
|
129
|
-
validator_kind = CoreArtifactValidator
|
|
130
|
-
case _:
|
|
131
|
-
validator_kind = CoreValidator
|
|
132
|
-
|
|
133
|
-
return validator_kind
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
from infrahub_sdk.protocols import CoreGeneratorValidator
|
|
2
|
-
from infrahub_sdk.uuidt import UUIDT
|
|
3
|
-
from prefect import flow
|
|
4
|
-
from prefect.logging import get_run_logger
|
|
5
|
-
|
|
6
|
-
from infrahub.core.constants import InfrahubKind
|
|
7
|
-
from infrahub.core.timestamp import Timestamp
|
|
8
|
-
from infrahub.message_bus import InfrahubMessage, Meta, messages
|
|
9
|
-
from infrahub.message_bus.types import KVTTL
|
|
10
|
-
from infrahub.services import InfrahubServices
|
|
11
|
-
from infrahub.validators.tasks import start_validator
|
|
12
|
-
from infrahub.workflows.utils import add_tags
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@flow(
|
|
16
|
-
name="generator-definition-check",
|
|
17
|
-
flow_run_name="Validate Generator selection for {message.generator_definition.definition_name}",
|
|
18
|
-
)
|
|
19
|
-
async def check(message: messages.RequestGeneratorDefinitionCheck, service: InfrahubServices) -> None:
|
|
20
|
-
log = get_run_logger()
|
|
21
|
-
await add_tags(branches=[message.source_branch], nodes=[message.proposed_change])
|
|
22
|
-
events: list[InfrahubMessage] = []
|
|
23
|
-
|
|
24
|
-
proposed_change = await service.client.get(kind=InfrahubKind.PROPOSEDCHANGE, id=message.proposed_change)
|
|
25
|
-
|
|
26
|
-
validator_name = f"Generator Validator: {message.generator_definition.definition_name}"
|
|
27
|
-
validator_execution_id = str(UUIDT())
|
|
28
|
-
check_execution_ids: list[str] = []
|
|
29
|
-
|
|
30
|
-
await proposed_change.validations.fetch()
|
|
31
|
-
|
|
32
|
-
previous_validator: CoreGeneratorValidator | None = None
|
|
33
|
-
for relationship in proposed_change.validations.peers:
|
|
34
|
-
existing_validator = relationship.peer
|
|
35
|
-
if (
|
|
36
|
-
existing_validator.typename == InfrahubKind.GENERATORVALIDATOR
|
|
37
|
-
and existing_validator.definition.id == message.generator_definition.definition_id
|
|
38
|
-
):
|
|
39
|
-
previous_validator = existing_validator
|
|
40
|
-
|
|
41
|
-
validator = await start_validator(
|
|
42
|
-
service=service,
|
|
43
|
-
validator=previous_validator,
|
|
44
|
-
validator_type=CoreGeneratorValidator,
|
|
45
|
-
proposed_change=message.proposed_change,
|
|
46
|
-
data={
|
|
47
|
-
"label": validator_name,
|
|
48
|
-
"definition": message.generator_definition.definition_id,
|
|
49
|
-
},
|
|
50
|
-
context=message.context,
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
group = await service.client.get(
|
|
54
|
-
kind=InfrahubKind.GENERICGROUP,
|
|
55
|
-
prefetch_relationships=True,
|
|
56
|
-
populate_store=True,
|
|
57
|
-
id=message.generator_definition.group_id,
|
|
58
|
-
branch=message.source_branch,
|
|
59
|
-
)
|
|
60
|
-
await group.members.fetch()
|
|
61
|
-
|
|
62
|
-
existing_instances = await service.client.filters(
|
|
63
|
-
kind=InfrahubKind.GENERATORINSTANCE,
|
|
64
|
-
definition__ids=[message.generator_definition.definition_id],
|
|
65
|
-
include=["object"],
|
|
66
|
-
branch=message.source_branch,
|
|
67
|
-
)
|
|
68
|
-
instance_by_member = {}
|
|
69
|
-
for instance in existing_instances:
|
|
70
|
-
instance_by_member[instance.object.peer.id] = instance.id
|
|
71
|
-
|
|
72
|
-
repository = message.branch_diff.get_repository(repository_id=message.generator_definition.repository_id)
|
|
73
|
-
requested_instances = 0
|
|
74
|
-
impacted_instances = message.branch_diff.get_subscribers_ids(kind=InfrahubKind.GENERATORINSTANCE)
|
|
75
|
-
|
|
76
|
-
for relationship in group.members.peers:
|
|
77
|
-
member = relationship.peer
|
|
78
|
-
generator_instance = instance_by_member.get(member.id)
|
|
79
|
-
if _run_generator(
|
|
80
|
-
instance_id=generator_instance,
|
|
81
|
-
managed_branch=message.source_branch_sync_with_git,
|
|
82
|
-
impacted_instances=impacted_instances,
|
|
83
|
-
):
|
|
84
|
-
check_execution_id = str(UUIDT())
|
|
85
|
-
check_execution_ids.append(check_execution_id)
|
|
86
|
-
requested_instances += 1
|
|
87
|
-
log.info(f"Trigger execution of {message.generator_definition.definition_name} for {member.display_label}")
|
|
88
|
-
events.append(
|
|
89
|
-
messages.CheckGeneratorRun(
|
|
90
|
-
context=message.context,
|
|
91
|
-
generator_definition=message.generator_definition,
|
|
92
|
-
generator_instance=generator_instance,
|
|
93
|
-
commit=repository.source_commit,
|
|
94
|
-
repository_id=repository.repository_id,
|
|
95
|
-
repository_name=repository.repository_name,
|
|
96
|
-
repository_kind=repository.kind,
|
|
97
|
-
branch_name=message.source_branch,
|
|
98
|
-
query=message.generator_definition.query_name,
|
|
99
|
-
variables=member.extract(params=message.generator_definition.parameters),
|
|
100
|
-
target_id=member.id,
|
|
101
|
-
target_name=member.display_label,
|
|
102
|
-
validator_id=validator.id,
|
|
103
|
-
proposed_change=message.proposed_change,
|
|
104
|
-
meta=Meta(validator_execution_id=validator_execution_id, check_execution_id=check_execution_id),
|
|
105
|
-
)
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
checks_in_execution = ",".join(check_execution_ids)
|
|
109
|
-
await service.cache.set(
|
|
110
|
-
key=f"validator_execution_id:{validator_execution_id}:checks",
|
|
111
|
-
value=checks_in_execution,
|
|
112
|
-
expires=KVTTL.TWO_HOURS,
|
|
113
|
-
)
|
|
114
|
-
events.append(
|
|
115
|
-
messages.FinalizeValidatorExecution(
|
|
116
|
-
start_time=Timestamp().to_string(),
|
|
117
|
-
validator_id=validator.id,
|
|
118
|
-
validator_execution_id=validator_execution_id,
|
|
119
|
-
validator_type=InfrahubKind.GENERATORVALIDATOR,
|
|
120
|
-
context=message.context,
|
|
121
|
-
proposed_change=message.proposed_change,
|
|
122
|
-
)
|
|
123
|
-
)
|
|
124
|
-
for event in events:
|
|
125
|
-
event.assign_meta(parent=message)
|
|
126
|
-
await service.message_bus.send(message=event)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
def _run_generator(instance_id: str | None, managed_branch: bool, impacted_instances: list[str]) -> bool:
|
|
130
|
-
"""Returns a boolean to indicate if a generator instance needs to be executed
|
|
131
|
-
Will return true if:
|
|
132
|
-
* The instance_id wasn't set which could be that it's a new object that doesn't have a previous generator instance
|
|
133
|
-
* The source branch is set to sync with Git which would indicate that it could contain updates in git to the generator
|
|
134
|
-
* The instance_id exists in the impacted_instances list
|
|
135
|
-
Will return false if:
|
|
136
|
-
* The source branch is a not one that syncs with git and the instance_id exists and is not in the impacted list
|
|
137
|
-
"""
|
|
138
|
-
if not instance_id or managed_branch:
|
|
139
|
-
return True
|
|
140
|
-
return instance_id in impacted_instances
|