infrahub-server 1.6.3__py3-none-any.whl → 1.7.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 (161) hide show
  1. infrahub/actions/tasks.py +4 -2
  2. infrahub/api/schema.py +3 -1
  3. infrahub/artifacts/tasks.py +1 -0
  4. infrahub/auth.py +2 -2
  5. infrahub/cli/db.py +6 -6
  6. infrahub/computed_attribute/gather.py +3 -4
  7. infrahub/computed_attribute/tasks.py +23 -6
  8. infrahub/config.py +8 -0
  9. infrahub/constants/enums.py +12 -0
  10. infrahub/core/account.py +5 -8
  11. infrahub/core/attribute.py +106 -108
  12. infrahub/core/branch/models.py +44 -71
  13. infrahub/core/branch/tasks.py +5 -3
  14. infrahub/core/changelog/diff.py +1 -20
  15. infrahub/core/changelog/models.py +0 -7
  16. infrahub/core/constants/__init__.py +17 -0
  17. infrahub/core/constants/database.py +0 -1
  18. infrahub/core/constants/schema.py +0 -1
  19. infrahub/core/convert_object_type/repository_conversion.py +3 -4
  20. infrahub/core/diff/data_check_synchronizer.py +3 -2
  21. infrahub/core/diff/enricher/cardinality_one.py +1 -1
  22. infrahub/core/diff/merger/merger.py +27 -1
  23. infrahub/core/diff/merger/serializer.py +3 -10
  24. infrahub/core/diff/model/diff.py +1 -1
  25. infrahub/core/diff/query/merge.py +376 -135
  26. infrahub/core/graph/__init__.py +1 -1
  27. infrahub/core/graph/constraints.py +2 -2
  28. infrahub/core/graph/schema.py +2 -12
  29. infrahub/core/manager.py +132 -126
  30. infrahub/core/metadata/__init__.py +0 -0
  31. infrahub/core/metadata/interface.py +37 -0
  32. infrahub/core/metadata/model.py +31 -0
  33. infrahub/core/metadata/query/__init__.py +0 -0
  34. infrahub/core/metadata/query/node_metadata.py +301 -0
  35. infrahub/core/migrations/graph/__init__.py +4 -0
  36. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +3 -8
  37. infrahub/core/migrations/graph/m017_add_core_profile.py +5 -2
  38. infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -1
  39. infrahub/core/migrations/graph/m019_restore_rels_to_time.py +0 -10
  40. infrahub/core/migrations/graph/m020_duplicate_edges.py +0 -8
  41. infrahub/core/migrations/graph/m025_uniqueness_nulls.py +2 -1
  42. infrahub/core/migrations/graph/m026_0000_prefix_fix.py +2 -1
  43. infrahub/core/migrations/graph/m029_duplicates_cleanup.py +0 -1
  44. infrahub/core/migrations/graph/m031_check_number_attributes.py +2 -2
  45. infrahub/core/migrations/graph/m038_redo_0000_prefix_fix.py +2 -1
  46. infrahub/core/migrations/graph/m049_remove_is_visible_relationship.py +38 -0
  47. infrahub/core/migrations/graph/m050_backfill_vertex_metadata.py +168 -0
  48. infrahub/core/migrations/query/attribute_add.py +17 -6
  49. infrahub/core/migrations/query/attribute_remove.py +19 -5
  50. infrahub/core/migrations/query/attribute_rename.py +21 -5
  51. infrahub/core/migrations/query/node_duplicate.py +19 -4
  52. infrahub/core/migrations/schema/attribute_kind_update.py +25 -7
  53. infrahub/core/migrations/schema/attribute_supports_profile.py +3 -1
  54. infrahub/core/migrations/schema/models.py +3 -0
  55. infrahub/core/migrations/schema/node_attribute_add.py +4 -1
  56. infrahub/core/migrations/schema/node_remove.py +24 -2
  57. infrahub/core/migrations/schema/tasks.py +4 -1
  58. infrahub/core/migrations/shared.py +13 -6
  59. infrahub/core/models.py +6 -6
  60. infrahub/core/node/__init__.py +156 -57
  61. infrahub/core/node/create.py +7 -3
  62. infrahub/core/node/standard.py +100 -14
  63. infrahub/core/property.py +0 -1
  64. infrahub/core/protocols_base.py +6 -2
  65. infrahub/core/query/__init__.py +6 -7
  66. infrahub/core/query/attribute.py +161 -46
  67. infrahub/core/query/branch.py +57 -69
  68. infrahub/core/query/diff.py +4 -4
  69. infrahub/core/query/node.py +618 -180
  70. infrahub/core/query/relationship.py +449 -300
  71. infrahub/core/query/standard_node.py +25 -5
  72. infrahub/core/query/utils.py +2 -4
  73. infrahub/core/relationship/constraints/profiles_removal.py +168 -0
  74. infrahub/core/relationship/model.py +293 -139
  75. infrahub/core/schema/attribute_parameters.py +1 -28
  76. infrahub/core/schema/attribute_schema.py +17 -11
  77. infrahub/core/schema/manager.py +63 -43
  78. infrahub/core/schema/relationship_schema.py +6 -2
  79. infrahub/core/schema/schema_branch.py +48 -76
  80. infrahub/core/task/task.py +4 -2
  81. infrahub/core/utils.py +0 -22
  82. infrahub/core/validators/attribute/kind.py +2 -5
  83. infrahub/core/validators/determiner.py +3 -3
  84. infrahub/database/__init__.py +3 -3
  85. infrahub/dependencies/builder/constraint/grouped/node_runner.py +2 -0
  86. infrahub/dependencies/builder/constraint/relationship_manager/profiles_removal.py +8 -0
  87. infrahub/dependencies/registry.py +2 -0
  88. infrahub/display_labels/tasks.py +12 -3
  89. infrahub/git/integrator.py +18 -18
  90. infrahub/git/tasks.py +1 -1
  91. infrahub/graphql/app.py +2 -2
  92. infrahub/graphql/constants.py +3 -0
  93. infrahub/graphql/context.py +1 -1
  94. infrahub/graphql/initialization.py +11 -0
  95. infrahub/graphql/loaders/account.py +134 -0
  96. infrahub/graphql/loaders/node.py +5 -12
  97. infrahub/graphql/loaders/peers.py +5 -7
  98. infrahub/graphql/manager.py +158 -18
  99. infrahub/graphql/metadata.py +91 -0
  100. infrahub/graphql/models.py +33 -3
  101. infrahub/graphql/mutations/account.py +5 -5
  102. infrahub/graphql/mutations/attribute.py +0 -2
  103. infrahub/graphql/mutations/branch.py +9 -5
  104. infrahub/graphql/mutations/computed_attribute.py +1 -1
  105. infrahub/graphql/mutations/display_label.py +1 -1
  106. infrahub/graphql/mutations/hfid.py +1 -1
  107. infrahub/graphql/mutations/ipam.py +4 -6
  108. infrahub/graphql/mutations/main.py +9 -4
  109. infrahub/graphql/mutations/profile.py +16 -22
  110. infrahub/graphql/mutations/proposed_change.py +4 -4
  111. infrahub/graphql/mutations/relationship.py +40 -10
  112. infrahub/graphql/mutations/repository.py +14 -12
  113. infrahub/graphql/mutations/schema.py +2 -2
  114. infrahub/graphql/queries/branch.py +62 -6
  115. infrahub/graphql/queries/diff/tree.py +5 -5
  116. infrahub/graphql/resolvers/account_metadata.py +84 -0
  117. infrahub/graphql/resolvers/ipam.py +6 -8
  118. infrahub/graphql/resolvers/many_relationship.py +77 -35
  119. infrahub/graphql/resolvers/resolver.py +16 -12
  120. infrahub/graphql/resolvers/single_relationship.py +87 -23
  121. infrahub/graphql/subscription/graphql_query.py +2 -0
  122. infrahub/graphql/types/__init__.py +0 -1
  123. infrahub/graphql/types/attribute.py +10 -5
  124. infrahub/graphql/types/branch.py +40 -53
  125. infrahub/graphql/types/enums.py +3 -0
  126. infrahub/graphql/types/metadata.py +28 -0
  127. infrahub/graphql/types/node.py +22 -2
  128. infrahub/graphql/types/relationship.py +10 -2
  129. infrahub/graphql/types/standard_node.py +4 -3
  130. infrahub/hfid/tasks.py +12 -3
  131. infrahub/profiles/gather.py +56 -0
  132. infrahub/profiles/mandatory_fields_checker.py +116 -0
  133. infrahub/profiles/models.py +66 -0
  134. infrahub/profiles/node_applier.py +153 -12
  135. infrahub/profiles/queries/get_profile_data.py +143 -31
  136. infrahub/profiles/tasks.py +79 -27
  137. infrahub/profiles/triggers.py +22 -0
  138. infrahub/proposed_change/tasks.py +4 -1
  139. infrahub/tasks/artifact.py +1 -0
  140. infrahub/transformations/tasks.py +2 -2
  141. infrahub/trigger/catalogue.py +2 -0
  142. infrahub/trigger/models.py +1 -0
  143. infrahub/trigger/setup.py +3 -3
  144. infrahub/trigger/tasks.py +3 -0
  145. infrahub/validators/tasks.py +1 -0
  146. infrahub/webhook/models.py +1 -1
  147. infrahub/webhook/tasks.py +1 -1
  148. infrahub/workers/dependencies.py +9 -3
  149. infrahub/workers/infrahub_async.py +13 -4
  150. infrahub/workflows/catalogue.py +19 -0
  151. infrahub_sdk/node/constants.py +1 -0
  152. infrahub_sdk/node/related_node.py +13 -4
  153. infrahub_sdk/node/relationship.py +8 -0
  154. {infrahub_server-1.6.3.dist-info → infrahub_server-1.7.0b0.dist-info}/METADATA +17 -16
  155. {infrahub_server-1.6.3.dist-info → infrahub_server-1.7.0b0.dist-info}/RECORD +161 -143
  156. infrahub_testcontainers/container.py +3 -3
  157. infrahub_testcontainers/docker-compose-cluster.test.yml +7 -7
  158. infrahub_testcontainers/docker-compose.test.yml +13 -5
  159. {infrahub_server-1.6.3.dist-info → infrahub_server-1.7.0b0.dist-info}/WHEEL +0 -0
  160. {infrahub_server-1.6.3.dist-info → infrahub_server-1.7.0b0.dist-info}/entry_points.txt +0 -0
  161. {infrahub_server-1.6.3.dist-info → infrahub_server-1.7.0b0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING, Any
4
4
 
5
- from infrahub import config
6
5
  from infrahub.core.branch.enums import BranchStatus
7
6
  from infrahub.core.constants import GLOBAL_BRANCH_NAME
8
7
  from infrahub.core.query import Query, QueryType
@@ -70,89 +69,78 @@ CALL (vertex_id) {
70
69
  self.add_to_query(query)
71
70
 
72
71
 
73
- class GetAllBranchInternalRelationshipQuery(Query):
74
- name: str = "get_internal_relationship"
72
+ class RebaseBranchQuery(Query):
73
+ """Rebase a branch onto the default branch by updating edge timestamps
75
74
 
76
- type: QueryType = QueryType.READ
77
- insert_return: bool = False
78
-
79
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
80
- query = """
81
- MATCH p = ()-[r]-()
82
- WHERE r.branch = $branch_name
83
- RETURN DISTINCT r
84
- """
85
- self.add_to_query(query=query)
86
- self.params["branch_name"] = self.branch.name
87
- self.return_labels = ["r"]
88
-
89
-
90
- class RebaseBranchUpdateRelationshipQuery(Query):
91
- name: str = "rebase_branch_update"
75
+ For every edge on this branch
76
+ if it has a from time before $at and no to time, update it to $at
77
+ if it has a to time before $at, delete the edge
78
+ if it has a to time after $at, update the from time to $at
79
+ Then delete any orphaned vertices
80
+ """
92
81
 
82
+ name: str = "rebase_branch"
93
83
  type: QueryType = QueryType.WRITE
94
-
95
- def __init__(self, ids: list[str], **kwargs: Any) -> None:
96
- self.ids = ids
97
- super().__init__(**kwargs)
84
+ insert_return: bool = False
85
+ raise_error_if_empty: bool = False
98
86
 
99
87
  async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
100
- query = """
101
- MATCH ()-[r]->()
102
- WHERE %(id_func)s(r) IN $ids
103
- SET r.from = $at
104
- SET r.conflict = NULL
105
- """ % {
106
- "id_func": db.get_id_function_name(),
107
- }
108
-
109
- self.add_to_query(query=query)
110
-
88
+ self.params["branch_name"] = self.branch.name
111
89
  self.params["at"] = self.at.to_string()
112
- self.params["ids"] = [db.to_database_id(id) for id in self.ids]
113
- self.return_labels = [f"{db.get_id_function_name()}(r)"]
114
-
115
-
116
- class RebaseBranchDeleteRelationshipQuery(Query):
117
- name: str = "rebase_branch_delete"
118
90
 
119
- type: QueryType = QueryType.WRITE
120
- insert_return: bool = False
121
-
122
- def __init__(self, ids: list[str], **kwargs: Any) -> None:
123
- self.ids = ids
124
- super().__init__(**kwargs)
91
+ query = """
92
+ // --------------
93
+ // Get all edges on this branch with their source and destination vertices
94
+ // --------------
95
+ MATCH (s)-[r]-(d)
96
+ WHERE r.branch = $branch_name
97
+ WITH DISTINCT r, s, d
98
+ WITH r, s, d,
99
+ CASE
100
+ // No `to` and `from` <= at: update
101
+ WHEN r.to IS NULL AND r.from <= $at THEN TRUE
102
+ // Has `to` and `to` < at: delete
103
+ WHEN r.to IS NOT NULL AND r.to < $at THEN FALSE
104
+ // Has `to` and `to` >= at: update
105
+ ELSE TRUE
106
+ END AS do_update
125
107
 
126
- async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
127
- if config.SETTINGS.database.db_type == config.DatabaseType.MEMGRAPH:
128
- query = """
129
- MATCH p = (s)-[r]-(d)
130
- WHERE %(id_func)s(r) IN $ids
131
- DELETE r
132
- """
133
- else:
134
- query = """
135
- MATCH p = (s)-[r]-(d)
136
- WHERE %(id_func)s(r) IN $ids
137
- DELETE r
138
- WITH *
139
- UNWIND nodes(p) AS n
140
- MATCH (n)
141
- WHERE NOT exists((n)--())
142
- DELETE n
143
- """
144
- query %= {
145
- "id_func": db.get_id_function_name(),
146
- }
108
+ // --------------
109
+ // Process updates: set from = at for relationships we're keeping
110
+ // --------------
111
+ CALL (r, do_update) {
112
+ WITH r, do_update
113
+ WHERE do_update = TRUE
114
+ SET r.from = $at
115
+ }
147
116
 
117
+ // --------------
118
+ // Delete the edges
119
+ // --------------
120
+ WITH r, s, d, do_update
121
+ WHERE do_update = FALSE
122
+ CALL (r, s, d) {
123
+ DELETE r
124
+ }
125
+ // --------------
126
+ // Clean up any orpahned nodes edges
127
+ // --------------
128
+ WITH DISTINCT s, d
129
+ UNWIND [s, d] AS n
130
+ WITH DISTINCT n
131
+ CALL (n) {
132
+ MATCH (n)
133
+ WHERE NOT exists((n)--())
134
+ DELETE n
135
+ }
136
+ """
148
137
  self.add_to_query(query=query)
149
138
 
150
- self.params["ids"] = [db.to_database_id(id) for id in self.ids]
151
-
152
139
 
153
140
  class BranchNodeGetListQuery(StandardNodeGetListQuery):
154
141
  def __init__(self, exclude_global: bool = False, **kwargs: Any) -> None:
155
142
  self.raw_filter = f"n.status <> '{BranchStatus.DELETING.value}'"
143
+
156
144
  if exclude_global:
157
145
  self.raw_filter += f" AND n.name <> '{GLOBAL_BRANCH_NAME}'"
158
146
 
@@ -77,7 +77,7 @@ class DiffCountChanges(Query):
77
77
  AND diff_rel.branch in $branch_names
78
78
  AND (
79
79
  (diff_rel.from >= $from_time AND diff_rel.from < $to_time)
80
- OR (diff_rel.to >= $to_time AND diff_rel.to < $to_time)
80
+ OR (diff_rel.to >= $from_time AND diff_rel.to < $to_time)
81
81
  )
82
82
  AND (p.branch_support = "aware" OR q.branch_support = "aware")
83
83
  WITH diff_rel.branch AS branch_name, count(*) AS num_changes
@@ -335,7 +335,7 @@ CALL (p, q, diff_rel, row_from_time) {
335
335
  AND type(r_node) IN ["HAS_ATTRIBUTE", "IS_RELATED"]
336
336
  AND any(l in labels(node) WHERE l in ["Attribute", "Relationship"])
337
337
  AND node.branch_support IN [$branch_aware, $branch_agnostic]
338
- AND type(r_prop) IN ["IS_VISIBLE", "IS_PROTECTED", "HAS_SOURCE", "HAS_OWNER", "HAS_VALUE", "IS_RELATED"]
338
+ AND type(r_prop) IN ["IS_PROTECTED", "HAS_SOURCE", "HAS_OWNER", "HAS_VALUE", "IS_RELATED"]
339
339
  AND any(l in labels(prop) WHERE l in ["Boolean", "Node", "AttributeValue"])
340
340
  AND (top_diff_rel.to IS NULL OR top_diff_rel.to >= r_node.from)
341
341
  AND (r_node.to IS NULL OR r_node.to >= r_prop.from)
@@ -532,7 +532,7 @@ CALL (root, r_root, p, diff_rel, q) {
532
532
  )
533
533
  WHERE %(id_func)s(mid_r_root) = %(id_func)s(r_root)
534
534
  AND %(id_func)s(mid_diff_rel) = %(id_func)s(diff_rel)
535
- AND type(r_prop) IN ["IS_VISIBLE", "IS_PROTECTED", "HAS_SOURCE", "HAS_OWNER", "HAS_VALUE", "IS_RELATED"]
535
+ AND type(r_prop) IN ["IS_PROTECTED", "HAS_SOURCE", "HAS_OWNER", "HAS_VALUE", "IS_RELATED"]
536
536
  AND any(l in labels(prop) WHERE l in ["Boolean", "Node", "AttributeValue"])
537
537
  AND r_prop.from < $to_time AND r_prop.branch = mid_diff_rel.branch
538
538
  AND (mid_diff_rel.to IS NULL OR mid_diff_rel.to >= r_prop.from)
@@ -609,7 +609,7 @@ class DiffPropertyPathsQuery(DiffCalculationQuery):
609
609
  MATCH diff_rel_path = (root:Root)<-[r_root:IS_PART_OF]-(n:Node)-[r_node]-(p)-[diff_rel {branch: $branch_name}]->(q)
610
610
  WHERE p.branch_support = $branch_aware
611
611
  AND any(l in labels(p) WHERE l in ["Attribute", "Relationship"])
612
- AND type(diff_rel) IN ["IS_VISIBLE", "IS_PROTECTED", "HAS_SOURCE", "HAS_OWNER", "HAS_VALUE"]
612
+ AND type(diff_rel) IN ["IS_PROTECTED", "HAS_SOURCE", "HAS_OWNER", "HAS_VALUE"]
613
613
  AND any(l in labels(q) WHERE l in ["Boolean", "Node", "AttributeValue"])
614
614
  AND type(r_node) IN ["HAS_ATTRIBUTE", "IS_RELATED"]
615
615
  // node ID and field name filtering first pass