infrahub-server 1.3.0a0__py3-none-any.whl → 1.3.0b2__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 (123) hide show
  1. infrahub/actions/tasks.py +4 -11
  2. infrahub/branch/__init__.py +0 -0
  3. infrahub/branch/tasks.py +29 -0
  4. infrahub/branch/triggers.py +22 -0
  5. infrahub/cli/db.py +2 -2
  6. infrahub/computed_attribute/gather.py +3 -1
  7. infrahub/computed_attribute/tasks.py +23 -29
  8. infrahub/core/attribute.py +3 -3
  9. infrahub/core/constants/__init__.py +10 -0
  10. infrahub/core/constants/database.py +1 -0
  11. infrahub/core/constants/infrahubkind.py +2 -0
  12. infrahub/core/convert_object_type/conversion.py +1 -1
  13. infrahub/core/diff/query/save.py +67 -40
  14. infrahub/core/diff/query/time_range_query.py +0 -1
  15. infrahub/core/graph/__init__.py +1 -1
  16. infrahub/core/migrations/graph/__init__.py +6 -0
  17. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +0 -2
  18. infrahub/core/migrations/graph/m029_duplicates_cleanup.py +662 -0
  19. infrahub/core/migrations/graph/m030_illegal_edges.py +82 -0
  20. infrahub/core/migrations/query/attribute_add.py +13 -9
  21. infrahub/core/migrations/query/attribute_rename.py +2 -4
  22. infrahub/core/migrations/query/delete_element_in_schema.py +16 -11
  23. infrahub/core/migrations/query/node_duplicate.py +16 -15
  24. infrahub/core/migrations/query/relationship_duplicate.py +16 -12
  25. infrahub/core/migrations/schema/node_attribute_remove.py +1 -2
  26. infrahub/core/migrations/schema/node_remove.py +16 -14
  27. infrahub/core/node/__init__.py +74 -14
  28. infrahub/core/node/base.py +1 -1
  29. infrahub/core/node/resource_manager/ip_address_pool.py +6 -2
  30. infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -2
  31. infrahub/core/node/resource_manager/number_pool.py +31 -5
  32. infrahub/core/node/standard.py +6 -1
  33. infrahub/core/path.py +1 -1
  34. infrahub/core/protocols.py +10 -0
  35. infrahub/core/query/node.py +1 -1
  36. infrahub/core/query/relationship.py +4 -6
  37. infrahub/core/query/standard_node.py +19 -5
  38. infrahub/core/relationship/constraints/peer_relatives.py +72 -0
  39. infrahub/core/relationship/model.py +1 -1
  40. infrahub/core/schema/attribute_parameters.py +129 -5
  41. infrahub/core/schema/attribute_schema.py +62 -14
  42. infrahub/core/schema/basenode_schema.py +2 -2
  43. infrahub/core/schema/definitions/core/__init__.py +16 -2
  44. infrahub/core/schema/definitions/core/group.py +45 -0
  45. infrahub/core/schema/definitions/core/resource_pool.py +29 -0
  46. infrahub/core/schema/definitions/internal.py +25 -4
  47. infrahub/core/schema/generated/attribute_schema.py +12 -5
  48. infrahub/core/schema/generated/relationship_schema.py +6 -1
  49. infrahub/core/schema/manager.py +7 -2
  50. infrahub/core/schema/schema_branch.py +69 -5
  51. infrahub/core/validators/__init__.py +8 -0
  52. infrahub/core/validators/attribute/choices.py +0 -1
  53. infrahub/core/validators/attribute/enum.py +0 -1
  54. infrahub/core/validators/attribute/kind.py +0 -1
  55. infrahub/core/validators/attribute/length.py +0 -1
  56. infrahub/core/validators/attribute/min_max.py +118 -0
  57. infrahub/core/validators/attribute/number_pool.py +106 -0
  58. infrahub/core/validators/attribute/optional.py +0 -2
  59. infrahub/core/validators/attribute/regex.py +0 -1
  60. infrahub/core/validators/enum.py +5 -0
  61. infrahub/core/validators/tasks.py +1 -1
  62. infrahub/database/__init__.py +16 -4
  63. infrahub/database/validation.py +100 -0
  64. infrahub/dependencies/builder/constraint/grouped/node_runner.py +2 -0
  65. infrahub/dependencies/builder/constraint/relationship_manager/peer_relatives.py +8 -0
  66. infrahub/dependencies/builder/diff/deserializer.py +1 -1
  67. infrahub/dependencies/registry.py +2 -0
  68. infrahub/events/models.py +1 -1
  69. infrahub/git/base.py +5 -3
  70. infrahub/git/integrator.py +102 -3
  71. infrahub/graphql/mutations/main.py +1 -1
  72. infrahub/graphql/mutations/resource_manager.py +54 -6
  73. infrahub/graphql/queries/resource_manager.py +7 -1
  74. infrahub/graphql/queries/task.py +10 -0
  75. infrahub/graphql/resolvers/many_relationship.py +1 -1
  76. infrahub/graphql/resolvers/resolver.py +2 -2
  77. infrahub/graphql/resolvers/single_relationship.py +1 -1
  78. infrahub/graphql/types/task_log.py +3 -2
  79. infrahub/menu/menu.py +8 -7
  80. infrahub/message_bus/operations/refresh/registry.py +3 -3
  81. infrahub/patch/queries/delete_duplicated_edges.py +40 -29
  82. infrahub/pools/number.py +5 -3
  83. infrahub/pools/registration.py +22 -0
  84. infrahub/pools/tasks.py +56 -0
  85. infrahub/schema/__init__.py +0 -0
  86. infrahub/schema/tasks.py +27 -0
  87. infrahub/schema/triggers.py +23 -0
  88. infrahub/task_manager/task.py +44 -4
  89. infrahub/trigger/catalogue.py +4 -0
  90. infrahub/trigger/models.py +5 -4
  91. infrahub/trigger/setup.py +26 -2
  92. infrahub/trigger/tasks.py +1 -1
  93. infrahub/types.py +6 -0
  94. infrahub/webhook/tasks.py +6 -9
  95. infrahub/workflows/catalogue.py +27 -1
  96. infrahub_sdk/client.py +43 -10
  97. infrahub_sdk/node/__init__.py +39 -0
  98. infrahub_sdk/node/attribute.py +122 -0
  99. infrahub_sdk/node/constants.py +21 -0
  100. infrahub_sdk/{node.py → node/node.py} +50 -749
  101. infrahub_sdk/node/parsers.py +15 -0
  102. infrahub_sdk/node/property.py +24 -0
  103. infrahub_sdk/node/related_node.py +266 -0
  104. infrahub_sdk/node/relationship.py +302 -0
  105. infrahub_sdk/protocols.py +112 -0
  106. infrahub_sdk/protocols_base.py +34 -2
  107. infrahub_sdk/query_groups.py +13 -2
  108. infrahub_sdk/schema/main.py +1 -0
  109. infrahub_sdk/schema/repository.py +16 -0
  110. infrahub_sdk/spec/object.py +1 -1
  111. infrahub_sdk/store.py +1 -1
  112. infrahub_sdk/testing/schemas/car_person.py +1 -0
  113. {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/METADATA +3 -3
  114. {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/RECORD +122 -100
  115. {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/WHEEL +1 -1
  116. infrahub_testcontainers/container.py +239 -64
  117. infrahub_testcontainers/docker-compose-cluster.test.yml +321 -0
  118. infrahub_testcontainers/docker-compose.test.yml +1 -0
  119. infrahub_testcontainers/helpers.py +15 -1
  120. infrahub_testcontainers/plugin.py +9 -0
  121. infrahub/patch/queries/consolidate_duplicated_nodes.py +0 -106
  122. {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/LICENSE.txt +0 -0
  123. {infrahub_server-1.3.0a0.dist-info → infrahub_server-1.3.0b2.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,122 @@
1
+ from __future__ import annotations
2
+
3
+ import ipaddress
4
+ from typing import TYPE_CHECKING, Any, Callable, get_args
5
+
6
+ from ..protocols_base import CoreNodeBase
7
+ from ..uuidt import UUIDT
8
+ from .constants import IP_TYPES, PROPERTIES_FLAG, PROPERTIES_OBJECT, SAFE_VALUE
9
+ from .property import NodeProperty
10
+
11
+ if TYPE_CHECKING:
12
+ from ..schema import AttributeSchemaAPI
13
+
14
+
15
+ class Attribute:
16
+ """Represents an attribute of a Node, including its schema, value, and properties."""
17
+
18
+ def __init__(self, name: str, schema: AttributeSchemaAPI, data: Any | dict):
19
+ """
20
+ Args:
21
+ name (str): The name of the attribute.
22
+ schema (AttributeSchema): The schema defining the attribute.
23
+ data (Union[Any, dict]): The data for the attribute, either in raw form or as a dictionary.
24
+ """
25
+ self.name = name
26
+ self._schema = schema
27
+
28
+ if not isinstance(data, dict) or "value" not in data.keys():
29
+ data = {"value": data}
30
+
31
+ self._properties_flag = PROPERTIES_FLAG
32
+ self._properties_object = PROPERTIES_OBJECT
33
+ self._properties = self._properties_flag + self._properties_object
34
+
35
+ self._read_only = ["updated_at", "is_inherited"]
36
+
37
+ self.id: str | None = data.get("id", None)
38
+
39
+ self._value: Any | None = data.get("value", None)
40
+ self.value_has_been_mutated = False
41
+ self.is_default: bool | None = data.get("is_default", None)
42
+ self.is_from_profile: bool | None = data.get("is_from_profile", None)
43
+
44
+ if self._value:
45
+ value_mapper: dict[str, Callable] = {
46
+ "IPHost": ipaddress.ip_interface,
47
+ "IPNetwork": ipaddress.ip_network,
48
+ }
49
+ mapper = value_mapper.get(schema.kind, lambda value: value)
50
+ self._value = mapper(data.get("value"))
51
+
52
+ self.is_inherited: bool | None = data.get("is_inherited", None)
53
+ self.updated_at: str | None = data.get("updated_at", None)
54
+
55
+ self.is_visible: bool | None = data.get("is_visible", None)
56
+ self.is_protected: bool | None = data.get("is_protected", None)
57
+
58
+ self.source: NodeProperty | None = None
59
+ self.owner: NodeProperty | None = None
60
+
61
+ for prop_name in self._properties_object:
62
+ if data.get(prop_name):
63
+ setattr(self, prop_name, NodeProperty(data=data.get(prop_name))) # type: ignore[arg-type]
64
+
65
+ @property
66
+ def value(self) -> Any:
67
+ return self._value
68
+
69
+ @value.setter
70
+ def value(self, value: Any) -> None:
71
+ self._value = value
72
+ self.value_has_been_mutated = True
73
+
74
+ def _generate_input_data(self) -> dict | None:
75
+ data: dict[str, Any] = {}
76
+ variables: dict[str, Any] = {}
77
+
78
+ if self.value is None:
79
+ return data
80
+
81
+ if isinstance(self.value, str):
82
+ if SAFE_VALUE.match(self.value):
83
+ data["value"] = self.value
84
+ else:
85
+ var_name = f"value_{UUIDT.new().hex}"
86
+ variables[var_name] = self.value
87
+ data["value"] = f"${var_name}"
88
+ elif isinstance(self.value, get_args(IP_TYPES)):
89
+ data["value"] = self.value.with_prefixlen
90
+ elif isinstance(self.value, CoreNodeBase) and self.value.is_resource_pool():
91
+ data["from_pool"] = {"id": self.value.id}
92
+ else:
93
+ data["value"] = self.value
94
+
95
+ for prop_name in self._properties_flag:
96
+ if getattr(self, prop_name) is not None:
97
+ data[prop_name] = getattr(self, prop_name)
98
+
99
+ for prop_name in self._properties_object:
100
+ if getattr(self, prop_name) is not None:
101
+ data[prop_name] = getattr(self, prop_name)._generate_input_data()
102
+
103
+ return {"data": data, "variables": variables}
104
+
105
+ def _generate_query_data(self, property: bool = False) -> dict | None:
106
+ data: dict[str, Any] = {"value": None}
107
+
108
+ if property:
109
+ data.update({"is_default": None, "is_from_profile": None})
110
+
111
+ for prop_name in self._properties_flag:
112
+ data[prop_name] = None
113
+ for prop_name in self._properties_object:
114
+ data[prop_name] = {"id": None, "display_label": None, "__typename": None}
115
+
116
+ return data
117
+
118
+ def _generate_mutation_query(self) -> dict[str, Any]:
119
+ if isinstance(self.value, CoreNodeBase) and self.value.is_resource_pool():
120
+ # If it points to a pool, ask for the value of the pool allocated resource
121
+ return {self.name: {"value": None}}
122
+ return {}
@@ -0,0 +1,21 @@
1
+ import ipaddress
2
+ import re
3
+ from typing import Union
4
+
5
+ PROPERTIES_FLAG = ["is_visible", "is_protected"]
6
+ PROPERTIES_OBJECT = ["source", "owner"]
7
+ SAFE_VALUE = re.compile(r"(^[\. /:a-zA-Z0-9_-]+$)|(^$)")
8
+
9
+ IP_TYPES = Union[ipaddress.IPv4Interface, ipaddress.IPv6Interface, ipaddress.IPv4Network, ipaddress.IPv6Network]
10
+
11
+ ARTIFACT_FETCH_FEATURE_NOT_SUPPORTED_MESSAGE = (
12
+ "calling artifact_fetch is only supported for nodes that are Artifact Definition target"
13
+ )
14
+ ARTIFACT_GENERATE_FEATURE_NOT_SUPPORTED_MESSAGE = (
15
+ "calling artifact_generate is only supported for nodes that are Artifact Definition targets"
16
+ )
17
+ ARTIFACT_DEFINITION_GENERATE_FEATURE_NOT_SUPPORTED_MESSAGE = (
18
+ "calling generate is only supported for CoreArtifactDefinition nodes"
19
+ )
20
+
21
+ HFID_STR_SEPARATOR = "__"