Skip to content

ANTA Inventory API

AntaInventory

Bases: dict[str, AntaDevice]

Inventory abstraction for ANTA framework.

devices property

devices: list[AntaDevice]

List of AntaDevice in this inventory.

max_potential_connections property

max_potential_connections: int | None

Max potential connections of this inventory.

add_device

add_device(device: AntaDevice) -> None

Add a device to final inventory.

Parameters:

Name Type Description Default
device AntaDevice

Device object to be added.

required
Source code in anta/inventory/__init__.py
462
463
464
465
466
467
468
469
470
471
def add_device(self, device: AntaDevice) -> None:
    """Add a device to final inventory.

    Parameters
    ----------
    device
        Device object to be added.

    """
    self[device.name] = device

connect_inventory async

connect_inventory() -> None

Run refresh() coroutines for all AntaDevice objects in this inventory.

Source code in anta/inventory/__init__.py
477
478
479
480
481
482
483
484
485
486
487
async def connect_inventory(self) -> None:
    """Run `refresh()` coroutines for all AntaDevice objects in this inventory."""
    logger.debug("Refreshing devices...")
    results = await asyncio.gather(
        *(device.refresh() for device in self.values()),
        return_exceptions=True,
    )
    for r in results:
        if isinstance(r, Exception):
            message = "Error when refreshing inventory"
            anta_log_exception(r, message, logger)

disconnect_inventory async

disconnect_inventory() -> None

Run disconnect() coroutines for all AntaDevice objects in this inventory.

Source code in anta/inventory/__init__.py
493
494
495
496
497
498
499
500
501
async def disconnect_inventory(self) -> None:
    """Run `disconnect()` coroutines for all AntaDevice objects in this inventory."""
    results = await asyncio.gather(
        *(device.disconnect() for device in self.values()),
        return_exceptions=True,
    )
    for r in results:
        if isinstance(r, Exception):
            logger.warning("Error when disconnecting inventory: %s", exc_to_str(r))

dump

Dump the AntaInventory to an AntaInventoryInput.

Each hosts is dumped individually.

Source code in anta/inventory/__init__.py
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
def dump(self) -> AntaInventoryInput:
    """Dump the AntaInventory to an AntaInventoryInput.

    Each hosts is dumped individually.
    """
    hosts = [
        AntaInventoryHost(
            name=device.name,
            host=device.host if not self.is_base_class(device) else device.name,
            port=device.port if not self.is_base_class(device) else None,
            tags=device.tags,
            disable_cache=device.cache is None,
            use_session_auth=device.use_session_auth if isinstance(device, AsyncEOSDevice) else False,
            **({"ssl_params": device.ssl_params} if isinstance(device, AsyncEOSDevice) and device.ssl_params is not None else {}),
        )
        for device in self.devices
    ]
    return AntaInventoryInput(hosts=hosts)

get_inventory

get_inventory(*, established_only: bool = False, tags: set[str] | None = None, devices: set[str] | None = None) -> AntaInventory

Return a filtered inventory.

Parameters:

Name Type Description Default
established_only bool

Whether or not to include only established devices.

False
tags set[str] | None

Tags to filter devices.

None
devices set[str] | None

Names to filter devices.

None

Returns:

Type Description
AntaInventory

An inventory with filtered AntaDevice objects.

Source code in anta/inventory/__init__.py
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
def get_inventory(self, *, established_only: bool = False, tags: set[str] | None = None, devices: set[str] | None = None) -> AntaInventory:
    """Return a filtered inventory.

    Parameters
    ----------
    established_only
        Whether or not to include only established devices.
    tags
        Tags to filter devices.
    devices
        Names to filter devices.

    Returns
    -------
    AntaInventory
        An inventory with filtered AntaDevice objects.
    """

    def _filter_devices(device: AntaDevice) -> bool:
        """Select the devices based on the inputs `tags`, `devices` and `established_only`."""
        if tags is not None and all(tag not in tags for tag in device.tags):
            return False
        if devices is None or device.name in devices:
            return bool(not established_only or device.established)
        return False

    filtered_devices: list[AntaDevice] = list(filter(_filter_devices, self.values()))
    result = AntaInventory()
    for device in filtered_devices:
        result.add_device(device)
    return result

is_base_class

is_base_class(device: AntaDevice) -> TypeIs[AntaDevice]

Check the type of device, return True if the device is an AntaDevice.

Source code in anta/inventory/__init__.py
489
490
491
def is_base_class(self, device: AntaDevice) -> TypeIs[AntaDevice]:
    """Check the type of device, return True if the device is an AntaDevice."""
    return not hasattr(device, "host") and not hasattr(device, "port")

parse staticmethod

parse(filename: str | Path, username: str, password: str, enable_password: str | None = None, timeout: float | None = None, file_format: Literal['yaml', 'json'] = 'yaml', *, enable: bool = False, insecure: bool = False, disable_cache: bool = False, use_session_auth: bool | None = None) -> AntaInventory

Create an AntaInventory instance from an inventory file.

The inventory devices are AsyncEOSDevice instances.

Parameters:

Name Type Description Default
filename str | Path

Path to device inventory YAML file.

required
username str

Username to use to connect to devices.

required
password str

Password to use to connect to devices.

required
enable_password str | None

Enable password to use if required.

None
timeout float | None

Global timeout value in seconds for outgoing eAPI calls. None means no timeout.

None
file_format Literal['yaml', 'json']

Whether the inventory file is in JSON or YAML.

'yaml'
enable bool

Whether or not the commands need to be run in enable mode towards the devices.

False
insecure bool

Disable SSH Host Key validation.

False
disable_cache bool

Disable cache globally.

False
use_session_auth bool | None

Session authentication override. True forces session auth on for all devices, False (--no-session-auth) forces it off regardless of inventory settings, None (unset) defers to the per-device inventory value.

None

Raises:

Type Description
InventoryRootKeyError

Root key of inventory is missing.

InventoryIncorrectSchemaError

Inventory file is not following AntaInventory Schema.

Source code in anta/inventory/__init__.py
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
@staticmethod
def parse(
    filename: str | Path,
    username: str,
    password: str,
    enable_password: str | None = None,
    timeout: float | None = None,
    file_format: Literal["yaml", "json"] = "yaml",
    *,
    enable: bool = False,
    insecure: bool = False,
    disable_cache: bool = False,
    use_session_auth: bool | None = None,
) -> AntaInventory:
    """Create an AntaInventory instance from an inventory file.

    The inventory devices are AsyncEOSDevice instances.

    Parameters
    ----------
    filename
        Path to device inventory YAML file.
    username
        Username to use to connect to devices.
    password
        Password to use to connect to devices.
    enable_password
        Enable password to use if required.
    timeout
        Global timeout value in seconds for outgoing eAPI calls. None means no timeout.
    file_format
        Whether the inventory file is in JSON or YAML.
    enable
        Whether or not the commands need to be run in enable mode towards the devices.
    insecure
        Disable SSH Host Key validation.
    disable_cache
        Disable cache globally.
    use_session_auth
        Session authentication override. ``True`` forces session auth on for all devices,
        ``False`` (``--no-session-auth``) forces it off regardless of inventory settings,
        ``None`` (unset) defers to the per-device inventory value.

    Raises
    ------
    InventoryRootKeyError
        Root key of inventory is missing.
    InventoryIncorrectSchemaError
        Inventory file is not following AntaInventory Schema.

    """
    if file_format not in ["yaml", "json"]:
        message = f"'{file_format}' is not a valid format for an AntaInventory file. Only 'yaml' and 'json' are supported."
        raise ValueError(message)

    inventory = AntaInventory()
    kwargs: dict[str, Any] = {
        "username": username,
        "password": password,
        "enable": enable,
        "enable_password": enable_password,
        "timeout": timeout,
        "insecure": insecure,
        "disable_cache": disable_cache,
    }

    try:
        filename = Path(filename)
        with filename.open(encoding="UTF-8") as file:
            data = safe_load(file) if file_format == "yaml" else json_load(file)
    except (TypeError, YAMLError, OSError, ValueError) as e:
        message = f"Unable to parse ANTA Device Inventory file '{filename}'"
        anta_log_exception(e, message, logger)
        raise

    if AntaInventory.INVENTORY_ROOT_KEY not in data:
        exc = InventoryRootKeyError(f"Inventory root key ({AntaInventory.INVENTORY_ROOT_KEY}) is not defined in your inventory")
        anta_log_exception(exc, f"Device inventory is invalid! (from {filename})", logger)
        raise exc

    try:
        inventory_input = AntaInventoryInput(**data[AntaInventory.INVENTORY_ROOT_KEY])
    except ValidationError as e:
        anta_log_exception(e, f"Device inventory is invalid! (from {filename})", logger)
        raise

    # Read data from input
    AntaInventory._parse_hosts(inventory_input, inventory, use_session_auth_override=use_session_auth, **kwargs)
    AntaInventory._parse_networks(inventory_input, inventory, use_session_auth_override=use_session_auth, **kwargs)
    AntaInventory._parse_ranges(inventory_input, inventory, use_session_auth_override=use_session_auth, **kwargs)

    return inventory

AntaInventoryInput

Bases: BaseModel

Device inventory input model.

to_json

to_json() -> str

Return a JSON representation string of this model.

Returns:

Type Description
The JSON representation string of this model.
Source code in anta/inventory/models.py
139
140
141
142
143
144
145
146
def to_json(self) -> str:
    """Return a JSON representation string of this model.

    Returns
    -------
        The JSON representation string of this model.
    """
    return self.model_dump_json(exclude_unset=True, indent=2)

yaml

yaml() -> str

Return a YAML representation string of this model.

Returns:

Type Description
str

The YAML representation string of this model.

Source code in anta/inventory/models.py
125
126
127
128
129
130
131
132
133
134
135
136
137
def yaml(self) -> str:
    """Return a YAML representation string of this model.

    Returns
    -------
    str
        The YAML representation string of this model.
    """
    # TODO: Pydantic and YAML serialization/deserialization is not supported natively.
    # This could be improved.
    # https://github.com/pydantic/pydantic/issues/1043
    # Explore if this worth using this: https://github.com/NowanIlfideme/pydantic-yaml
    return yaml.safe_dump(yaml.safe_load(self.model_dump_json(serialize_as_any=True, exclude_unset=True)), width=math.inf)

AntaInventoryHost

Bases: AntaInventoryBaseModel

Host entry of AntaInventoryInput.

Attributes:

Name Type Description
host Hostname | IPvAnyAddress

IP Address or FQDN of the device.

port Port | None

Custom eAPI port to use.

name str | None

Custom name of the device.

tags set[str]

Tags of the device.

disable_cache bool

Disable cache for this device.

use_session_auth bool

Use session based authentication for this device if supported.

ssl_params SSLParameters | None

SSL parameters for this device.

AntaInventoryNetwork

Bases: AntaInventoryBaseModel

Network entry of AntaInventoryInput.

Attributes:

Name Type Description
network IPvAnyNetwork

Subnet to use for scanning.

tags set[str]

Tags of the devices in this network.

disable_cache bool

Disable cache for all devices in this network.

use_session_auth bool

Use session based authentication for all devices if supported in this network.

ssl_params SSLParameters | None

SSL parameters for all devices in this network.

AntaInventoryRange

Bases: AntaInventoryBaseModel

IP Range entry of AntaInventoryInput.

Attributes:

Name Type Description
start IPvAnyAddress

IPv4 or IPv6 address for the beginning of the range.

stop IPvAnyAddress

IPv4 or IPv6 address for the end of the range.

tags set[str]

Tags of the devices in this IP range.

disable_cache bool

Disable cache for all devices in this IP range.

use_session_auth bool

Use session based authentication for all devices if supported in this IP range.

ssl_params SSLParameters | None

SSL parameters for all devices in this IP range.

exceptions

Manage Exception in Inventory module.

InventoryIncorrectSchemaError

Bases: Exception

Error when user data does not follow ANTA schema.

InventoryRootKeyError

Bases: Exception

Error raised when inventory root key is not found.