infrahub-server 1.7.0b0__py3-none-any.whl → 1.7.0rc0__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 (112) hide show
  1. infrahub/api/exceptions.py +2 -2
  2. infrahub/cli/db.py +48 -22
  3. infrahub/core/account.py +12 -9
  4. infrahub/core/diff/branch_differ.py +1 -1
  5. infrahub/core/diff/conflict_transferer.py +1 -1
  6. infrahub/core/diff/data_check_synchronizer.py +1 -1
  7. infrahub/core/diff/enricher/cardinality_one.py +1 -1
  8. infrahub/core/diff/enricher/hierarchy.py +1 -1
  9. infrahub/core/diff/enricher/labels.py +1 -1
  10. infrahub/core/diff/merger/merger.py +1 -1
  11. infrahub/core/diff/repository/repository.py +3 -1
  12. infrahub/core/graph/constraints.py +1 -1
  13. infrahub/core/ipam/reconciler.py +8 -6
  14. infrahub/core/ipam/utilization.py +8 -15
  15. infrahub/core/manager.py +1 -26
  16. infrahub/core/merge.py +1 -1
  17. infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -12
  18. infrahub/core/migrations/graph/m013_convert_git_password_credential.py +4 -4
  19. infrahub/core/migrations/graph/m041_deleted_dup_edges.py +1 -1
  20. infrahub/core/migrations/graph/m049_remove_is_visible_relationship.py +16 -1
  21. infrahub/core/migrations/query/__init__.py +2 -2
  22. infrahub/core/migrations/query/schema_attribute_update.py +1 -1
  23. infrahub/core/migrations/schema/attribute_name_update.py +1 -1
  24. infrahub/core/migrations/schema/attribute_supports_profile.py +2 -2
  25. infrahub/core/migrations/schema/node_attribute_add.py +1 -1
  26. infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
  27. infrahub/core/migrations/schema/node_kind_update.py +1 -1
  28. infrahub/core/node/__init__.py +1 -1
  29. infrahub/core/node/base.py +9 -5
  30. infrahub/core/node/delete_validator.py +1 -1
  31. infrahub/core/order.py +30 -0
  32. infrahub/core/protocols.py +1 -0
  33. infrahub/core/protocols_base.py +4 -0
  34. infrahub/core/query/__init__.py +8 -5
  35. infrahub/core/query/attribute.py +3 -3
  36. infrahub/core/query/branch.py +1 -1
  37. infrahub/core/query/delete.py +1 -1
  38. infrahub/core/query/diff.py +3 -3
  39. infrahub/core/query/ipam.py +104 -43
  40. infrahub/core/query/node.py +454 -101
  41. infrahub/core/query/relationship.py +83 -26
  42. infrahub/core/query/resource_manager.py +107 -18
  43. infrahub/core/relationship/constraints/count.py +1 -1
  44. infrahub/core/relationship/constraints/peer_kind.py +1 -1
  45. infrahub/core/relationship/constraints/peer_parent.py +1 -1
  46. infrahub/core/relationship/constraints/peer_relatives.py +1 -1
  47. infrahub/core/relationship/constraints/profiles_kind.py +1 -1
  48. infrahub/core/relationship/constraints/profiles_removal.py +1 -1
  49. infrahub/core/schema/attribute_schema.py +0 -13
  50. infrahub/core/schema/basenode_schema.py +3 -0
  51. infrahub/core/schema/definitions/core/__init__.py +8 -2
  52. infrahub/core/schema/definitions/core/account.py +10 -10
  53. infrahub/core/schema/definitions/core/artifact.py +14 -8
  54. infrahub/core/schema/definitions/core/check.py +10 -4
  55. infrahub/core/schema/definitions/core/generator.py +26 -6
  56. infrahub/core/schema/definitions/core/graphql_query.py +1 -1
  57. infrahub/core/schema/definitions/core/group.py +9 -2
  58. infrahub/core/schema/definitions/core/ipam.py +80 -10
  59. infrahub/core/schema/definitions/core/menu.py +41 -7
  60. infrahub/core/schema/definitions/core/permission.py +16 -2
  61. infrahub/core/schema/definitions/core/profile.py +16 -2
  62. infrahub/core/schema/definitions/core/propose_change.py +24 -4
  63. infrahub/core/schema/definitions/core/propose_change_comment.py +23 -11
  64. infrahub/core/schema/definitions/core/propose_change_validator.py +50 -21
  65. infrahub/core/schema/definitions/core/repository.py +10 -0
  66. infrahub/core/schema/definitions/core/resource_pool.py +8 -1
  67. infrahub/core/schema/definitions/core/template.py +19 -2
  68. infrahub/core/schema/definitions/core/transform.py +11 -5
  69. infrahub/core/schema/definitions/core/webhook.py +27 -9
  70. infrahub/core/schema/schema_branch.py +68 -2
  71. infrahub/core/utils.py +3 -3
  72. infrahub/core/validators/aggregated_checker.py +1 -1
  73. infrahub/core/validators/attribute/choices.py +1 -1
  74. infrahub/core/validators/attribute/enum.py +1 -1
  75. infrahub/core/validators/attribute/kind.py +1 -1
  76. infrahub/core/validators/attribute/length.py +1 -1
  77. infrahub/core/validators/attribute/min_max.py +1 -1
  78. infrahub/core/validators/attribute/number_pool.py +1 -1
  79. infrahub/core/validators/attribute/optional.py +1 -1
  80. infrahub/core/validators/attribute/regex.py +1 -1
  81. infrahub/core/validators/node/attribute.py +1 -1
  82. infrahub/core/validators/node/relationship.py +1 -1
  83. infrahub/core/validators/relationship/peer.py +1 -1
  84. infrahub/database/__init__.py +1 -1
  85. infrahub/git/utils.py +1 -1
  86. infrahub/graphql/app.py +2 -2
  87. infrahub/graphql/field_extractor.py +1 -1
  88. infrahub/graphql/manager.py +9 -1
  89. infrahub/graphql/mutations/account.py +1 -1
  90. infrahub/graphql/order.py +14 -0
  91. infrahub/graphql/queries/diff/tree.py +5 -5
  92. infrahub/graphql/queries/resource_manager.py +25 -24
  93. infrahub/graphql/resolvers/ipam.py +3 -3
  94. infrahub/graphql/resolvers/resolver.py +44 -3
  95. infrahub/graphql/types/standard_node.py +8 -4
  96. infrahub/menu/repository.py +1 -1
  97. infrahub/patch/queries/base.py +1 -1
  98. infrahub/pools/number.py +1 -8
  99. infrahub/profiles/node_applier.py +1 -1
  100. infrahub/profiles/queries/get_profile_data.py +1 -1
  101. infrahub/proposed_change/action_checker.py +1 -1
  102. infrahub/services/__init__.py +1 -1
  103. infrahub/services/adapters/cache/nats.py +1 -1
  104. infrahub/webhook/gather.py +1 -1
  105. infrahub/webhook/tasks.py +22 -6
  106. {infrahub_server-1.7.0b0.dist-info → infrahub_server-1.7.0rc0.dist-info}/METADATA +1 -1
  107. {infrahub_server-1.7.0b0.dist-info → infrahub_server-1.7.0rc0.dist-info}/RECORD +111 -110
  108. infrahub_testcontainers/models.py +3 -3
  109. infrahub/graphql/models.py +0 -36
  110. {infrahub_server-1.7.0b0.dist-info → infrahub_server-1.7.0rc0.dist-info}/WHEEL +0 -0
  111. {infrahub_server-1.7.0b0.dist-info → infrahub_server-1.7.0rc0.dist-info}/entry_points.txt +0 -0
  112. {infrahub_server-1.7.0b0.dist-info → infrahub_server-1.7.0rc0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -43,7 +43,7 @@ class Migration012RenameTypeAttributeData(AttributeRenameQuery):
43
43
  name = "migration_012_rename_attr_type"
44
44
  type = QueryType.WRITE
45
45
 
46
- def __init__(self, **kwargs: Any):
46
+ def __init__(self, **kwargs: Any) -> None:
47
47
  new_attr = AttributeInfo(
48
48
  name="account_type",
49
49
  node_kind=InfrahubKind.ACCOUNT,
@@ -83,7 +83,7 @@ class Migration012AddLabelData(NodeDuplicateQuery):
83
83
  name = "migration_012_add_labels"
84
84
  type = QueryType.WRITE
85
85
 
86
- def __init__(self, **kwargs: Any):
86
+ def __init__(self, **kwargs: Any) -> None:
87
87
  new_node = SchemaNodeInfo(
88
88
  name="Account",
89
89
  namespace="Core",
@@ -132,7 +132,7 @@ class Migration012RenameTypeAttributeSchema(SchemaAttributeUpdateQuery):
132
132
  type = QueryType.WRITE
133
133
  insert_return = False
134
134
 
135
- def __init__(self, **kwargs: Any):
135
+ def __init__(self, **kwargs: Any) -> None:
136
136
  super().__init__(
137
137
  attribute_name="name",
138
138
  node_name="Account",
@@ -150,7 +150,7 @@ class Migration012RenameRelationshipAccountTokenData(RelationshipDuplicateQuery)
150
150
  name = "migration_012_rename_rel_account_token_data"
151
151
  type = QueryType.WRITE
152
152
 
153
- def __init__(self, **kwargs: Any):
153
+ def __init__(self, **kwargs: Any) -> None:
154
154
  new_rel = SchemaRelationshipInfo(
155
155
  name="account__token",
156
156
  branch_support=BranchSupportType.AGNOSTIC.value,
@@ -173,7 +173,7 @@ class Migration012RenameRelationshipRefreshTokenData(RelationshipDuplicateQuery)
173
173
  name = "migration_012_rename_rel_refresh_token_data"
174
174
  type = QueryType.WRITE
175
175
 
176
- def __init__(self, **kwargs: Any):
176
+ def __init__(self, **kwargs: Any) -> None:
177
177
  new_rel = SchemaRelationshipInfo(
178
178
  name="account__refreshtoken",
179
179
  branch_support=BranchSupportType.AGNOSTIC.value,
@@ -196,7 +196,7 @@ class Migration012RenameRelationshipThreadData(RelationshipDuplicateQuery):
196
196
  name = "migration_012_rename_rel_thread_data"
197
197
  type = QueryType.WRITE
198
198
 
199
- def __init__(self, **kwargs: Any):
199
+ def __init__(self, **kwargs: Any) -> None:
200
200
  new_rel = SchemaRelationshipInfo(
201
201
  name="thread__account",
202
202
  branch_support=BranchSupportType.AGNOSTIC.value,
@@ -219,7 +219,7 @@ class Migration012RenameRelationshipCommentData(RelationshipDuplicateQuery):
219
219
  name = "migration_012_rename_rel_comment_data"
220
220
  type = QueryType.WRITE
221
221
 
222
- def __init__(self, **kwargs: Any):
222
+ def __init__(self, **kwargs: Any) -> None:
223
223
  new_rel = SchemaRelationshipInfo(
224
224
  name="comment__account",
225
225
  branch_support=BranchSupportType.AGNOSTIC.value,
@@ -243,7 +243,7 @@ class Migration012DeleteOldElementsSchema(DeleteElementInSchemaQuery):
243
243
  type = QueryType.WRITE
244
244
  insert_return = False
245
245
 
246
- def __init__(self, **kwargs: Any):
246
+ def __init__(self, **kwargs: Any) -> None:
247
247
  kwargs.pop("branch", None)
248
248
 
249
249
  super().__init__(
@@ -260,7 +260,7 @@ class Migration012UpdateDisplayLabels(SchemaAttributeUpdateQuery):
260
260
  type = QueryType.WRITE
261
261
  insert_return = False
262
262
 
263
- def __init__(self, **kwargs: Any):
263
+ def __init__(self, **kwargs: Any) -> None:
264
264
  kwargs.pop("branch", None)
265
265
 
266
266
  super().__init__(
@@ -277,7 +277,7 @@ class Migration012UpdateOrderBy(SchemaAttributeUpdateQuery):
277
277
  type = QueryType.WRITE
278
278
  insert_return = False
279
279
 
280
- def __init__(self, **kwargs: Any):
280
+ def __init__(self, **kwargs: Any) -> None:
281
281
  kwargs.pop("branch", None)
282
282
 
283
283
  super().__init__(
@@ -294,7 +294,7 @@ class Migration012UpdateDefaultFilter(SchemaAttributeUpdateQuery):
294
294
  type = QueryType.WRITE
295
295
  insert_return = False
296
296
 
297
- def __init__(self, **kwargs: Any):
297
+ def __init__(self, **kwargs: Any) -> None:
298
298
  kwargs.pop("branch", None)
299
299
 
300
300
  super().__init__(
@@ -311,7 +311,7 @@ class Migration012UpdateHFID(SchemaAttributeUpdateQuery):
311
311
  type = QueryType.WRITE
312
312
  insert_return = False
313
313
 
314
- def __init__(self, **kwargs: Any):
314
+ def __init__(self, **kwargs: Any) -> None:
315
315
  kwargs.pop("branch", None)
316
316
 
317
317
  super().__init__(
@@ -228,7 +228,7 @@ class Migration013DeleteUsernamePasswordGenericSchema(DeleteElementInSchemaQuery
228
228
  type = QueryType.WRITE
229
229
  insert_return = False
230
230
 
231
- def __init__(self, **kwargs: Any):
231
+ def __init__(self, **kwargs: Any) -> None:
232
232
  kwargs.pop("branch", None)
233
233
 
234
234
  super().__init__(
@@ -245,7 +245,7 @@ class Migration013DeleteUsernamePasswordReadWriteSchema(DeleteElementInSchemaQue
245
245
  type = QueryType.WRITE
246
246
  insert_return = False
247
247
 
248
- def __init__(self, **kwargs: Any):
248
+ def __init__(self, **kwargs: Any) -> None:
249
249
  kwargs.pop("branch", None)
250
250
 
251
251
  super().__init__(
@@ -262,7 +262,7 @@ class Migration013DeleteUsernamePasswordReadOnlySchema(DeleteElementInSchemaQuer
262
262
  type = QueryType.WRITE
263
263
  insert_return = False
264
264
 
265
- def __init__(self, **kwargs: Any):
265
+ def __init__(self, **kwargs: Any) -> None:
266
266
  kwargs.pop("branch", None)
267
267
 
268
268
  super().__init__(
@@ -277,7 +277,7 @@ class Migration013DeleteUsernamePasswordReadOnlySchema(DeleteElementInSchemaQuer
277
277
  class Migration013AddInternalStatusData(AttributeAddQuery):
278
278
  type = QueryType.WRITE
279
279
 
280
- def __init__(self, **kwargs: Any):
280
+ def __init__(self, **kwargs: Any) -> None:
281
281
  kwargs.pop("branch", None)
282
282
 
283
283
  super().__init__(
@@ -73,7 +73,7 @@ class DeleteDuplicatedRelationshipEdges(Query):
73
73
  type = QueryType.WRITE
74
74
  insert_return = False
75
75
 
76
- def __init__(self, migrated_kind_nodes_only: bool = True, **kwargs: Any):
76
+ def __init__(self, migrated_kind_nodes_only: bool = True, **kwargs: Any) -> None:
77
77
  self.migrated_kind_nodes_only = migrated_kind_nodes_only
78
78
  super().__init__(**kwargs)
79
79
 
@@ -26,10 +26,25 @@ class RemoveIsVisibleRelationshipQuery(Query):
26
26
  self.add_to_query(query)
27
27
 
28
28
 
29
+ class RemoveIsVisibleFromDiffsQuery(Query):
30
+ name = "remove_is_visible_from_diffs"
31
+ type = QueryType.WRITE
32
+ insert_return = False
33
+
34
+ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa: ARG002
35
+ query = """
36
+ MATCH (diff_prop:DiffProperty {property_type: "IS_VISIBLE"})
37
+ CALL (diff_prop) {
38
+ DETACH DELETE diff_prop
39
+ } IN TRANSACTIONS
40
+ """
41
+ self.add_to_query(query)
42
+
43
+
29
44
  class Migration049(GraphMigration):
30
45
  name: str = "049_remove_is_visible_relationship"
31
46
  minimum_version: int = 48
32
- queries: Sequence[type[Query]] = [RemoveIsVisibleRelationshipQuery]
47
+ queries: Sequence[type[Query]] = [RemoveIsVisibleRelationshipQuery, RemoveIsVisibleFromDiffsQuery]
33
48
 
34
49
  async def validate_migration(self, db: InfrahubDatabase) -> MigrationResult: # noqa: ARG002
35
50
  return MigrationResult()
@@ -20,7 +20,7 @@ class MigrationQuery(MigrationBaseQuery):
20
20
  self,
21
21
  migration: SchemaMigration,
22
22
  **kwargs: Any,
23
- ):
23
+ ) -> None:
24
24
  self.migration = migration
25
25
  super().__init__(**kwargs)
26
26
 
@@ -32,6 +32,6 @@ class AttributeMigrationQuery(MigrationBaseQuery):
32
32
  self,
33
33
  migration: AttributeSchemaMigration,
34
34
  **kwargs: Any,
35
- ):
35
+ ) -> None:
36
36
  self.migration = migration
37
37
  super().__init__(**kwargs)
@@ -24,7 +24,7 @@ class SchemaAttributeUpdateQuery(Query):
24
24
  new_value: Any,
25
25
  previous_value: Any | None = None,
26
26
  **kwargs: Any,
27
- ):
27
+ ) -> None:
28
28
  self.attr_name = attribute_name
29
29
  self.node_name = node_name
30
30
  self.node_namespace = node_namespace
@@ -14,7 +14,7 @@ class AttributeNameUpdateMigrationQuery01(AttributeMigrationQuery, AttributeRena
14
14
  self,
15
15
  migration: AttributeSchemaMigration,
16
16
  **kwargs: Any,
17
- ):
17
+ ) -> None:
18
18
  new_attr = AttributeInfo(
19
19
  name=migration.new_attribute_schema.name,
20
20
  node_kind=migration.new_schema.kind,
@@ -34,7 +34,7 @@ class ProfilesAttributeAddMigrationQuery(AttributeMigrationQuery, AttributeAddQu
34
34
  self,
35
35
  migration: AttributeSchemaMigration,
36
36
  **kwargs: Any,
37
- ):
37
+ ) -> None:
38
38
  node_kinds = _get_node_kinds(migration.new_schema)
39
39
  super().__init__(
40
40
  migration=migration,
@@ -54,7 +54,7 @@ class ProfilesAttributeRemoveMigrationQuery(AttributeMigrationQuery, AttributeRe
54
54
  self,
55
55
  migration: AttributeSchemaMigration,
56
56
  **kwargs: Any,
57
- ):
57
+ ) -> None:
58
58
  node_kinds = _get_node_kinds(migration.new_schema)
59
59
  super().__init__(
60
60
  migration=migration,
@@ -41,7 +41,7 @@ class NodeAttributeAddMigrationQuery01(AttributeMigrationQuery, AttributeAddQuer
41
41
  self,
42
42
  migration: AttributeSchemaMigration,
43
43
  **kwargs: Any,
44
- ):
44
+ ) -> None:
45
45
  node_kinds = self._get_node_kinds(
46
46
  schema=migration.new_schema, new_attribute_schema=migration.new_attribute_schema
47
47
  )
@@ -15,7 +15,7 @@ class NodeAttributeRemoveMigrationQuery01(AttributeMigrationQuery, AttributeRemo
15
15
  self,
16
16
  migration: AttributeSchemaMigration,
17
17
  **kwargs: Any,
18
- ):
18
+ ) -> None:
19
19
  super().__init__(
20
20
  migration=migration,
21
21
  attribute_name=migration.previous_attribute_schema.name,
@@ -14,7 +14,7 @@ class NodeKindUpdateMigrationQuery01(MigrationQuery, NodeDuplicateQuery):
14
14
  self,
15
15
  migration: SchemaMigration,
16
16
  **kwargs: Any,
17
- ):
17
+ ) -> None:
18
18
  new_node = SchemaNodeInfo(
19
19
  name=migration.new_schema.name,
20
20
  namespace=migration.new_schema.namespace,
@@ -82,7 +82,7 @@ class Node(BaseNode, MetadataInterface, metaclass=BaseNodeMeta):
82
82
  _meta.default_filter = default_filter
83
83
  super().__init_subclass_with_meta__(_meta=_meta, **options)
84
84
 
85
- def __init__(self, schema: NodeSchema | ProfileSchema | TemplateSchema, branch: Branch, at: Timestamp):
85
+ def __init__(self, schema: NodeSchema | ProfileSchema | TemplateSchema, branch: Branch, at: Timestamp) -> None:
86
86
  super().__init__()
87
87
  self._schema: NodeSchema | ProfileSchema | TemplateSchema = schema
88
88
  self._branch: Branch = branch
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing import Any
4
+
3
5
  from ..utils import SubclassWithMeta, SubclassWithMeta_Meta
4
6
 
5
7
 
@@ -9,19 +11,19 @@ class BaseOptions:
9
11
 
10
12
  _frozen: bool = False
11
13
 
12
- def __init__(self, class_type):
14
+ def __init__(self, class_type: type) -> None:
13
15
  self.class_type = class_type
14
16
 
15
17
  def freeze(self) -> None:
16
18
  self._frozen = True
17
19
 
18
- def __setattr__(self, name, value):
20
+ def __setattr__(self, name: str, value: Any) -> None:
19
21
  if not self._frozen:
20
22
  super().__setattr__(name, value)
21
23
  else:
22
24
  raise Exception(f"Can't modify frozen Options {self}")
23
25
 
24
- def __repr__(self):
26
+ def __repr__(self) -> str:
25
27
  return f"<{self.__class__.__name__} name={repr(self.name)}>"
26
28
 
27
29
 
@@ -34,7 +36,9 @@ class BaseNode(SubclassWithMeta):
34
36
  # return type(class_name, (cls,), {"Meta": options})
35
37
 
36
38
  @classmethod
37
- def __init_subclass_with_meta__(cls, name=None, description=None, _meta=None, **_kwargs) -> None:
39
+ def __init_subclass_with_meta__(
40
+ cls, name: str | None = None, description: str | None = None, _meta: BaseOptions | None = None, **_kwargs: Any
41
+ ) -> None:
38
42
  assert "_meta" not in cls.__dict__, "Can't assign meta directly"
39
43
  if not _meta:
40
44
  return
@@ -52,7 +56,7 @@ class BaseNodeOptions(BaseOptions):
52
56
 
53
57
 
54
58
  class ObjectNodeMeta(BaseNodeMeta):
55
- def __new__(mcs, name_, bases, namespace, **options):
59
+ def __new__(mcs, name_: str, bases: tuple[type, ...], namespace: dict[str, Any], **options: Any) -> type:
56
60
  # Note: it's safe to pass options as keyword arguments as they are still type-checked by NodeOptions.
57
61
 
58
62
  # We create this type, to then overload it with the dataclass attrs
@@ -117,7 +117,7 @@ class NodeDeleteIndex:
117
117
 
118
118
 
119
119
  class NodeDeleteValidator:
120
- def __init__(self, db: InfrahubDatabase, branch: Branch):
120
+ def __init__(self, db: InfrahubDatabase, branch: Branch) -> None:
121
121
  self.db = db
122
122
  self.branch = branch
123
123
  schema_branch = registry.schema.get_schema_branch(name=self.branch.name)
infrahub/core/order.py ADDED
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Self
4
+
5
+ from pydantic import BaseModel, model_validator
6
+
7
+ from infrahub.constants.enums import OrderDirection # noqa: TC001
8
+ from infrahub.exceptions import ValidationError
9
+
10
+ # Metadata field name constants
11
+ METADATA_CREATED_AT = "created_at"
12
+ METADATA_CREATED_BY = "created_by"
13
+ METADATA_UPDATED_AT = "updated_at"
14
+ METADATA_UPDATED_BY = "updated_by"
15
+
16
+
17
+ class NodeMetaOrder(BaseModel):
18
+ created_at: OrderDirection | None = None
19
+ updated_at: OrderDirection | None = None
20
+
21
+
22
+ class OrderModel(BaseModel):
23
+ disable: bool | None = None
24
+ node_metadata: NodeMetaOrder | None = None
25
+
26
+ @model_validator(mode="after")
27
+ def validate_metadata(self) -> Self:
28
+ if self.node_metadata and self.node_metadata.created_at and self.node_metadata.updated_at:
29
+ raise ValidationError("Cannot order by both created_at and updated_at simultaneously.")
30
+ return self
@@ -221,6 +221,7 @@ class CoreValidator(CoreNode):
221
221
  class CoreWebhook(CoreNode):
222
222
  name: String
223
223
  event_type: Enum
224
+ active: Boolean
224
225
  branch_scope: Dropdown
225
226
  node_kind: StringOptional
226
227
  description: StringOptional
@@ -106,3 +106,7 @@ class CoreNode(Protocol):
106
106
  ) -> dict: ...
107
107
  async def render_display_label(self, db: InfrahubDatabase | None = None) -> str: ...
108
108
  async def from_graphql(self, data: dict, db: InfrahubDatabase) -> bool: ...
109
+ def _get_created_at(self) -> Timestamp | None: ...
110
+ def _get_created_by(self) -> str | None: ...
111
+ def _get_updated_at(self) -> Timestamp | None: ...
112
+ def _get_updated_by(self) -> str | None: ...
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- from abc import ABC, abstractmethod
4
3
  from collections import defaultdict
5
4
  from dataclasses import dataclass, field
6
5
  from enum import Enum
@@ -160,7 +159,7 @@ def cleanup_return_labels(labels: list[str]) -> list[str]:
160
159
 
161
160
 
162
161
  class QueryResult:
163
- def __init__(self, data: list[Neo4jNode | Neo4jRelationship | list[Neo4jNode]], labels: list[str]):
162
+ def __init__(self, data: list[Neo4jNode | Neo4jRelationship | list[Neo4jNode]], labels: list[str]) -> None:
164
163
  self.data = data
165
164
  self.labels = labels
166
165
  self.branch_score: int = 0
@@ -336,7 +335,7 @@ class QueryStat:
336
335
  return cls(**data)
337
336
 
338
337
 
339
- class Query(ABC):
338
+ class Query:
340
339
  name: str = "base-query"
341
340
  type: QueryType
342
341
 
@@ -353,7 +352,7 @@ class Query(ABC):
353
352
  order_by: list[str] | None = None,
354
353
  branch_agnostic: bool = False,
355
354
  user_id: str = SYSTEM_USER_ID,
356
- ):
355
+ ) -> None:
357
356
  if branch:
358
357
  self.branch = branch
359
358
 
@@ -405,8 +404,12 @@ class Query(ABC):
405
404
 
406
405
  return query
407
406
 
408
- @abstractmethod
409
407
  async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
408
+ # Avoid using this method for new queries and look at migrating older queries. The
409
+ # problem here is that we loose so much information with the `**kwargs` we should instead
410
+ # populate this information via the constructor and anything done within the existing query_init methods
411
+ # could either be handled within __init__ or via dedicated methods within each Query class where appropriate,
412
+ # i.e. things might need to happend in a certain order or we just want to separate the logic better.
410
413
  raise NotImplementedError
411
414
 
412
415
  def get_context(self) -> dict[str, str]:
@@ -31,7 +31,7 @@ class AttributeQuery(Query):
31
31
  at: Timestamp | str | None = None,
32
32
  branch: Branch | None = None,
33
33
  **kwargs: Any,
34
- ):
34
+ ) -> None:
35
35
  self.attr = attr
36
36
  self.attr_id = attr_id or attr.db_id
37
37
 
@@ -171,7 +171,7 @@ class AttributeUpdateNodePropertyQuery(AttributeQuery):
171
171
  prop_name: str,
172
172
  prop_id: str | None = None,
173
173
  **kwargs: Any,
174
- ):
174
+ ) -> None:
175
175
  self.prop_name = prop_name
176
176
  self.prop_id = prop_id
177
177
 
@@ -246,7 +246,7 @@ class AttributeClearNodePropertyQuery(AttributeQuery):
246
246
  self,
247
247
  prop_name: str,
248
248
  **kwargs: Any,
249
- ):
249
+ ) -> None:
250
250
  self.prop_name = prop_name
251
251
 
252
252
  super().__init__(**kwargs)
@@ -17,7 +17,7 @@ class DeleteBranchRelationshipsQuery(Query):
17
17
 
18
18
  type: QueryType = QueryType.WRITE
19
19
 
20
- def __init__(self, branch_name: str, **kwargs: Any):
20
+ def __init__(self, branch_name: str, **kwargs: Any) -> None:
21
21
  self.branch_name = branch_name
22
22
  super().__init__(**kwargs)
23
23
 
@@ -11,7 +11,7 @@ class DeleteAfterTimeQuery(Query):
11
11
  insert_return: bool = False
12
12
  type: QueryType = QueryType.WRITE
13
13
 
14
- def __init__(self, timestamp: Timestamp, **kwargs: Any):
14
+ def __init__(self, timestamp: Timestamp, **kwargs: Any) -> None:
15
15
  self.timestamp = timestamp
16
16
  super().__init__(**kwargs)
17
17
 
@@ -26,7 +26,7 @@ class DiffQuery(Query):
26
26
  diff_from: Timestamp | str = None,
27
27
  diff_to: Timestamp | str = None,
28
28
  **kwargs,
29
- ):
29
+ ) -> None:
30
30
  """A diff is always in the context of a branch"""
31
31
 
32
32
  if not diff_from and branch.is_default:
@@ -59,7 +59,7 @@ class DiffCountChanges(Query):
59
59
  diff_from: Timestamp,
60
60
  diff_to: Timestamp,
61
61
  **kwargs,
62
- ):
62
+ ) -> None:
63
63
  self.branch_names = branch_names
64
64
  self.diff_from = diff_from
65
65
  self.diff_to = diff_to
@@ -122,7 +122,7 @@ class DiffCalculationQuery(DiffQuery):
122
122
  current_node_field_specifiers: NodeFieldSpecifierMap | None = None,
123
123
  new_node_field_specifiers: NodeFieldSpecifierMap | None = None,
124
124
  **kwargs: Any,
125
- ):
125
+ ) -> None:
126
126
  self.base_branch = base_branch
127
127
  self.diff_branch_from_time = diff_branch_from_time
128
128
  self.current_node_field_specifiers = current_node_field_specifiers