infrahub-server 1.4.12__py3-none-any.whl → 1.5.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 (234) hide show
  1. infrahub/actions/tasks.py +208 -16
  2. infrahub/api/artifact.py +3 -0
  3. infrahub/api/diff/diff.py +1 -1
  4. infrahub/api/internal.py +2 -0
  5. infrahub/api/query.py +2 -0
  6. infrahub/api/schema.py +27 -3
  7. infrahub/auth.py +5 -5
  8. infrahub/cli/__init__.py +2 -0
  9. infrahub/cli/db.py +160 -157
  10. infrahub/cli/dev.py +118 -0
  11. infrahub/cli/tasks.py +46 -0
  12. infrahub/cli/upgrade.py +56 -9
  13. infrahub/computed_attribute/tasks.py +19 -7
  14. infrahub/config.py +7 -2
  15. infrahub/core/attribute.py +35 -24
  16. infrahub/core/branch/enums.py +1 -1
  17. infrahub/core/branch/models.py +9 -5
  18. infrahub/core/branch/needs_rebase_status.py +11 -0
  19. infrahub/core/branch/tasks.py +72 -10
  20. infrahub/core/changelog/models.py +2 -10
  21. infrahub/core/constants/__init__.py +4 -0
  22. infrahub/core/constants/infrahubkind.py +1 -0
  23. infrahub/core/convert_object_type/object_conversion.py +201 -0
  24. infrahub/core/convert_object_type/repository_conversion.py +89 -0
  25. infrahub/core/convert_object_type/schema_mapping.py +27 -3
  26. infrahub/core/diff/calculator.py +2 -2
  27. infrahub/core/diff/model/path.py +4 -0
  28. infrahub/core/diff/payload_builder.py +1 -1
  29. infrahub/core/diff/query/artifact.py +1 -0
  30. infrahub/core/diff/query/delete_query.py +9 -5
  31. infrahub/core/diff/query/field_summary.py +1 -0
  32. infrahub/core/diff/query/merge.py +39 -23
  33. infrahub/core/graph/__init__.py +1 -1
  34. infrahub/core/initialization.py +7 -4
  35. infrahub/core/manager.py +3 -81
  36. infrahub/core/migrations/__init__.py +3 -0
  37. infrahub/core/migrations/exceptions.py +4 -0
  38. infrahub/core/migrations/graph/__init__.py +13 -10
  39. infrahub/core/migrations/graph/load_schema_branch.py +21 -0
  40. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +1 -1
  41. infrahub/core/migrations/graph/m037_index_attr_vals.py +11 -30
  42. infrahub/core/migrations/graph/m039_ipam_reconcile.py +9 -7
  43. infrahub/core/migrations/graph/m041_deleted_dup_edges.py +149 -0
  44. infrahub/core/migrations/graph/m042_profile_attrs_in_db.py +147 -0
  45. infrahub/core/migrations/graph/m043_create_hfid_display_label_in_db.py +164 -0
  46. infrahub/core/migrations/graph/m044_backfill_hfid_display_label_in_db.py +864 -0
  47. infrahub/core/migrations/query/__init__.py +7 -8
  48. infrahub/core/migrations/query/attribute_add.py +8 -6
  49. infrahub/core/migrations/query/attribute_remove.py +134 -0
  50. infrahub/core/migrations/runner.py +54 -0
  51. infrahub/core/migrations/schema/attribute_kind_update.py +9 -3
  52. infrahub/core/migrations/schema/attribute_supports_profile.py +90 -0
  53. infrahub/core/migrations/schema/node_attribute_add.py +26 -5
  54. infrahub/core/migrations/schema/node_attribute_remove.py +13 -109
  55. infrahub/core/migrations/schema/node_kind_update.py +2 -1
  56. infrahub/core/migrations/schema/node_remove.py +2 -1
  57. infrahub/core/migrations/schema/placeholder_dummy.py +3 -2
  58. infrahub/core/migrations/shared.py +66 -19
  59. infrahub/core/models.py +2 -2
  60. infrahub/core/node/__init__.py +207 -54
  61. infrahub/core/node/create.py +53 -49
  62. infrahub/core/node/lock_utils.py +124 -0
  63. infrahub/core/node/node_property_attribute.py +230 -0
  64. infrahub/core/node/resource_manager/ip_address_pool.py +2 -1
  65. infrahub/core/node/resource_manager/ip_prefix_pool.py +2 -1
  66. infrahub/core/node/resource_manager/number_pool.py +2 -1
  67. infrahub/core/node/standard.py +1 -1
  68. infrahub/core/property.py +11 -0
  69. infrahub/core/protocols.py +8 -1
  70. infrahub/core/query/attribute.py +82 -15
  71. infrahub/core/query/diff.py +61 -16
  72. infrahub/core/query/ipam.py +16 -4
  73. infrahub/core/query/node.py +92 -212
  74. infrahub/core/query/relationship.py +44 -26
  75. infrahub/core/query/subquery.py +0 -8
  76. infrahub/core/relationship/model.py +69 -24
  77. infrahub/core/schema/__init__.py +56 -0
  78. infrahub/core/schema/attribute_schema.py +4 -2
  79. infrahub/core/schema/basenode_schema.py +42 -2
  80. infrahub/core/schema/definitions/core/__init__.py +2 -0
  81. infrahub/core/schema/definitions/core/check.py +1 -1
  82. infrahub/core/schema/definitions/core/generator.py +2 -0
  83. infrahub/core/schema/definitions/core/group.py +16 -2
  84. infrahub/core/schema/definitions/core/repository.py +7 -0
  85. infrahub/core/schema/definitions/core/transform.py +1 -1
  86. infrahub/core/schema/definitions/internal.py +12 -3
  87. infrahub/core/schema/generated/attribute_schema.py +2 -2
  88. infrahub/core/schema/generated/base_node_schema.py +6 -1
  89. infrahub/core/schema/manager.py +3 -0
  90. infrahub/core/schema/node_schema.py +1 -0
  91. infrahub/core/schema/relationship_schema.py +0 -1
  92. infrahub/core/schema/schema_branch.py +295 -10
  93. infrahub/core/schema/schema_branch_display.py +135 -0
  94. infrahub/core/schema/schema_branch_hfid.py +120 -0
  95. infrahub/core/validators/aggregated_checker.py +1 -1
  96. infrahub/database/graph.py +21 -0
  97. infrahub/display_labels/__init__.py +0 -0
  98. infrahub/display_labels/gather.py +48 -0
  99. infrahub/display_labels/models.py +240 -0
  100. infrahub/display_labels/tasks.py +192 -0
  101. infrahub/display_labels/triggers.py +22 -0
  102. infrahub/events/branch_action.py +27 -1
  103. infrahub/events/group_action.py +1 -1
  104. infrahub/events/node_action.py +1 -1
  105. infrahub/generators/constants.py +7 -0
  106. infrahub/generators/models.py +38 -12
  107. infrahub/generators/tasks.py +34 -16
  108. infrahub/git/base.py +42 -2
  109. infrahub/git/integrator.py +22 -14
  110. infrahub/git/tasks.py +52 -2
  111. infrahub/graphql/analyzer.py +9 -0
  112. infrahub/graphql/api/dependencies.py +2 -4
  113. infrahub/graphql/api/endpoints.py +16 -6
  114. infrahub/graphql/app.py +2 -4
  115. infrahub/graphql/initialization.py +2 -3
  116. infrahub/graphql/manager.py +213 -137
  117. infrahub/graphql/middleware.py +12 -0
  118. infrahub/graphql/mutations/branch.py +16 -0
  119. infrahub/graphql/mutations/computed_attribute.py +110 -3
  120. infrahub/graphql/mutations/convert_object_type.py +44 -13
  121. infrahub/graphql/mutations/display_label.py +118 -0
  122. infrahub/graphql/mutations/generator.py +25 -7
  123. infrahub/graphql/mutations/hfid.py +125 -0
  124. infrahub/graphql/mutations/ipam.py +73 -41
  125. infrahub/graphql/mutations/main.py +61 -178
  126. infrahub/graphql/mutations/profile.py +195 -0
  127. infrahub/graphql/mutations/proposed_change.py +8 -1
  128. infrahub/graphql/mutations/relationship.py +2 -2
  129. infrahub/graphql/mutations/repository.py +22 -83
  130. infrahub/graphql/mutations/resource_manager.py +2 -2
  131. infrahub/graphql/mutations/webhook.py +1 -1
  132. infrahub/graphql/queries/resource_manager.py +1 -1
  133. infrahub/graphql/registry.py +173 -0
  134. infrahub/graphql/resolvers/resolver.py +2 -0
  135. infrahub/graphql/schema.py +8 -1
  136. infrahub/graphql/schema_sort.py +170 -0
  137. infrahub/graphql/types/branch.py +4 -1
  138. infrahub/graphql/types/enums.py +3 -0
  139. infrahub/groups/tasks.py +1 -1
  140. infrahub/hfid/__init__.py +0 -0
  141. infrahub/hfid/gather.py +48 -0
  142. infrahub/hfid/models.py +240 -0
  143. infrahub/hfid/tasks.py +191 -0
  144. infrahub/hfid/triggers.py +22 -0
  145. infrahub/lock.py +119 -42
  146. infrahub/locks/__init__.py +0 -0
  147. infrahub/locks/tasks.py +37 -0
  148. infrahub/message_bus/types.py +1 -0
  149. infrahub/patch/plan_writer.py +2 -2
  150. infrahub/permissions/constants.py +2 -0
  151. infrahub/profiles/__init__.py +0 -0
  152. infrahub/profiles/node_applier.py +101 -0
  153. infrahub/profiles/queries/__init__.py +0 -0
  154. infrahub/profiles/queries/get_profile_data.py +98 -0
  155. infrahub/profiles/tasks.py +63 -0
  156. infrahub/proposed_change/tasks.py +67 -14
  157. infrahub/repositories/__init__.py +0 -0
  158. infrahub/repositories/create_repository.py +113 -0
  159. infrahub/server.py +9 -1
  160. infrahub/services/__init__.py +8 -5
  161. infrahub/services/adapters/http/__init__.py +5 -0
  162. infrahub/services/adapters/workflow/worker.py +14 -3
  163. infrahub/task_manager/event.py +5 -0
  164. infrahub/task_manager/models.py +7 -0
  165. infrahub/task_manager/task.py +73 -0
  166. infrahub/tasks/registry.py +6 -4
  167. infrahub/trigger/catalogue.py +4 -0
  168. infrahub/trigger/models.py +2 -0
  169. infrahub/trigger/setup.py +13 -4
  170. infrahub/trigger/tasks.py +6 -0
  171. infrahub/webhook/models.py +1 -1
  172. infrahub/workers/dependencies.py +3 -1
  173. infrahub/workers/infrahub_async.py +10 -2
  174. infrahub/workflows/catalogue.py +118 -3
  175. infrahub/workflows/initialization.py +21 -0
  176. infrahub/workflows/models.py +17 -2
  177. infrahub/workflows/utils.py +2 -1
  178. infrahub_sdk/branch.py +17 -8
  179. infrahub_sdk/checks.py +1 -1
  180. infrahub_sdk/client.py +376 -95
  181. infrahub_sdk/config.py +29 -2
  182. infrahub_sdk/convert_object_type.py +61 -0
  183. infrahub_sdk/ctl/branch.py +3 -0
  184. infrahub_sdk/ctl/check.py +2 -3
  185. infrahub_sdk/ctl/cli_commands.py +20 -12
  186. infrahub_sdk/ctl/config.py +8 -2
  187. infrahub_sdk/ctl/generator.py +6 -3
  188. infrahub_sdk/ctl/graphql.py +184 -0
  189. infrahub_sdk/ctl/repository.py +39 -1
  190. infrahub_sdk/ctl/schema.py +40 -10
  191. infrahub_sdk/ctl/task.py +110 -0
  192. infrahub_sdk/ctl/utils.py +4 -0
  193. infrahub_sdk/ctl/validate.py +5 -3
  194. infrahub_sdk/diff.py +4 -5
  195. infrahub_sdk/exceptions.py +2 -0
  196. infrahub_sdk/generator.py +7 -1
  197. infrahub_sdk/graphql/__init__.py +12 -0
  198. infrahub_sdk/graphql/constants.py +1 -0
  199. infrahub_sdk/graphql/plugin.py +85 -0
  200. infrahub_sdk/graphql/query.py +77 -0
  201. infrahub_sdk/{graphql.py → graphql/renderers.py} +88 -75
  202. infrahub_sdk/graphql/utils.py +40 -0
  203. infrahub_sdk/node/attribute.py +2 -0
  204. infrahub_sdk/node/node.py +28 -20
  205. infrahub_sdk/node/relationship.py +1 -3
  206. infrahub_sdk/playback.py +1 -2
  207. infrahub_sdk/protocols.py +54 -6
  208. infrahub_sdk/pytest_plugin/plugin.py +7 -4
  209. infrahub_sdk/pytest_plugin/utils.py +40 -0
  210. infrahub_sdk/repository.py +1 -2
  211. infrahub_sdk/schema/__init__.py +70 -4
  212. infrahub_sdk/schema/main.py +1 -0
  213. infrahub_sdk/schema/repository.py +8 -0
  214. infrahub_sdk/spec/models.py +7 -0
  215. infrahub_sdk/spec/object.py +54 -6
  216. infrahub_sdk/spec/processors/__init__.py +0 -0
  217. infrahub_sdk/spec/processors/data_processor.py +10 -0
  218. infrahub_sdk/spec/processors/factory.py +34 -0
  219. infrahub_sdk/spec/processors/range_expand_processor.py +56 -0
  220. infrahub_sdk/spec/range_expansion.py +118 -0
  221. infrahub_sdk/task/models.py +6 -4
  222. infrahub_sdk/timestamp.py +18 -6
  223. infrahub_sdk/transforms.py +1 -1
  224. {infrahub_server-1.4.12.dist-info → infrahub_server-1.5.0.dist-info}/METADATA +9 -10
  225. {infrahub_server-1.4.12.dist-info → infrahub_server-1.5.0.dist-info}/RECORD +233 -176
  226. infrahub_testcontainers/container.py +114 -2
  227. infrahub_testcontainers/docker-compose-cluster.test.yml +5 -0
  228. infrahub_testcontainers/docker-compose.test.yml +5 -0
  229. infrahub_testcontainers/models.py +2 -2
  230. infrahub_testcontainers/performance_test.py +4 -4
  231. infrahub/core/convert_object_type/conversion.py +0 -134
  232. {infrahub_server-1.4.12.dist-info → infrahub_server-1.5.0.dist-info}/LICENSE.txt +0 -0
  233. {infrahub_server-1.4.12.dist-info → infrahub_server-1.5.0.dist-info}/WHEEL +0 -0
  234. {infrahub_server-1.4.12.dist-info → infrahub_server-1.5.0.dist-info}/entry_points.txt +0 -0
infrahub/trigger/setup.py CHANGED
@@ -6,6 +6,7 @@ from prefect.cache_policies import NONE
6
6
  from prefect.client.orchestration import PrefectClient, get_client
7
7
  from prefect.client.schemas.filters import DeploymentFilter, DeploymentFilterName
8
8
  from prefect.events.schemas.automations import Automation
9
+ from prefect.exceptions import PrefectHTTPStatusError
9
10
 
10
11
  from infrahub import lock
11
12
  from infrahub.database import InfrahubDatabase
@@ -51,7 +52,7 @@ async def setup_triggers_specific(
51
52
  ) # type: ignore[misc]
52
53
 
53
54
 
54
- @task(name="trigger-setup", task_run_name="Setup triggers", cache_policy=NONE) # type: ignore[arg-type]
55
+ @task(name="trigger-setup", task_run_name="Setup triggers", cache_policy=NONE)
55
56
  async def setup_triggers(
56
57
  client: PrefectClient,
57
58
  triggers: list[TriggerDefinition],
@@ -83,7 +84,9 @@ async def setup_triggers(
83
84
  existing_automations: dict[str, Automation] = {}
84
85
  if trigger_type:
85
86
  existing_automations = {
86
- item.name: item for item in await client.read_automations() if item.name.startswith(trigger_type.value)
87
+ item.name: item
88
+ for item in await client.read_automations()
89
+ if item.name.startswith(f"{trigger_type.value}::")
87
90
  }
88
91
  else:
89
92
  existing_automations = {item.name: item for item in await client.read_automations()}
@@ -133,8 +136,14 @@ async def setup_triggers(
133
136
  continue
134
137
 
135
138
  report.deleted.append(existing_automation)
136
- await client.delete_automation(automation_id=existing_automation.id)
137
- log.info(f"{item_to_delete} Deleted")
139
+ try:
140
+ await client.delete_automation(automation_id=existing_automation.id)
141
+ log.info(f"{item_to_delete} Deleted")
142
+ except PrefectHTTPStatusError as exc:
143
+ if exc.response.status_code == 404:
144
+ log.info(f"{item_to_delete} was already deleted")
145
+ else:
146
+ raise
138
147
 
139
148
  if trigger_type:
140
149
  log.info(
infrahub/trigger/tasks.py CHANGED
@@ -6,6 +6,8 @@ from infrahub.computed_attribute.gather import (
6
6
  gather_trigger_computed_attribute_jinja2,
7
7
  gather_trigger_computed_attribute_python,
8
8
  )
9
+ from infrahub.display_labels.gather import gather_trigger_display_labels_jinja2
10
+ from infrahub.hfid.gather import gather_trigger_hfid
9
11
  from infrahub.trigger.catalogue import builtin_triggers
10
12
  from infrahub.webhook.gather import gather_trigger_webhook
11
13
  from infrahub.workers.dependencies import get_database
@@ -18,6 +20,8 @@ async def trigger_configure_all() -> None:
18
20
  database = await get_database()
19
21
  async with database.start_session() as db:
20
22
  webhook_trigger = await gather_trigger_webhook(db=db)
23
+ display_label_triggers = await gather_trigger_display_labels_jinja2()
24
+ human_friendly_id_triggers = await gather_trigger_hfid()
21
25
  computed_attribute_j2_triggers = await gather_trigger_computed_attribute_jinja2()
22
26
  (
23
27
  computed_attribute_python_triggers,
@@ -28,6 +32,8 @@ async def trigger_configure_all() -> None:
28
32
  computed_attribute_j2_triggers
29
33
  + computed_attribute_python_triggers
30
34
  + computed_attribute_python_query_triggers
35
+ + display_label_triggers
36
+ + human_friendly_id_triggers
31
37
  + builtin_triggers
32
38
  + webhook_trigger
33
39
  + action_rules
@@ -231,7 +231,7 @@ class TransformWebhook(Webhook):
231
231
  commit=commit,
232
232
  location=f"{self.transform_file}::{self.transform_class}",
233
233
  convert_query_response=self.convert_query_response,
234
- data={"data": data, **context.model_dump()},
234
+ data={"data": {"data": data, **context.model_dump()}},
235
235
  client=client,
236
236
  ) # type: ignore[misc]
237
237
 
@@ -35,7 +35,9 @@ def get_component_type() -> ComponentType:
35
35
 
36
36
 
37
37
  def build_client() -> InfrahubClient:
38
- client = InfrahubClient(config=Config(address=config.SETTINGS.main.internal_address, retry_on_failure=True))
38
+ client_config = Config(address=config.SETTINGS.main.internal_address, retry_on_failure=True)
39
+ client_config.set_ssl_context(context=get_http().verify_tls())
40
+ client = InfrahubClient(config=client_config)
39
41
  # Populate client schema cache using our internal schema cache
40
42
  if registry.schema:
41
43
  for branch in registry.schema.get_branches():
@@ -8,6 +8,7 @@ from infrahub_sdk import Config, InfrahubClient
8
8
  from infrahub_sdk.exceptions import Error as SdkError
9
9
  from prefect import settings as prefect_settings
10
10
  from prefect.client.schemas.objects import FlowRun
11
+ from prefect.context import AsyncClientContext
11
12
  from prefect.flow_engine import run_flow_async
12
13
  from prefect.logging.handlers import APILogHandler
13
14
  from prefect.workers.base import BaseJobConfiguration, BaseVariables, BaseWorker, BaseWorkerResult
@@ -18,6 +19,7 @@ from infrahub import config
18
19
  from infrahub.components import ComponentType
19
20
  from infrahub.core import registry
20
21
  from infrahub.core.initialization import initialization
22
+ from infrahub.database.graph import validate_graph_version
21
23
  from infrahub.dependencies.registry import build_component_registry
22
24
  from infrahub.git import initialize_repositories_directory
23
25
  from infrahub.lock import initialize_lock
@@ -27,6 +29,7 @@ from infrahub.workers.dependencies import (
27
29
  get_cache,
28
30
  get_component,
29
31
  get_database,
32
+ get_http,
30
33
  get_message_bus,
31
34
  get_workflow,
32
35
  set_component_type,
@@ -129,6 +132,9 @@ class InfrahubWorkerAsync(BaseWorker):
129
132
 
130
133
  await self.service.component.refresh_schema_hash()
131
134
 
135
+ async with self.service.database.start_session() as dbs:
136
+ await validate_graph_version(db=dbs)
137
+
132
138
  initialize_repositories_directory()
133
139
  build_component_registry()
134
140
  await self.service.scheduler.start_schedule()
@@ -138,7 +144,7 @@ class InfrahubWorkerAsync(BaseWorker):
138
144
  self,
139
145
  flow_run: FlowRun,
140
146
  configuration: BaseJobConfiguration,
141
- task_status: TaskStatus | None = None,
147
+ task_status: TaskStatus[int] | None = None,
142
148
  ) -> BaseWorkerResult:
143
149
  flow_run_logger = self.get_flow_run_logger(flow_run)
144
150
 
@@ -154,7 +160,9 @@ class InfrahubWorkerAsync(BaseWorker):
154
160
  if task_status:
155
161
  task_status.started(True)
156
162
 
157
- await run_flow_async(flow=flow_func, flow_run=flow_run, parameters=params, return_type="state")
163
+ async with AsyncClientContext(httpx_settings={"verify": get_http().verify_tls()}) as ctx:
164
+ ctx._httpx_settings = None # Hack to make all child task/flow runs use the same client
165
+ await run_flow_async(flow=flow_func, flow_run=flow_run, parameters=params, return_type="state")
158
166
 
159
167
  return InfrahubWorkerAsyncResult(status_code=0, identifier=str(flow_run.id))
160
168
 
@@ -1,6 +1,7 @@
1
1
  import random
2
2
 
3
3
  from fast_depends import Depends, inject
4
+ from prefect.client.schemas.objects import ConcurrencyLimitStrategy
4
5
 
5
6
  from .constants import WorkflowTag, WorkflowType
6
7
  from .models import WorkerPoolDefinition, WorkflowDefinition
@@ -17,14 +18,14 @@ ACTION_ADD_NODE_TO_GROUP = WorkflowDefinition(
17
18
 
18
19
  ACTION_RUN_GENERATOR = WorkflowDefinition(
19
20
  name="action-run-generator",
20
- type=WorkflowType.CORE,
21
+ type=WorkflowType.INTERNAL,
21
22
  module="infrahub.actions.tasks",
22
23
  function="run_generator",
23
24
  )
24
25
 
25
26
  ACTION_RUN_GENERATOR_GROUP_EVENT = WorkflowDefinition(
26
27
  name="action-run-generator-group-event",
27
- type=WorkflowType.CORE,
28
+ type=WorkflowType.INTERNAL,
28
29
  module="infrahub.actions.tasks",
29
30
  function="run_generator_group_event",
30
31
  )
@@ -83,7 +84,7 @@ TRIGGER_ARTIFACT_DEFINITION_GENERATE = WorkflowDefinition(
83
84
 
84
85
  TRIGGER_GENERATOR_DEFINITION_RUN = WorkflowDefinition(
85
86
  name="generator-definition-run",
86
- type=WorkflowType.CORE,
87
+ type=WorkflowType.INTERNAL,
87
88
  module="infrahub.generators.tasks",
88
89
  function="run_generator_definition",
89
90
  tags=[WorkflowTag.DATABASE_CHANGE],
@@ -179,6 +180,8 @@ GIT_REPOSITORIES_SYNC = WorkflowDefinition(
179
180
  cron="* * * * *",
180
181
  module="infrahub.git.tasks",
181
182
  function="sync_remote_repositories",
183
+ concurrency_limit=1,
184
+ concurrency_limit_strategy=ConcurrencyLimitStrategy.CANCEL_NEW,
182
185
  )
183
186
 
184
187
  GIT_REPOSITORIES_CREATE_BRANCH = WorkflowDefinition(
@@ -227,6 +230,13 @@ BRANCH_REBASE = WorkflowDefinition(
227
230
  function="rebase_branch",
228
231
  tags=[WorkflowTag.DATABASE_CHANGE],
229
232
  )
233
+ BRANCH_MIGRATE = WorkflowDefinition(
234
+ name="branch-migrate",
235
+ type=WorkflowType.CORE,
236
+ module="infrahub.core.branch.tasks",
237
+ function="migrate_branch",
238
+ tags=[WorkflowTag.DATABASE_CHANGE],
239
+ )
230
240
 
231
241
  BRANCH_CREATE = WorkflowDefinition(
232
242
  name="create-branch",
@@ -320,6 +330,62 @@ COMPUTED_ATTRIBUTE_JINJA2_UPDATE_VALUE = WorkflowDefinition(
320
330
  tags=[WorkflowTag.DATABASE_CHANGE],
321
331
  )
322
332
 
333
+ DISPLAY_LABELS_PROCESS_JINJA2 = WorkflowDefinition(
334
+ name="display-label-process-jinja2",
335
+ type=WorkflowType.CORE,
336
+ module="infrahub.display_labels.tasks",
337
+ function="process_display_label",
338
+ tags=[WorkflowTag.DATABASE_CHANGE],
339
+ )
340
+
341
+ DISPLAY_LABEL_JINJA2_UPDATE_VALUE = WorkflowDefinition(
342
+ name="display-label-jinja2-update-value",
343
+ type=WorkflowType.CORE,
344
+ module="infrahub.display_labels.tasks",
345
+ function="display_label_jinja2_update_value",
346
+ tags=[WorkflowTag.DATABASE_CHANGE],
347
+ )
348
+
349
+ HFID_PROCESS = WorkflowDefinition(
350
+ name="hfid-process",
351
+ type=WorkflowType.CORE,
352
+ module="infrahub.hfid.tasks",
353
+ function="process_hfid",
354
+ tags=[WorkflowTag.DATABASE_CHANGE],
355
+ )
356
+
357
+ HFID_SETUP = WorkflowDefinition(
358
+ name="hfid-setup",
359
+ type=WorkflowType.CORE,
360
+ module="infrahub.hfid.tasks",
361
+ function="hfid_setup",
362
+ )
363
+
364
+
365
+ HFID_UPDATE_VALUE = WorkflowDefinition(
366
+ name="hfid-update-value",
367
+ type=WorkflowType.CORE,
368
+ module="infrahub.hfid.tasks",
369
+ function="hfid_update_value",
370
+ tags=[WorkflowTag.DATABASE_CHANGE],
371
+ )
372
+
373
+ TRIGGER_UPDATE_DISPLAY_LABELS = WorkflowDefinition(
374
+ name="trigger-update-display-labels",
375
+ type=WorkflowType.CORE,
376
+ module="infrahub.display_labels.tasks",
377
+ function="trigger_update_display_labels",
378
+ tags=[WorkflowTag.DATABASE_CHANGE],
379
+ )
380
+
381
+ TRIGGER_UPDATE_HFID = WorkflowDefinition(
382
+ name="trigger-update-hfid",
383
+ type=WorkflowType.CORE,
384
+ module="infrahub.hfid.tasks",
385
+ function="trigger_update_hfid",
386
+ tags=[WorkflowTag.DATABASE_CHANGE],
387
+ )
388
+
323
389
  TRIGGER_UPDATE_JINJA_COMPUTED_ATTRIBUTES = WorkflowDefinition(
324
390
  name="trigger_update_jinja2_computed_attributes",
325
391
  type=WorkflowType.CORE,
@@ -356,6 +422,14 @@ COMPUTED_ATTRIBUTE_PROCESS_TRANSFORM = WorkflowDefinition(
356
422
  tags=[WorkflowTag.DATABASE_CHANGE],
357
423
  )
358
424
 
425
+ DISPLAY_LABELS_SETUP_JINJA2 = WorkflowDefinition(
426
+ name="display-labels-setup-jinja2",
427
+ type=WorkflowType.CORE,
428
+ module="infrahub.display_labels.tasks",
429
+ function="display_labels_setup_jinja2",
430
+ )
431
+
432
+
359
433
  QUERY_COMPUTED_ATTRIBUTE_TRANSFORM_TARGETS = WorkflowDefinition(
360
434
  name="query-computed-attribute-transform-targets",
361
435
  type=WorkflowType.CORE,
@@ -531,6 +605,35 @@ VALIDATE_SCHEMA_NUMBER_POOLS = WorkflowDefinition(
531
605
  )
532
606
 
533
607
 
608
+ PROFILE_REFRESH_MULTIPLE = WorkflowDefinition(
609
+ name="objects-profiles-refresh-multiple",
610
+ type=WorkflowType.CORE,
611
+ module="infrahub.profiles.tasks",
612
+ function="objects_profiles_refresh_multiple",
613
+ tags=[WorkflowTag.DATABASE_CHANGE],
614
+ )
615
+
616
+
617
+ PROFILE_REFRESH = WorkflowDefinition(
618
+ name="object-profiles-refresh",
619
+ type=WorkflowType.CORE,
620
+ module="infrahub.profiles.tasks",
621
+ function="object_profiles_refresh",
622
+ tags=[WorkflowTag.DATABASE_CHANGE],
623
+ )
624
+
625
+
626
+ CLEAN_UP_DEADLOCKS = WorkflowDefinition(
627
+ name="clean-up-deadlocks",
628
+ type=WorkflowType.INTERNAL,
629
+ cron="* * * * *",
630
+ module="infrahub.locks.tasks",
631
+ function="clean_up_deadlocks",
632
+ concurrency_limit=1,
633
+ concurrency_limit_strategy=ConcurrencyLimitStrategy.CANCEL_NEW,
634
+ )
635
+
636
+
534
637
  WORKER_POOLS = [INFRAHUB_WORKER_POOL]
535
638
 
536
639
  WORKFLOWS = [
@@ -545,8 +648,10 @@ WORKFLOWS = [
545
648
  BRANCH_MERGED,
546
649
  BRANCH_MERGE_MUTATION,
547
650
  BRANCH_MERGE_POST_PROCESS,
651
+ BRANCH_MIGRATE,
548
652
  BRANCH_REBASE,
549
653
  BRANCH_VALIDATE,
654
+ CLEAN_UP_DEADLOCKS,
550
655
  COMPUTED_ATTRIBUTE_JINJA2_UPDATE_VALUE,
551
656
  COMPUTED_ATTRIBUTE_PROCESS_JINJA2,
552
657
  COMPUTED_ATTRIBUTE_PROCESS_TRANSFORM,
@@ -556,6 +661,9 @@ WORKFLOWS = [
556
661
  DIFF_REFRESH,
557
662
  DIFF_REFRESH_ALL,
558
663
  DIFF_UPDATE,
664
+ DISPLAY_LABELS_PROCESS_JINJA2,
665
+ DISPLAY_LABELS_SETUP_JINJA2,
666
+ DISPLAY_LABEL_JINJA2_UPDATE_VALUE,
559
667
  GIT_REPOSITORIES_CHECK_ARTIFACT_CREATE,
560
668
  GIT_REPOSITORIES_CREATE_BRANCH,
561
669
  GIT_REPOSITORIES_DIFF_NAMES_ONLY,
@@ -571,7 +679,12 @@ WORKFLOWS = [
571
679
  GIT_REPOSITORY_USER_CHECKS_TRIGGER,
572
680
  GIT_REPOSITORY_USER_CHECK_RUN,
573
681
  GRAPHQL_QUERY_GROUP_UPDATE,
682
+ HFID_PROCESS,
683
+ HFID_SETUP,
684
+ HFID_UPDATE_VALUE,
574
685
  IPAM_RECONCILIATION,
686
+ PROFILE_REFRESH,
687
+ PROFILE_REFRESH_MULTIPLE,
575
688
  PROPOSED_CHANGE_MERGE,
576
689
  QUERY_COMPUTED_ATTRIBUTE_TRANSFORM_TARGETS,
577
690
  REMOVE_ADD_NODE_FROM_GROUP,
@@ -597,6 +710,8 @@ WORKFLOWS = [
597
710
  TRIGGER_ARTIFACT_DEFINITION_GENERATE,
598
711
  TRIGGER_CONFIGURE_ALL,
599
712
  TRIGGER_GENERATOR_DEFINITION_RUN,
713
+ TRIGGER_UPDATE_DISPLAY_LABELS,
714
+ TRIGGER_UPDATE_HFID,
600
715
  TRIGGER_UPDATE_JINJA_COMPUTED_ATTRIBUTES,
601
716
  TRIGGER_UPDATE_PYTHON_COMPUTED_ATTRIBUTES,
602
717
  VALIDATE_SCHEMA_NUMBER_POOLS,
@@ -7,6 +7,8 @@ from prefect.exceptions import ObjectAlreadyExists
7
7
  from prefect.logging import get_run_logger
8
8
 
9
9
  from infrahub import config
10
+ from infrahub.display_labels.gather import gather_trigger_display_labels_jinja2
11
+ from infrahub.hfid.gather import gather_trigger_hfid
10
12
  from infrahub.trigger.catalogue import builtin_triggers
11
13
  from infrahub.trigger.models import TriggerType
12
14
  from infrahub.trigger.setup import setup_triggers
@@ -74,3 +76,22 @@ async def setup_task_manager() -> None:
74
76
  await setup_triggers(
75
77
  client=client, triggers=builtin_triggers, trigger_type=TriggerType.BUILTIN, force_update=True
76
78
  )
79
+
80
+
81
+ @flow(name="task-manager-identifiers", flow_run_name="Setup Task Manager Display Labels and HFID")
82
+ async def setup_task_manager_identifiers() -> None:
83
+ async with get_client(sync_client=False) as client:
84
+ display_label_triggers = await gather_trigger_display_labels_jinja2()
85
+ await setup_triggers(
86
+ client=client,
87
+ triggers=display_label_triggers,
88
+ trigger_type=TriggerType.DISPLAY_LABEL_JINJA2,
89
+ force_update=True,
90
+ ) # type: ignore[misc]
91
+ hfid_triggers = await gather_trigger_hfid()
92
+ await setup_triggers(
93
+ client=client,
94
+ triggers=hfid_triggers,
95
+ trigger_type=TriggerType.HUMAN_FRIENDLY_ID,
96
+ force_update=True,
97
+ ) # type: ignore[misc]
@@ -6,7 +6,7 @@ from uuid import UUID
6
6
  from prefect import Flow
7
7
  from prefect.client.orchestration import PrefectClient
8
8
  from prefect.client.schemas.actions import DeploymentScheduleCreate
9
- from prefect.client.schemas.objects import FlowRun
9
+ from prefect.client.schemas.objects import ConcurrencyLimitStrategy, FlowRun
10
10
  from prefect.client.schemas.schedules import CronSchedule
11
11
  from pydantic import BaseModel, Field
12
12
  from typing_extensions import Self
@@ -48,6 +48,14 @@ class WorkflowDefinition(BaseModel):
48
48
  function: str
49
49
  cron: str | None = None
50
50
  tags: list[WorkflowTag] = Field(default_factory=list)
51
+ concurrency_limit: int | None = Field(
52
+ default=None,
53
+ description="The concurrency limit for the deployment.",
54
+ )
55
+ concurrency_limit_strategy: ConcurrencyLimitStrategy | None = Field(
56
+ default=None,
57
+ description="The concurrency options for the deployment.",
58
+ )
51
59
 
52
60
  @property
53
61
  def entrypoint(self) -> str:
@@ -60,7 +68,14 @@ class WorkflowDefinition(BaseModel):
60
68
  return f"{self.name}/{self.name}"
61
69
 
62
70
  def to_deployment(self) -> dict[str, Any]:
63
- payload: dict[str, Any] = {"name": self.name, "entrypoint": self.entrypoint, "tags": self.get_tags()}
71
+ payload: dict[str, Any] = {
72
+ "name": self.name,
73
+ "entrypoint": self.entrypoint,
74
+ "tags": self.get_tags(),
75
+ "concurrency_limit": self.concurrency_limit,
76
+ }
77
+ if self.concurrency_limit_strategy:
78
+ payload["concurrency_options"] = {"collision_strategy": self.concurrency_limit_strategy}
64
79
  if self.type == WorkflowType.CORE:
65
80
  payload["version"] = __version__
66
81
  if self.cron:
@@ -9,6 +9,7 @@ from prefect.runtime import flow_run
9
9
  from infrahub.core.constants import GLOBAL_BRANCH_NAME
10
10
  from infrahub.core.registry import registry
11
11
  from infrahub.tasks.registry import refresh_branches
12
+ from infrahub.workers.dependencies import get_http
12
13
 
13
14
  from .constants import TAG_NAMESPACE, WorkflowTag
14
15
 
@@ -26,7 +27,7 @@ async def add_tags(
26
27
  namespace: bool = True,
27
28
  db_change: bool = False,
28
29
  ) -> None:
29
- client = get_client(sync_client=False)
30
+ client = get_client(httpx_settings={"verify": get_http().verify_tls()}, sync_client=False)
30
31
  current_flow_run_id = flow_run.id
31
32
  current_tags: list[str] = flow_run.tags
32
33
  branch_tags = (
infrahub_sdk/branch.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import warnings
4
+ from enum import Enum
4
5
  from typing import TYPE_CHECKING, Any, Literal, overload
5
6
  from urllib.parse import urlencode
6
7
 
@@ -14,6 +15,13 @@ if TYPE_CHECKING:
14
15
  from .client import InfrahubClient, InfrahubClientSync
15
16
 
16
17
 
18
+ class BranchStatus(str, Enum):
19
+ OPEN = "OPEN"
20
+ NEED_REBASE = "NEED_REBASE"
21
+ NEED_UPGRADE_REBASE = "NEED_UPGRADE_REBASE"
22
+ DELETING = "DELETING"
23
+
24
+
17
25
  class BranchData(BaseModel):
18
26
  id: str
19
27
  name: str
@@ -21,6 +29,8 @@ class BranchData(BaseModel):
21
29
  sync_with_git: bool
22
30
  is_default: bool
23
31
  has_schema_changes: bool
32
+ graph_version: int | None = None
33
+ status: BranchStatus = BranchStatus.OPEN
24
34
  origin_branch: str | None = None
25
35
  branched_from: str
26
36
 
@@ -34,6 +44,8 @@ BRANCH_DATA = {
34
44
  "is_default": None,
35
45
  "sync_with_git": None,
36
46
  "has_schema_changes": None,
47
+ "graph_version": None,
48
+ "status": None,
37
49
  }
38
50
 
39
51
  BRANCH_DATA_FILTER = {"@filters": {"name": "$branch_name"}}
@@ -188,9 +200,7 @@ class InfrahubBranchManager(InfraHubBranchManagerBase):
188
200
  query = Query(name="GetAllBranch", query=QUERY_ALL_BRANCHES_DATA)
189
201
  data = await self.client.execute_graphql(query=query.render(), tracker="query-branch-all")
190
202
 
191
- branches = {branch["name"]: BranchData(**branch) for branch in data["Branch"]}
192
-
193
- return branches
203
+ return {branch["name"]: BranchData(**branch) for branch in data["Branch"]}
194
204
 
195
205
  async def get(self, branch_name: str) -> BranchData:
196
206
  query = Query(name="GetBranch", query=QUERY_ONE_BRANCH_DATA, variables={"branch_name": str})
@@ -230,9 +240,7 @@ class InfrahubBranchManagerSync(InfraHubBranchManagerBase):
230
240
  query = Query(name="GetAllBranch", query=QUERY_ALL_BRANCHES_DATA)
231
241
  data = self.client.execute_graphql(query=query.render(), tracker="query-branch-all")
232
242
 
233
- branches = {branch["name"]: BranchData(**branch) for branch in data["Branch"]}
234
-
235
- return branches
243
+ return {branch["name"]: BranchData(**branch) for branch in data["Branch"]}
236
244
 
237
245
  def get(self, branch_name: str) -> BranchData:
238
246
  query = Query(name="GetBranch", query=QUERY_ONE_BRANCH_DATA, variables={"branch_name": str})
@@ -292,13 +300,14 @@ class InfrahubBranchManagerSync(InfraHubBranchManagerBase):
292
300
  },
293
301
  }
294
302
 
295
- query = Mutation(mutation="BranchCreate", input_data=input_data, query=MUTATION_QUERY_DATA)
303
+ mutation_query = MUTATION_QUERY_TASK if background_execution else MUTATION_QUERY_DATA
304
+ query = Mutation(mutation="BranchCreate", input_data=input_data, query=mutation_query)
296
305
  response = self.client.execute_graphql(query=query.render(), tracker="mutation-branch-create")
297
306
 
298
307
  # Make sure server version is recent enough to support background execution, as previously
299
308
  # using background_execution=True had no effect.
300
309
  if background_execution and "task" in response["BranchCreate"]:
301
- return BranchData(**response["BranchCreate"]["task"]["id"])
310
+ return response["BranchCreate"]["task"]["id"]
302
311
  return BranchData(**response["BranchCreate"]["object"])
303
312
 
304
313
  def delete(self, branch_name: str) -> bool:
infrahub_sdk/checks.py CHANGED
@@ -33,7 +33,7 @@ class InfrahubCheckInitializer(BaseModel):
33
33
  class InfrahubCheck:
34
34
  name: str | None = None
35
35
  query: str = ""
36
- timeout: int = 10
36
+ timeout: int = 60
37
37
 
38
38
  def __init__(
39
39
  self,