|
20 | 20 |
|
21 | 21 | from __future__ import annotations |
22 | 22 |
|
23 | | -from typing import ClassVar, Optional, Type |
| 23 | +from collections import defaultdict |
| 24 | +from typing import ClassVar, List, Optional, Type |
24 | 25 |
|
25 | 26 | from ansible_collections.cisco.nd.plugins.module_utils.endpoints.base import NDEndpointBaseModel |
26 | 27 | from ansible_collections.cisco.nd.plugins.module_utils.endpoints.v1.manage.manage_interfaces import ( |
@@ -76,12 +77,16 @@ class LoopbackInterfaceOrchestrator(NDBaseOrchestrator[LoopbackInterfaceModel]): |
76 | 77 | """ |
77 | 78 |
|
78 | 79 | model_class: ClassVar[Type[NDBaseModel]] = LoopbackInterfaceModel |
| 80 | + supports_bulk_create: ClassVar[bool] = True |
| 81 | + supports_bulk_delete: ClassVar[bool] = True |
79 | 82 |
|
80 | 83 | create_endpoint: Type[NDEndpointBaseModel] = EpManageInterfacesPost |
81 | 84 | update_endpoint: Type[NDEndpointBaseModel] = EpManageInterfacesPut |
82 | 85 | delete_endpoint: Type[NDEndpointBaseModel] = NDEndpointBaseModel # unused; delete() uses bulk remove |
83 | 86 | query_one_endpoint: Type[NDEndpointBaseModel] = EpManageInterfacesGet |
84 | 87 | query_all_endpoint: Type[NDEndpointBaseModel] = EpManageInterfacesListGet |
| 88 | + create_bulk_endpoint: Type[NDEndpointBaseModel] = EpManageInterfacesPost |
| 89 | + delete_bulk_endpoint: Type[NDEndpointBaseModel] = EpManageInterfacesRemove |
85 | 90 |
|
86 | 91 | deploy: bool = True |
87 | 92 |
|
@@ -338,6 +343,57 @@ def delete(self, model_instance: LoopbackInterfaceModel, **kwargs) -> None: |
338 | 343 | self._queue_remove(model_instance.interface_name, switch_id) |
339 | 344 | self._queue_deploy(model_instance.interface_name, switch_id) |
340 | 345 |
|
| 346 | + def create_bulk(self, model_instances: List[LoopbackInterfaceModel], **kwargs) -> ResponseType: |
| 347 | + """ |
| 348 | + # Summary |
| 349 | +
|
| 350 | + Create multiple loopback interfaces in bulk. Groups interfaces by switch and sends one POST per switch with all |
| 351 | + interfaces in the `interfaces` array, reducing API calls from N to one-per-switch. Queues deploys for all created |
| 352 | + interfaces for later bulk execution via `deploy_pending`. |
| 353 | +
|
| 354 | + ## Raises |
| 355 | +
|
| 356 | + ### RuntimeError |
| 357 | +
|
| 358 | + - If any create API request fails. |
| 359 | + """ |
| 360 | + try: |
| 361 | + groups: dict[str, list[tuple[str, dict]]] = defaultdict(list) |
| 362 | + for model_instance in model_instances: |
| 363 | + switch_id = self._resolve_switch_id(model_instance.switch_ip) |
| 364 | + payload = model_instance.to_payload() |
| 365 | + payload["switchId"] = switch_id |
| 366 | + groups[switch_id].append((model_instance.interface_name, payload)) |
| 367 | + |
| 368 | + results = [] |
| 369 | + for switch_id, items in groups.items(): |
| 370 | + api_endpoint = self._configure_endpoint(self.create_bulk_endpoint(), switch_sn=switch_id) |
| 371 | + request_body = {"interfaces": [payload for _, payload in items]} |
| 372 | + result = self.sender.request(path=api_endpoint.path, method=api_endpoint.verb, data=request_body) |
| 373 | + results.append(result) |
| 374 | + for interface_name, _ in items: |
| 375 | + self._queue_deploy(interface_name, switch_id) |
| 376 | + return results |
| 377 | + except Exception as e: |
| 378 | + raise RuntimeError(f"Bulk create failed: {e}") from e |
| 379 | + |
| 380 | + def delete_bulk(self, model_instances: List[LoopbackInterfaceModel], **kwargs) -> None: |
| 381 | + """ |
| 382 | + # Summary |
| 383 | +
|
| 384 | + Queue multiple loopback interfaces for deferred bulk removal and deployment. Each interface is queued for removal |
| 385 | + via `remove_pending` and deployment via `deploy_pending`. No API calls are made until those methods are called |
| 386 | + after `manage_state` completes. |
| 387 | +
|
| 388 | + ## Raises |
| 389 | +
|
| 390 | + None |
| 391 | + """ |
| 392 | + for model_instance in model_instances: |
| 393 | + switch_id = self._resolve_switch_id(model_instance.switch_ip) |
| 394 | + self._queue_remove(model_instance.interface_name, switch_id) |
| 395 | + self._queue_deploy(model_instance.interface_name, switch_id) |
| 396 | + |
341 | 397 | def query_one(self, model_instance: LoopbackInterfaceModel, **kwargs) -> ResponseType: |
342 | 398 | """ |
343 | 399 | # Summary |
|
0 commit comments