diff --git a/anta/catalog.py b/anta/catalog.py index 66520f9fa..ee56639f7 100644 --- a/anta/catalog.py +++ b/anta/catalog.py @@ -328,6 +328,10 @@ def parse(filename: str | Path, file_format: Literal["yaml", "json"] = "yaml") - file_format Format of the file, either 'yaml' or 'json'. + Returns + ------- + AntaCatalog + An AntaCatalog populated with the file content. """ if file_format not in ["yaml", "json"]: message = f"'{file_format}' is not a valid format for an AntaCatalog file. Only 'yaml' and 'json' are supported." @@ -356,8 +360,13 @@ def from_dict(data: RawCatalogInput, filename: str | Path | None = None) -> Anta ---------- data Python dictionary used to instantiate the AntaCatalog instance. - filename: value to be set as AntaCatalog instance attribute + filename + value to be set as AntaCatalog instance attribute + Returns + ------- + AntaCatalog + An AntaCatalog populated with the 'data' dictionary content. """ tests: list[AntaTestDefinition] = [] if data is None: @@ -392,6 +401,10 @@ def from_list(data: ListAntaTestTuples) -> AntaCatalog: data Python list used to instantiate the AntaCatalog instance. + Returns + ------- + AntaCatalog + An AntaCatalog populated with the 'data' list content. """ tests: list[AntaTestDefinition] = [] try: diff --git a/anta/reporter/__init__.py b/anta/reporter/__init__.py index 01baf3a6e..73ba83538 100644 --- a/anta/reporter/__init__.py +++ b/anta/reporter/__init__.py @@ -90,12 +90,13 @@ def _color_result(self, status: AntaTestStatus) -> str: Parameters ---------- - status: AntaTestStatus enum to color. + status + AntaTestStatus enum to color. Returns ------- - The colored string. - + str + The colored string. """ color = RICH_COLOR_THEME.get(str(status), "") return f"[{color}]{status}" if color != "" else str(status) @@ -115,8 +116,7 @@ def report_all(self, manager: ResultManager, title: str = "All tests results") - Returns ------- Table - A fully populated rich `Table` - + A fully populated rich `Table`. """ table = Table(title=title, show_lines=True) headers = ["Device", "Test Name", "Test Status", "Message(s)", "Test description", "Test category"] diff --git a/anta/reporter/csv_reporter.py b/anta/reporter/csv_reporter.py index 570da9e6b..4263c1e59 100644 --- a/anta/reporter/csv_reporter.py +++ b/anta/reporter/csv_reporter.py @@ -62,7 +62,7 @@ def convert_to_list(cls, result: TestResult) -> list[str]: Parameters ---------- - results + result A TestResult to convert into list. Returns diff --git a/anta/result_manager/__init__.py b/anta/result_manager/__init__.py index b1fd9c2d4..f0f4cadfa 100644 --- a/anta/result_manager/__init__.py +++ b/anta/result_manager/__init__.py @@ -301,7 +301,8 @@ def filter_by_devices(self, devices: set[str]) -> ResultManager: Parameters ---------- - devices: Set of device names to filter the results. + devices + Set of device names to filter the results. Returns ------- diff --git a/anta/runner.py b/anta/runner.py index c818d192d..6e3290267 100644 --- a/anta/runner.py +++ b/anta/runner.py @@ -88,6 +88,8 @@ async def setup_inventory(inventory: AntaInventory, tags: set[str] | None, devic Tags to filter devices from the inventory. devices Devices on which to run tests. None means all devices. + established_only + If True use return only devices where a connection is established. Returns ------- diff --git a/anta/tests/routing/isis.py b/anta/tests/routing/isis.py index 344605d3a..684578ce1 100644 --- a/anta/tests/routing/isis.py +++ b/anta/tests/routing/isis.py @@ -604,10 +604,6 @@ def test(self) -> None: This method performs the main test logic for verifying ISIS Segment Routing tunnels. It checks the command output, initiates defaults, and performs various checks on the tunnels. - - Returns - ------- - None """ command_output = self.instance_commands[0].json_output self.result.is_success() @@ -647,12 +643,15 @@ def _check_tunnel_type(self, via_input: VerifyISISSegmentRoutingTunnels.Input.En Parameters ---------- - via_input (VerifyISISSegmentRoutingTunnels.Input.Entry.Vias): The input tunnel type to check. - eos_entry (dict[str, Any]): The EOS entry containing the tunnel types. + via_input : VerifyISISSegmentRoutingTunnels.Input.Entry.Vias + The input tunnel type to check. + eos_entry : dict[str, Any] + The EOS entry containing the tunnel types. Returns ------- - bool: True if the tunnel type matches any of the tunnel types in `eos_entry`, False otherwise. + bool + True if the tunnel type matches any of the tunnel types in `eos_entry`, False otherwise. """ if via_input.type is not None: return any( @@ -672,12 +671,15 @@ def _check_tunnel_nexthop(self, via_input: VerifyISISSegmentRoutingTunnels.Input Parameters ---------- - via_input (VerifyISISSegmentRoutingTunnels.Input.Entry.Vias): The input via object. - eos_entry (dict[str, Any]): The EOS entry dictionary. + via_input : VerifyISISSegmentRoutingTunnels.Input.Entry.Vias + The input via object. + eos_entry : dict[str, Any] + The EOS entry dictionary. Returns ------- - bool: True if the tunnel nexthop matches, False otherwise. + bool + True if the tunnel nexthop matches, False otherwise. """ if via_input.nexthop is not None: return any( @@ -697,12 +699,15 @@ def _check_tunnel_interface(self, via_input: VerifyISISSegmentRoutingTunnels.Inp Parameters ---------- - via_input (VerifyISISSegmentRoutingTunnels.Input.Entry.Vias): The input via object. - eos_entry (dict[str, Any]): The EOS entry dictionary. + via_input : VerifyISISSegmentRoutingTunnels.Input.Entry.Vias + The input via object. + eos_entry : dict[str, Any] + The EOS entry dictionary. Returns ------- - bool: True if the tunnel interface exists, False otherwise. + bool + True if the tunnel interface exists, False otherwise. """ if via_input.interface is not None: return any( @@ -722,12 +727,15 @@ def _check_tunnel_id(self, via_input: VerifyISISSegmentRoutingTunnels.Input.Entr Parameters ---------- - via_input (VerifyISISSegmentRoutingTunnels.Input.Entry.Vias): The input vias to check. - eos_entry (dict[str, Any]): The EOS entry to compare against. + via_input : VerifyISISSegmentRoutingTunnels.Input.Entry.Vias + The input vias to check. + eos_entry : dict[str, Any]) + The EOS entry to compare against. Returns ------- - bool: True if the tunnel ID matches any of the tunnel IDs in the EOS entry's vias, False otherwise. + bool + True if the tunnel ID matches any of the tunnel IDs in the EOS entry's vias, False otherwise. """ if via_input.tunnel_id is not None: return any( diff --git a/asynceapi/aio_portcheck.py b/asynceapi/aio_portcheck.py index 79f4562fa..0cab94cb3 100644 --- a/asynceapi/aio_portcheck.py +++ b/asynceapi/aio_portcheck.py @@ -37,12 +37,17 @@ async def port_check_url(url: URL, timeout: int = 5) -> bool: """ Open the port designated by the URL given the timeout in seconds. - If the port is available then return True; False otherwise. - Parameters ---------- - url: The URL that provides the target system - timeout: Time to await for the port to open in seconds + url + The URL that provides the target system. + timeout + Time to await for the port to open in seconds. + + Returns + ------- + bool + If the port is available then return True; False otherwise. """ port = url.port or socket.getservbyname(url.scheme) diff --git a/asynceapi/config_session.py b/asynceapi/config_session.py index 558b7fed4..df26d7def 100644 --- a/asynceapi/config_session.py +++ b/asynceapi/config_session.py @@ -52,8 +52,10 @@ def __init__(self, device: Device, name: str) -> None: Parameters ---------- - device: The associated device instance - name: The name of the config session + device + The associated device instance. + name + The name of the config session. """ self._device = device self._cli = device.cli @@ -87,30 +89,35 @@ async def status_all(self) -> dict[str, Any]: Returns ------- - Dict object of native EOS eAPI response; see `status` method for + dict[str, Any] + Dictionary of native EOS eAPI response; see `status` method for details. Examples -------- - { - "maxSavedSessions": 1, - "maxOpenSessions": 5, - "sessions": { - "jeremy1": { - "instances": {}, - "state": "pending", - "commitUser": "", - "description": "" - }, - "ansible_167510439362": { - "instances": {}, - "state": "completed", - "commitUser": "joe.bob", - "description": "", - "completedTime": 1675104396.4500246 - } - } + Return example: + + ``` + { + "maxSavedSessions": 1, + "maxOpenSessions": 5, + "sessions": { + "jeremy1": { + "instances": {}, + "state": "pending", + "commitUser": "", + "description": "" + }, + "ansible_167510439362": { + "instances": {}, + "state": "completed", + "commitUser": "joe.bob", + "description": "", + "completedTime": 1675104396.4500246 } + } + } + ``` """ return await self._cli("show configuration sessions detail") # type: ignore[return-value] # json outformat returns dict[str, Any] @@ -126,41 +133,47 @@ async def status(self) -> dict[str, Any] | None: Returns ------- - Dict instance of the session status. If the session does not exist, + dict[str, Any] | None + Dictionary instance of the session status. If the session does not exist, then this method will return None. - The native eAPI results from JSON output, see example: - Examples -------- - all results: - { - "maxSavedSessions": 1, - "maxOpenSessions": 5, - "sessions": { - "jeremy1": { - "instances": {}, - "state": "pending", - "commitUser": "", - "description": "" - }, - "ansible_167510439362": { - "instances": {}, - "state": "completed", - "commitUser": "joe.bob", - "description": "", - "completedTime": 1675104396.4500246 - } + The return is the native eAPI results from JSON output: + + ``` + all results: + { + "maxSavedSessions": 1, + "maxOpenSessions": 5, + "sessions": { + "jeremy1": { + "instances": {}, + "state": "pending", + "commitUser": "", + "description": "" + }, + "ansible_167510439362": { + "instances": {}, + "state": "completed", + "commitUser": "joe.bob", + "description": "", + "completedTime": 1675104396.4500246 } } - - if the session name was 'jeremy1', then this method would return - { - "instances": {}, - "state": "pending", - "commitUser": "", - "description": "" - } + } + ``` + + If the session name was 'jeremy1', then this method would return: + + ``` + { + "instances": {}, + "state": "pending", + "commitUser": "", + "description": "" + } + ``` """ res = await self.status_all() return res["sessions"].get(self.name) @@ -174,15 +187,15 @@ async def push(self, content: list[str] | str, *, replace: bool = False) -> None Parameters ---------- - content: - The text configuration CLI commands, as a list of strings, that - will be sent to the device. If the parameter is a string, and not - a list, then split the string across linebreaks. In either case - any empty lines will be discarded before they are send to the - device. - replace: - When True, the content will replace the existing configuration - on the device. + content + The text configuration CLI commands, as a list of strings, that + will be sent to the device. If the parameter is a string, and not + a list, then split the string across linebreaks. In either case + any empty lines will be discarded before they are send to the + device. + replace + When True, the content will replace the existing configuration + on the device. """ # if given s string, we need to break it up into individual command # lines. @@ -212,10 +225,13 @@ async def commit(self, timer: str | None = None) -> None: # configure session # commit - If the timer is specified, format is "hh:mm:ss", then a commit timer is - started. A second commit action must be made to confirm the config - session before the timer expires; otherwise the config-session is - automatically aborted. + Parameters + ---------- + timer + If the timer is specified, format is "hh:mm:ss", then a commit timer is + started. A second commit action must be made to confirm the config + session before the timer expires; otherwise the config-session is + automatically aborted. """ command = f"{self._cli_config_session} commit" @@ -242,6 +258,7 @@ async def diff(self) -> str: Returns ------- + str Return a string in diff-patch format. References @@ -258,17 +275,18 @@ async def load_file(self, filename: str, *, replace: bool = False) -> None: Parameters ---------- - filename: - The name of the configuration file. The caller is required to - specify the filesystem, for example, the - filename="flash:thisfile.cfg" + filename + The name of the configuration file. The caller is required to + specify the filesystem, for example, the + filename="flash:thisfile.cfg". - replace: - When True, the contents of the file will completely replace the - session config for a load-replace behavior. + replace + When True, the contents of the file will completely replace the + session config for a load-replace behavior. Raises ------ + RuntimeError If there are any issues with loading the configuration file then a RuntimeError is raised with the error messages content. """ diff --git a/asynceapi/device.py b/asynceapi/device.py index ca5a30c25..933ae649c 100644 --- a/asynceapi/device.py +++ b/asynceapi/device.py @@ -71,23 +71,31 @@ def __init__( Parameters ---------- - host: The EOS target device, either hostname (DNS) or ipaddress. - username: The login user-name; requires the password parameter. - password: The login password; requires the username parameter. - proto: The protocol, http or https, to communicate eAPI with the device. - port: If not provided, the proto value is used to look up the associated + host + The EOS target device, either hostname (DNS) or ipaddress. + username + The login user-name; requires the password parameter. + password + The login password; requires the username parameter. + proto + The protocol, http or https, to communicate eAPI with the device. + port + If not provided, the proto value is used to look up the associated port (http=80, https=443). If provided, overrides the port used to communite with the device. + kwargs + Other named keyword arguments, some of them are being used in the function + cf Other Parameters section below, others are just passed as is to the httpx.AsyncClient. Other Parameters ---------------- - base_url: str - If provided, the complete URL to the device eAPI endpoint. + base_url : str + If provided, the complete URL to the device eAPI endpoint. - auth: - If provided, used as the httpx authorization initializer value. If - not provided, then username+password is assumed by the Caller and - used to create a BasicAuth instance. + auth : + If provided, used as the httpx authorization initializer value. If + not provided, then username+password is assumed by the Caller and + used to create a BasicAuth instance. """ self.port = port or getservbyname(proto) self.host = host @@ -111,6 +119,7 @@ async def check_connection(self) -> bool: Returns ------- + bool True when the device eAPI is accessible, False otherwise. """ return await port_check_url(self.base_url) @@ -132,18 +141,18 @@ async def cli( # noqa: PLR0913 Parameters ---------- - command: - A single command to execute; results in a single output response - commands: - A list of commands to execute; results in a list of output responses - ofmt: + command + A single command to execute; results in a single output response. + commands + A list of commands to execute; results in a list of output responses. + ofmt Either 'json' or 'text'; indicates the output format for the CLI commands. - version: + version By default the eAPI will use "version 1" for all API object models. This driver will, by default, always set version to "latest" so that the behavior matches the CLI of the device. The caller can override the "latest" behavior by explicitly setting the version. - suppress_error: + suppress_error When not False, then if the execution of the command would-have raised an EapiCommandError, rather than raising this exception this routine will return the value None. @@ -152,13 +161,13 @@ async def cli( # noqa: PLR0913 EapiCommandError, now response would be set to None instead. response = dev.cli(..., suppress_error=True) - auto_complete: + auto_complete Enabled/disables the command auto-compelete feature of the EAPI. Per the documentation: Allows users to use shorthand commands in eAPI calls. With this parameter included a user can send 'sh ver' via eAPI to get the output of 'show version'. - expand_aliases: + expand_aliases Enables/disables the command use of User defined alias. Per the documentation: Allowed users to provide the expandAliases parameter to eAPI @@ -166,11 +175,12 @@ async def cli( # noqa: PLR0913 For example if an alias is configured as 'sv' for 'show version' then an API call with sv and the expandAliases parameter will return the output of show version. - req_id: + req_id A unique identifier that will be echoed back by the switch. May be a string or number. Returns ------- + list[dict[str, Any] | str] | dict[str, Any] | str | None One or List of output responses, per the description above. """ if not any((command, commands)): @@ -199,7 +209,42 @@ def _jsonrpc_command( # noqa: PLR0913 expand_aliases: bool = False, req_id: int | str | None = None, ) -> dict[str, Any]: - """Create the JSON-RPC command dictionary object.""" + """Create the JSON-RPC command dictionary object. + + Parameters + ---------- + commands + A list of commands to execute; results in a list of output responses. + ofmt + Either 'json' or 'text'; indicates the output format for the CLI commands. + version + By default the eAPI will use "version 1" for all API object models. + This driver will, by default, always set version to "latest" so + that the behavior matches the CLI of the device. The caller can + override the "latest" behavior by explicitly setting the version. + auto_complete + Enabled/disables the command auto-compelete feature of the EAPI. Per the + documentation: + Allows users to use shorthand commands in eAPI calls. With this + parameter included a user can send 'sh ver' via eAPI to get the + output of 'show version'. + expand_aliases + Enables/disables the command use of User defined alias. Per the + documentation: + Allowed users to provide the expandAliases parameter to eAPI + calls. This allows users to use aliased commands via the API. + For example if an alias is configured as 'sv' for 'show version' + then an API call with sv and the expandAliases parameter will + return the output of show version. + req_id + A unique identifier that will be echoed back by the switch. May be a string or number. + + Returns + ------- + dict[str, Any]: + dict containing the JSON payload to run the command. + + """ cmd: dict[str, Any] = { "jsonrpc": "2.0", "method": "runCmds", @@ -224,16 +269,17 @@ async def jsonrpc_exec(self, jsonrpc: dict[str, Any]) -> list[dict[str, Any] | s Parameters ---------- - jsonrpc: - The JSON-RPC as created by the `meth`:_jsonrpc_command(). + jsonrpc + The JSON-RPC as created by the `meth`:_jsonrpc_command(). Raises ------ - EapiCommandError - In the event that a command resulted in an error response. + EapiCommandError + In the event that a command resulted in an error response. Returns ------- + list[dict[str, Any] | str] The list of command results; either dict or text depending on the JSON-RPC format parameter. """ @@ -282,11 +328,16 @@ async def jsonrpc_exec(self, jsonrpc: dict[str, Any]) -> list[dict[str, Any] | s ) def config_session(self, name: str) -> SessionConfig: - """ - return a SessionConfig instance bound to this device with the given session name. + """Return a SessionConfig instance bound to this device with the given session name. Parameters ---------- - name: The config-session name + name + The config-session name. + + Returns + ------- + SessionConfig + SessionConfig instance bound to this device with the given session name. """ return SessionConfig(self, name) diff --git a/pyproject.toml b/pyproject.toml index c07dd0e96..b9dfdad8c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -336,7 +336,7 @@ select = ["ALL", # TODO: Augment the numpy convention rules to make sure we add all the params # Uncomment below D417 "D415", - # "D417", + "D417", ] ignore = [ "COM812", # Ignoring conflicting rules that may cause conflicts when used with the formatter