|
21 | 21 | from infrahub.workflows.utils import add_branch_tag |
22 | 22 |
|
23 | 23 | from .constants import AUTOMATION_NAME, AUTOMATION_NAME_PREFIX |
24 | | -from .models import ComputedAttributeAutomations |
| 24 | +from .models import ComputedAttributeAutomations, PythonTransformComputedAttribute |
25 | 25 |
|
26 | 26 | if TYPE_CHECKING: |
27 | 27 | from infrahub.core.schema.computed_attribute import ComputedAttribute |
@@ -251,3 +251,109 @@ async def computed_attribute_setup() -> None: |
251 | 251 | else: |
252 | 252 | await client.create_automation(automation=automation) |
253 | 253 | log.info(f"{computed_attribute.key_name} Created") |
| 254 | + |
| 255 | + |
| 256 | +@flow( |
| 257 | + name="computed-attribute-setup-python", |
| 258 | + flow_run_name="Setup computed attributes for Python transforms in task-manager", |
| 259 | +) |
| 260 | +async def computed_attribute_setup_python() -> None: |
| 261 | + service = services.service |
| 262 | + schema_branch = registry.schema.get_schema_branch(name=registry.default_branch) |
| 263 | + log = get_run_logger() |
| 264 | + |
| 265 | + transform_attributes = schema_branch.computed_attributes.python_attributes_by_transform |
| 266 | + |
| 267 | + transform_names = list(transform_attributes.keys()) |
| 268 | + |
| 269 | + transforms = await service.client.filters( |
| 270 | + kind="CoreTransformPython", |
| 271 | + branch=registry.default_branch, |
| 272 | + prefetch_relationships=True, |
| 273 | + populate_store=True, |
| 274 | + name__values=transform_names, |
| 275 | + ) |
| 276 | + |
| 277 | + found_transforms_names = [transform.name.value for transform in transforms] |
| 278 | + for transform_name in transform_names: |
| 279 | + if transform_name not in found_transforms_names: |
| 280 | + log.warning( |
| 281 | + msg=f"The transform {transform_name} is assigned to a computed attribute but the transform could not be found in the database." |
| 282 | + ) |
| 283 | + |
| 284 | + computed_attributes: list[PythonTransformComputedAttribute] = [] |
| 285 | + for transform in transforms: |
| 286 | + for attribute in transform_attributes[transform.name.value]: |
| 287 | + computed_attributes.append( |
| 288 | + PythonTransformComputedAttribute( |
| 289 | + name=transform.name.value, |
| 290 | + repository_id=transform.repository.peer.id, |
| 291 | + repository_name=transform.repository.peer.name.value, |
| 292 | + repository_kind=transform.repository.peer.typename, |
| 293 | + query_name=transform.query.peer.name.value, |
| 294 | + query_models=transform.query.peer.models.value, |
| 295 | + computed_attribute=attribute, |
| 296 | + ) |
| 297 | + ) |
| 298 | + |
| 299 | + async with get_client(sync_client=False) as client: |
| 300 | + deployments = { |
| 301 | + item.name: item |
| 302 | + for item in await client.read_deployments( |
| 303 | + deployment_filter=DeploymentFilter( |
| 304 | + name=DeploymentFilterName(any_=[UPDATE_COMPUTED_ATTRIBUTE_TRANSFORM.name]) |
| 305 | + ) |
| 306 | + ) |
| 307 | + } |
| 308 | + if UPDATE_COMPUTED_ATTRIBUTE_TRANSFORM.name not in deployments: |
| 309 | + raise ValueError("Unable to find the deployment for UPDATE_COMPUTED_ATTRIBUTE_TRANSFORM") |
| 310 | + |
| 311 | + deployment_id_python = deployments[UPDATE_COMPUTED_ATTRIBUTE_TRANSFORM.name].id |
| 312 | + |
| 313 | + automations = await client.read_automations() |
| 314 | + existing_computed_attr_automations = ComputedAttributeAutomations.from_prefect(automations=automations) |
| 315 | + |
| 316 | + for computed_attribute in computed_attributes: |
| 317 | + log.info(f"processing {computed_attribute.computed_attribute.key_name}") |
| 318 | + scope = "default" |
| 319 | + |
| 320 | + automation = AutomationCore( |
| 321 | + name=AUTOMATION_NAME.format( |
| 322 | + prefix=AUTOMATION_NAME_PREFIX, |
| 323 | + identifier=computed_attribute.computed_attribute.key_name, |
| 324 | + scope=scope, |
| 325 | + ), |
| 326 | + description=f"Process value of the computed attribute for {computed_attribute.computed_attribute.key_name} [{scope}]", |
| 327 | + enabled=True, |
| 328 | + trigger=EventTrigger( |
| 329 | + posture=Posture.Reactive, |
| 330 | + expect={"infrahub.node.*"}, |
| 331 | + within=timedelta(0), |
| 332 | + match=ResourceSpecification({"infrahub.node.kind": [computed_attribute.computed_attribute.kind]}), |
| 333 | + threshold=1, |
| 334 | + ), |
| 335 | + actions=[ |
| 336 | + RunDeployment( |
| 337 | + source="selected", |
| 338 | + deployment_id=deployment_id_python, |
| 339 | + parameters={ |
| 340 | + "branch_name": "{{ event.resource['infrahub.branch.name'] }}", |
| 341 | + "node_kind": "{{ event.resource['infrahub.node.kind'] }}", |
| 342 | + "object_id": "{{ event.resource['infrahub.node.id'] }}", |
| 343 | + }, |
| 344 | + job_variables={}, |
| 345 | + ) |
| 346 | + ], |
| 347 | + ) |
| 348 | + |
| 349 | + if existing_computed_attr_automations.has( |
| 350 | + identifier=computed_attribute.computed_attribute.key_name, scope=scope |
| 351 | + ): |
| 352 | + existing = existing_computed_attr_automations.get( |
| 353 | + identifier=computed_attribute.computed_attribute.key_name, scope=scope |
| 354 | + ) |
| 355 | + await client.update_automation(automation_id=existing.id, automation=automation) |
| 356 | + log.info(f"{computed_attribute.computed_attribute.key_name} Updated") |
| 357 | + else: |
| 358 | + await client.create_automation(automation=automation) |
| 359 | + log.info(f"{computed_attribute.computed_attribute.key_name} Created") |
0 commit comments