infrahub-server 1.2.5__py3-none-any.whl → 1.2.6__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.
infrahub/core/manager.py CHANGED
@@ -803,8 +803,21 @@ class NodeManager:
803
803
 
804
804
  hfid_str = " :: ".join(hfid)
805
805
 
806
- if not node_schema.human_friendly_id or len(node_schema.human_friendly_id) != len(hfid):
807
- raise NodeNotFoundError(branch_name=branch.name, node_type=kind_str, identifier=hfid_str)
806
+ if not node_schema.human_friendly_id:
807
+ raise NodeNotFoundError(
808
+ branch_name=branch.name,
809
+ node_type=kind_str,
810
+ identifier=hfid_str,
811
+ message=f"Unable to lookup node by HFID, schema '{node_schema.kind}' does not have a HFID defined.",
812
+ )
813
+
814
+ if len(node_schema.human_friendly_id) != len(hfid):
815
+ raise NodeNotFoundError(
816
+ branch_name=branch.name,
817
+ node_type=kind_str,
818
+ identifier=hfid_str,
819
+ message=f"Unable to lookup node by HFID, schema '{node_schema.kind}' HFID does not contain the same number of elements as {hfid}",
820
+ )
808
821
 
809
822
  filters = {}
810
823
  for key, item in zip(node_schema.human_friendly_id, hfid, strict=False):
infrahub/core/registry.py CHANGED
@@ -222,7 +222,7 @@ class Registry:
222
222
 
223
223
  async def purge_inactive_branches(
224
224
  self, db: InfrahubDatabase, active_branches: list[Branch] | None = None
225
- ) -> list[str]:
225
+ ) -> set[str]:
226
226
  """Return a list of branches that were purged from the registry."""
227
227
  active_branches = active_branches or await self.branch_object.get_list(db=db)
228
228
  active_branch_names = [branch.name for branch in active_branches]
@@ -235,8 +235,7 @@ class Registry:
235
235
 
236
236
  purged_branches.update(self.schema.purge_inactive_branches(active_branches=active_branch_names))
237
237
  purged_branches.update(db.purge_inactive_schemas(active_branches=active_branch_names))
238
-
239
- return sorted(purged_branches)
238
+ return purged_branches
240
239
 
241
240
 
242
241
  registry = Registry()
@@ -1909,10 +1909,8 @@ class SchemaBranch:
1909
1909
 
1910
1910
  self.set(name=node_name, schema=node_schema)
1911
1911
 
1912
- def add_relationships_to_template(self, node: NodeSchema) -> None:
1912
+ def add_relationships_to_template(self, node: NodeSchema | GenericSchema) -> None:
1913
1913
  template_schema = self.get(name=self._get_object_template_kind(node_kind=node.kind), duplicate=False)
1914
- if template_schema.is_generic_schema:
1915
- return
1916
1914
 
1917
1915
  # Remove previous relationships to account for new ones
1918
1916
  template_schema.relationships = [
@@ -1954,6 +1952,7 @@ class SchemaBranch:
1954
1952
  label=f"{relationship.name} template".title()
1955
1953
  if relationship.kind in [RelationshipKind.COMPONENT, RelationshipKind.PARENT]
1956
1954
  else relationship.name.title(),
1955
+ inherited=relationship.inherited,
1957
1956
  )
1958
1957
  )
1959
1958
 
@@ -1983,9 +1982,6 @@ class SchemaBranch:
1983
1982
  need_template_kinds = [n.kind for n in need_templates]
1984
1983
 
1985
1984
  if node.is_generic_schema:
1986
- # When needing a template for a generic, we generate an empty shell mostly to make sure that schemas (including the GraphQL one) will
1987
- # look right. We don't really care about applying inheritance of fields as it was already processed and actual templates will have the
1988
- # correct attributes and relationships
1989
1985
  template = GenericSchema(
1990
1986
  name=node.kind,
1991
1987
  namespace="Template",
@@ -1994,43 +1990,44 @@ class SchemaBranch:
1994
1990
  generate_profile=False,
1995
1991
  branch=node.branch,
1996
1992
  include_in_menu=False,
1993
+ display_labels=["template_name__value"],
1994
+ human_friendly_id=["template_name__value"],
1995
+ uniqueness_constraints=[["template_name__value"]],
1997
1996
  attributes=[template_name_attr],
1998
1997
  )
1999
1998
 
2000
1999
  for used in node.used_by:
2001
2000
  if used in need_template_kinds:
2002
2001
  template.used_by.append(self._get_object_template_kind(node_kind=used))
2002
+ else:
2003
+ template = TemplateSchema(
2004
+ name=node.kind,
2005
+ namespace="Template",
2006
+ label=f"Object template {node.label}",
2007
+ description=f"Object template for {node.kind}",
2008
+ branch=node.branch,
2009
+ include_in_menu=False,
2010
+ display_labels=["template_name__value"],
2011
+ human_friendly_id=["template_name__value"],
2012
+ uniqueness_constraints=[["template_name__value"]],
2013
+ inherit_from=[InfrahubKind.LINEAGESOURCE, InfrahubKind.NODE, core_template_schema.kind],
2014
+ default_filter="template_name__value",
2015
+ attributes=[template_name_attr],
2016
+ relationships=[
2017
+ RelationshipSchema(
2018
+ name="related_nodes",
2019
+ identifier="node__objecttemplate",
2020
+ peer=node.kind,
2021
+ kind=RelationshipKind.TEMPLATE,
2022
+ cardinality=RelationshipCardinality.MANY,
2023
+ branch=BranchSupportType.AWARE,
2024
+ )
2025
+ ],
2026
+ )
2003
2027
 
2004
- return template
2005
-
2006
- template = TemplateSchema(
2007
- name=node.kind,
2008
- namespace="Template",
2009
- label=f"Object template {node.label}",
2010
- description=f"Object template for {node.kind}",
2011
- branch=node.branch,
2012
- include_in_menu=False,
2013
- display_labels=["template_name__value"],
2014
- human_friendly_id=["template_name__value"],
2015
- uniqueness_constraints=[["template_name__value"]],
2016
- inherit_from=[InfrahubKind.LINEAGESOURCE, InfrahubKind.NODE, core_template_schema.kind],
2017
- default_filter="template_name__value",
2018
- attributes=[template_name_attr],
2019
- relationships=[
2020
- RelationshipSchema(
2021
- name="related_nodes",
2022
- identifier="node__objecttemplate",
2023
- peer=node.kind,
2024
- kind=RelationshipKind.TEMPLATE,
2025
- cardinality=RelationshipCardinality.MANY,
2026
- branch=BranchSupportType.AWARE,
2027
- )
2028
- ],
2029
- )
2030
-
2031
- for inherited in node.inherit_from:
2032
- if inherited in need_template_kinds:
2033
- template.inherit_from.append(self._get_object_template_kind(node_kind=inherited))
2028
+ for inherited in node.inherit_from:
2029
+ if inherited in need_template_kinds:
2030
+ template.inherit_from.append(self._get_object_template_kind(node_kind=inherited))
2034
2031
 
2035
2032
  for node_attr in node.attributes:
2036
2033
  if node_attr.unique or node_attr.read_only:
@@ -2038,7 +2035,7 @@ class SchemaBranch:
2038
2035
 
2039
2036
  attr = AttributeSchema(
2040
2037
  optional=node_attr.optional if is_autogenerated_subtemplate else True,
2041
- **node_attr.model_dump(exclude=["id", "unique", "optional", "read_only", "inherited"]),
2038
+ **node_attr.model_dump(exclude=["id", "unique", "optional", "read_only"]),
2042
2039
  )
2043
2040
  template.attributes.append(attr)
2044
2041
 
@@ -394,8 +394,10 @@ class InfrahubDatabase:
394
394
  with QUERY_EXECUTION_METRICS.labels(**labels).time():
395
395
  response = await self.run_query(query=query, params=params, name=name)
396
396
  if response is None:
397
+ span.set_attribute("rows", "empty")
397
398
  return [], {}
398
399
  results = [item async for item in response]
400
+ span.set_attribute("rows", len(results))
399
401
  return results, response._metadata or {}
400
402
 
401
403
  async def run_query(
@@ -113,6 +113,16 @@ class GraphQLSchemaManager:
113
113
  def clear_cache(cls) -> None:
114
114
  cls._branch_details_by_name = {}
115
115
 
116
+ @classmethod
117
+ def purge_inactive(cls, active_branches: list[str]) -> set[str]:
118
+ """Return inactive branches that were purged"""
119
+ inactive_branches: set[str] = set()
120
+ for branch_name in list(cls._branch_details_by_name):
121
+ if branch_name not in active_branches:
122
+ inactive_branches.add(branch_name)
123
+ del cls._branch_details_by_name[branch_name]
124
+ return inactive_branches
125
+
116
126
  @classmethod
117
127
  def _cache_branch(
118
128
  cls, branch: Branch, schema_branch: SchemaBranch, schema_hash: str | None = None
@@ -489,7 +489,8 @@ class InfrahubMutationMixin:
489
489
  we would update the node without rerunning uniqueness constraint.
490
490
  """
491
491
 
492
- schema_name = cls._meta.active_schema.kind
492
+ schema = cls._meta.active_schema
493
+ schema_name = schema.kind
493
494
 
494
495
  graphql_context: GraphqlContext = info.context
495
496
  db = database or graphql_context.db
@@ -509,10 +510,8 @@ class InfrahubMutationMixin:
509
510
  )
510
511
  return updated_obj, mutation, False
511
512
 
512
- if cls._meta.active_schema.default_filter is not None:
513
- node = await node_getter_default_filter.get_node(
514
- node_schema=cls._meta.active_schema, data=data, branch=branch
515
- )
513
+ if not schema.human_friendly_id and schema.default_filter is not None:
514
+ node = await node_getter_default_filter.get_node(node_schema=schema, data=data, branch=branch)
516
515
 
517
516
  if "hfid" in data:
518
517
  node = await NodeManager.get_one_by_hfid(db=db, hfid=dict_data["hfid"], kind=schema_name, branch=branch)
@@ -177,9 +177,9 @@ class InfrahubNumberPoolMutation(InfrahubMutationMixin, Mutation):
177
177
  database: InfrahubDatabase | None = None, # noqa: ARG003
178
178
  ) -> Any:
179
179
  try:
180
- pool_node = registry.get_node_schema(name=data["node"].value)
181
- except ValueError as exc:
182
- raise ValidationError(input_value="The selected model is not a Node") from exc
180
+ pool_node = registry.schema.get(name=data["node"].value)
181
+ if not pool_node.is_generic_schema and not pool_node.is_node_schema:
182
+ raise ValidationError(input_value="The selected model is not a Node or a Generic")
183
183
  except SchemaNotFoundError as exc:
184
184
  exc.message = "The selected model does not exist"
185
185
  raise exc
@@ -61,5 +61,8 @@ async def refresh_branches(db: InfrahubDatabase) -> None:
61
61
  )
62
62
 
63
63
  purged_branches = await registry.purge_inactive_branches(db=db, active_branches=branches)
64
- for branch_name in purged_branches:
64
+ purged_branches.update(
65
+ GraphQLSchemaManager.purge_inactive(active_branches=[branch.name for branch in branches])
66
+ )
67
+ for branch_name in sorted(purged_branches):
65
68
  log.info(f"Removed branch {branch_name!r} from the registry", branch=branch_name, worker=WORKER_IDENTITY)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: infrahub-server
3
- Version: 1.2.5
3
+ Version: 1.2.6
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
@@ -130,7 +130,7 @@ infrahub/core/ipam/reconciler.py,sha256=48do6rx12G25gaKuOguSrVdUDXVpMr3t6ogU1hdP
130
130
  infrahub/core/ipam/size.py,sha256=Iu7cVvN9MkilyG_AGvYm3g3dSDesKRVdDh_AKH7yAqk,614
131
131
  infrahub/core/ipam/tasks.py,sha256=TUoP6WZjQkd7DdGLxKnBVVH4SxTHkH2xmJCU8nRWqH8,1483
132
132
  infrahub/core/ipam/utilization.py,sha256=d-zpXCaWsHgJxBLopCDd7y4sJYvHcIzzpYhbTMIgH74,6733
133
- infrahub/core/manager.py,sha256=nE5IL3Hk1ro_4seIbofEdIer3kbVVBtdvmVTbQFAyek,46169
133
+ infrahub/core/manager.py,sha256=v-Owvn60w85TIHrAtt5C9OF5vGdpf88ElTMDMGVacxE,46671
134
134
  infrahub/core/merge.py,sha256=bZvToLKyphJlWMbQAzGuSHcrG2DfeqL69KSfqb1wWdc,10430
135
135
  infrahub/core/migrations/__init__.py,sha256=syPb3-Irf11dXCHgbT0UdmTnEBbpf4wXJ3m8ADYXDpk,1175
136
136
  infrahub/core/migrations/graph/__init__.py,sha256=CB4j35V5VRpJxnSJN_HOYzUv_cPMVCHwpFGYjWjhoaA,2608
@@ -210,7 +210,7 @@ infrahub/core/query/subquery.py,sha256=40MEDGSFPeXG6M4DpwfQfJMVqB_ET6WTMwhgueKV-
210
210
  infrahub/core/query/task.py,sha256=tLgn8S_KaLYLuOB66D1YM155teHZIHNThkt2iUiKKD4,3137
211
211
  infrahub/core/query/task_log.py,sha256=2RdthOAQrmpKZU8uhV_dJCPqwdsSA_1CYSKpL_eZ_yk,1120
212
212
  infrahub/core/query/utils.py,sha256=t9LMvZWdmi10c3E0HAU_5m7x5zMHhYXsUjX7ZBl2RpU,1091
213
- infrahub/core/registry.py,sha256=LJfLiqw1fUrPWTI8k-hL0KYTLnK2nBCkKJYX5PZtduY,8570
213
+ infrahub/core/registry.py,sha256=eSDFD8gbE1rasYIuLQDWlTKO06HVfuDsuEdT9uqn-6U,8560
214
214
  infrahub/core/relationship/__init__.py,sha256=broUBD0iwpSSGKJbUdG66uau67TQ_DRhqT_PFhuk1ag,154
215
215
  infrahub/core/relationship/constraints/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
216
216
  infrahub/core/relationship/constraints/count.py,sha256=4wSjiJtRd4fQ5qYNzGyWrt1WLV7x5Go2ZatMTtK79QQ,4157
@@ -261,7 +261,7 @@ infrahub/core/schema/manager.py,sha256=4lPjjtE_MtJ0acJdYAJEkuK4jap3NnTdxB5esEB71
261
261
  infrahub/core/schema/node_schema.py,sha256=ld_Wrqf-RsoEUVz_lKE0tcSf5n_oYZYtRI0lTqtd63o,6150
262
262
  infrahub/core/schema/profile_schema.py,sha256=cOPSOt5KLgQ0nbqrAN_o33hY_pUtrKmiwSbY_YpVolI,1092
263
263
  infrahub/core/schema/relationship_schema.py,sha256=lVbyQKMP2jPZZwZGK6DBvXdXfEQEsQGMbZ2WYxOZKTw,8261
264
- infrahub/core/schema/schema_branch.py,sha256=WcQlPi_UWspPMZ801b4biZcX8iOBSdEJEckIW_TiH9Y,97799
264
+ infrahub/core/schema/schema_branch.py,sha256=9ut8iS4nUCjY81lJiX0VVTNWEA4K6bfS4yWpQe9NSTA,97723
265
265
  infrahub/core/schema/schema_branch_computed.py,sha256=14UUsQJDLMHkYhg7QMqeLiTF3PO8c8rGa90ul3F2ZZo,10629
266
266
  infrahub/core/schema/template_schema.py,sha256=O-PBS9IRM4JX6PxeoyZKwqZ0u0SdQ2zxWMc01PJ2_EA,1084
267
267
  infrahub/core/task/__init__.py,sha256=Ied1NvKGJUDmff27z_-yWW8ArenHxGvSvQTaQyx1iHs,128
@@ -305,7 +305,7 @@ infrahub/core/validators/uniqueness/checker.py,sha256=RpiLpIjbdkwwjivry-vjEkVim6
305
305
  infrahub/core/validators/uniqueness/index.py,sha256=Jw1o-UVinQquNduZ5vCCzt8GUfIEdVzBo-1XyRti8F8,5068
306
306
  infrahub/core/validators/uniqueness/model.py,sha256=V2aejcuHPhgC5nTrS7xX0JFMzprVu90QAau-rUzruCY,5135
307
307
  infrahub/core/validators/uniqueness/query.py,sha256=em_DKmzv0kiKl6VhD9G4-LkrtuQj4mTxT5kc5ZgFv7M,10150
308
- infrahub/database/__init__.py,sha256=m8Rkw7byTaz6eoYp3N9QlyJIxHQW8x2KXfn16sSAgwI,20982
308
+ infrahub/database/__init__.py,sha256=CQek6w4hoihLP9ClNya_QZ-UquXZTf9F3iNKPNpZBUw,21095
309
309
  infrahub/database/constants.py,sha256=WmV1iuOk4xulxZHOVvO3sS_VF1eTf7fKh0TPe_RnfV4,507
310
310
  infrahub/database/index.py,sha256=y0sWXO3tdIr1wL1XC9O6iNRV-Elu2KAXFOiYXRIIhN4,1659
311
311
  infrahub/database/manager.py,sha256=BDXNw1RNBeSFV-EZd0aGFbPNuoqlKwrkDqmYB7sy4tU,317
@@ -422,7 +422,7 @@ infrahub/graphql/loaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
422
422
  infrahub/graphql/loaders/node.py,sha256=ciATamtiU1-yHrvqnScjYlLRJJX2lyxlaDZVIXlL-7E,2604
423
423
  infrahub/graphql/loaders/peers.py,sha256=fOdgaaPBtBiiLKg8Rws4zXvpyCzUhszgxhDAeXkzETA,2785
424
424
  infrahub/graphql/loaders/shared.py,sha256=hUxLy8iVgfpEZiUMKNkUAeshPKKzEVSDMDsuaBbjJW4,389
425
- infrahub/graphql/manager.py,sha256=3LKW3LRJE6ne7BiTFNHufw_4q0loB_esHrNMu4q1nH8,44777
425
+ infrahub/graphql/manager.py,sha256=1q3HcaIcg82-t7dq0M3uIAihmVka-7w2KKsols5UMww,45222
426
426
  infrahub/graphql/metrics.py,sha256=viq_M57mDYd4DDK7suUttf1FJTgzQ3U50yOuSw_Nd-s,2267
427
427
  infrahub/graphql/models.py,sha256=7kr3DSO_rujPocMIfPyZ5Hwy3Mpnu4ySDMAIE9G5Y7Y,147
428
428
  infrahub/graphql/mutations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -436,7 +436,7 @@ infrahub/graphql/mutations/diff_conflict.py,sha256=JngQfyKXCVlmtlqQ_VyabmrOEDOEK
436
436
  infrahub/graphql/mutations/generator.py,sha256=Ulw4whZm8Gc8lJjwfUFoFSsR0cOUliFKl87Oca4B9O0,3579
437
437
  infrahub/graphql/mutations/graphql_query.py,sha256=mp_O2byChneCihUrEAFEiIAgJ1gW9WrgtwPetUQmkJw,3562
438
438
  infrahub/graphql/mutations/ipam.py,sha256=wIN8OcTNCHVy32YgatWZi2Of-snFYBd4wlxOAJvE-AY,15961
439
- infrahub/graphql/mutations/main.py,sha256=QpB_iV4VFWYkUpk5tcSe0eFJXAn1YcwFruzNjyccvUY,26618
439
+ infrahub/graphql/mutations/main.py,sha256=EgO0U8U0FmgwuTrDrKuafSOWjO7pNR5YZzYYZbQMfec,26611
440
440
  infrahub/graphql/mutations/menu.py,sha256=u2UbOA-TFDRcZRGFkgYTmpGxN2IAUgOvJXd7SnsufyI,3708
441
441
  infrahub/graphql/mutations/models.py,sha256=ilkSLr8OxVO9v3Ra_uDyUTJT9qPOmdPMqQbuWIydJMo,264
442
442
  infrahub/graphql/mutations/node_getter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -447,7 +447,7 @@ infrahub/graphql/mutations/node_getter/interface.py,sha256=3MVTz_3EQnI7REp-ytQvg
447
447
  infrahub/graphql/mutations/proposed_change.py,sha256=TyZF3adwbB517iVoOL5HC8ifGxddlcUciHxqJ9k55T0,10117
448
448
  infrahub/graphql/mutations/relationship.py,sha256=b-zi8O0JZo52zVoGabIrWvIFh64PbhHzjF9klZ7p8ac,20139
449
449
  infrahub/graphql/mutations/repository.py,sha256=Whrt1uYWt7Ro6omJYN8zc3D-poZ6bOBrpBHIG4odAmo,11316
450
- infrahub/graphql/mutations/resource_manager.py,sha256=782N1iwAgtTpl0I-Y-ou16u_ModhccJ3F28tap-uD1E,8874
450
+ infrahub/graphql/mutations/resource_manager.py,sha256=Nykdo4pIJ9BOossg24-dw_nU71qelYki896NIJk5O5I,8924
451
451
  infrahub/graphql/mutations/schema.py,sha256=vOwP8SIcQxamhP_JwbeXPG5iOEwxHhHawgqU6bD-4us,12897
452
452
  infrahub/graphql/mutations/tasks.py,sha256=j2t5pMXRQ1i3ohQ-WjfDaDNQpj-CnFnqYCTZ3y5p7ec,3806
453
453
  infrahub/graphql/mutations/webhook.py,sha256=IW_WPpBRySd-mpbkuGnR28VpU9naM2bLZBjJOaAGuH4,4777
@@ -595,7 +595,7 @@ infrahub/tasks/check.py,sha256=WEdktFP1XzahHtF6N782OnNFzkg5uX3KIeNFRy3NEUM,730
595
595
  infrahub/tasks/dummy.py,sha256=6SxlQqQXZqgTuwLaAsK-p1O1TYNKfdGmUYjNJFNHe9s,1209
596
596
  infrahub/tasks/keepalive.py,sha256=D6yh3Vmlr1WCEpZibk2YLc2n0dCcX6tM62HCSxyGEu8,783
597
597
  infrahub/tasks/recurring.py,sha256=RJO2zdzCU-38Kb81lmCUbFQOBhGui8qn2QizTV4vj9I,447
598
- infrahub/tasks/registry.py,sha256=wox2lo8JoW8abirN0LFF3Qeerspthviq8yFVe-LDu2g,3017
598
+ infrahub/tasks/registry.py,sha256=o1ybJvkNOSpFBvqem6wkOrtxqm6nqnbDA7JcptP-aC8,3169
599
599
  infrahub/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
600
600
  infrahub/telemetry/constants.py,sha256=_5mJAZaT_wTCaF7Yzsd---Zn1N6GZkoP_954GK8K4-c,184
601
601
  infrahub/telemetry/database.py,sha256=0yqrfotO3lF-ij15v-tG1nxtoUJppXzHaKubN0Jw9CQ,3097
@@ -737,18 +737,18 @@ infrahub_sdk/uuidt.py,sha256=Tz-4nHkJwbi39UT3gaIe2wJeZNAoBqf6tm3sw7LZbXc,2155
737
737
  infrahub_sdk/yaml.py,sha256=L_sj5ds-0_uKe3aIfZu86kDLq8tffKzle9dcyDUTaEc,2937
738
738
  infrahub_testcontainers/__init__.py,sha256=oPpmesGgYBSdKTg1L37FGwYBeao1EHury5SJGul-CT8,216
739
739
  infrahub_testcontainers/constants.py,sha256=mZ4hLvcf4rKk9wC7EId4MQxAY0sk4V99deB04N0J2bg,85
740
- infrahub_testcontainers/container.py,sha256=FUkEVkPwUtYGfjHd6brLkI_3D4-qYmH5BGAOlyJrFU4,10652
741
- infrahub_testcontainers/docker-compose.test.yml,sha256=MqN8TPIAWNOZg93m_P2HH5etyYvtgYmwR92SyHR_GDQ,7017
740
+ infrahub_testcontainers/container.py,sha256=HMWCwQpXgNnUYhGDNr1yEdfAO-t-TDzG2RgkZ1ye4tc,12257
741
+ infrahub_testcontainers/docker-compose.test.yml,sha256=6zAf4sVr3cAfMtZgvKv8SX8uD9FolTsNFlhSfzs8eI0,8229
742
742
  infrahub_testcontainers/haproxy.cfg,sha256=QUkG2Xu-hKoknPOeYKAkBT_xJH6U9CfIS0DTMFZJsnk,1305
743
743
  infrahub_testcontainers/helpers.py,sha256=zsvBOql5qM2OX1ybPcklqF-nzWYHkZI3Gk3KZhxWOtU,3578
744
744
  infrahub_testcontainers/host.py,sha256=Z4_gGoGKKeM_HGVS7SdYL1FTNGyLBk8wzicdSKHpfmM,1486
745
745
  infrahub_testcontainers/measurements.py,sha256=gR-uTasSIFCXrwvnNpIpfsQIopKftT7pBiarCgIShaQ,2214
746
746
  infrahub_testcontainers/models.py,sha256=ASYyvl7d_WQz_i7y8-3iab9hwwmCl3OCJavqVbe8nXU,954
747
- infrahub_testcontainers/performance_test.py,sha256=PSE03jevzv63n-v5rxNIzuQsbtCR-pVqLVpJddjCHhs,6025
748
- infrahub_testcontainers/plugin.py,sha256=vk33oG44MA2zxZwqMsS8_CkScm5LwuwwFmSOtmeAdMU,5357
747
+ infrahub_testcontainers/performance_test.py,sha256=CZ0YeGqnc9RCEPPk5-jFh0b0zFz-DYweOBF-Lfo0bc8,6037
748
+ infrahub_testcontainers/plugin.py,sha256=g24SMg4EAqVe2N8i9F66EV34cNqIdDU4mRP7OeOJO1w,5381
749
749
  infrahub_testcontainers/prometheus.yml,sha256=610xQEyj3xuVJMzPkC4m1fRnCrjGpiRBrXA2ytCLa54,599
750
- infrahub_server-1.2.5.dist-info/LICENSE.txt,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
751
- infrahub_server-1.2.5.dist-info/METADATA,sha256=wnu7F6hrzd7PmzNKsQt9gNeSVanc9mj2Yyd-ZBGEtlo,8189
752
- infrahub_server-1.2.5.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
753
- infrahub_server-1.2.5.dist-info/entry_points.txt,sha256=UXIeFWDsrV-4IllNvUEd6KieYGzQfn9paga2YyABOQI,393
754
- infrahub_server-1.2.5.dist-info/RECORD,,
750
+ infrahub_server-1.2.6.dist-info/LICENSE.txt,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
751
+ infrahub_server-1.2.6.dist-info/METADATA,sha256=aH_88DkVv0zFyrXXGQaEESBXsfe7DFMoZy6vFjnJp2E,8189
752
+ infrahub_server-1.2.6.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
753
+ infrahub_server-1.2.6.dist-info/entry_points.txt,sha256=UXIeFWDsrV-4IllNvUEd6KieYGzQfn9paga2YyABOQI,393
754
+ infrahub_server-1.2.6.dist-info/RECORD,,
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import shutil
3
+ import time
3
4
  import uuid
4
5
  from dataclasses import dataclass, field
5
6
  from functools import cached_property
@@ -265,9 +266,58 @@ class InfrahubDockerCompose(DockerCompose):
265
266
  )
266
267
 
267
268
  self.exec_in_container(
268
- command=["cypher-shell", "-d", "system", "-u", "neo4j", "-p", "admin", "START DATABASE neo4j;"],
269
+ command=["chown", "-R", "neo4j:neo4j", "/data"],
269
270
  service_name=service_name,
270
271
  )
271
272
 
273
+ (restore_output, _, _) = self.exec_in_container(
274
+ command=[
275
+ "cypher-shell",
276
+ "--format",
277
+ "plain",
278
+ "-d",
279
+ "system",
280
+ "-u",
281
+ "neo4j",
282
+ "-p",
283
+ "admin",
284
+ "START DATABASE neo4j;",
285
+ ],
286
+ service_name=service_name,
287
+ )
288
+
289
+ for _ in range(3):
290
+ (stdout, _, _) = self.exec_in_container(
291
+ command=[
292
+ "cypher-shell",
293
+ "--format",
294
+ "plain",
295
+ "-d",
296
+ "system",
297
+ "-u",
298
+ "neo4j",
299
+ "-p",
300
+ "admin",
301
+ "SHOW DATABASES WHERE name = 'neo4j' AND currentStatus = 'online';",
302
+ ],
303
+ service_name=service_name,
304
+ )
305
+ if stdout:
306
+ break
307
+ time.sleep(5)
308
+ else:
309
+ (debug_logs, _, _) = self.exec_in_container(
310
+ command=["cat", "logs/debug.log"],
311
+ service_name=service_name,
312
+ )
313
+ raise Exception(f"Failed to restore database:\n{restore_output}\nDebug logs:\n{debug_logs}")
314
+
315
+ old_services = self.services
316
+ self.services = ["infrahub-server", "task-worker"]
272
317
  self.stop(down=False)
273
- self.start()
318
+ try:
319
+ self.start()
320
+ except Exception as exc:
321
+ stdout, stderr = self.get_logs()
322
+ raise Exception(f"Failed to start docker compose:\nStdout:\n{stdout}\nStderr:\n{stderr}") from exc
323
+ self.services = old_services
@@ -45,6 +45,11 @@ services:
45
45
  - ${INFRAHUB_TESTING_SERVER_PORT:-0}:8000
46
46
 
47
47
  database:
48
+ deploy:
49
+ resources:
50
+ limits:
51
+ cpus: ${INFRAHUB_TESTING_DB_CPU_LIMIT:-0.0}
52
+ memory: ${INFRAHUB_TESTING_DB_MEMORY_LIMIT:-0}
48
53
  image: ${NEO4J_DOCKER_IMAGE:-neo4j:5.20.0-community}
49
54
  restart: unless-stopped
50
55
  environment:
@@ -52,6 +57,8 @@ services:
52
57
  NEO4J_dbms_security_procedures_unrestricted: "apoc.*"
53
58
  NEO4J_dbms_security_auth__minimum__password__length: 4
54
59
  NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes"
60
+ NEO4J_dbms_memory_heap_initial__size: ${INFRAHUB_TESTING_DB_HEAP_INITIAL_SIZE}
61
+ NEO4J_dbms_memory_heap_max__size: ${INFRAHUB_TESTING_DB_HEAP_MAX_SIZE}
55
62
  volumes:
56
63
  - "database_data:/data"
57
64
  - "database_logs:/logs"
@@ -116,6 +123,13 @@ services:
116
123
  INFRAHUB_INITIAL_AGENT_TOKEN: ${INFRAHUB_TESTING_INITIAL_AGENT_TOKEN}
117
124
  INFRAHUB_SECURITY_SECRET_KEY: ${INFRAHUB_TESTING_SECURITY_SECRET_KEY}
118
125
  PREFECT_API_URL: ${INFRAHUB_TESTING_PREFECT_API}
126
+ # Tracing
127
+ INFRAHUB_TRACE_ENABLE: ${INFRAHUB_TRACE_ENABLE:-false}
128
+ INFRAHUB_TRACE_EXPORTER_ENDPOINT:
129
+ INFRAHUB_TRACE_EXPORTER_PROTOCOL: ${INFRAHUB_TRACE_EXPORTER_PROTOCOL:-grpc}
130
+ INFRAHUB_TRACE_EXPORTER_TYPE: ${INFRAHUB_TRACE_EXPORTER_TYPE:-console}
131
+ INFRAHUB_TRACE_INSECURE: ${INFRAHUB_TRACE_INSECURE:-true}
132
+ OTEL_RESOURCE_ATTRIBUTES:
119
133
  depends_on:
120
134
  database:
121
135
  condition: service_healthy
@@ -155,6 +169,13 @@ services:
155
169
  INFRAHUB_WORKFLOW_ADDRESS: ${INFRAHUB_TESTING_WORKFLOW_ADDRESS}
156
170
  INFRAHUB_TIMEOUT: ${INFRAHUB_TESTING_TIMEOUT}
157
171
  PREFECT_API_URL: ${INFRAHUB_TESTING_PREFECT_API}
172
+ # Tracing
173
+ INFRAHUB_TRACE_ENABLE: ${INFRAHUB_TRACE_ENABLE:-false}
174
+ INFRAHUB_TRACE_EXPORTER_ENDPOINT:
175
+ INFRAHUB_TRACE_EXPORTER_PROTOCOL: ${INFRAHUB_TRACE_EXPORTER_PROTOCOL:-grpc}
176
+ INFRAHUB_TRACE_EXPORTER_TYPE: ${INFRAHUB_TRACE_EXPORTER_TYPE:-console}
177
+ INFRAHUB_TRACE_INSECURE: ${INFRAHUB_TRACE_INSECURE:-true}
178
+ OTEL_RESOURCE_ATTRIBUTES:
158
179
  depends_on:
159
180
  - infrahub-server
160
181
  volumes:
@@ -187,6 +208,12 @@ services:
187
208
  - "--promscrape.config=/etc/prometheus/prometheus.yml"
188
209
  ports:
189
210
  - ${INFRAHUB_TESTING_SCRAPER_PORT:-0}:8428
211
+ healthcheck:
212
+ test: wget -qO- http://127.0.0.1:8428/-/healthy
213
+ start_period: 10s
214
+ interval: 5s
215
+ timeout: 5s
216
+ retries: 10
190
217
 
191
218
  volumes:
192
219
  database_data:
@@ -100,7 +100,7 @@ class InfrahubPerformanceTest:
100
100
  return self
101
101
 
102
102
  def fetch_metrics(self) -> None:
103
- with httpx.Client() as client:
103
+ with httpx.Client(timeout=30.0) as client:
104
104
  # Get Infrahub metrics
105
105
  response = client.post(
106
106
  url=self.scraper_endpoint,
@@ -125,7 +125,7 @@ def pytest_terminal_summary(
125
125
  performance_test = terminalreporter._session.infrahub_performance_test
126
126
 
127
127
  report = [
128
- f"{measurement.name}: {measurement.value} {measurement.unit.value}"
128
+ f"{measurement.name} ({measurement.context}): {measurement.value} {measurement.unit.value}"
129
129
  for measurement in performance_test.measurements
130
130
  ]
131
131
  terminalreporter.write("\n" + "\n".join(report) + "\n")