infrahub-server 1.4.10__py3-none-any.whl → 1.5.0b0__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 (103) hide show
  1. infrahub/actions/tasks.py +200 -16
  2. infrahub/api/artifact.py +3 -0
  3. infrahub/api/query.py +2 -0
  4. infrahub/api/schema.py +3 -0
  5. infrahub/auth.py +5 -5
  6. infrahub/cli/db.py +2 -2
  7. infrahub/config.py +7 -2
  8. infrahub/core/attribute.py +22 -19
  9. infrahub/core/branch/models.py +2 -2
  10. infrahub/core/branch/needs_rebase_status.py +11 -0
  11. infrahub/core/branch/tasks.py +2 -2
  12. infrahub/core/constants/__init__.py +1 -0
  13. infrahub/core/convert_object_type/object_conversion.py +201 -0
  14. infrahub/core/convert_object_type/repository_conversion.py +89 -0
  15. infrahub/core/convert_object_type/schema_mapping.py +27 -3
  16. infrahub/core/diff/query/artifact.py +1 -1
  17. infrahub/core/graph/__init__.py +1 -1
  18. infrahub/core/initialization.py +2 -2
  19. infrahub/core/manager.py +3 -81
  20. infrahub/core/migrations/graph/__init__.py +2 -0
  21. infrahub/core/migrations/graph/m040_profile_attrs_in_db.py +166 -0
  22. infrahub/core/node/__init__.py +23 -2
  23. infrahub/core/node/create.py +67 -35
  24. infrahub/core/node/lock_utils.py +98 -0
  25. infrahub/core/property.py +11 -0
  26. infrahub/core/protocols.py +1 -0
  27. infrahub/core/query/attribute.py +27 -15
  28. infrahub/core/query/node.py +47 -184
  29. infrahub/core/query/relationship.py +43 -26
  30. infrahub/core/query/subquery.py +0 -8
  31. infrahub/core/relationship/model.py +59 -19
  32. infrahub/core/schema/attribute_schema.py +0 -2
  33. infrahub/core/schema/definitions/core/repository.py +7 -0
  34. infrahub/core/schema/relationship_schema.py +0 -1
  35. infrahub/core/schema/schema_branch.py +3 -2
  36. infrahub/generators/models.py +31 -12
  37. infrahub/generators/tasks.py +3 -1
  38. infrahub/git/base.py +38 -1
  39. infrahub/graphql/api/dependencies.py +2 -4
  40. infrahub/graphql/api/endpoints.py +2 -2
  41. infrahub/graphql/app.py +2 -4
  42. infrahub/graphql/initialization.py +2 -3
  43. infrahub/graphql/manager.py +212 -137
  44. infrahub/graphql/middleware.py +12 -0
  45. infrahub/graphql/mutations/branch.py +11 -0
  46. infrahub/graphql/mutations/computed_attribute.py +110 -3
  47. infrahub/graphql/mutations/convert_object_type.py +34 -13
  48. infrahub/graphql/mutations/ipam.py +21 -8
  49. infrahub/graphql/mutations/main.py +37 -153
  50. infrahub/graphql/mutations/profile.py +195 -0
  51. infrahub/graphql/mutations/proposed_change.py +2 -1
  52. infrahub/graphql/mutations/repository.py +22 -83
  53. infrahub/graphql/mutations/webhook.py +1 -1
  54. infrahub/graphql/registry.py +173 -0
  55. infrahub/graphql/schema.py +4 -1
  56. infrahub/lock.py +52 -26
  57. infrahub/locks/__init__.py +0 -0
  58. infrahub/locks/tasks.py +37 -0
  59. infrahub/patch/plan_writer.py +2 -2
  60. infrahub/profiles/__init__.py +0 -0
  61. infrahub/profiles/node_applier.py +101 -0
  62. infrahub/profiles/queries/__init__.py +0 -0
  63. infrahub/profiles/queries/get_profile_data.py +99 -0
  64. infrahub/profiles/tasks.py +63 -0
  65. infrahub/repositories/__init__.py +0 -0
  66. infrahub/repositories/create_repository.py +113 -0
  67. infrahub/tasks/registry.py +6 -4
  68. infrahub/webhook/models.py +1 -1
  69. infrahub/workflows/catalogue.py +38 -3
  70. infrahub/workflows/models.py +17 -2
  71. infrahub_sdk/branch.py +5 -8
  72. infrahub_sdk/client.py +364 -84
  73. infrahub_sdk/convert_object_type.py +61 -0
  74. infrahub_sdk/ctl/check.py +2 -3
  75. infrahub_sdk/ctl/cli_commands.py +16 -12
  76. infrahub_sdk/ctl/config.py +8 -2
  77. infrahub_sdk/ctl/generator.py +2 -3
  78. infrahub_sdk/ctl/repository.py +39 -1
  79. infrahub_sdk/ctl/schema.py +12 -1
  80. infrahub_sdk/ctl/utils.py +4 -0
  81. infrahub_sdk/ctl/validate.py +5 -3
  82. infrahub_sdk/diff.py +4 -5
  83. infrahub_sdk/exceptions.py +2 -0
  84. infrahub_sdk/graphql.py +7 -2
  85. infrahub_sdk/node/attribute.py +2 -0
  86. infrahub_sdk/node/node.py +28 -20
  87. infrahub_sdk/playback.py +1 -2
  88. infrahub_sdk/protocols.py +40 -6
  89. infrahub_sdk/pytest_plugin/plugin.py +7 -4
  90. infrahub_sdk/pytest_plugin/utils.py +40 -0
  91. infrahub_sdk/repository.py +1 -2
  92. infrahub_sdk/schema/main.py +1 -0
  93. infrahub_sdk/spec/object.py +43 -4
  94. infrahub_sdk/spec/range_expansion.py +118 -0
  95. infrahub_sdk/timestamp.py +18 -6
  96. {infrahub_server-1.4.10.dist-info → infrahub_server-1.5.0b0.dist-info}/METADATA +6 -9
  97. {infrahub_server-1.4.10.dist-info → infrahub_server-1.5.0b0.dist-info}/RECORD +102 -84
  98. infrahub_testcontainers/models.py +2 -2
  99. infrahub_testcontainers/performance_test.py +4 -4
  100. infrahub/core/convert_object_type/conversion.py +0 -134
  101. {infrahub_server-1.4.10.dist-info → infrahub_server-1.5.0b0.dist-info}/LICENSE.txt +0 -0
  102. {infrahub_server-1.4.10.dist-info → infrahub_server-1.5.0b0.dist-info}/WHEEL +0 -0
  103. {infrahub_server-1.4.10.dist-info → infrahub_server-1.5.0b0.dist-info}/entry_points.txt +0 -0
@@ -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(
@@ -531,6 +534,35 @@ VALIDATE_SCHEMA_NUMBER_POOLS = WorkflowDefinition(
531
534
  )
532
535
 
533
536
 
537
+ PROFILE_REFRESH_MULTIPLE = WorkflowDefinition(
538
+ name="objects-profiles-refresh-multiple",
539
+ type=WorkflowType.CORE,
540
+ module="infrahub.profiles.tasks",
541
+ function="objects_profiles_refresh_multiple",
542
+ tags=[WorkflowTag.DATABASE_CHANGE],
543
+ )
544
+
545
+
546
+ PROFILE_REFRESH = WorkflowDefinition(
547
+ name="object-profiles-refresh",
548
+ type=WorkflowType.CORE,
549
+ module="infrahub.profiles.tasks",
550
+ function="object_profiles_refresh",
551
+ tags=[WorkflowTag.DATABASE_CHANGE],
552
+ )
553
+
554
+
555
+ CLEAN_UP_DEADLOCKS = WorkflowDefinition(
556
+ name="clean-up-deadlocks",
557
+ type=WorkflowType.INTERNAL,
558
+ cron="* * * * *",
559
+ module="infrahub.locks.tasks",
560
+ function="clean_up_deadlocks",
561
+ concurrency_limit=1,
562
+ concurrency_limit_strategy=ConcurrencyLimitStrategy.CANCEL_NEW,
563
+ )
564
+
565
+
534
566
  WORKER_POOLS = [INFRAHUB_WORKER_POOL]
535
567
 
536
568
  WORKFLOWS = [
@@ -547,6 +579,7 @@ WORKFLOWS = [
547
579
  BRANCH_MERGE_POST_PROCESS,
548
580
  BRANCH_REBASE,
549
581
  BRANCH_VALIDATE,
582
+ CLEAN_UP_DEADLOCKS,
550
583
  COMPUTED_ATTRIBUTE_JINJA2_UPDATE_VALUE,
551
584
  COMPUTED_ATTRIBUTE_PROCESS_JINJA2,
552
585
  COMPUTED_ATTRIBUTE_PROCESS_TRANSFORM,
@@ -572,6 +605,8 @@ WORKFLOWS = [
572
605
  GIT_REPOSITORY_USER_CHECK_RUN,
573
606
  GRAPHQL_QUERY_GROUP_UPDATE,
574
607
  IPAM_RECONCILIATION,
608
+ PROFILE_REFRESH,
609
+ PROFILE_REFRESH_MULTIPLE,
575
610
  PROPOSED_CHANGE_MERGE,
576
611
  QUERY_COMPUTED_ATTRIBUTE_TRANSFORM_TARGETS,
577
612
  REMOVE_ADD_NODE_FROM_GROUP,
@@ -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:
infrahub_sdk/branch.py CHANGED
@@ -188,9 +188,7 @@ class InfrahubBranchManager(InfraHubBranchManagerBase):
188
188
  query = Query(name="GetAllBranch", query=QUERY_ALL_BRANCHES_DATA)
189
189
  data = await self.client.execute_graphql(query=query.render(), tracker="query-branch-all")
190
190
 
191
- branches = {branch["name"]: BranchData(**branch) for branch in data["Branch"]}
192
-
193
- return branches
191
+ return {branch["name"]: BranchData(**branch) for branch in data["Branch"]}
194
192
 
195
193
  async def get(self, branch_name: str) -> BranchData:
196
194
  query = Query(name="GetBranch", query=QUERY_ONE_BRANCH_DATA, variables={"branch_name": str})
@@ -230,9 +228,7 @@ class InfrahubBranchManagerSync(InfraHubBranchManagerBase):
230
228
  query = Query(name="GetAllBranch", query=QUERY_ALL_BRANCHES_DATA)
231
229
  data = self.client.execute_graphql(query=query.render(), tracker="query-branch-all")
232
230
 
233
- branches = {branch["name"]: BranchData(**branch) for branch in data["Branch"]}
234
-
235
- return branches
231
+ return {branch["name"]: BranchData(**branch) for branch in data["Branch"]}
236
232
 
237
233
  def get(self, branch_name: str) -> BranchData:
238
234
  query = Query(name="GetBranch", query=QUERY_ONE_BRANCH_DATA, variables={"branch_name": str})
@@ -292,13 +288,14 @@ class InfrahubBranchManagerSync(InfraHubBranchManagerBase):
292
288
  },
293
289
  }
294
290
 
295
- query = Mutation(mutation="BranchCreate", input_data=input_data, query=MUTATION_QUERY_DATA)
291
+ mutation_query = MUTATION_QUERY_TASK if background_execution else MUTATION_QUERY_DATA
292
+ query = Mutation(mutation="BranchCreate", input_data=input_data, query=mutation_query)
296
293
  response = self.client.execute_graphql(query=query.render(), tracker="mutation-branch-create")
297
294
 
298
295
  # Make sure server version is recent enough to support background execution, as previously
299
296
  # using background_execution=True had no effect.
300
297
  if background_execution and "task" in response["BranchCreate"]:
301
- return BranchData(**response["BranchCreate"]["task"]["id"])
298
+ return response["BranchCreate"]["task"]["id"]
302
299
  return BranchData(**response["BranchCreate"]["object"])
303
300
 
304
301
  def delete(self, branch_name: str) -> bool: