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

feat(anta.tests): Added testcase to verify Login and Motd banner #526

Merged
merged 2 commits into from
Jan 29, 2024
Merged
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
62 changes: 62 additions & 0 deletions anta/tests/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,65 @@ def test(self) -> None:
failed_log = f"SSL certificate `{certificate.certificate_name}` is not configured properly:"
failed_log += get_failed_logs(expected_certificate_details, actual_certificate_details)
self.result.is_failure(f"{failed_log}\n")


class VerifyBannerLogin(AntaTest):
"""
This class verifies the login banner of a device.
Expected results:
* success: The test will pass if the login banner matches the provided input.
* failure: The test will fail if the login banner does not match the provided input.
"""

name = "VerifyBannerLogin"
description = "Verifies the login banner of a device."
categories = ["security"]
commands = [AntaCommand(command="show banner login")]

class Input(AntaTest.Input):
"""Defines the input parameters for this test case."""

login_banner: str
"""Expected login banner of the device."""

@AntaTest.anta_test
def test(self) -> None:
login_banner = self.instance_commands[0].json_output["loginBanner"]

# Remove leading and trailing whitespaces from each line
cleaned_banner = "\n".join(line.strip() for line in self.inputs.login_banner.split("\n"))
if login_banner != cleaned_banner:
self.result.is_failure(f"Expected `{cleaned_banner}` as the login banner, but found `{login_banner}` instead.")
else:
self.result.is_success()


class VerifyBannerMotd(AntaTest):
"""
This class verifies the motd banner of a device.
Expected results:
* success: The test will pass if the motd banner matches the provided input.
* failure: The test will fail if the motd banner does not match the provided input.
"""

name = "VerifyBannerMotd"
description = "Verifies the motd banner of a device."
categories = ["security"]
commands = [AntaCommand(command="show banner motd")]

class Input(AntaTest.Input):
"""Defines the input parameters for this test case."""

motd_banner: str
"""Expected motd banner of the device."""

@AntaTest.anta_test
def test(self) -> None:
motd_banner = self.instance_commands[0].json_output["motd"]

# Remove leading and trailing whitespaces from each line
cleaned_banner = "\n".join(line.strip() for line in self.inputs.motd_banner.split("\n"))
if motd_banner != cleaned_banner:
self.result.is_failure(f"Expected `{cleaned_banner}` as the motd banner, but found `{motd_banner}` instead.")
else:
self.result.is_success()
10 changes: 10 additions & 0 deletions examples/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,16 @@ anta.tests.security:
common_name: Arista Networks Internal IT Root Cert Authority
encryption_algorithm: RSA
key_size: 4096
- VerifyBannerLogin:
login_banner: |
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
- VerifyBannerMotd:
motd_banner: |
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.

anta.tests.snmp:
- VerifySnmpStatus:
Expand Down
108 changes: 108 additions & 0 deletions tests/units/anta_tests/test_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
VerifyAPIIPv4Acl,
VerifyAPIIPv6Acl,
VerifyAPISSLCertificate,
VerifyBannerLogin,
VerifyBannerMotd,
VerifySSHIPv4Acl,
VerifySSHIPv6Acl,
VerifySSHStatus,
Expand Down Expand Up @@ -569,4 +571,110 @@
],
},
},
{
"name": "success",
"test": VerifyBannerLogin,
"eos_data": [
{
"loginBanner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"login_banner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
},
"expected": {"result": "success"},
},
{
"name": "success-multiline",
"test": VerifyBannerLogin,
"eos_data": [
{
"loginBanner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"login_banner": """Copyright (c) 2023-2024 Arista Networks, Inc.
Use of this source code is governed by the Apache License 2.0
that can be found in the LICENSE file."""
},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-login-banner",
"test": VerifyBannerLogin,
"eos_data": [
{
"loginBanner": "Copyright (c) 2023 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
mtache marked this conversation as resolved.
Show resolved Hide resolved
"that can be found in the LICENSE file."
}
],
"inputs": {
"login_banner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
},
"expected": {
"result": "failure",
"messages": [
"Expected `Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file.` as the login banner, but found `Copyright (c) 2023 Arista Networks, Inc.\nUse of this source code is "
"governed by the Apache License 2.0\nthat can be found in the LICENSE file.` instead."
],
},
},
{
"name": "success",
"test": VerifyBannerMotd,
"eos_data": [
{
"motd": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"motd_banner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
},
"expected": {"result": "success"},
},
{
"name": "success-multiline",
"test": VerifyBannerMotd,
"eos_data": [
{
"motd": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"motd_banner": """Copyright (c) 2023-2024 Arista Networks, Inc.
Use of this source code is governed by the Apache License 2.0
that can be found in the LICENSE file."""
},
"expected": {"result": "success"},
},
{
"name": "failure-incorrect-motd-banner",
"test": VerifyBannerMotd,
"eos_data": [
{
"motd": "Copyright (c) 2023 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
}
],
"inputs": {
"motd_banner": "Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file."
},
"expected": {
"result": "failure",
"messages": [
"Expected `Copyright (c) 2023-2024 Arista Networks, Inc.\nUse of this source code is governed by the Apache License 2.0\n"
"that can be found in the LICENSE file.` as the motd banner, but found `Copyright (c) 2023 Arista Networks, Inc.\nUse of this source code is "
"governed by the Apache License 2.0\nthat can be found in the LICENSE file.` instead."
],
},
},
]