Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(anta.tests): Updated Logging Module with Adding a user defined field for send cmd severity level #1008

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions anta/custom_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,4 @@ def validate_regex(value: str) -> str:
SnmpHashingAlgorithm = Literal["MD5", "SHA", "SHA-224", "SHA-256", "SHA-384", "SHA-512"]
SnmpEncryptionAlgorithm = Literal["AES-128", "AES-192", "AES-256", "DES"]
DynamicVlanSource = Literal["dmf", "dot1x", "dynvtep", "evpn", "mlag", "mlagsync", "mvpn", "swfwd", "vccbfd"]
LogSeverityLevel = Literal["alerts", "critical", "debugging", "emergencies", "errors", "informational", "notifications", "warnings"]
101 changes: 62 additions & 39 deletions anta/tests/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@
from ipaddress import IPv4Address
from typing import TYPE_CHECKING, ClassVar

from anta.models import AntaCommand, AntaTest
from anta.custom_types import LogSeverityLevel
from anta.models import AntaCommand, AntaTemplate, AntaTest

if TYPE_CHECKING:
import logging

from anta.models import AntaTemplate


def _get_logging_states(logger: logging.Logger, command_output: str) -> str:
"""Parse `show logging` output and gets operational logging states used in the tests in this module.
Expand Down Expand Up @@ -201,35 +200,43 @@ class VerifyLoggingLogsGeneration(AntaTest):
This test performs the following checks:
1. Sends a test log message at the **informational** level
2. Retrieves the most recent logs (last 30 seconds)
3. Verifies that the test message was successfully logged
!!! warning
EOS logging buffer should be set to severity level `informational` or higher for this test to work.
1. Sends a test log message at the specified severity log level.
2. Retrieves the most recent logs (last 30 seconds).
3. Verifies that the test message was successfully logged.
Expected Results
----------------
* Success: If logs are being generated and the test message is found in recent logs.
* Failure: If any of the following occur:
- The test message is not found in recent logs
- The logging system is not capturing new messages
- No logs are being generated
- The test message is not found in recent logs.
- The logging system is not capturing new messages.
- No logs are being generated.
Examples
--------
```yaml
anta.tests.logging:
- VerifyLoggingLogsGeneration:
severity_level: informational
```
"""

categories: ClassVar[list[str]] = ["logging"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
AntaCommand(command="send log level informational message ANTA VerifyLoggingLogsGeneration validation", ofmt="text"),
AntaCommand(command="show logging informational last 30 seconds | grep ANTA", ofmt="text", use_cache=False),
AntaTemplate(template="send log level {severity_level} message ANTA VerifyLoggingLogsGeneration validation", ofmt="text"),
AntaTemplate(template="show logging {severity_level} last 30 seconds | grep ANTA", ofmt="text", use_cache=False),
]

class Input(AntaTest.Input):
"""Input model for the VerifyLoggingLogsGeneration test."""

severity_level: LogSeverityLevel = "informational"
"""Specify log severity level, Defaults to informational."""

def render(self, template: AntaTemplate) -> list[AntaCommand]:
"""Render the template for log severity level in the input."""
return [template.render(severity_level=self.inputs.severity_level)]

@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyLoggingLogsGeneration."""
Expand All @@ -248,37 +255,45 @@ class VerifyLoggingHostname(AntaTest):
This test performs the following checks:
1. Retrieves the device's configured FQDN
2. Sends a test log message at the **informational** level
3. Retrieves the most recent logs (last 30 seconds)
4. Verifies that the test message includes the complete FQDN of the device
!!! warning
EOS logging buffer should be set to severity level `informational` or higher for this test to work.
1. Retrieves the device's configured FQDN.
2. Sends a test log message at the specified severity log level.
3. Retrieves the most recent logs (last 30 seconds).
4. Verifies that the test message includes the complete FQDN of the device.
Expected Results
----------------
* Success: If logs are generated with the device's complete FQDN.
* Failure: If any of the following occur:
- The test message is not found in recent logs
- The log message does not include the device's FQDN
- The FQDN in the log message doesn't match the configured FQDN
- The test message is not found in recent logs.
- The log message does not include the device's FQDN.
- The FQDN in the log message doesn't match the configured FQDN.
Examples
--------
```yaml
anta.tests.logging:
- VerifyLoggingHostname:
severity_level: informational
```
"""

categories: ClassVar[list[str]] = ["logging"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
AntaCommand(command="show hostname", revision=1),
AntaCommand(command="send log level informational message ANTA VerifyLoggingHostname validation", ofmt="text"),
AntaCommand(command="show logging informational last 30 seconds | grep ANTA", ofmt="text", use_cache=False),
AntaTemplate(template="send log level {severity_level} message ANTA VerifyLoggingHostname validation", ofmt="text"),
AntaTemplate(template="show logging {severity_level} last 30 seconds | grep ANTA", ofmt="text", use_cache=False),
]

class Input(AntaTest.Input):
"""Input model for the VerifyLoggingHostname test."""

severity_level: LogSeverityLevel = "informational"
"""Specify log severity level, Defaults to informational."""

def render(self, template: AntaTemplate) -> list[AntaCommand]:
"""Render the template for log severity level in the input."""
return [template.render(severity_level=self.inputs.severity_level)]

@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyLoggingHostname."""
Expand All @@ -303,37 +318,45 @@ class VerifyLoggingTimestamp(AntaTest):
This test performs the following checks:
1. Sends a test log message at the **informational** level
2. Retrieves the most recent logs (last 30 seconds)
3. Verifies that the test message is present with a high-resolution RFC3339 timestamp format
- Example format: `2024-01-25T15:30:45.123456+00:00`
- Includes microsecond precision
- Contains timezone offset
!!! warning
EOS logging buffer should be set to severity level `informational` or higher for this test to work.
1. Sends a test log message at the specified severity log level.
2. Retrieves the most recent logs (last 30 seconds).
3. Verifies that the test message is present with a high-resolution RFC3339 timestamp format.
- Example format: `2024-01-25T15:30:45.123456+00:00`.
- Includes microsecond precision.
- Contains timezone offset.
Expected Results
----------------
* Success: If logs are generated with the correct high-resolution RFC3339 timestamp format.
* Failure: If any of the following occur:
- The test message is not found in recent logs
- The timestamp format does not match the expected RFC3339 format
- The test message is not found in recent logs.
- The timestamp format does not match the expected RFC3339 format.
Examples
--------
```yaml
anta.tests.logging:
- VerifyLoggingTimestamp:
severity_level: informational
```
"""

categories: ClassVar[list[str]] = ["logging"]
commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
AntaCommand(command="send log level informational message ANTA VerifyLoggingTimestamp validation", ofmt="text"),
AntaCommand(command="show logging informational last 30 seconds | grep ANTA", ofmt="text", use_cache=False),
AntaTemplate(template="send log level {severity_level} message ANTA VerifyLoggingTimestamp validation", ofmt="text"),
AntaTemplate(template="show logging {severity_level} last 30 seconds | grep ANTA", ofmt="text", use_cache=False),
]

class Input(AntaTest.Input):
"""Input model for the VerifyLoggingTimestamp test."""

severity_level: LogSeverityLevel = "informational"
"""Specify log severity level, Defaults to informational."""

def render(self, template: AntaTemplate) -> list[AntaCommand]:
"""Render the template for log severity level in the input."""
return [template.render(severity_level=self.inputs.severity_level)]

@AntaTest.anta_test
def test(self) -> None:
"""Main test function for VerifyLoggingTimestamp."""
Expand Down
3 changes: 3 additions & 0 deletions examples/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ anta.tests.logging:
# Verifies there are no syslog messages with a severity of ERRORS or higher.
- VerifyLoggingHostname:
# Verifies if logs are generated with the device FQDN.
severity_level: informational
- VerifyLoggingHosts:
# Verifies logging hosts (syslog servers) for a specified VRF.
hosts:
Expand All @@ -299,6 +300,7 @@ anta.tests.logging:
vrf: default
- VerifyLoggingLogsGeneration:
# Verifies if logs are generated.
severity_level: informational
- VerifyLoggingPersistent:
# Verifies if logging persistent is enabled and logs are saved in flash.
- VerifyLoggingSourceIntf:
Expand All @@ -307,6 +309,7 @@ anta.tests.logging:
vrf: default
- VerifyLoggingTimestamp:
# Verifies if logs are generated with the appropriate timestamp.
severity_level: informational
- VerifySyslogLogging:
# Verifies if syslog logging is enabled.
anta.tests.mlag:
Expand Down
22 changes: 11 additions & 11 deletions tests/units/anta_tests/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@
"2023-05-10T13:54:21.463497-05:00 NW-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
"Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingLogsGeneration validation\n",
],
"inputs": None,
"inputs": {"severity_level": "informational"},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyLoggingLogsGeneration,
"eos_data": ["", "Log Buffer:\n"],
"inputs": None,
"inputs": {"severity_level": "notifications"},
"expected": {"result": "failure", "messages": ["Logs are not generated"]},
},
{
Expand All @@ -186,7 +186,7 @@
"2023-05-10T15:41:44.701810-05:00 NW-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
"Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingHostname validation\n",
],
"inputs": None,
"inputs": {"severity_level": "informational"},
"expected": {"result": "success"},
},
{
Expand All @@ -195,10 +195,10 @@
"eos_data": [
{"hostname": "NW-CORE", "fqdn": "NW-CORE.example.org"},
"",
"2023-05-10T13:54:21.463497-05:00 NW-CORE ConfigAgent: %SYS-6-LOGMSG_INFO: "
"2023-05-10T13:54:21.463497-05:00 NW-CORE ConfigAgent: %SYS-6-LOGMSG_NOTICE: "
"Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingLogsHostname validation\n",
],
"inputs": None,
"inputs": {"severity_level": "notifications"},
"expected": {"result": "failure", "messages": ["Logs are not generated with the device FQDN"]},
},
{
Expand All @@ -211,7 +211,7 @@
"2023-05-10T15:42:44.680813-05:00 NW-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
"Other log\n",
],
"inputs": None,
"inputs": {"severity_level": "informational"},
"expected": {"result": "success"},
},
{
Expand All @@ -224,28 +224,28 @@
"2023-05-10T15:42:44.680813+05:00 NW-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
"Other log\n",
],
"inputs": None,
"inputs": {"severity_level": "informational"},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyLoggingTimestamp,
"eos_data": [
"",
"May 10 13:54:22 NE-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
"May 10 13:54:22 NE-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_ALERT: "
"Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingTimestamp validation\n",
],
"inputs": None,
"inputs": {"severity_level": "alerts"},
"expected": {"result": "failure", "messages": ["Logs are not generated with the appropriate timestamp format"]},
},
{
"name": "failure-no-matching-log",
"test": VerifyLoggingTimestamp,
"eos_data": [
"",
"May 10 13:54:22 NE-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: Message from arista on command-api (10.22.1.107): BLAH\n",
"May 10 13:54:22 NE-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_NOTICE: Message from arista on command-api (10.22.1.107): BLAH\n",
],
"inputs": None,
"inputs": {"severity_level": "notifications"},
"expected": {"result": "failure", "messages": ["Logs are not generated with the appropriate timestamp format"]},
},
{
Expand Down
Loading