Skip to content

Commit

Permalink
Merge pull request #5377 from opsmill/dga-20250106-stable-develop
Browse files Browse the repository at this point in the history
Merge back stable into develop (1.1.1)
  • Loading branch information
dgarros authored Jan 6, 2025
2 parents 6044ca2 + 477b5c7 commit 137e07a
Show file tree
Hide file tree
Showing 34 changed files with 596 additions and 175 deletions.
14 changes: 14 additions & 0 deletions .github/file-filters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ yaml_all: &yaml_all
markdown_all: &markdown_all
- "**/*.{md,mdx}"

infrahub_reference_generated: &infrahub_reference_generated
- "docs/docs/reference/infrahub-cli/*.mdx"
- "docs/docs/reference/schema/*.mdx"
- "docs/docs/reference/dotinfrahub.mdx"
- "docs/docs/python-sdk/reference/config.mdx"
- "docs/docs/reference/message-bus-events.mdx"

infrahub_ctl_generated: &infrahub_ctl_generated
- "docs/docs/infrahubctl/*.mdx"

backend_all:
- *backend_files
- *ci_config
Expand All @@ -66,6 +76,10 @@ documentation_all:
- *doc_files
- *markdown_all

documentation_generated_all:
- *infrahub_reference_generated
- *infrahub_ctl_generated

release_all:
- *release_files

Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ jobs:
outputs:
backend: ${{ steps.changes.outputs.backend_all }}
documentation: ${{ steps.changes.outputs.documentation_all }}
documentation_generated: ${{ steps.changes.outputs.documentation_generated_all }}
release: ${{ steps.changes.outputs.release_all }}
frontend: ${{ steps.changes.outputs.frontend_all }}
helm: ${{ steps.changes.outputs.helm_all }}
Expand Down Expand Up @@ -446,7 +447,7 @@ jobs:
python-version: 3.12
- name: "Setup environment"
run: |
pipx install poetry
pipx install poetry==1.8.5
poetry config virtualenvs.prefer-active-python true
pip install invoke toml
- name: "Install Package"
Expand Down Expand Up @@ -540,7 +541,7 @@ jobs:
always() && !cancelled() &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled') &&
needs.files-changed.outputs.python == 'true'
(needs.files-changed.outputs.python == 'true') || (needs.files-changed.outputs.documentation_generated == 'true')
needs: ["files-changed", "yaml-lint", "python-lint"]
runs-on: "ubuntu-22.04"
timeout-minutes: 5
Expand All @@ -555,7 +556,7 @@ jobs:
python-version: "3.12"
- name: "Setup Python environment"
run: |
pipx install poetry
pipx install poetry==1.8.5
poetry config virtualenvs.create true --local
poetry env use 3.12
- name: "Install dependencies"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/poetry-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
python-version: "3.12"
- name: "Setup environment"
run: |
pipx install poetry
pipx install poetry==1.8.5
- name: "Validate pyproject.toml and consistency with poetry.lock"
run: |
poetry check
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
- name: "Install Poetry"
uses: "snok/install-poetry@v1"
with:
version: 1.8.5
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
- name: "Install Poetry"
uses: "snok/install-poetry@v1"
with:
version: 1.8.5
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-compose-file-and-chart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
python-version: 3.12
- name: "Setup environment"
run: |
pipx install poetry
pipx install poetry==1.8.5
poetry config virtualenvs.prefer-active-python true
- name: "Install Package"
run: "poetry install --all-extras"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/version-upgrade.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
python-version: 3.12
- name: "Setup python environment"
run: |
pipx install poetry
pipx install poetry==1.8.5
poetry config virtualenvs.prefer-active-python true
pip install invoke toml
- name: "Install Package"
Expand Down
3 changes: 2 additions & 1 deletion .vale/styles/Infrahub/spelling.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ message: "Did you really mean '%s'?"
level: error
filters:
- '[pP]y.*\b'
- '\bimport_.*\b' # New filter to ignore variables starting with 'import_'
- '\bimport_.*\b' # New filter to ignore variables starting with 'import_'
- '\w+__value' # New filter to skip Infrahub filters in documentation (name__value)
ignore: spelling-exceptions.txt
2 changes: 1 addition & 1 deletion .vale/styles/spelling-exceptions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ rebased
Redoc
repo
REST
ressources
resources
schema_mapping
sdk
subcommand
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang

<!-- towncrier release notes start -->

## [Infrahub - v1.1.1](https://github.com/opsmill/infrahub/tree/infrahub-v1.1.1) - 2025-01-05

### Fixed

- Raise a better error when trying to resolve an invalid HFID for a relationship ([#5360](https://github.com/opsmill/infrahub/issues/5360))
- Fix an issue with session management that could lead to the crash of the GraphQL resolver
- Fix query response time when the number of historical value for a given attribute is large
- Fixed an issue that prevented using an IP Namespace on a branch

## [Infrahub - v1.1.0](https://github.com/opsmill/infrahub/tree/infrahub-v1.1.0) - 2024-12-30

### Removed
Expand Down
3 changes: 2 additions & 1 deletion backend/infrahub/core/query/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,8 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None:
WITH n1 as n, r1, a1 as a
WHERE r1.status = "active"
WITH n, r1, a
MATCH (a)-[:HAS_VALUE]-(av:AttributeValue)
MATCH (a)-[r:HAS_VALUE]-(av:AttributeValue)
WHERE %(branch_filter)s
CALL {
WITH a, av
MATCH (a)-[r:HAS_VALUE]-(av:AttributeValue)
Expand Down
19 changes: 13 additions & 6 deletions backend/infrahub/core/query/relationship.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,23 +581,30 @@ async def query_init(self, db: InfrahubDatabase, **kwargs) -> None: # pylint: d
branch_level_str = "reduce(br_lvl = 0, r in relationships(path) | br_lvl + r.branch_level)"
froms_str = db.render_list_comprehension(items="relationships(path)", item_name="from")
query = """
MATCH (rl:Relationship { name: $rel_identifier })
MATCH (source_node:Node)%(arrow_left_start)s[:IS_RELATED]%(arrow_left_end)s(rl:Relationship { name: $rel_identifier })
WHERE source_node.uuid IN $source_ids
CALL {
WITH rl
MATCH path = (source_node:Node)%(path)s(peer:Node)
WITH rl, source_node
MATCH path = (source_node)%(path)s(peer:Node)
WHERE
source_node.uuid IN $source_ids AND
$source_kind IN LABELS(source_node) AND
peer.uuid <> source_node.uuid AND
$peer_kind IN LABELS(peer) AND
all(r IN relationships(path) WHERE (%(branch_filter)s))
WITH source_node, peer, rl, relationships(path) as rels, %(branch_level)s AS branch_level, %(froms)s AS froms
RETURN source_node, peer as peer, rels, rl as rl1
RETURN peer as peer, rels, rl as rl1
ORDER BY branch_level DESC, froms[-1] DESC, froms[-2] DESC
LIMIT 1
}
WITH peer, rl1 as rl, rels, source_node
""" % {"path": path_str, "branch_filter": branch_filter, "branch_level": branch_level_str, "froms": froms_str}
""" % {
"path": path_str,
"branch_filter": branch_filter,
"branch_level": branch_level_str,
"froms": froms_str,
"arrow_left_start": arrows.left.start,
"arrow_left_end": arrows.left.end,
}

self.add_to_query(query)
where_clause = ['all(r IN rels WHERE r.status = "active")']
Expand Down
10 changes: 7 additions & 3 deletions backend/infrahub/core/relationship/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,10 +432,14 @@ async def resolve(self, db: InfrahubDatabase) -> None:
else self.schema.peer
)
peer = await registry.manager.get_one_by_hfid(
db=db, hfid=self.peer_hfid, branch=self.branch, kind=kind, fields={"display_label": None}
db=db,
hfid=self.peer_hfid,
branch=self.branch,
kind=kind,
fields={"display_label": None},
raise_on_error=True,
)
if peer:
await self.set_peer(value=peer)
await self.set_peer(value=peer)

if not self.peer_id and self.from_pool and "id" in self.from_pool:
pool_id = str(self.from_pool.get("id"))
Expand Down
2 changes: 1 addition & 1 deletion backend/infrahub/core/schema/definitions/internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ def to_dict(self) -> dict[str, Any]:
name="optional",
kind="Boolean",
description="Indicate if this attribute is mandatory or optional.",
default_value=True,
default_value=False,
override_default_value=False,
optional=True,
extra={"update": UpdateSupport.VALIDATE_CONSTRAINT},
Expand Down
21 changes: 13 additions & 8 deletions backend/infrahub/graphql/mutations/ipam.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,20 @@


async def validate_namespace(
db: InfrahubDatabase, data: InputObjectType, existing_namespace_id: Optional[str] = None
db: InfrahubDatabase,
branch: Branch | str | None,
data: InputObjectType,
existing_namespace_id: Optional[str] = None,
) -> str:
"""Validate or set (if not present) the namespace to pass to the mutation and return its ID."""
namespace_id: Optional[str] = None
if "ip_namespace" not in data or not data["ip_namespace"]:
namespace_id = existing_namespace_id or registry.default_ipnamespace
data["ip_namespace"] = {"id": namespace_id}
elif "id" in data["ip_namespace"]:
namespace = await registry.manager.get_one(db=db, kind=InfrahubKind.IPNAMESPACE, id=data["ip_namespace"]["id"])
namespace = await registry.manager.get_one(
db=db, branch=branch, kind=InfrahubKind.IPNAMESPACE, id=data["ip_namespace"]["id"]
)
namespace_id = namespace.id
else:
raise ValidationError(
Expand Down Expand Up @@ -130,7 +135,7 @@ async def mutate_create(
context: GraphqlContext = info.context
db = database or context.db
ip_address = ipaddress.ip_interface(data["address"]["value"])
namespace_id = await validate_namespace(db=db, data=data)
namespace_id = await validate_namespace(db=db, branch=branch, data=data)

async with db.start_transaction() as dbt:
if lock_name := cls._get_lock_name(namespace_id, branch):
Expand Down Expand Up @@ -186,7 +191,7 @@ async def mutate_update(
include_source=True,
)
namespace = await address.ip_namespace.get_peer(db)
namespace_id = await validate_namespace(db=db, data=data, existing_namespace_id=namespace.id)
namespace_id = await validate_namespace(db=db, branch=branch, data=data, existing_namespace_id=namespace.id)
try:
async with db.start_transaction() as dbt:
if lock_name := cls._get_lock_name(namespace_id, branch):
Expand Down Expand Up @@ -217,7 +222,7 @@ async def mutate_upsert(
context: GraphqlContext = info.context
db = database or context.db

await validate_namespace(db=db, data=data)
await validate_namespace(db=db, branch=branch, data=data)
prefix, result, created = await super().mutate_upsert(
info=info, data=data, branch=branch, node_getters=node_getters, database=db
)
Expand Down Expand Up @@ -283,7 +288,7 @@ async def mutate_create(
) -> tuple[Node, Self]:
context: GraphqlContext = info.context
db = database or context.db
namespace_id = await validate_namespace(db=db, data=data)
namespace_id = await validate_namespace(db=db, branch=branch, data=data)

async with db.start_transaction() as dbt:
if lock_name := cls._get_lock_name(namespace_id, branch):
Expand Down Expand Up @@ -337,7 +342,7 @@ async def mutate_update(
include_source=True,
)
namespace = await prefix.ip_namespace.get_peer(db)
namespace_id = await validate_namespace(db=db, data=data, existing_namespace_id=namespace.id)
namespace_id = await validate_namespace(db=db, branch=branch, data=data, existing_namespace_id=namespace.id)
try:
async with db.start_transaction() as dbt:
if lock_name := cls._get_lock_name(namespace_id, branch):
Expand Down Expand Up @@ -367,7 +372,7 @@ async def mutate_upsert(
context: GraphqlContext = info.context
db = database or context.db

await validate_namespace(db=db, data=data)
await validate_namespace(db=db, branch=branch, data=data)
prefix, result, created = await super().mutate_upsert(
info=info, data=data, branch=branch, node_getters=node_getters, database=db
)
Expand Down
3 changes: 2 additions & 1 deletion backend/infrahub/graphql/resolvers/single_relationship.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,5 @@ async def _get_entities_with_data_loader(
node = await loader.load(key=peer_id)
if not node:
return None
return await node.to_graphql(db=db, fields=node_fields, related_node_ids=related_node_ids)
async with db.start_session() as dbs:
return await node.to_graphql(db=dbs, fields=node_fields, related_node_ids=related_node_ids)
14 changes: 7 additions & 7 deletions backend/tests/integration/profiles/test_profile_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async def person_profile_1(self, db: InfrahubDatabase, schema_person_base) -> No
async def test_step_01_one_person_no_profile(
self, db: InfrahubDatabase, schema_person_base, person_1, person_profile_1, client: InfrahubClient
):
retrieved_person = await client.get(kind="TestingPerson", id=person_1.id)
retrieved_person = await client.get(kind="TestingPerson", id=person_1.id, property=True)

assert retrieved_person.profiles.peer_ids == []
assert retrieved_person.name.value == "Starbuck"
Expand Down Expand Up @@ -251,7 +251,7 @@ async def test_step_05_add_profile_with_person(

async def test_step_06_get_person_multiple_profiles(self, person_1, person_profile_1, client: InfrahubClient):
person_profile_2 = await client.get(kind="ProfileTestingPerson", profile_name__value="profile-two")
retrieved_person = await client.get(kind="TestingPerson", id=person_1.id)
retrieved_person = await client.get(kind="TestingPerson", id=person_1.id, property=True)
await retrieved_person.profiles.fetch()

assert set(retrieved_person.profiles.peer_ids) == {person_profile_1.id, person_profile_2.id}
Expand All @@ -268,7 +268,7 @@ async def test_step_07_update_person_delete_profile(
default_branch,
client,
):
person_2 = await client.get(kind="TestingPerson", name__value="Apollo")
person_2 = await client.get(kind="TestingPerson", name__value="Apollo", property=True)
mutation = """
mutation {
TestingPersonUpdate(data: {id: "%(person_id)s", profiles: []}) {
Expand Down Expand Up @@ -341,9 +341,9 @@ async def test_step_08_delete_profile(
async def test_step_09_check_persons(
self, db: InfrahubDatabase, person_1, person_profile_1, client: InfrahubClient
):
retrieved_person_1 = await client.get(kind="TestingPerson", id=person_1.id)
retrieved_person_1 = await client.get(kind="TestingPerson", id=person_1.id, property=True)
await retrieved_person_1.profiles.fetch()
retrieved_person_2 = await client.get(kind="TestingPerson", name__value="Apollo")
retrieved_person_2 = await client.get(kind="TestingPerson", name__value="Apollo", property=True)

assert retrieved_person_1.profiles.peer_ids == [person_profile_1.id]
assert retrieved_person_1.name.value == "Kara Thrace"
Expand Down Expand Up @@ -450,9 +450,9 @@ async def test_step_11_add_profile_with_person(
assert attributes["height"] == {"value": 134}

async def test_step_12_check_persons_again(self, person_1, person_profile_1, client: InfrahubClient):
retrieved_person_1 = await client.get(kind="TestingPerson", id=person_1.id)
retrieved_person_1 = await client.get(kind="TestingPerson", id=person_1.id, property=True)
await retrieved_person_1.profiles.fetch()
retrieved_person_2 = await client.get(kind="TestingPerson", name__value="Apollo")
retrieved_person_2 = await client.get(kind="TestingPerson", name__value="Apollo", property=True)

assert retrieved_person_1.profiles.peer_ids == [person_profile_1.id]
assert retrieved_person_1.name.value == "Kara Thrace"
Expand Down
Loading

0 comments on commit 137e07a

Please sign in to comment.