infrahub-server 1.2.10__py3-none-any.whl → 1.2.11__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 (34) hide show
  1. infrahub/config.py +9 -0
  2. infrahub/core/constants/infrahubkind.py +1 -0
  3. infrahub/core/constraint/node/runner.py +1 -1
  4. infrahub/core/diff/query_parser.py +5 -1
  5. infrahub/core/diff/tasks.py +3 -3
  6. infrahub/core/node/resource_manager/ip_address_pool.py +6 -2
  7. infrahub/core/node/resource_manager/ip_prefix_pool.py +6 -2
  8. infrahub/core/protocols.py +4 -0
  9. infrahub/core/query/diff.py +7 -0
  10. infrahub/core/schema/definitions/core/__init__.py +8 -1
  11. infrahub/core/schema/definitions/core/resource_pool.py +20 -0
  12. infrahub/core/validators/tasks.py +1 -1
  13. infrahub/database/__init__.py +5 -4
  14. infrahub/graphql/app.py +1 -1
  15. infrahub/graphql/loaders/node.py +1 -1
  16. infrahub/graphql/loaders/peers.py +1 -1
  17. infrahub/graphql/mutations/proposed_change.py +1 -1
  18. infrahub/graphql/queries/relationship.py +1 -1
  19. infrahub/graphql/queries/task.py +10 -0
  20. infrahub/graphql/resolvers/many_relationship.py +4 -4
  21. infrahub/graphql/resolvers/resolver.py +4 -4
  22. infrahub/graphql/resolvers/single_relationship.py +2 -2
  23. infrahub/graphql/subscription/graphql_query.py +2 -2
  24. infrahub/graphql/types/branch.py +1 -1
  25. infrahub/graphql/types/task_log.py +3 -2
  26. infrahub/message_bus/operations/refresh/registry.py +1 -1
  27. infrahub/task_manager/task.py +44 -4
  28. infrahub/telemetry/database.py +1 -1
  29. infrahub/telemetry/tasks.py +1 -1
  30. {infrahub_server-1.2.10.dist-info → infrahub_server-1.2.11.dist-info}/METADATA +1 -1
  31. {infrahub_server-1.2.10.dist-info → infrahub_server-1.2.11.dist-info}/RECORD +34 -34
  32. {infrahub_server-1.2.10.dist-info → infrahub_server-1.2.11.dist-info}/LICENSE.txt +0 -0
  33. {infrahub_server-1.2.10.dist-info → infrahub_server-1.2.11.dist-info}/WHEEL +0 -0
  34. {infrahub_server-1.2.10.dist-info → infrahub_server-1.2.11.dist-info}/entry_points.txt +0 -0
infrahub/config.py CHANGED
@@ -269,6 +269,7 @@ class DatabaseSettings(BaseSettings):
269
269
  address: str = "localhost"
270
270
  port: int = 7687
271
271
  database: str | None = Field(default=None, pattern=VALID_DATABASE_NAME_REGEX, description="Name of the database")
272
+ policy: str | None = Field(default=None, description="Routing policy for database connections")
272
273
  tls_enabled: bool = Field(default=False, description="Indicates if TLS is enabled for the connection")
273
274
  tls_insecure: bool = Field(default=False, description="Indicates if TLS certificates are verified")
274
275
  tls_ca_file: str | None = Field(default=None, description="File path to CA cert or bundle in PEM format")
@@ -293,6 +294,14 @@ class DatabaseSettings(BaseSettings):
293
294
  default=0.01, ge=0, description="Delay to add when max_concurrent_queries is reached."
294
295
  )
295
296
 
297
+ @property
298
+ def database_uri(self) -> str:
299
+ """Constructs the database URI based on the configuration settings."""
300
+ base_uri = f"{self.protocol}://{self.address}:{self.port}"
301
+ if self.policy is not None:
302
+ return f"{base_uri}?policy={self.policy}"
303
+ return base_uri
304
+
296
305
  @property
297
306
  def database_name(self) -> str:
298
307
  return self.database or self.db_type.value
@@ -70,3 +70,4 @@ TRANSFORMPYTHON = "CoreTransformPython"
70
70
  USERVALIDATOR = "CoreUserValidator"
71
71
  VALIDATOR = "CoreValidator"
72
72
  WEBHOOK = "CoreWebhook"
73
+ WEIGHTED_POOL_RESOURCE = "CoreWeightedPoolResource"
@@ -26,7 +26,7 @@ class NodeConstraintRunner:
26
26
  async def check(
27
27
  self, node: Node, field_filters: list[str] | None = None, skip_uniqueness_check: bool = False
28
28
  ) -> None:
29
- async with self.db.start_session() as db:
29
+ async with self.db.start_session(read_only=False) as db:
30
30
  await node.resolve_relationships(db=db)
31
31
 
32
32
  if not skip_uniqueness_check:
@@ -526,7 +526,11 @@ class DiffQueryParser:
526
526
  return self._current_node_field_specifiers
527
527
 
528
528
  def read_result(self, query_result: QueryResult) -> None:
529
- path = query_result.get_path(label="diff_path")
529
+ try:
530
+ path = query_result.get_path(label="diff_path")
531
+ except ValueError:
532
+ # the path was null, so nothing to read
533
+ return
530
534
  database_path = DatabasePath.from_cypher_path(cypher_path=path)
531
535
  self._parse_path(database_path=database_path)
532
536
  self._current_node_field_specifiers = None
@@ -20,7 +20,7 @@ log = get_logger()
20
20
  async def update_diff(model: RequestDiffUpdate, service: InfrahubServices) -> None:
21
21
  await add_tags(branches=[model.branch_name])
22
22
 
23
- async with service.database.start_session() as db:
23
+ async with service.database.start_session(read_only=False) as db:
24
24
  component_registry = get_component_registry()
25
25
  base_branch = await registry.get_branch(db=db, branch=registry.default_branch)
26
26
  diff_branch = await registry.get_branch(db=db, branch=model.branch_name)
@@ -40,7 +40,7 @@ async def update_diff(model: RequestDiffUpdate, service: InfrahubServices) -> No
40
40
  async def refresh_diff(branch_name: str, diff_id: str, service: InfrahubServices) -> None:
41
41
  await add_tags(branches=[branch_name])
42
42
 
43
- async with service.database.start_session() as db:
43
+ async with service.database.start_session(read_only=False) as db:
44
44
  component_registry = get_component_registry()
45
45
  base_branch = await registry.get_branch(db=db, branch=registry.default_branch)
46
46
  diff_branch = await registry.get_branch(db=db, branch=branch_name)
@@ -53,7 +53,7 @@ async def refresh_diff(branch_name: str, diff_id: str, service: InfrahubServices
53
53
  async def refresh_diff_all(branch_name: str, context: InfrahubContext, service: InfrahubServices) -> None:
54
54
  await add_tags(branches=[branch_name])
55
55
 
56
- async with service.database.start_session() as db:
56
+ async with service.database.start_session(read_only=True) as db:
57
57
  component_registry = get_component_registry()
58
58
  default_branch = registry.get_branch_from_registry()
59
59
  diff_repository = await component_registry.get_component(DiffRepository, db=db, branch=default_branch)
@@ -81,11 +81,15 @@ class CoreIPAddressPool(Node):
81
81
  return node
82
82
 
83
83
  async def get_next(self, db: InfrahubDatabase, prefixlen: int | None = None) -> IPAddressType:
84
- # Measure utilization of all prefixes identified as resources
85
84
  resources = await self.resources.get_peers(db=db) # type: ignore[attr-defined]
86
85
  ip_namespace = await self.ip_namespace.get_peer(db=db) # type: ignore[attr-defined]
87
86
 
88
- for resource in resources.values():
87
+ try:
88
+ weighted_resources = sorted(resources.values(), key=lambda r: r.allocation_weight.value or 0, reverse=True)
89
+ except AttributeError:
90
+ weighted_resources = list(resources.values())
91
+
92
+ for resource in weighted_resources:
89
93
  ip_prefix = ipaddress.ip_network(resource.prefix.value) # type: ignore[attr-defined]
90
94
  prefix_length = prefixlen or ip_prefix.prefixlen
91
95
 
@@ -88,11 +88,15 @@ class CoreIPPrefixPool(Node):
88
88
  return node
89
89
 
90
90
  async def get_next(self, db: InfrahubDatabase, prefixlen: int) -> IPNetworkType:
91
- # Measure utilization of all prefixes identified as resources
92
91
  resources = await self.resources.get_peers(db=db) # type: ignore[attr-defined]
93
92
  ip_namespace = await self.ip_namespace.get_peer(db=db) # type: ignore[attr-defined]
94
93
 
95
- for resource in resources.values():
94
+ try:
95
+ weighted_resources = sorted(resources.values(), key=lambda r: r.allocation_weight.value or 0, reverse=True)
96
+ except AttributeError:
97
+ weighted_resources = list(resources.values())
98
+
99
+ for resource in weighted_resources:
96
100
  subnets = await get_subnets(
97
101
  db=db,
98
102
  ip_prefix=ipaddress.ip_network(resource.prefix.value), # type: ignore[attr-defined]
@@ -209,6 +209,10 @@ class CoreWebhook(CoreNode):
209
209
  validate_certificates: BooleanOptional
210
210
 
211
211
 
212
+ class CoreWeightedPoolResource(CoreNode):
213
+ allocation_weight: IntegerOptional
214
+
215
+
212
216
  class LineageOwner(CoreNode):
213
217
  pass
214
218
 
@@ -201,6 +201,13 @@ WITH reduce(
201
201
  diff_rel_paths = [], item IN [penultimate_path, peer_path] |
202
202
  CASE WHEN item IS NULL THEN diff_rel_paths ELSE diff_rel_paths + [item] END
203
203
  ) AS diff_rel_paths, has_more_data
204
+ // ------------------------
205
+ // make sure we still include has_more_data if diff_rel_paths is empty
206
+ // ------------------------
207
+ WITH CASE
208
+ WHEN diff_rel_paths = [] THEN [NULL]
209
+ ELSE diff_rel_paths
210
+ END AS diff_rel_paths, has_more_data
204
211
  """
205
212
 
206
213
  def get_previous_base_path_query(self, db: InfrahubDatabase) -> str:
@@ -56,7 +56,13 @@ from .propose_change_validator import (
56
56
  core_user_validator,
57
57
  )
58
58
  from .repository import core_generic_repository, core_read_only_repository, core_repository
59
- from .resource_pool import core_ip_address_pool, core_ip_prefix_pool, core_number_pool, core_resource_pool
59
+ from .resource_pool import (
60
+ core_ip_address_pool,
61
+ core_ip_prefix_pool,
62
+ core_number_pool,
63
+ core_resource_pool,
64
+ core_weighted_pool_resource,
65
+ )
60
66
  from .template import core_object_component_template, core_object_template
61
67
  from .transform import core_transform, core_transform_jinja2, core_transform_python
62
68
  from .webhook import core_custom_webhook, core_standard_webhook, core_webhook
@@ -81,6 +87,7 @@ core_models_mixed: dict[str, list] = {
81
87
  builtin_ip_prefix,
82
88
  builtin_ip_address,
83
89
  core_resource_pool,
90
+ core_weighted_pool_resource,
84
91
  core_generic_account,
85
92
  core_base_permission,
86
93
  core_credential,
@@ -32,6 +32,26 @@ core_resource_pool = GenericSchema(
32
32
  ],
33
33
  )
34
34
 
35
+ core_weighted_pool_resource = GenericSchema(
36
+ name="WeightedPoolResource",
37
+ namespace="Core",
38
+ label="Weighted Pool Resource",
39
+ description="Resource to be used in a pool, its weight is used to determine its priority on allocation.",
40
+ include_in_menu=False,
41
+ branch=BranchSupportType.AWARE,
42
+ generate_profile=False,
43
+ attributes=[
44
+ Attr(
45
+ name="allocation_weight",
46
+ label="Weight",
47
+ description="Weight determines allocation priority, resources with higher values are selected first.",
48
+ kind="Number",
49
+ optional=True,
50
+ order_weight=10000,
51
+ )
52
+ ],
53
+ )
54
+
35
55
  core_ip_prefix_pool = NodeSchema(
36
56
  name="IPPrefixPool",
37
57
  namespace="Core",
@@ -71,7 +71,7 @@ async def schema_path_validate(
71
71
  schema_branch: SchemaBranch,
72
72
  service: InfrahubServices,
73
73
  ) -> SchemaValidatorPathResponseData:
74
- async with service.database.start_session() as db:
74
+ async with service.database.start_session(read_only=True) as db:
75
75
  constraint_request = SchemaConstraintValidatorRequest(
76
76
  branch=branch,
77
77
  constraint_name=constraint_name,
@@ -476,8 +476,6 @@ async def validate_database(
476
476
 
477
477
 
478
478
  async def get_db(retry: int = 0) -> AsyncDriver:
479
- URI = f"{config.SETTINGS.database.protocol}://{config.SETTINGS.database.address}:{config.SETTINGS.database.port}"
480
-
481
479
  trusted_certificates = TrustSystemCAs()
482
480
  if config.SETTINGS.database.tls_insecure:
483
481
  trusted_certificates = TrustAll()
@@ -485,11 +483,14 @@ async def get_db(retry: int = 0) -> AsyncDriver:
485
483
  trusted_certificates = TrustCustomCAs(config.SETTINGS.database.tls_ca_file)
486
484
 
487
485
  driver = AsyncGraphDatabase.driver(
488
- URI,
486
+ config.SETTINGS.database.database_uri,
489
487
  auth=(config.SETTINGS.database.username, config.SETTINGS.database.password),
490
488
  encrypted=config.SETTINGS.database.tls_enabled,
491
489
  trusted_certificates=trusted_certificates,
492
- notifications_disabled_categories=[NotificationDisabledCategory.UNRECOGNIZED],
490
+ notifications_disabled_categories=[
491
+ NotificationDisabledCategory.UNRECOGNIZED,
492
+ NotificationDisabledCategory.DEPRECATION, # TODO: Remove me with 1.3
493
+ ],
493
494
  notifications_min_severity=NotificationMinimumSeverity.WARNING,
494
495
  )
495
496
 
infrahub/graphql/app.py CHANGED
@@ -155,7 +155,7 @@ class InfrahubGraphQLApp:
155
155
 
156
156
  db = websocket.app.state.db
157
157
 
158
- async with db.start_session() as db:
158
+ async with db.start_session(read_only=True) as db:
159
159
  branch_name = websocket.path_params.get("branch_name", registry.default_branch)
160
160
  branch = await registry.get_branch(db=db, branch=branch_name)
161
161
 
@@ -53,7 +53,7 @@ class NodeDataLoader(DataLoader[str, Node | None]):
53
53
  self.db = db
54
54
 
55
55
  async def batch_load_fn(self, keys: list[Any]) -> list[Node | None]:
56
- async with self.db.start_session() as db:
56
+ async with self.db.start_session(read_only=True) as db:
57
57
  nodes_by_id = await NodeManager.get_many(
58
58
  db=db,
59
59
  ids=keys,
@@ -51,7 +51,7 @@ class PeerRelationshipsDataLoader(DataLoader[str, list[Relationship]]):
51
51
  self.db = db
52
52
 
53
53
  async def batch_load_fn(self, keys: list[Any]) -> list[list[Relationship]]: # pylint: disable=method-hidden
54
- async with self.db.start_session() as db:
54
+ async with self.db.start_session(read_only=True) as db:
55
55
  peer_rels = await NodeManager.query_peers(
56
56
  db=db,
57
57
  ids=keys,
@@ -222,7 +222,7 @@ class ProposedChangeMerge(Mutation):
222
222
 
223
223
  async with graphql_context.db.start_session() as db:
224
224
  proposed_change.state.value = ProposedChangeState.MERGING.value
225
- proposed_change.save(db=db)
225
+ await proposed_change.save(db=db)
226
226
 
227
227
  if wait_until_completion:
228
228
  await graphql_context.service.workflow.execute_workflow(
@@ -34,7 +34,7 @@ class Relationships(ObjectType):
34
34
 
35
35
  response: dict[str, Any] = {"edges": [], "count": None}
36
36
 
37
- async with graphql_context.db.start_session() as db:
37
+ async with graphql_context.db.start_session(read_only=True) as db:
38
38
  query = await RelationshipGetByIdentifierQuery.init(
39
39
  db=db,
40
40
  branch=graphql_context.branch,
@@ -32,6 +32,8 @@ class Tasks(ObjectType):
32
32
  workflow: list[str] | None = None,
33
33
  related_node__ids: list | None = None,
34
34
  q: str | None = None,
35
+ log_limit: int | None = None,
36
+ log_offset: int | None = None,
35
37
  ) -> dict[str, Any]:
36
38
  related_nodes = related_node__ids or []
37
39
  ids = ids or []
@@ -45,6 +47,8 @@ class Tasks(ObjectType):
45
47
  statuses=state,
46
48
  workflows=workflow,
47
49
  related_nodes=related_nodes,
50
+ log_limit=log_limit,
51
+ log_offset=log_offset,
48
52
  )
49
53
 
50
54
  @staticmethod
@@ -71,6 +75,8 @@ class Tasks(ObjectType):
71
75
  branch: str | None = None,
72
76
  limit: int | None = None,
73
77
  offset: int | None = None,
78
+ log_limit: int | None = None,
79
+ log_offset: int | None = None,
74
80
  ) -> dict[str, Any]:
75
81
  graphql_context: GraphqlContext = info.context
76
82
  fields = await extract_fields_first_node(info)
@@ -87,6 +93,8 @@ class Tasks(ObjectType):
87
93
  related_nodes=related_nodes,
88
94
  limit=limit,
89
95
  offset=offset,
96
+ log_limit=log_limit,
97
+ log_offset=log_offset,
90
98
  )
91
99
  prefect_count = prefect_tasks.get("count", None)
92
100
  return {
@@ -105,6 +113,8 @@ Task = Field(
105
113
  workflow=List(String),
106
114
  ids=List(String),
107
115
  q=String(required=False),
116
+ log_limit=Int(required=False),
117
+ log_offset=Int(required=False),
108
118
  resolver=Tasks.resolve,
109
119
  required=True,
110
120
  )
@@ -33,7 +33,7 @@ class ManyRelationshipResolver:
33
33
  parent_id: str,
34
34
  node_schema: NodeSchema,
35
35
  ) -> list[str]:
36
- async with db.start_session() as dbs:
36
+ async with db.start_session(read_only=True) as dbs:
37
37
  query = await NodeGetHierarchyQuery.init(
38
38
  db=dbs,
39
39
  direction=RelationshipHierarchyDirection.DESCENDANTS,
@@ -55,7 +55,7 @@ class ManyRelationshipResolver:
55
55
  rel_schema: RelationshipSchema,
56
56
  filters: dict[str, Any],
57
57
  ) -> int:
58
- async with db.start_session() as dbs:
58
+ async with db.start_session(read_only=True) as dbs:
59
59
  return await NodeManager.count_peers(
60
60
  db=dbs,
61
61
  ids=ids,
@@ -194,7 +194,7 @@ class ManyRelationshipResolver:
194
194
  offset: int | None = None,
195
195
  limit: int | None = None,
196
196
  ) -> list[dict[str, Any]] | None:
197
- async with db.start_session() as dbs:
197
+ async with db.start_session(read_only=True) as dbs:
198
198
  objs = await NodeManager.query_peers(
199
199
  db=dbs,
200
200
  ids=ids,
@@ -257,7 +257,7 @@ class ManyRelationshipResolver:
257
257
  all_peer_rels.extend(node_peer_rels)
258
258
  if not all_peer_rels:
259
259
  return None
260
- async with db.start_session() as dbs:
260
+ async with db.start_session(read_only=True) as dbs:
261
261
  return [
262
262
  await obj.to_graphql(db=dbs, fields=node_fields, related_node_ids=related_node_ids)
263
263
  for obj in all_peer_rels
@@ -29,7 +29,7 @@ async def account_resolver(
29
29
  fields = await extract_fields(info.field_nodes[0].selection_set)
30
30
  graphql_context: GraphqlContext = info.context
31
31
 
32
- async with graphql_context.db.start_session() as db:
32
+ async with graphql_context.db.start_session(read_only=True) as db:
33
33
  results = await NodeManager.query(
34
34
  schema=InfrahubKind.GENERICACCOUNT,
35
35
  filters={"ids": [graphql_context.account_session.account_id]},
@@ -102,7 +102,7 @@ async def default_resolver(*args: Any, **kwargs) -> dict | list[dict] | None:
102
102
  if "__" in key and value or key in ["id", "ids"]
103
103
  }
104
104
 
105
- async with graphql_context.db.start_session() as db:
105
+ async with graphql_context.db.start_session(read_only=True) as db:
106
106
  objs = await NodeManager.query_peers(
107
107
  db=db,
108
108
  ids=[parent["id"]],
@@ -158,7 +158,7 @@ async def default_paginated_list_resolver(
158
158
  fields = await extract_selection(info.field_nodes[0], schema=schema)
159
159
 
160
160
  graphql_context: GraphqlContext = info.context
161
- async with graphql_context.db.start_session() as db:
161
+ async with graphql_context.db.start_session(read_only=True) as db:
162
162
  response: dict[str, Any] = {"edges": []}
163
163
  filters = {
164
164
  key: value for key, value in kwargs.items() if ("__" in key and value is not None) or key in ("ids", "hfid")
@@ -293,7 +293,7 @@ async def hierarchy_resolver(
293
293
 
294
294
  response: dict[str, Any] = {"edges": [], "count": None}
295
295
 
296
- async with graphql_context.db.start_session() as db:
296
+ async with graphql_context.db.start_session(read_only=True) as db:
297
297
  if "count" in fields:
298
298
  response["count"] = await NodeManager.count_hierarchy(
299
299
  db=db,
@@ -109,7 +109,7 @@ class SingleRelationshipResolver:
109
109
  for key, value in kwargs.items()
110
110
  if "__" in key and value or key in ["id", "ids"]
111
111
  }
112
- async with db.start_session() as dbs:
112
+ async with db.start_session(read_only=True) as dbs:
113
113
  objs = await NodeManager.query_peers(
114
114
  db=dbs,
115
115
  ids=[parent_id],
@@ -171,5 +171,5 @@ class SingleRelationshipResolver:
171
171
  node = await loader.load(key=peer_id)
172
172
  if not node:
173
173
  return None
174
- async with db.start_session() as dbs:
174
+ async with db.start_session(read_only=True) as dbs:
175
175
  return await node.to_graphql(db=dbs, fields=node_fields, related_node_ids=related_node_ids)
@@ -29,7 +29,7 @@ async def resolver_graphql_query(
29
29
  graphql_context: GraphqlContext = info.context
30
30
  at = Timestamp()
31
31
 
32
- async with graphql_context.db.start_session() as db:
32
+ async with graphql_context.db.start_session(read_only=True) as db:
33
33
  # Find the GraphQLQuery and the GraphQL Schema
34
34
  graphql_query = await NodeManager.get_one_by_default_filter(
35
35
  db=db, id=name, kind=CoreGraphQLQuery, branch=graphql_context.branch, at=at
@@ -38,7 +38,7 @@ async def resolver_graphql_query(
38
38
  raise ValueError(f"Unable to find the {InfrahubKind.GRAPHQLQUERY} {name}")
39
39
 
40
40
  while True:
41
- async with graphql_context.db.start_session() as db:
41
+ async with graphql_context.db.start_session(read_only=True) as db:
42
42
  result = await graphql(
43
43
  schema=graphql_schema,
44
44
  source=graphql_query.query.value,
@@ -37,7 +37,7 @@ class BranchType(InfrahubObjectType):
37
37
  graphql_context: GraphqlContext,
38
38
  **kwargs: Any,
39
39
  ) -> list[dict[str, Any]]:
40
- async with graphql_context.db.start_session() as db:
40
+ async with graphql_context.db.start_session(read_only=True) as db:
41
41
  objs = await Branch.get_list(db=db, **kwargs)
42
42
 
43
43
  if not objs:
@@ -1,4 +1,4 @@
1
- from graphene import Field, InputObjectType, List, ObjectType, String
1
+ from graphene import Field, InputObjectType, Int, List, NonNull, ObjectType, String
2
2
  from graphene.types.uuid import UUID
3
3
 
4
4
  from .enums import Severity
@@ -26,4 +26,5 @@ class TaskLogNodes(ObjectType):
26
26
 
27
27
 
28
28
  class TaskLogEdge(ObjectType):
29
- edges = List(TaskLogNodes)
29
+ edges = List(NonNull(TaskLogNodes), required=True)
30
+ count = Int(required=True)
@@ -11,7 +11,7 @@ async def branches(message: messages.RefreshRegistryBranches, service: InfrahubS
11
11
  service.log.info("Ignoring refresh registry refresh request originating from self", worker=WORKER_IDENTITY)
12
12
  return
13
13
 
14
- async with service.database.start_session() as db:
14
+ async with service.database.start_session(read_only=True) as db:
15
15
  await refresh_branches(db=db)
16
16
 
17
17
  await service.component.refresh_schema_hash()
@@ -35,6 +35,9 @@ from .models import FlowLogs, FlowProgress, RelatedNodesInfo
35
35
 
36
36
  log = get_logger()
37
37
 
38
+ NB_LOGS_LIMIT = 10_000
39
+ PREFECT_MAX_LOGS_PER_CALL = 200
40
+
38
41
 
39
42
  class PrefectTask:
40
43
  @classmethod
@@ -83,9 +86,42 @@ class PrefectTask:
83
86
  return related_nodes
84
87
 
85
88
  @classmethod
86
- async def _get_logs(cls, client: PrefectClient, flow_ids: list[UUID]) -> FlowLogs:
89
+ async def _get_logs(
90
+ cls, client: PrefectClient, flow_ids: list[UUID], log_limit: int | None, log_offset: int | None
91
+ ) -> FlowLogs:
92
+ """
93
+ Return the logs for a flow run, based on log_limit and log_offset.
94
+ At most, NB_LOGS_LIMIT logs will be returned per flow.
95
+ """
96
+
87
97
  logs_flow = FlowLogs()
88
- all_logs = await client.read_logs(log_filter=LogFilter(flow_run_id=LogFilterFlowRunId(any_=flow_ids)))
98
+
99
+ log_limit = log_limit if log_limit is not None else NB_LOGS_LIMIT
100
+ log_offset = log_offset or 0
101
+ current_offset = log_offset
102
+
103
+ if log_limit > NB_LOGS_LIMIT:
104
+ raise ValueError(f"log_limit cannot be greater than {NB_LOGS_LIMIT}")
105
+
106
+ all_logs = []
107
+
108
+ # Fetch the logs in batches of PREFECT_MAX_LOGS_PER_CALL, as prefect does not allow to fetch more logs at once.
109
+ remaining = min(log_limit, NB_LOGS_LIMIT)
110
+ while remaining > 0:
111
+ batch_limit = min(PREFECT_MAX_LOGS_PER_CALL, remaining)
112
+ logs_batch = await client.read_logs(
113
+ log_filter=LogFilter(flow_run_id=LogFilterFlowRunId(any_=flow_ids)),
114
+ offset=current_offset,
115
+ limit=batch_limit,
116
+ )
117
+ all_logs.extend(logs_batch)
118
+ nb_fetched = len(logs_batch)
119
+ if nb_fetched < batch_limit:
120
+ break # No more logs to fetch
121
+
122
+ current_offset += nb_fetched
123
+ remaining -= nb_fetched
124
+
89
125
  for flow_log in all_logs:
90
126
  if flow_log.flow_run_id and flow_log.message not in ["Finished in state Completed()"]:
91
127
  logs_flow.logs[flow_log.flow_run_id].append(flow_log)
@@ -188,6 +224,8 @@ class PrefectTask:
188
224
  branch: str | None = None,
189
225
  limit: int | None = None,
190
226
  offset: int | None = None,
227
+ log_limit: int | None = None,
228
+ log_offset: int | None = None,
191
229
  ) -> dict[str, Any]:
192
230
  nodes: list[dict] = []
193
231
  count = None
@@ -219,7 +257,9 @@ class PrefectTask:
219
257
  sort=FlowRunSort.START_TIME_DESC,
220
258
  )
221
259
  if log_fields:
222
- logs_flow = await cls._get_logs(client=client, flow_ids=[flow.id for flow in flows])
260
+ logs_flow = await cls._get_logs(
261
+ client=client, flow_ids=[flow.id for flow in flows], log_limit=log_limit, log_offset=log_offset
262
+ )
223
263
 
224
264
  if "progress" in node_fields:
225
265
  progress_flow = await cls._get_progress(client=client, flow_ids=[flow.id for flow in flows])
@@ -265,7 +305,7 @@ class PrefectTask:
265
305
  "updated_at": flow.updated.to_iso8601_string(), # type: ignore
266
306
  "start_time": flow.start_time.to_iso8601_string() if flow.start_time else None,
267
307
  "id": flow.id,
268
- "logs": {"edges": logs},
308
+ "logs": {"edges": logs, "count": len(logs)},
269
309
  }
270
310
  }
271
311
  )
@@ -49,7 +49,7 @@ async def get_system_info(db: InfrahubDatabase) -> TelemetryDatabaseSystemInfoDa
49
49
 
50
50
  @task(name="telemetry-gather-db", task_run_name="Gather Database Information", cache_policy=NONE)
51
51
  async def gather_database_information(db: InfrahubDatabase) -> TelemetryDatabaseData:
52
- async with db.start_session() as dbs:
52
+ async with db.start_session(read_only=True) as dbs:
53
53
  server_info = []
54
54
  system_info = None
55
55
  database_type = db.db_type.value
@@ -38,7 +38,7 @@ async def gather_schema_information(branch: Branch) -> TelemetrySchemaData:
38
38
 
39
39
  @task(name="telemetry-feature-information", task_run_name="Gather Feature Information", cache_policy=NONE)
40
40
  async def gather_feature_information(service: InfrahubServices) -> dict[str, int]:
41
- async with service.database.start_session() as db:
41
+ async with service.database.start_session(read_only=True) as db:
42
42
  data = {}
43
43
  features_to_count = [
44
44
  InfrahubKind.ARTIFACT,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: infrahub-server
3
- Version: 1.2.10
3
+ Version: 1.2.11
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
  Home-page: https://opsmill.com
6
6
  License: AGPL-3.0-only
@@ -41,7 +41,7 @@ infrahub/computed_attribute/gather.py,sha256=TSv6_CWZH1DYRv430jzyJpFJWKzwPGka5wF
41
41
  infrahub/computed_attribute/models.py,sha256=P_MijLwCVd7394oyTTfYQ3HmX5wIF966jdchuZaLRbs,17361
42
42
  infrahub/computed_attribute/tasks.py,sha256=k3qNNKxF2lS9tZDRKrB_sKX552rpfM-Q-4yj6WJLvs4,17880
43
43
  infrahub/computed_attribute/triggers.py,sha256=ve1cUj0CZ7dU1VtZkxET9LD8StszKIL9mCkTZpCeUaI,2304
44
- infrahub/config.py,sha256=IXLp97Y2pxtGcQxwwuBSuBQotFGdHEtj1rf9EZ5z-_I,35255
44
+ infrahub/config.py,sha256=XxyVP8hT7zKxRRMkKzqgUargAqnsI2BRc8jBZqVYF5E,35665
45
45
  infrahub/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  infrahub/constants/database.py,sha256=WmV1iuOk4xulxZHOVvO3sS_VF1eTf7fKh0TPe_RnfV4,507
47
47
  infrahub/context.py,sha256=8SZRKSECkkcsNNzDaKEUJ7Nyr0EzUfToAy969LXjQVk,1554
@@ -56,12 +56,12 @@ infrahub/core/changelog/diff.py,sha256=0BxCpsgJ-38x5BBz5XDtAvc9FPy82M0NlzXl8nQ-c
56
56
  infrahub/core/changelog/models.py,sha256=UgfJdOFUkMmjeUKe1mPCO7WE3jNENw0UJU3LWFf20HQ,29920
57
57
  infrahub/core/constants/__init__.py,sha256=Q2pEX_-Z1-TE5OM_PWKIPIvAOxuYzk2cWZnFjemkT2k,8618
58
58
  infrahub/core/constants/database.py,sha256=lxesWX2z6SZgGok1bAY6_pCBm5rFfu7k4ayMBr6w_Vo,336
59
- infrahub/core/constants/infrahubkind.py,sha256=08iJTK_RMMHbyF67bZLAIZFYiWaDv_IxU6Al53LPE6s,2492
59
+ infrahub/core/constants/infrahubkind.py,sha256=lrSae8gu4EOXaDHxX1jDkENkfr0fw5t32FP-vdXLrRs,2544
60
60
  infrahub/core/constants/relationship_label.py,sha256=AWbWghu5MoAKg2DBE-ysdzSOXnWoWdBn98zpIHzn_co,87
61
61
  infrahub/core/constants/schema.py,sha256=uuddQniyGlSlvKjM5mQ_V2VhgZmQ8fUCAHysbZLvTEU,2006
62
62
  infrahub/core/constraint/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
63
  infrahub/core/constraint/node/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
- infrahub/core/constraint/node/runner.py,sha256=l60GfQxqn6OaLUvfVYddsWor9qy2NiMY_0avnIb_Heg,1848
64
+ infrahub/core/constraint/node/runner.py,sha256=43ngwnu6fvxzdX0ZUUCSTzGtKBc8fSRSGSX1sovZvxQ,1863
65
65
  infrahub/core/diff/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  infrahub/core/diff/artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
67
  infrahub/core/diff/artifacts/calculator.py,sha256=qk1DspB3bkKeWJFesLbmziCALVnbRadjrez1kn_IZWU,4435
@@ -113,11 +113,11 @@ infrahub/core/diff/query/save.py,sha256=j0YuT_V5kZUHIuD6CXT8bcIVv3fewAckqcuukDYn
113
113
  infrahub/core/diff/query/summary_counts_enricher.py,sha256=dSmbmbvLx8SE1DyAAw4mbLyW5BWLbMrYOnEchA2uBZc,10239
114
114
  infrahub/core/diff/query/time_range_query.py,sha256=0pjsFBur8jcSU6su-iA4IMjnHw3RtNWI787wAPcyepI,3003
115
115
  infrahub/core/diff/query/update_conflict_query.py,sha256=kQkFazz88wnApr8UU_qb0ruzhmrhWiqhbErukSAMhLA,1212
116
- infrahub/core/diff/query_parser.py,sha256=RWA_noQ4Wm5Zhb-XvEe0UwFBI36lENgavCVqYOjNzms,37102
116
+ infrahub/core/diff/query_parser.py,sha256=6OWI_ynplysO6VH1vCfqiV_VmXvAfoa-bIRJ7heVTjY,37217
117
117
  infrahub/core/diff/repository/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
118
118
  infrahub/core/diff/repository/deserializer.py,sha256=bhN9ao8HxqKyRz273QGLNV9z9_SS4EQnM9JoY5ptx78,21337
119
119
  infrahub/core/diff/repository/repository.py,sha256=b54YvGDaFg3FEDNjOTS-WC3Rvtq4bdpDb1NGEKURnqg,25851
120
- infrahub/core/diff/tasks.py,sha256=kHapEy7isn9zGsThYFauDkDnG-dIODanBaa-TaFD9EY,3278
120
+ infrahub/core/diff/tasks.py,sha256=7_k-ZNcJZsiDp-xCZvCQfPJjg0xRxpaGTiVVNuRPfBI,3322
121
121
  infrahub/core/enums.py,sha256=qGbhRVoH43Xi0iDkUfWdQiKapJbLT9UKsCobFk_paIk,491
122
122
  infrahub/core/graph/__init__.py,sha256=Oqh1AEiVhTvWd71qOpyM6Qfxj59fjCI5OQE4mxZgDlM,19
123
123
  infrahub/core/graph/constraints.py,sha256=lmuzrKDFoeSKRiLtycB9PXi6zhMYghczKrPYvfWyy90,10396
@@ -195,19 +195,19 @@ infrahub/core/node/delete_validator.py,sha256=mj_HQXkTeP_A3po65-R5bCJnDM9CmFFmcU
195
195
  infrahub/core/node/ipam.py,sha256=NWb3TUlVQOGAzq1VvDwISLh61HML0jnalsJ7QojqGwQ,2669
196
196
  infrahub/core/node/permissions.py,sha256=uQzQ62IHcSly6fzPre0nQzlrkCIKzH4HyQkODKB3ZWM,2207
197
197
  infrahub/core/node/resource_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
198
- infrahub/core/node/resource_manager/ip_address_pool.py,sha256=M5Kgx56VvT61TTQaYf4NLSF1z6UGUxvKMhRYDhVkapU,4678
199
- infrahub/core/node/resource_manager/ip_prefix_pool.py,sha256=L7Psmcto5kHRd3AVt6JGUK-3-tQoG1gnAK3UUDi_dCs,4895
198
+ infrahub/core/node/resource_manager/ip_address_pool.py,sha256=-UQT5kaXSNK-sp7KnT0lsqOg1G3P1uFX0zX5OcHzj48,4831
199
+ infrahub/core/node/resource_manager/ip_prefix_pool.py,sha256=HRonATGel6Hk8svPv_I_OZx3VY33nx5jEkWsLbwpQaU,5048
200
200
  infrahub/core/node/resource_manager/number_pool.py,sha256=6mczrHTNd8jbXoW8Q6xHpBWi-JOSk5QSlwOegkMbNEQ,2479
201
201
  infrahub/core/node/standard.py,sha256=Niyc7mNxEGn6K7a1MXHkiLJhyTNR3uvTWLLbHvm6-Bo,7113
202
202
  infrahub/core/path.py,sha256=qHoC5cJwb3nwh-kUiuWqrCgkN2Dleatygn3KNid70sg,5844
203
203
  infrahub/core/property.py,sha256=rwsqeaIvCMkHfJYl4WfsNPAS7KS0POo5rAN7vAprXGA,5102
204
- infrahub/core/protocols.py,sha256=VvKNvfJxoQiaTF26Jam_6Yi_1GsGzGtuoZrFN5rxevA,11001
204
+ infrahub/core/protocols.py,sha256=iSw8cKxKo6EWapvnV5bG-D42kjI0zUu0Z7_HLTcLCgw,11084
205
205
  infrahub/core/protocols_base.py,sha256=IqX1C82C4skCJrNiVLSYCIwIviPfp2sP7bOS6rLxhTk,3296
206
206
  infrahub/core/query/__init__.py,sha256=ftH8xHCAo8DfdYEx3-CBPuU2xpGOc83_ITNxZ4q4sNg,23055
207
207
  infrahub/core/query/attribute.py,sha256=DzwbElgTaZs6-nBYGmnDpBr9n0lmUPK3p7eyI30Snh8,11783
208
208
  infrahub/core/query/branch.py,sha256=Fqycgk8kzhmc1H_-gfiw3c-ZjNjAHw64XU7OQUkhDi0,4976
209
209
  infrahub/core/query/delete.py,sha256=_PL97nz-ybF0JqDSYlTPhIa4oCxwPiFerwd8Wjw-x-8,1918
210
- infrahub/core/query/diff.py,sha256=7kIJjSUa4mBNdis5WhlYgwu37JEDEoXFXtjL93jkSTw,35899
210
+ infrahub/core/query/diff.py,sha256=9kur4wyab7XdI8bD3ff0gqVcA1TWIVRJex237JB_BA4,36138
211
211
  infrahub/core/query/ipam.py,sha256=66snB2ANAUcGk-Ke88Y1CIoXO7CCBOsOx8JZTFXnPfA,28384
212
212
  infrahub/core/query/node.py,sha256=AAO20pbFy_rk9RKRIQ1DCKrUEYr7yz1fCTcgiKEu22s,65411
213
213
  infrahub/core/query/relationship.py,sha256=Z9qlhqr-EfyQ8Mcg4SfqaTmngfVyj1RCjhTTGJXmkX0,46296
@@ -232,7 +232,7 @@ infrahub/core/schema/basenode_schema.py,sha256=4px_CJjhjT7m5eGVDXRT0VVLhJ9m3M85Z
232
232
  infrahub/core/schema/computed_attribute.py,sha256=9rznZJpGqX8fxLx0EguPmww8LoHsadMtQQUKaMoJPcI,1809
233
233
  infrahub/core/schema/constants.py,sha256=KtFrvwNckyKZSGIMD4XfxI5eFTZqBRiw54R7BE5h39Q,374
234
234
  infrahub/core/schema/definitions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
235
- infrahub/core/schema/definitions/core/__init__.py,sha256=4-26SV_yzXYgsgbn4DxiQQI6TN_BGfOuq8-RsnNr-_o,4640
235
+ infrahub/core/schema/definitions/core/__init__.py,sha256=RdrpFVFxprxvEfOIvffNgfju4W65QgadTW2QurJemJ0,4731
236
236
  infrahub/core/schema/definitions/core/account.py,sha256=5-yJJJRtAi1MyJZw88pyTqAklUPTsBzMa2LZkf4FtOs,5421
237
237
  infrahub/core/schema/definitions/core/artifact.py,sha256=6TX4zgK2j2vO7F0lCYLv6Bu7GTAKlD0P3rO7yuXX85o,3954
238
238
  infrahub/core/schema/definitions/core/builtin.py,sha256=eSGZXXV_caLm2WHvRsK6c88EfLjkMlm7VAZ-JVAaEPw,703
@@ -250,7 +250,7 @@ infrahub/core/schema/definitions/core/propose_change.py,sha256=zAmZuhKtTTTVfURkz
250
250
  infrahub/core/schema/definitions/core/propose_change_comment.py,sha256=tCYy0uazr4bOeQeuOHtN-v1ilLxaIO9T7fxkr4mLmDQ,5743
251
251
  infrahub/core/schema/definitions/core/propose_change_validator.py,sha256=IwrEQvutsxSFcDrcAFoevCzkwnPF3E6iyF0lUOi61RM,9947
252
252
  infrahub/core/schema/definitions/core/repository.py,sha256=SZDztZRCqdAOXgURaZk1X-OPGXqBMrVur8_DhPcwQ_E,9630
253
- infrahub/core/schema/definitions/core/resource_pool.py,sha256=Vr6CXpDInK4AlQCtwcWBAoZ5TDe3U_mruwEzT41iHZk,5411
253
+ infrahub/core/schema/definitions/core/resource_pool.py,sha256=1xE3xAc4wMJCutID4S_TOY6WlM4mCGsIUYZLqb8aYuM,6066
254
254
  infrahub/core/schema/definitions/core/template.py,sha256=rgYhpimxW0vhTmpo5cv_QA2I6MFT4r_ED7xA4BtzdKY,1037
255
255
  infrahub/core/schema/definitions/core/transform.py,sha256=UB2TaBjabIiErivBR16srxq7fgYoKjmjZaVun8vxXvY,3061
256
256
  infrahub/core/schema/definitions/core/webhook.py,sha256=YHeFMdsQDoG804iO6beozkfzln5cZnXKAsjB0Twlqw0,4224
@@ -306,13 +306,13 @@ infrahub/core/validators/relationship/count.py,sha256=097U8nv52Txnx5fgWNiIX56-Lg
306
306
  infrahub/core/validators/relationship/optional.py,sha256=FFAUjS9TT-IM7qO6YhMQWLcI9S-CwtBSpoD0AdWsPls,4369
307
307
  infrahub/core/validators/relationship/peer.py,sha256=pg6dzv_aBvu2DOqKUXuyPa2IsoW0TYQU-tR2NMOJmAw,5609
308
308
  infrahub/core/validators/shared.py,sha256=dhCz2oTM5JxA3mpcQvN83KIKIv-VNPSiG0lh4ZiTAFw,1345
309
- infrahub/core/validators/tasks.py,sha256=6UkGxLo00UZm13_fIiDmOnuDT5r8M415AQTfEFZ4hsY,3471
309
+ infrahub/core/validators/tasks.py,sha256=2lnF1o5YfhST7n9DyFoCKYkiTaV1NzX5nVOlBJbeoPY,3485
310
310
  infrahub/core/validators/uniqueness/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
311
311
  infrahub/core/validators/uniqueness/checker.py,sha256=RpiLpIjbdkwwjivry-vjEkVim6ZoC-t2H5Bal7ngASQ,10375
312
312
  infrahub/core/validators/uniqueness/index.py,sha256=Jw1o-UVinQquNduZ5vCCzt8GUfIEdVzBo-1XyRti8F8,5068
313
313
  infrahub/core/validators/uniqueness/model.py,sha256=V2aejcuHPhgC5nTrS7xX0JFMzprVu90QAau-rUzruCY,5135
314
314
  infrahub/core/validators/uniqueness/query.py,sha256=NudW0JziATlCloFOFIyoABeu1IGvCl2ug9itEmXS500,11843
315
- infrahub/database/__init__.py,sha256=yDdkliw-BS7aj7akxvURIoaS_LCgBaz2vss_I9O0dH8,20544
315
+ infrahub/database/__init__.py,sha256=R-Hc5qOlWdPex_4mDTDPDw9N2_9prOXCP90mQDvk-VE,20564
316
316
  infrahub/database/index.py,sha256=ATLqw9Grqbq7haGGm14VSEPmcPniid--YATiffo4sA0,1676
317
317
  infrahub/database/memgraph.py,sha256=Fg3xHP9s0MiBBmMvcEmsJvuIUSq8U_XCS362HDE9d1s,1742
318
318
  infrahub/database/metrics.py,sha256=xU4OSKFbsxcw_yZlt_39PmGtF7S7yPbPuOIlSCu5sI0,739
@@ -408,7 +408,7 @@ infrahub/graphql/analyzer.py,sha256=LNdNbgCKWc50rwO3VrmbchRgYy6GvSDcRFdZXXmM_pI,
408
408
  infrahub/graphql/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
409
409
  infrahub/graphql/api/dependencies.py,sha256=-NMUA_N4tWcVpS6ksCebAyza-JTmHqyYY_QZizgBR1c,1690
410
410
  infrahub/graphql/api/endpoints.py,sha256=wH9eO3CFT-eoSe1Y32BhU9mIf6smEnPeP3tAxZkdt4g,1510
411
- infrahub/graphql/app.py,sha256=hpOxYacCjq2E97zzhP4XJllkpUgN5vkf9Pe_X3LJnNs,20990
411
+ infrahub/graphql/app.py,sha256=4xKptosI6SXlBfQSNJHHGNrdCRAZQ2uMTpPPKY3_mzE,21004
412
412
  infrahub/graphql/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
413
413
  infrahub/graphql/auth/query_permission_checker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
414
414
  infrahub/graphql/auth/query_permission_checker/anonymous_checker.py,sha256=ibsmGyOelLJbN2Kfkmffv-5D79h7tRc1Fez5tauFY8w,1377
@@ -424,8 +424,8 @@ infrahub/graphql/directives.py,sha256=wyIkJFp7l0J4JqNl1Lqu7YfKXP7glrewlQFMDTUAPc
424
424
  infrahub/graphql/enums.py,sha256=9F0XWfjQpC__0YRccYG1T-3qL1V8_PmlRlVpU1-n7nQ,820
425
425
  infrahub/graphql/initialization.py,sha256=e97vYE7lQZm7OJxJrhKA6kdxKJ4QOcVbTpoNHq9fweM,4446
426
426
  infrahub/graphql/loaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
427
- infrahub/graphql/loaders/node.py,sha256=ciATamtiU1-yHrvqnScjYlLRJJX2lyxlaDZVIXlL-7E,2604
428
- infrahub/graphql/loaders/peers.py,sha256=fOdgaaPBtBiiLKg8Rws4zXvpyCzUhszgxhDAeXkzETA,2785
427
+ infrahub/graphql/loaders/node.py,sha256=p7qJxRpXSAddq2fcwJeaIRy-5ReSn2EUitQbDhlmdM4,2618
428
+ infrahub/graphql/loaders/peers.py,sha256=wsB-ZtaU-BlR99EvWUbf6_SFhFJYOspz5QaTln_MZ4Q,2799
429
429
  infrahub/graphql/loaders/shared.py,sha256=hUxLy8iVgfpEZiUMKNkUAeshPKKzEVSDMDsuaBbjJW4,389
430
430
  infrahub/graphql/manager.py,sha256=1q3HcaIcg82-t7dq0M3uIAihmVka-7w2KKsols5UMww,45222
431
431
  infrahub/graphql/metrics.py,sha256=viq_M57mDYd4DDK7suUttf1FJTgzQ3U50yOuSw_Nd-s,2267
@@ -449,7 +449,7 @@ infrahub/graphql/mutations/node_getter/by_default_filter.py,sha256=_owbYHXWqJ6x4
449
449
  infrahub/graphql/mutations/node_getter/by_hfid.py,sha256=txpj4xPeL3eYOB9lRiHEFxxcRf6bb6lyIJnhVCHr3x8,3120
450
450
  infrahub/graphql/mutations/node_getter/by_id.py,sha256=azERy5XBUe4fYf4t1rhKEn64MlGfm_zH4k-tJU6W69s,856
451
451
  infrahub/graphql/mutations/node_getter/interface.py,sha256=3MVTz_3EQnI7REp-ytQvgJuEgWUmrmnRIqKpP8WHCyY,419
452
- infrahub/graphql/mutations/proposed_change.py,sha256=TyZF3adwbB517iVoOL5HC8ifGxddlcUciHxqJ9k55T0,10117
452
+ infrahub/graphql/mutations/proposed_change.py,sha256=i56UkD0URwLykiOQPcVSnhsjBaoLUaKJvWFzGBJsmU0,10123
453
453
  infrahub/graphql/mutations/relationship.py,sha256=b-zi8O0JZo52zVoGabIrWvIFh64PbhHzjF9klZ7p8ac,20139
454
454
  infrahub/graphql/mutations/repository.py,sha256=Whrt1uYWt7Ro6omJYN8zc3D-poZ6bOBrpBHIG4odAmo,11316
455
455
  infrahub/graphql/mutations/resource_manager.py,sha256=Nykdo4pIJ9BOossg24-dw_nU71qelYki896NIJk5O5I,8924
@@ -466,22 +466,22 @@ infrahub/graphql/queries/diff/tree.py,sha256=4XcHIMDtJLA6nDBzGNn2WR_HeY_7lrmIU38
466
466
  infrahub/graphql/queries/event.py,sha256=9kHi37WmM4bwGgnIPaPLVOaXp124tn10v60kNx5C7aU,4204
467
467
  infrahub/graphql/queries/internal.py,sha256=pcGLpLrY1fC_HxHNs8NAFjr5FTFzcgRlS1F7b65gqfE,647
468
468
  infrahub/graphql/queries/ipam.py,sha256=peN--58IhLgS06O44AEthefEkaVDc7f38Sib3JyGKu4,4106
469
- infrahub/graphql/queries/relationship.py,sha256=zeejoyxG4DD5hxfBKEpuxqMCrS9fNRZPNA48pU3XhPk,2568
469
+ infrahub/graphql/queries/relationship.py,sha256=QaSqr42NHW5wCbgHiYTI9Bgo7Qov9I0-jO8xcj-RBlU,2582
470
470
  infrahub/graphql/queries/resource_manager.py,sha256=VqULXcLZBgkisQOkuFRP-YtgAdkRxvifpcDyY9dzrNQ,14932
471
471
  infrahub/graphql/queries/search.py,sha256=0_yp6yxPSy8TQoTmp6zpc3u0b1TRuGgUOiMTfZo6LqU,4958
472
472
  infrahub/graphql/queries/status.py,sha256=4GtTKOUBsVSHdPoWbGAka52V99iz39fsrgmWgm8HoIY,2116
473
- infrahub/graphql/queries/task.py,sha256=i9OnZxa2dlMJ9T2aQzacCmsIE3eDrKlG1HdCXs2p-DU,3553
473
+ infrahub/graphql/queries/task.py,sha256=-b443BY8XlE03F-RUcH3mxX_veuQP8Jf2GLCWKrAtWc,3914
474
474
  infrahub/graphql/resolvers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
475
- infrahub/graphql/resolvers/many_relationship.py,sha256=Tq63gVz45iKnTT6Uj0-rVFuj7m8jnLcJzddZZWVnFzQ,9707
476
- infrahub/graphql/resolvers/resolver.py,sha256=ERHNGpXEUsGI3LVFRC4tNsHDJV48MIbvY6UWqQBmZNA,11874
477
- infrahub/graphql/resolvers/single_relationship.py,sha256=ncxRrl48uo1DAFjtL2QIJZTsqWSs0cMchsolzvVA-Po,6948
475
+ infrahub/graphql/resolvers/many_relationship.py,sha256=B9D0cXlVIFntp7tDeZsvMjq30dsJpVRMCdLbeK9sqdI,9763
476
+ infrahub/graphql/resolvers/resolver.py,sha256=CgCfeARqwp9khmqdyq5G0W9q1Xvr6XapnSdWr-IW404,11930
477
+ infrahub/graphql/resolvers/single_relationship.py,sha256=TODob8c54RJmtrDjel-KU9XUv-zncvdmvtYP2_AcjoU,6976
478
478
  infrahub/graphql/schema.py,sha256=ekON1ic2MVHSMG_yrHJ9Zfclo2dpVOpZ3IWdpgv4G_g,3691
479
479
  infrahub/graphql/subscription/__init__.py,sha256=rVgLryqg-kbzkd3Dywb1gMPsthR8wFqB7nluuRKKfrE,1154
480
480
  infrahub/graphql/subscription/events.py,sha256=tDg9fy66dLmbXaf_9YC-3LmC1sqsj-smbq_LOsHdZ5Y,1838
481
- infrahub/graphql/subscription/graphql_query.py,sha256=gXCVYmS4z419umnIJbwm2bNjy7E0XtSlQRF0OCqbpOE,2238
481
+ infrahub/graphql/subscription/graphql_query.py,sha256=U9PwREMghxbuIoGWh3_rV33wKPzDyMILZ8_tuniwukg,2266
482
482
  infrahub/graphql/types/__init__.py,sha256=oP4DhYAteHkc8LiQsIRHE1q2jaksfc-VvAO1urkmI4k,1895
483
483
  infrahub/graphql/types/attribute.py,sha256=bc2q44q8j5DTNdwBMe0SgG7Rbk8si1h-8SyqGIa-Rn0,6594
484
- infrahub/graphql/types/branch.py,sha256=8iaE3Zyo0PMIRm0Hcgwdli09po1YbIUFJBpZaFGZWJE,1409
484
+ infrahub/graphql/types/branch.py,sha256=CUYvw02AovhfJVi14QQvFMytB2zBSQqC_zJqmp5kv1Q,1423
485
485
  infrahub/graphql/types/common.py,sha256=3I3p1bPOorwWgTqKbHqcDB7AvNG0JMdRyzIGxUrrREA,401
486
486
  infrahub/graphql/types/context.py,sha256=PrgEOGq0ERAsbFFNDA40WMlids72StbL2q88nGW46cQ,405
487
487
  infrahub/graphql/types/enums.py,sha256=Va-39ysZXciR8arQGqRZo9piKb5b0oufUl6uiyijwNc,383
@@ -492,7 +492,7 @@ infrahub/graphql/types/permission.py,sha256=zptTaTR-ndIbcb8AEwBXm-TRxgr400T8untx
492
492
  infrahub/graphql/types/relationship.py,sha256=2Bs-cRbP4ihY8gelaLnNNgBUdY1SBFZkkwien-qWgOI,436
493
493
  infrahub/graphql/types/standard_node.py,sha256=6OnB0U2QW0PyCDV2cyvHye4-g7agnTuD4HyQ4Q6x_gw,1821
494
494
  infrahub/graphql/types/task.py,sha256=ozjcm24Qj81JmiR2scW5APlPGs__dhFIGjlqzYXSnoo,1439
495
- infrahub/graphql/types/task_log.py,sha256=Z3EFUpBM13QWZm8J8vCIlqr3qS9bmhUSIApsfw2SiIc,684
495
+ infrahub/graphql/types/task_log.py,sha256=jqB2SzIDVaVHRKbe10IFOvbzUv4pbTv-lb0ydwkdt7w,753
496
496
  infrahub/graphql/utils.py,sha256=cVnF_FNR2-R8TnxxgKVgwjC6N1tXSChg5A8sKeMvE9g,3859
497
497
  infrahub/groups/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
498
498
  infrahub/groups/ancestors.py,sha256=ORNXupyZLOhtuQ-TxToONqJn-2OHFBPGubz-2cQpSwc,981
@@ -533,7 +533,7 @@ infrahub/message_bus/operations/git/__init__.py,sha256=0Fbz1AnU8lWKdX7PS_b0BvjiK
533
533
  infrahub/message_bus/operations/git/file.py,sha256=uW1dXVCMrQNC5-DFrVJ6PvfU47CQ2CQJec-bOXoBkjc,1472
534
534
  infrahub/message_bus/operations/git/repository.py,sha256=eQ6csfEoCbyOTAgoA5mzHerW8-TlbrQaZQ4Htj6qZu8,2432
535
535
  infrahub/message_bus/operations/refresh/__init__.py,sha256=vBuvTL4zRRpOMXATmckQ3bx2GnNwhxicFECA8-8ZZXk,47
536
- infrahub/message_bus/operations/refresh/registry.py,sha256=AWyIVoh7DvwqD_ihPAa6zbPogUGBZcz8tzTJpySoiUY,1301
536
+ infrahub/message_bus/operations/refresh/registry.py,sha256=dfLLISZ8qxwxFbGD5CaNguTicZBmACPMa82q6lAVXsM,1315
537
537
  infrahub/message_bus/operations/requests/__init__.py,sha256=7BWa2wc4XSNk13zySOEUdFfcaldSIZT6WXdR6eDxk-U,131
538
538
  infrahub/message_bus/operations/requests/generator_definition.py,sha256=AE2x0NiGoyqD5PYp7XmmjzD23SqNCTyzI8KwcTcVurg,6093
539
539
  infrahub/message_bus/operations/requests/proposed_change.py,sha256=fILCF3QnsU2c8UAhDyYBjXbfFvj0QF6xbF37A7lLUPM,23044
@@ -609,7 +609,7 @@ infrahub/task_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
609
609
  infrahub/task_manager/constants.py,sha256=1t1BZRa8_y89gIDPNHzIbRKo63nHOP37-r5OvtHa56c,559
610
610
  infrahub/task_manager/event.py,sha256=Dx6LHRMsx1B1BFz9HIyPqhujAK2DR-JjRB7RJVAH3ik,11091
611
611
  infrahub/task_manager/models.py,sha256=98hoEqScfwQVc-Col_rZE5UISccYlb-1fgT3nKklZSk,8100
612
- infrahub/task_manager/task.py,sha256=yKZuQ8p6Q8dWECTH9jOITQdQb1RQlyAU3IG-8-ZO5Hc,11004
612
+ infrahub/task_manager/task.py,sha256=Rtb_v0D43jMRq7cmi0XMpMX-WHRPPMDmE67yqLXAJ3o,12390
613
613
  infrahub/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
614
614
  infrahub/tasks/artifact.py,sha256=AJTbD6hv2q0QIMkCvxUtC8L7n1-8Ka2nC5yo_rb7Rjo,1983
615
615
  infrahub/tasks/check.py,sha256=WEdktFP1XzahHtF6N782OnNFzkg5uX3KIeNFRy3NEUM,730
@@ -619,10 +619,10 @@ infrahub/tasks/recurring.py,sha256=RJO2zdzCU-38Kb81lmCUbFQOBhGui8qn2QizTV4vj9I,4
619
619
  infrahub/tasks/registry.py,sha256=o1ybJvkNOSpFBvqem6wkOrtxqm6nqnbDA7JcptP-aC8,3169
620
620
  infrahub/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
621
621
  infrahub/telemetry/constants.py,sha256=_5mJAZaT_wTCaF7Yzsd---Zn1N6GZkoP_954GK8K4-c,184
622
- infrahub/telemetry/database.py,sha256=0yqrfotO3lF-ij15v-tG1nxtoUJppXzHaKubN0Jw9CQ,3097
622
+ infrahub/telemetry/database.py,sha256=9UVPOxRionVF65jjo8slRIaNBOv-KMRzq7I-7fe3wZE,3111
623
623
  infrahub/telemetry/models.py,sha256=q3h_wSX0A2OZgDHo05TXTgcHrzDSxx8hSyqRKPGLvwc,1405
624
624
  infrahub/telemetry/task_manager.py,sha256=x7bUCQ2jXi93VWmrjKZHZTzR3JhD7r0OhhqK7ymCnAM,2864
625
- infrahub/telemetry/tasks.py,sha256=fqzDjgeluBuQY_3hO6BLxShQb59B6GzHu8GTg6LEcAk,4443
625
+ infrahub/telemetry/tasks.py,sha256=8-eB6lCUOKCmy5SWFD5GAEu0Mz0T41aQWmENwGQbSfA,4457
626
626
  infrahub/telemetry/utils.py,sha256=K-gmj4QilO3HXAqJRzUwVcpqdA9KcM4RYJPU_zUYpHA,308
627
627
  infrahub/trace.py,sha256=Hir9hMWx_6IKF_dhDnMxYjusJdy0ycjB5CHWge2wXNE,3759
628
628
  infrahub/transformations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -771,8 +771,8 @@ infrahub_testcontainers/models.py,sha256=ASYyvl7d_WQz_i7y8-3iab9hwwmCl3OCJavqVbe
771
771
  infrahub_testcontainers/performance_test.py,sha256=hvwiy6tc_lWniYqGkqfOXVGAmA_IV15VOZqbiD9ezno,6149
772
772
  infrahub_testcontainers/plugin.py,sha256=g24SMg4EAqVe2N8i9F66EV34cNqIdDU4mRP7OeOJO1w,5381
773
773
  infrahub_testcontainers/prometheus.yml,sha256=610xQEyj3xuVJMzPkC4m1fRnCrjGpiRBrXA2ytCLa54,599
774
- infrahub_server-1.2.10.dist-info/LICENSE.txt,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
775
- infrahub_server-1.2.10.dist-info/METADATA,sha256=jIU3vIOb6nVuLMlEDps3sUh-jqgmD976HbR8g79bSiY,8194
776
- infrahub_server-1.2.10.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
777
- infrahub_server-1.2.10.dist-info/entry_points.txt,sha256=UXIeFWDsrV-4IllNvUEd6KieYGzQfn9paga2YyABOQI,393
778
- infrahub_server-1.2.10.dist-info/RECORD,,
774
+ infrahub_server-1.2.11.dist-info/LICENSE.txt,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
775
+ infrahub_server-1.2.11.dist-info/METADATA,sha256=Yg5ituzKXHWEo3K_-WUf45_fpZU5oVRm8HG6L13B1vE,8194
776
+ infrahub_server-1.2.11.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
777
+ infrahub_server-1.2.11.dist-info/entry_points.txt,sha256=UXIeFWDsrV-4IllNvUEd6KieYGzQfn9paga2YyABOQI,393
778
+ infrahub_server-1.2.11.dist-info/RECORD,,