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.
Files changed (211) hide show
  1. infrahub/actions/constants.py +130 -0
  2. infrahub/actions/gather.py +114 -0
  3. infrahub/actions/models.py +243 -0
  4. infrahub/actions/parsers.py +104 -0
  5. infrahub/actions/schema.py +393 -0
  6. infrahub/actions/tasks.py +119 -0
  7. infrahub/actions/triggers.py +21 -0
  8. infrahub/branch/__init__.py +0 -0
  9. infrahub/branch/tasks.py +29 -0
  10. infrahub/branch/triggers.py +22 -0
  11. infrahub/cli/db.py +3 -4
  12. infrahub/computed_attribute/gather.py +3 -1
  13. infrahub/computed_attribute/tasks.py +23 -29
  14. infrahub/core/account.py +24 -47
  15. infrahub/core/attribute.py +13 -15
  16. infrahub/core/constants/__init__.py +10 -0
  17. infrahub/core/constants/database.py +1 -0
  18. infrahub/core/constants/infrahubkind.py +9 -0
  19. infrahub/core/constraint/node/runner.py +3 -1
  20. infrahub/core/convert_object_type/__init__.py +0 -0
  21. infrahub/core/convert_object_type/conversion.py +124 -0
  22. infrahub/core/convert_object_type/schema_mapping.py +56 -0
  23. infrahub/core/diff/coordinator.py +8 -1
  24. infrahub/core/diff/query/all_conflicts.py +1 -5
  25. infrahub/core/diff/query/artifact.py +10 -20
  26. infrahub/core/diff/query/delete_query.py +8 -4
  27. infrahub/core/diff/query/diff_get.py +3 -6
  28. infrahub/core/diff/query/field_specifiers.py +1 -1
  29. infrahub/core/diff/query/field_summary.py +2 -4
  30. infrahub/core/diff/query/merge.py +72 -125
  31. infrahub/core/diff/query/save.py +83 -68
  32. infrahub/core/diff/query/summary_counts_enricher.py +34 -54
  33. infrahub/core/diff/query/time_range_query.py +0 -1
  34. infrahub/core/diff/repository/repository.py +4 -0
  35. infrahub/core/graph/__init__.py +1 -1
  36. infrahub/core/manager.py +14 -11
  37. infrahub/core/migrations/graph/__init__.py +6 -0
  38. infrahub/core/migrations/graph/m003_relationship_parent_optional.py +1 -2
  39. infrahub/core/migrations/graph/m012_convert_account_generic.py +1 -1
  40. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +2 -6
  41. infrahub/core/migrations/graph/m015_diff_format_update.py +1 -2
  42. infrahub/core/migrations/graph/m016_diff_delete_bug_fix.py +1 -2
  43. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +11 -22
  44. infrahub/core/migrations/graph/m020_duplicate_edges.py +3 -6
  45. infrahub/core/migrations/graph/m021_missing_hierarchy_merge.py +1 -2
  46. infrahub/core/migrations/graph/m023_deduplicate_cardinality_one_relationships.py +2 -2
  47. infrahub/core/migrations/graph/m024_missing_hierarchy_backfill.py +1 -2
  48. infrahub/core/migrations/graph/m028_delete_diffs.py +1 -2
  49. infrahub/core/migrations/graph/m029_duplicates_cleanup.py +662 -0
  50. infrahub/core/migrations/graph/m030_illegal_edges.py +82 -0
  51. infrahub/core/migrations/query/attribute_add.py +14 -11
  52. infrahub/core/migrations/query/attribute_rename.py +6 -11
  53. infrahub/core/migrations/query/delete_element_in_schema.py +19 -17
  54. infrahub/core/migrations/query/node_duplicate.py +19 -21
  55. infrahub/core/migrations/query/relationship_duplicate.py +19 -18
  56. infrahub/core/migrations/schema/node_attribute_remove.py +4 -8
  57. infrahub/core/migrations/schema/node_remove.py +19 -20
  58. infrahub/core/models.py +29 -2
  59. infrahub/core/node/__init__.py +131 -28
  60. infrahub/core/node/base.py +1 -1
  61. infrahub/core/node/create.py +211 -0
  62. infrahub/core/node/resource_manager/number_pool.py +31 -5
  63. infrahub/core/node/standard.py +6 -1
  64. infrahub/core/path.py +15 -1
  65. infrahub/core/protocols.py +57 -0
  66. infrahub/core/protocols_base.py +3 -0
  67. infrahub/core/query/__init__.py +2 -2
  68. infrahub/core/query/delete.py +3 -3
  69. infrahub/core/query/diff.py +19 -32
  70. infrahub/core/query/ipam.py +10 -20
  71. infrahub/core/query/node.py +29 -47
  72. infrahub/core/query/relationship.py +55 -34
  73. infrahub/core/query/resource_manager.py +1 -2
  74. infrahub/core/query/standard_node.py +19 -5
  75. infrahub/core/query/subquery.py +2 -4
  76. infrahub/core/relationship/constraints/count.py +10 -9
  77. infrahub/core/relationship/constraints/interface.py +2 -1
  78. infrahub/core/relationship/constraints/peer_kind.py +2 -1
  79. infrahub/core/relationship/constraints/peer_parent.py +56 -0
  80. infrahub/core/relationship/constraints/peer_relatives.py +72 -0
  81. infrahub/core/relationship/constraints/profiles_kind.py +1 -1
  82. infrahub/core/relationship/model.py +4 -1
  83. infrahub/core/schema/__init__.py +2 -1
  84. infrahub/core/schema/attribute_parameters.py +160 -0
  85. infrahub/core/schema/attribute_schema.py +130 -7
  86. infrahub/core/schema/basenode_schema.py +27 -3
  87. infrahub/core/schema/definitions/core/__init__.py +29 -1
  88. infrahub/core/schema/definitions/core/group.py +45 -0
  89. infrahub/core/schema/definitions/core/resource_pool.py +9 -0
  90. infrahub/core/schema/definitions/internal.py +43 -5
  91. infrahub/core/schema/generated/attribute_schema.py +16 -3
  92. infrahub/core/schema/generated/relationship_schema.py +11 -1
  93. infrahub/core/schema/manager.py +7 -2
  94. infrahub/core/schema/schema_branch.py +109 -12
  95. infrahub/core/validators/__init__.py +15 -2
  96. infrahub/core/validators/attribute/choices.py +1 -3
  97. infrahub/core/validators/attribute/enum.py +1 -3
  98. infrahub/core/validators/attribute/kind.py +1 -3
  99. infrahub/core/validators/attribute/length.py +13 -7
  100. infrahub/core/validators/attribute/min_max.py +118 -0
  101. infrahub/core/validators/attribute/number_pool.py +106 -0
  102. infrahub/core/validators/attribute/optional.py +1 -4
  103. infrahub/core/validators/attribute/regex.py +5 -6
  104. infrahub/core/validators/attribute/unique.py +1 -3
  105. infrahub/core/validators/determiner.py +18 -2
  106. infrahub/core/validators/enum.py +12 -0
  107. infrahub/core/validators/node/hierarchy.py +3 -6
  108. infrahub/core/validators/query.py +1 -3
  109. infrahub/core/validators/relationship/count.py +6 -12
  110. infrahub/core/validators/relationship/optional.py +2 -4
  111. infrahub/core/validators/relationship/peer.py +177 -12
  112. infrahub/core/validators/tasks.py +1 -1
  113. infrahub/core/validators/uniqueness/query.py +5 -9
  114. infrahub/database/__init__.py +12 -4
  115. infrahub/database/validation.py +100 -0
  116. infrahub/dependencies/builder/constraint/grouped/node_runner.py +4 -0
  117. infrahub/dependencies/builder/constraint/relationship_manager/peer_parent.py +8 -0
  118. infrahub/dependencies/builder/constraint/relationship_manager/peer_relatives.py +8 -0
  119. infrahub/dependencies/builder/constraint/schema/aggregated.py +2 -0
  120. infrahub/dependencies/builder/constraint/schema/relationship_peer.py +8 -0
  121. infrahub/dependencies/builder/diff/deserializer.py +1 -1
  122. infrahub/dependencies/registry.py +4 -0
  123. infrahub/events/group_action.py +1 -0
  124. infrahub/events/models.py +1 -1
  125. infrahub/git/base.py +5 -3
  126. infrahub/git/integrator.py +96 -5
  127. infrahub/git/tasks.py +1 -0
  128. infrahub/graphql/analyzer.py +139 -18
  129. infrahub/graphql/manager.py +4 -0
  130. infrahub/graphql/mutations/action.py +164 -0
  131. infrahub/graphql/mutations/convert_object_type.py +71 -0
  132. infrahub/graphql/mutations/main.py +25 -176
  133. infrahub/graphql/mutations/proposed_change.py +20 -17
  134. infrahub/graphql/mutations/relationship.py +32 -0
  135. infrahub/graphql/mutations/resource_manager.py +63 -7
  136. infrahub/graphql/queries/convert_object_type_mapping.py +34 -0
  137. infrahub/graphql/queries/resource_manager.py +7 -1
  138. infrahub/graphql/resolvers/many_relationship.py +1 -1
  139. infrahub/graphql/resolvers/resolver.py +2 -2
  140. infrahub/graphql/resolvers/single_relationship.py +1 -1
  141. infrahub/graphql/schema.py +6 -0
  142. infrahub/menu/menu.py +34 -2
  143. infrahub/message_bus/messages/__init__.py +0 -10
  144. infrahub/message_bus/operations/__init__.py +0 -8
  145. infrahub/message_bus/operations/refresh/registry.py +4 -7
  146. infrahub/patch/queries/delete_duplicated_edges.py +45 -39
  147. infrahub/pools/models.py +14 -0
  148. infrahub/pools/number.py +5 -3
  149. infrahub/pools/registration.py +22 -0
  150. infrahub/pools/tasks.py +126 -0
  151. infrahub/prefect_server/models.py +1 -19
  152. infrahub/proposed_change/models.py +68 -3
  153. infrahub/proposed_change/tasks.py +911 -34
  154. infrahub/schema/__init__.py +0 -0
  155. infrahub/schema/tasks.py +27 -0
  156. infrahub/schema/triggers.py +23 -0
  157. infrahub/task_manager/models.py +10 -6
  158. infrahub/trigger/catalogue.py +6 -0
  159. infrahub/trigger/models.py +23 -6
  160. infrahub/trigger/setup.py +26 -2
  161. infrahub/trigger/tasks.py +4 -2
  162. infrahub/types.py +6 -0
  163. infrahub/webhook/tasks.py +6 -9
  164. infrahub/workflows/catalogue.py +103 -1
  165. infrahub_sdk/client.py +43 -10
  166. infrahub_sdk/ctl/generator.py +4 -4
  167. infrahub_sdk/ctl/repository.py +1 -1
  168. infrahub_sdk/node/__init__.py +39 -0
  169. infrahub_sdk/node/attribute.py +122 -0
  170. infrahub_sdk/node/constants.py +21 -0
  171. infrahub_sdk/{node.py → node/node.py} +158 -803
  172. infrahub_sdk/node/parsers.py +15 -0
  173. infrahub_sdk/node/property.py +24 -0
  174. infrahub_sdk/node/related_node.py +266 -0
  175. infrahub_sdk/node/relationship.py +302 -0
  176. infrahub_sdk/protocols.py +112 -0
  177. infrahub_sdk/protocols_base.py +34 -2
  178. infrahub_sdk/pytest_plugin/items/python_transform.py +2 -1
  179. infrahub_sdk/query_groups.py +17 -5
  180. infrahub_sdk/schema/main.py +1 -0
  181. infrahub_sdk/schema/repository.py +16 -0
  182. infrahub_sdk/spec/object.py +1 -1
  183. infrahub_sdk/store.py +1 -1
  184. infrahub_sdk/testing/schemas/car_person.py +1 -0
  185. infrahub_sdk/utils.py +7 -20
  186. infrahub_sdk/yaml.py +6 -5
  187. {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/METADATA +5 -5
  188. {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/RECORD +197 -168
  189. {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/WHEEL +1 -1
  190. infrahub_testcontainers/container.py +239 -65
  191. infrahub_testcontainers/docker-compose-cluster.test.yml +321 -0
  192. infrahub_testcontainers/docker-compose.test.yml +2 -1
  193. infrahub_testcontainers/helpers.py +23 -3
  194. infrahub_testcontainers/plugin.py +9 -0
  195. infrahub/message_bus/messages/check_generator_run.py +0 -26
  196. infrahub/message_bus/messages/finalize_validator_execution.py +0 -15
  197. infrahub/message_bus/messages/proposed_change/base_with_diff.py +0 -16
  198. infrahub/message_bus/messages/proposed_change/request_proposedchange_refreshartifacts.py +0 -11
  199. infrahub/message_bus/messages/request_generatordefinition_check.py +0 -20
  200. infrahub/message_bus/messages/request_proposedchange_pipeline.py +0 -23
  201. infrahub/message_bus/operations/check/__init__.py +0 -3
  202. infrahub/message_bus/operations/check/generator.py +0 -156
  203. infrahub/message_bus/operations/finalize/__init__.py +0 -3
  204. infrahub/message_bus/operations/finalize/validator.py +0 -133
  205. infrahub/message_bus/operations/requests/__init__.py +0 -9
  206. infrahub/message_bus/operations/requests/generator_definition.py +0 -140
  207. infrahub/message_bus/operations/requests/proposed_change.py +0 -629
  208. infrahub/patch/queries/consolidate_duplicated_nodes.py +0 -109
  209. /infrahub/{message_bus/messages/proposed_change → actions}/__init__.py +0 -0
  210. {infrahub_server-1.2.11.dist-info → infrahub_server-1.3.0.dist-info}/LICENSE.txt +0 -0
  211. {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,3 +0,0 @@
1
- from . import validator
2
-
3
- __all__ = ["validator"]
@@ -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,9 +0,0 @@
1
- from . import (
2
- generator_definition,
3
- proposed_change,
4
- )
5
-
6
- __all__ = [
7
- "generator_definition",
8
- "proposed_change",
9
- ]
@@ -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