Skip to content

Commit 643b736

Browse files
authored
Merge pull request #6572 from opsmill/pog-numberpool-deletion
Delete unused schema defined NumberPools when they are no longer in use
2 parents e62aadf + a220902 commit 643b736

File tree

17 files changed

+341
-13
lines changed

17 files changed

+341
-13
lines changed

backend/infrahub/branch/__init__.py

Whitespace-only changes.

backend/infrahub/branch/tasks.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from __future__ import annotations
2+
3+
from prefect import flow
4+
from prefect.logging import get_run_logger
5+
6+
from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
7+
from infrahub.core.registry import registry
8+
from infrahub.pools.tasks import validate_schema_number_pools
9+
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
10+
from infrahub.workflows.utils import wait_for_schema_to_converge
11+
12+
13+
@flow(
14+
name="branch-merged",
15+
flow_run_name="Running actions after '{source_branch}' was merged",
16+
)
17+
async def branch_merged(
18+
source_branch: str, # noqa: ARG001
19+
context: InfrahubContext,
20+
service: InfrahubServices,
21+
target_branch: str | None = None,
22+
) -> None:
23+
target_branch = target_branch or registry.default_branch
24+
log = get_run_logger()
25+
await wait_for_schema_to_converge(
26+
branch_name=target_branch, component=service.component, db=service.database, log=log
27+
)
28+
29+
await validate_schema_number_pools(branch_name=target_branch, context=context, service=service)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from infrahub.events.branch_action import BranchMergedEvent
2+
from infrahub.trigger.models import BuiltinTriggerDefinition, EventTrigger, ExecuteWorkflow
3+
from infrahub.workflows.catalogue import BRANCH_MERGED
4+
5+
TRIGGER_BRANCH_MERGED = BuiltinTriggerDefinition(
6+
name="branch-merged-trigger",
7+
trigger=EventTrigger(
8+
events={BranchMergedEvent.event_name},
9+
),
10+
actions=[
11+
ExecuteWorkflow(
12+
workflow=BRANCH_MERGED,
13+
parameters={
14+
"source_branch": "{{ event.payload['data']['branch_name'] }}",
15+
"context": {
16+
"__prefect_kind": "json",
17+
"value": {"__prefect_kind": "jinja", "template": "{{ event.payload['context'] | tojson }}"},
18+
},
19+
},
20+
),
21+
],
22+
)

backend/infrahub/core/constants/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ class AccountType(InfrahubStringEnum):
112112
Git = "Git"
113113

114114

115+
class NumberPoolType(InfrahubStringEnum):
116+
USER = "User"
117+
SCHEMA = "Schema"
118+
119+
115120
class AccountStatus(InfrahubStringEnum):
116121
ACTIVE = "active"
117122
INACTIVE = "inactive"

backend/infrahub/core/node/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
BranchSupportType,
1717
ComputedAttributeKind,
1818
InfrahubKind,
19+
NumberPoolType,
1920
RelationshipCardinality,
2021
RelationshipKind,
2122
)
@@ -328,6 +329,7 @@ async def _create_number_pool(
328329
node_attribute=attribute.schema.name,
329330
start_range=number_pool_parameters.start_range,
330331
end_range=number_pool_parameters.end_range,
332+
pool_type=NumberPoolType.SCHEMA.value,
331333
)
332334
await number_pool.save(db=db)
333335
# Do a lookup of the number pool to get the correct mapped type from the registry

backend/infrahub/core/protocols.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ class CoreNumberPool(CoreResourcePool, LineageSource):
455455
node_attribute: String
456456
start_range: Integer
457457
end_range: Integer
458+
pool_type: Enum
458459

459460

460461
class CoreObjectPermission(CoreBasePermission):

backend/infrahub/core/schema/definitions/core/resource_pool.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from infrahub.core.constants import (
22
BranchSupportType,
33
InfrahubKind,
4+
NumberPoolType,
45
)
56
from infrahub.core.constants import RelationshipCardinality as Cardinality
67
from infrahub.core.constants import RelationshipKind as RelKind
@@ -186,5 +187,13 @@
186187
Attr(
187188
name="end_range", kind="Number", optional=False, description="The end range for the pool", order_weight=6000
188189
),
190+
Attr(
191+
name="pool_type",
192+
kind="Text",
193+
description="Defines how this number pool was created",
194+
default_value=NumberPoolType.USER.value,
195+
enum=NumberPoolType.available_types(),
196+
read_only=True,
197+
),
189198
],
190199
)

backend/infrahub/graphql/mutations/resource_manager.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from infrahub.core.schema.attribute_parameters import NumberAttributeParameters
1515
from infrahub.database import retry_db_transaction
1616
from infrahub.exceptions import QueryValidationError, SchemaNotFoundError, ValidationError
17+
from infrahub.pools.registration import get_branches_with_schema_number_pool
1718

1819
from ..queries.resource_manager import PoolAllocatedNode
1920
from .main import DeleteResult, InfrahubMutationMixin, InfrahubMutationOptions
@@ -257,18 +258,9 @@ async def mutate_delete(
257258
branch=branch,
258259
)
259260

260-
active_branches = registry.schema.get_branches()
261-
violating_branches = []
262-
for active_branch in active_branches:
263-
try:
264-
schema = registry.schema.get(name=number_pool.node.value, branch=active_branch)
265-
except SchemaNotFoundError:
266-
continue
267-
268-
if number_pool.node_attribute.value in schema.attribute_names:
269-
attribute = schema.get_attribute(name=number_pool.node_attribute.value)
270-
if attribute.kind == "NumberPool":
271-
violating_branches.append(active_branch)
261+
violating_branches = get_branches_with_schema_number_pool(
262+
kind=number_pool.node.value, attribute_name=number_pool.node_attribute.value
263+
)
272264

273265
if violating_branches:
274266
raise ValidationError(
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from infrahub.core.registry import registry
2+
from infrahub.exceptions import SchemaNotFoundError
3+
4+
5+
def get_branches_with_schema_number_pool(kind: str, attribute_name: str) -> list[str]:
6+
"""Return branches where schema defined NumberPool exists"""
7+
8+
registered_branches = []
9+
active_branches = registry.schema.get_branches()
10+
11+
for active_branch in active_branches:
12+
try:
13+
schema = registry.schema.get(name=kind, branch=active_branch)
14+
except SchemaNotFoundError:
15+
continue
16+
17+
if attribute_name in schema.attribute_names:
18+
attribute = schema.get_attribute(name=attribute_name)
19+
if attribute.kind == "NumberPool":
20+
registered_branches.append(active_branch)
21+
22+
return registered_branches

backend/infrahub/pools/tasks.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from __future__ import annotations
2+
3+
from prefect import flow
4+
from prefect.logging import get_run_logger
5+
6+
from infrahub.context import InfrahubContext # noqa: TC001 needed for prefect flow
7+
from infrahub.core.constants import NumberPoolType
8+
from infrahub.core.manager import NodeManager
9+
from infrahub.core.protocols import CoreNumberPool
10+
from infrahub.core.registry import registry
11+
from infrahub.core.schema.attribute_parameters import NumberPoolParameters
12+
from infrahub.pools.registration import get_branches_with_schema_number_pool
13+
from infrahub.services import InfrahubServices # noqa: TC001 needed for prefect flow
14+
15+
16+
@flow(
17+
name="validate-schema-number-pools",
18+
flow_run_name="Validate schema number pools on {branch_name}",
19+
)
20+
async def validate_schema_number_pools(
21+
branch_name: str, # noqa: ARG001
22+
context: InfrahubContext, # noqa: ARG001
23+
service: InfrahubServices,
24+
) -> None:
25+
log = get_run_logger()
26+
27+
async with service.database.start_session() as dbs:
28+
schema_number_pools = await NodeManager.query(
29+
db=dbs, schema=CoreNumberPool, filters={"pool_type__value": NumberPoolType.SCHEMA.value}
30+
)
31+
32+
for schema_number_pool in list(schema_number_pools):
33+
defined_on_branches = get_branches_with_schema_number_pool(
34+
kind=schema_number_pool.node.value, attribute_name=schema_number_pool.node_attribute.value
35+
)
36+
if registry.default_branch in defined_on_branches:
37+
schema = registry.schema.get(name=schema_number_pool.node.value, branch=registry.default_branch)
38+
attribute = schema.get_attribute(name=schema_number_pool.node_attribute.value)
39+
number_pool_updated = False
40+
if isinstance(attribute.parameters, NumberPoolParameters):
41+
if schema_number_pool.start_range.value != attribute.parameters.start_range:
42+
schema_number_pool.start_range.value = attribute.parameters.start_range
43+
number_pool_updated = True
44+
if schema_number_pool.end_range.value != attribute.parameters.end_range:
45+
schema_number_pool.end_range.value = attribute.parameters.end_range
46+
number_pool_updated = True
47+
48+
if number_pool_updated:
49+
log.info(
50+
f"Updating NumberPool={schema_number_pool.id} based on changes in the schema on {registry.default_branch}"
51+
)
52+
await schema_number_pool.save(db=service.database)
53+
54+
elif not defined_on_branches:
55+
log.info(f"Deleting number pool (id={schema_number_pool.id}) as it is no longer defined in the schema")
56+
await schema_number_pool.delete(db=service.database)

0 commit comments

Comments
 (0)