infrahub-server 1.5.0b1__py3-none-any.whl → 1.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. infrahub/api/dependencies.py +4 -13
  2. infrahub/api/internal.py +2 -0
  3. infrahub/api/oauth2.py +13 -19
  4. infrahub/api/oidc.py +15 -21
  5. infrahub/api/schema.py +24 -3
  6. infrahub/api/transformation.py +22 -20
  7. infrahub/artifacts/models.py +2 -1
  8. infrahub/auth.py +137 -3
  9. infrahub/cli/__init__.py +2 -0
  10. infrahub/cli/db.py +158 -155
  11. infrahub/cli/dev.py +118 -0
  12. infrahub/cli/tasks.py +46 -0
  13. infrahub/cli/upgrade.py +56 -9
  14. infrahub/computed_attribute/tasks.py +20 -8
  15. infrahub/core/attribute.py +10 -2
  16. infrahub/core/branch/enums.py +1 -1
  17. infrahub/core/branch/models.py +7 -3
  18. infrahub/core/branch/tasks.py +68 -7
  19. infrahub/core/constants/__init__.py +3 -0
  20. infrahub/core/diff/calculator.py +2 -2
  21. infrahub/core/diff/query/artifact.py +1 -0
  22. infrahub/core/diff/query/delete_query.py +9 -5
  23. infrahub/core/diff/query/field_summary.py +1 -0
  24. infrahub/core/diff/query/merge.py +39 -23
  25. infrahub/core/graph/__init__.py +1 -1
  26. infrahub/core/initialization.py +5 -2
  27. infrahub/core/migrations/__init__.py +3 -0
  28. infrahub/core/migrations/exceptions.py +4 -0
  29. infrahub/core/migrations/graph/__init__.py +12 -13
  30. infrahub/core/migrations/graph/load_schema_branch.py +21 -0
  31. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +1 -1
  32. infrahub/core/migrations/graph/m037_index_attr_vals.py +11 -30
  33. infrahub/core/migrations/graph/m039_ipam_reconcile.py +9 -7
  34. infrahub/core/migrations/graph/m040_duplicated_attributes.py +81 -0
  35. infrahub/core/migrations/graph/m041_deleted_dup_edges.py +149 -0
  36. infrahub/core/migrations/graph/m042_profile_attrs_in_db.py +147 -0
  37. infrahub/core/migrations/graph/m043_create_hfid_display_label_in_db.py +164 -0
  38. infrahub/core/migrations/graph/m044_backfill_hfid_display_label_in_db.py +864 -0
  39. infrahub/core/migrations/query/__init__.py +7 -8
  40. infrahub/core/migrations/query/attribute_add.py +8 -6
  41. infrahub/core/migrations/query/attribute_remove.py +134 -0
  42. infrahub/core/migrations/runner.py +54 -0
  43. infrahub/core/migrations/schema/attribute_kind_update.py +9 -3
  44. infrahub/core/migrations/schema/attribute_supports_profile.py +90 -0
  45. infrahub/core/migrations/schema/node_attribute_add.py +30 -2
  46. infrahub/core/migrations/schema/node_attribute_remove.py +13 -109
  47. infrahub/core/migrations/schema/node_kind_update.py +2 -1
  48. infrahub/core/migrations/schema/node_remove.py +2 -1
  49. infrahub/core/migrations/schema/placeholder_dummy.py +3 -2
  50. infrahub/core/migrations/shared.py +62 -14
  51. infrahub/core/models.py +2 -2
  52. infrahub/core/node/__init__.py +42 -12
  53. infrahub/core/node/create.py +46 -63
  54. infrahub/core/node/lock_utils.py +70 -44
  55. infrahub/core/node/resource_manager/ip_address_pool.py +2 -1
  56. infrahub/core/node/resource_manager/ip_prefix_pool.py +2 -1
  57. infrahub/core/node/resource_manager/number_pool.py +2 -1
  58. infrahub/core/query/attribute.py +55 -0
  59. infrahub/core/query/diff.py +61 -16
  60. infrahub/core/query/ipam.py +16 -4
  61. infrahub/core/query/node.py +51 -43
  62. infrahub/core/query/relationship.py +1 -0
  63. infrahub/core/relationship/model.py +10 -5
  64. infrahub/core/schema/__init__.py +56 -0
  65. infrahub/core/schema/attribute_schema.py +4 -0
  66. infrahub/core/schema/definitions/core/check.py +1 -1
  67. infrahub/core/schema/definitions/core/transform.py +1 -1
  68. infrahub/core/schema/definitions/internal.py +2 -2
  69. infrahub/core/schema/generated/attribute_schema.py +2 -2
  70. infrahub/core/schema/manager.py +22 -1
  71. infrahub/core/schema/schema_branch.py +180 -22
  72. infrahub/core/schema/schema_branch_display.py +12 -0
  73. infrahub/core/schema/schema_branch_hfid.py +6 -0
  74. infrahub/core/validators/uniqueness/checker.py +2 -1
  75. infrahub/database/__init__.py +0 -13
  76. infrahub/database/graph.py +21 -0
  77. infrahub/display_labels/tasks.py +13 -7
  78. infrahub/events/branch_action.py +27 -1
  79. infrahub/generators/tasks.py +3 -7
  80. infrahub/git/base.py +4 -1
  81. infrahub/git/integrator.py +1 -1
  82. infrahub/git/models.py +2 -1
  83. infrahub/git/repository.py +22 -5
  84. infrahub/git/tasks.py +66 -10
  85. infrahub/git/utils.py +123 -1
  86. infrahub/graphql/analyzer.py +9 -0
  87. infrahub/graphql/api/endpoints.py +14 -4
  88. infrahub/graphql/manager.py +4 -9
  89. infrahub/graphql/mutations/branch.py +5 -0
  90. infrahub/graphql/mutations/convert_object_type.py +11 -1
  91. infrahub/graphql/mutations/display_label.py +17 -10
  92. infrahub/graphql/mutations/hfid.py +17 -10
  93. infrahub/graphql/mutations/ipam.py +54 -35
  94. infrahub/graphql/mutations/main.py +27 -28
  95. infrahub/graphql/mutations/proposed_change.py +6 -0
  96. infrahub/graphql/schema_sort.py +170 -0
  97. infrahub/graphql/types/branch.py +4 -1
  98. infrahub/graphql/types/enums.py +3 -0
  99. infrahub/hfid/tasks.py +13 -7
  100. infrahub/lock.py +52 -12
  101. infrahub/message_bus/types.py +3 -1
  102. infrahub/permissions/constants.py +2 -0
  103. infrahub/profiles/queries/get_profile_data.py +4 -5
  104. infrahub/proposed_change/tasks.py +66 -23
  105. infrahub/server.py +6 -2
  106. infrahub/services/__init__.py +2 -2
  107. infrahub/services/adapters/http/__init__.py +5 -0
  108. infrahub/services/adapters/workflow/worker.py +14 -3
  109. infrahub/task_manager/event.py +5 -0
  110. infrahub/task_manager/models.py +7 -0
  111. infrahub/task_manager/task.py +73 -0
  112. infrahub/trigger/setup.py +13 -4
  113. infrahub/trigger/tasks.py +3 -0
  114. infrahub/workers/dependencies.py +10 -1
  115. infrahub/workers/infrahub_async.py +10 -2
  116. infrahub/workflows/catalogue.py +8 -0
  117. infrahub/workflows/initialization.py +5 -0
  118. infrahub/workflows/utils.py +2 -1
  119. infrahub_sdk/analyzer.py +1 -1
  120. infrahub_sdk/batch.py +2 -2
  121. infrahub_sdk/branch.py +14 -2
  122. infrahub_sdk/checks.py +1 -1
  123. infrahub_sdk/client.py +15 -14
  124. infrahub_sdk/config.py +29 -2
  125. infrahub_sdk/ctl/branch.py +3 -0
  126. infrahub_sdk/ctl/cli_commands.py +2 -0
  127. infrahub_sdk/ctl/exceptions.py +1 -1
  128. infrahub_sdk/ctl/schema.py +22 -7
  129. infrahub_sdk/ctl/task.py +110 -0
  130. infrahub_sdk/exceptions.py +18 -18
  131. infrahub_sdk/graphql/query.py +2 -2
  132. infrahub_sdk/node/attribute.py +1 -1
  133. infrahub_sdk/node/property.py +1 -1
  134. infrahub_sdk/node/related_node.py +3 -3
  135. infrahub_sdk/node/relationship.py +4 -6
  136. infrahub_sdk/object_store.py +2 -2
  137. infrahub_sdk/operation.py +1 -1
  138. infrahub_sdk/protocols_generator/generator.py +1 -1
  139. infrahub_sdk/pytest_plugin/exceptions.py +9 -9
  140. infrahub_sdk/pytest_plugin/items/base.py +1 -1
  141. infrahub_sdk/pytest_plugin/items/check.py +1 -1
  142. infrahub_sdk/pytest_plugin/items/python_transform.py +1 -1
  143. infrahub_sdk/repository.py +1 -1
  144. infrahub_sdk/schema/__init__.py +33 -5
  145. infrahub_sdk/spec/models.py +7 -0
  146. infrahub_sdk/spec/object.py +41 -102
  147. infrahub_sdk/spec/processors/__init__.py +0 -0
  148. infrahub_sdk/spec/processors/data_processor.py +10 -0
  149. infrahub_sdk/spec/processors/factory.py +34 -0
  150. infrahub_sdk/spec/processors/range_expand_processor.py +56 -0
  151. infrahub_sdk/task/exceptions.py +4 -4
  152. infrahub_sdk/task/manager.py +2 -2
  153. infrahub_sdk/task/models.py +6 -4
  154. infrahub_sdk/timestamp.py +1 -1
  155. infrahub_sdk/transfer/exporter/json.py +1 -1
  156. infrahub_sdk/transfer/importer/json.py +1 -1
  157. infrahub_sdk/transforms.py +1 -1
  158. {infrahub_server-1.5.0b1.dist-info → infrahub_server-1.5.1.dist-info}/METADATA +4 -2
  159. {infrahub_server-1.5.0b1.dist-info → infrahub_server-1.5.1.dist-info}/RECORD +168 -152
  160. infrahub_testcontainers/container.py +144 -6
  161. infrahub_testcontainers/docker-compose-cluster.test.yml +5 -0
  162. infrahub_testcontainers/docker-compose.test.yml +5 -0
  163. infrahub_testcontainers/helpers.py +19 -4
  164. infrahub_testcontainers/models.py +8 -6
  165. infrahub_testcontainers/performance_test.py +6 -4
  166. infrahub/core/migrations/graph/m040_profile_attrs_in_db.py +0 -166
  167. infrahub/core/migrations/graph/m041_create_hfid_display_label_in_db.py +0 -97
  168. infrahub/core/migrations/graph/m042_backfill_hfid_display_label_in_db.py +0 -86
  169. {infrahub_server-1.5.0b1.dist-info → infrahub_server-1.5.1.dist-info}/LICENSE.txt +0 -0
  170. {infrahub_server-1.5.0b1.dist-info → infrahub_server-1.5.1.dist-info}/WHEEL +0 -0
  171. {infrahub_server-1.5.0b1.dist-info → infrahub_server-1.5.1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+
3
+ import copy
4
+ import logging
5
+ import re
6
+ from typing import Any
7
+
8
+ from ...exceptions import ValidationError
9
+ from ..range_expansion import MATCH_PATTERN, range_expansion
10
+ from .data_processor import DataProcessor
11
+
12
+ log = logging.getLogger("infrahub_sdk")
13
+
14
+
15
+ class RangeExpandDataProcessor(DataProcessor):
16
+ """Process data with range expansion"""
17
+
18
+ @classmethod
19
+ async def process_data(
20
+ cls,
21
+ data: list[dict[str, Any]],
22
+ ) -> list[dict[str, Any]]:
23
+ """Expand any item in data with range pattern in any value. Supports multiple fields, requires equal expansion length."""
24
+ range_pattern = re.compile(MATCH_PATTERN)
25
+ expanded = []
26
+ for item in data:
27
+ # Find all fields to expand
28
+ expand_fields = {}
29
+ for key, value in item.items():
30
+ if isinstance(value, str) and range_pattern.search(value):
31
+ try:
32
+ expand_fields[key] = range_expansion(value)
33
+ except (ValueError, TypeError, KeyError):
34
+ # If expansion fails, treat as no expansion
35
+ log.debug(
36
+ f"Range expansion failed for value '{value}' in key '{key}'. Treating as no expansion."
37
+ )
38
+ expand_fields[key] = [value]
39
+ if not expand_fields:
40
+ expanded.append(item)
41
+ continue
42
+ # Check all expanded lists have the same length
43
+ lengths = [len(v) for v in expand_fields.values()]
44
+ if len(set(lengths)) > 1:
45
+ raise ValidationError(
46
+ identifier="range_expansion",
47
+ message=f"Range expansion mismatch: fields expanded to different lengths: {lengths}",
48
+ )
49
+ n = lengths[0]
50
+ # Zip expanded values and produce new items
51
+ for i in range(n):
52
+ new_item = copy.deepcopy(item)
53
+ for key, values in expand_fields.items():
54
+ new_item[key] = values[i]
55
+ expanded.append(new_item)
56
+ return expanded
@@ -2,24 +2,24 @@ from __future__ import annotations
2
2
 
3
3
 
4
4
  class TaskError(Exception):
5
- def __init__(self, message: str | None = None):
5
+ def __init__(self, message: str | None = None) -> None:
6
6
  self.message = message
7
7
  super().__init__(self.message)
8
8
 
9
9
 
10
10
  class TaskNotFoundError(TaskError):
11
- def __init__(self, id: str):
11
+ def __init__(self, id: str) -> None:
12
12
  self.message = f"Task with id {id} not found"
13
13
  super().__init__(self.message)
14
14
 
15
15
 
16
16
  class TooManyTasksError(TaskError):
17
- def __init__(self, expected_id: str, received_ids: list[str]):
17
+ def __init__(self, expected_id: str, received_ids: list[str]) -> None:
18
18
  self.message = f"Expected 1 task with id {expected_id}, but got {len(received_ids)}"
19
19
  super().__init__(self.message)
20
20
 
21
21
 
22
22
  class TaskNotCompletedError(TaskError):
23
- def __init__(self, id: str, message: str | None = None):
23
+ def __init__(self, id: str, message: str | None = None) -> None:
24
24
  self.message = message or f"Task with id {id} is not completed"
25
25
  super().__init__(self.message)
@@ -86,7 +86,7 @@ class InfraHubTaskManagerBase:
86
86
  class InfrahubTaskManager(InfraHubTaskManagerBase):
87
87
  client: InfrahubClient
88
88
 
89
- def __init__(self, client: InfrahubClient):
89
+ def __init__(self, client: InfrahubClient) -> None:
90
90
  self.client = client
91
91
 
92
92
  async def count(self, filters: TaskFilter | None = None) -> int:
@@ -321,7 +321,7 @@ class InfrahubTaskManager(InfraHubTaskManagerBase):
321
321
  class InfrahubTaskManagerSync(InfraHubTaskManagerBase):
322
322
  client: InfrahubClientSync
323
323
 
324
- def __init__(self, client: InfrahubClientSync):
324
+ def __init__(self, client: InfrahubClientSync) -> None:
325
325
  self.client = client
326
326
 
327
327
  def count(self, filters: TaskFilter | None = None) -> int:
@@ -49,12 +49,14 @@ class Task(BaseModel):
49
49
  related_nodes: list[TaskRelatedNode] = []
50
50
  logs: list[TaskLog] = []
51
51
 
52
- if data.get("related_nodes"):
53
- related_nodes = [TaskRelatedNode(**item) for item in data["related_nodes"]]
52
+ if "related_nodes" in data:
53
+ if data.get("related_nodes"):
54
+ related_nodes = [TaskRelatedNode(**item) for item in data["related_nodes"]]
54
55
  del data["related_nodes"]
55
56
 
56
- if data.get("logs"):
57
- logs = [TaskLog(**item["node"]) for item in data["logs"]["edges"]]
57
+ if "logs" in data:
58
+ if data.get("logs"):
59
+ logs = [TaskLog(**item["node"]) for item in data["logs"]["edges"]]
58
60
  del data["logs"]
59
61
 
60
62
  return cls(**data, related_nodes=related_nodes, logs=logs)
infrahub_sdk/timestamp.py CHANGED
@@ -29,7 +29,7 @@ REGEX_MAPPING = {
29
29
  class Timestamp:
30
30
  _obj: ZonedDateTime
31
31
 
32
- def __init__(self, value: str | ZonedDateTime | Timestamp | None = None):
32
+ def __init__(self, value: str | ZonedDateTime | Timestamp | None = None) -> None:
33
33
  if value and isinstance(value, ZonedDateTime):
34
34
  self._obj = value
35
35
  elif value and isinstance(value, self.__class__):
@@ -22,7 +22,7 @@ if TYPE_CHECKING:
22
22
 
23
23
 
24
24
  class LineDelimitedJSONExporter(ExporterInterface):
25
- def __init__(self, client: InfrahubClient, console: Console | None = None):
25
+ def __init__(self, client: InfrahubClient, console: Console | None = None) -> None:
26
26
  self.client = client
27
27
  self.console = console
28
28
 
@@ -31,7 +31,7 @@ class LineDelimitedJSONImporter(ImporterInterface):
31
31
  topological_sorter: InfrahubSchemaTopologicalSorter,
32
32
  continue_on_error: bool = False,
33
33
  console: Console | None = None,
34
- ):
34
+ ) -> None:
35
35
  self.client = client
36
36
  self.topological_sorter = topological_sorter
37
37
  self.continue_on_error = continue_on_error
@@ -27,7 +27,7 @@ class InfrahubTransform(InfrahubOperation):
27
27
  branch: str = "",
28
28
  root_directory: str = "",
29
29
  server_url: str = "",
30
- ):
30
+ ) -> None:
31
31
  super().__init__(
32
32
  client=client,
33
33
  infrahub_node=infrahub_node,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: infrahub-server
3
- Version: 1.5.0b1
3
+ Version: 1.5.1
4
4
  Summary: Infrahub is taking a new approach to Infrastructure Management by providing a new generation of datastore to organize and control all the data that defines how an infrastructure should run.
5
5
  License: Apache-2.0
6
6
  Author: OpsMill
@@ -18,11 +18,13 @@ Requires-Dist: asgi-correlation-id (==4.2.0)
18
18
  Requires-Dist: authlib (==1.6.5)
19
19
  Requires-Dist: bcrypt (>=4.1,<4.2)
20
20
  Requires-Dist: boto3 (==1.34.129)
21
+ Requires-Dist: cachetools-async (>=0.0.5,<0.0.6)
22
+ Requires-Dist: click (==8.1.7)
21
23
  Requires-Dist: copier (>=9.8.0,<10.0.0)
22
24
  Requires-Dist: dulwich (>=0.22.7,<0.23.0)
23
25
  Requires-Dist: email-validator (>=2.1,<2.2)
24
26
  Requires-Dist: fast-depends (>=2.4.12,<3.0.0)
25
- Requires-Dist: fastapi (==0.116.1)
27
+ Requires-Dist: fastapi (==0.121.1)
26
28
  Requires-Dist: fastapi-storages (>=0.3,<0.4)
27
29
  Requires-Dist: gitpython (>=3,<4)
28
30
  Requires-Dist: graphene (>=3.4,<3.5)