feat(NHN): add NHN cloud provider with 6 checks (#6870)

Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
This commit is contained in:
eeche
2025-04-09 22:13:24 +09:00
committed by Pepe Fagoaga
parent b81e12f697
commit d489c80857
62 changed files with 3615 additions and 4 deletions
+2 -2
View File
@@ -16,11 +16,11 @@ prowler_command = "prowler"
# capsys
# https://docs.pytest.org/en/7.1.x/how-to/capture-stdout-stderr.html
prowler_default_usage_error = "usage: prowler [-h] [--version] {aws,azure,gcp,kubernetes,microsoft365,dashboard} ..."
prowler_default_usage_error = "usage: prowler [-h] [--version] {aws,azure,gcp,kubernetes,microsoft365,nhn,dashboard} ..."
def mock_get_available_providers():
return ["aws", "azure", "gcp", "kubernetes", "microsoft365"]
return ["aws", "azure", "gcp", "kubernetes", "microsoft365", "nhn"]
@pytest.mark.arg_parser
@@ -0,0 +1,16 @@
### Account, Check and/or Region can be * to apply for all the cases.
### Resources and tags are lists that can have either Regex or Keywords.
### Tags is an optional list that matches on tuples of 'key=value' and are "ANDed" together.
### Use an alternation Regex to match one of multiple tags with "ORed" logic.
### For each check you can except Accounts, Regions, Resources and/or Tags.
########################### MUTELIST EXAMPLE ###########################
Mutelist:
Accounts:
"subscription_1":
Checks:
"compute_instance_public_ip":
Regions:
- "*"
Resources:
- "resource_1"
- "resource_2"
@@ -0,0 +1,100 @@
import yaml
from mock import MagicMock
from prowler.providers.nhn.lib.mutelist.mutelist import NHNMutelist
from tests.lib.outputs.fixtures.fixtures import generate_finding_output
MUTELIST_FIXTURE_PATH = "tests/providers/nhn/lib/mutelist/fixtures/nhn_mutelist.yaml"
class TestNHNMutelist:
def test_get_mutelist_file_from_local_file(self):
mutelist = NHNMutelist(mutelist_path=MUTELIST_FIXTURE_PATH)
with open(MUTELIST_FIXTURE_PATH) as f:
mutelist_fixture = yaml.safe_load(f)["Mutelist"]
assert mutelist.mutelist == mutelist_fixture
assert mutelist.mutelist_file_path == MUTELIST_FIXTURE_PATH
def test_get_mutelist_file_from_local_file_non_existent(self):
mutelist_path = "tests/lib/mutelist/fixtures/not_present"
mutelist = NHNMutelist(mutelist_path=mutelist_path)
assert mutelist.mutelist == {}
assert mutelist.mutelist_file_path == mutelist_path
def test_validate_mutelist_not_valid_key(self):
mutelist_path = MUTELIST_FIXTURE_PATH
with open(mutelist_path) as f:
mutelist_fixture = yaml.safe_load(f)["Mutelist"]
mutelist_fixture["Accounts1"] = mutelist_fixture["Accounts"]
del mutelist_fixture["Accounts"]
mutelist = NHNMutelist(mutelist_content=mutelist_fixture)
assert not mutelist.validate_mutelist()
assert mutelist.mutelist == {}
assert mutelist.mutelist_file_path is None
def test_is_finding_muted(self):
# Mutelist
mutelist_content = {
"Accounts": {
"resource_1": {
"Checks": {
"check_test": {
"Regions": ["*"],
"Resources": ["test_resource"],
}
}
}
}
}
mutelist = NHNMutelist(mutelist_content=mutelist_content)
finding = MagicMock()
finding.resource_id = "resource_1"
finding.check_metadata = MagicMock()
finding.check_metadata.CheckID = "check_test"
finding.status = "FAIL"
finding.resource_name = "test_resource"
finding.location = "test_region"
finding.resource_tags = []
assert mutelist.is_finding_muted(finding)
def test_mute_finding(self):
# Mutelist
mutelist_content = {
"Accounts": {
"resource_1": {
"Checks": {
"check_test": {
"Regions": ["*"],
"Resources": ["test_resource"],
}
}
}
}
}
mutelist = NHNMutelist(mutelist_content=mutelist_content)
finding_1 = generate_finding_output(
check_id="check_test",
status="FAIL",
account_uid="resource_1",
region="test_region",
resource_uid="test_resource",
resource_tags=[],
muted=False,
)
muted_finding = mutelist.mute_finding(finding=finding_1)
assert muted_finding.status == "MUTED"
assert muted_finding.muted
assert muted_finding.raw["status"] == "FAIL"
+29
View File
@@ -0,0 +1,29 @@
from mock import MagicMock
from prowler.providers.nhn.nhn_provider import NhnProvider
def set_mocked_nhn_provider(
username="test_user",
password="test_password",
tenant_id="tenant123",
audit_config=None,
fixer_config=None,
):
"""
Creates a mocked NHN Provider object for testing without real network calls.
"""
provider = MagicMock(spec=NhnProvider) # or just MagicMock()
provider.type = "nhn"
provider._username = username
provider._password = password
provider._tenant_id = tenant_id
provider._token = "fake_keystone_token"
provider.session = MagicMock()
provider.audit_config = audit_config
provider.fixer_config = fixer_config
return provider
+157
View File
@@ -0,0 +1,157 @@
import os
from unittest.mock import MagicMock, patch
import pytest
from prowler.providers.common.models import Connection
from prowler.providers.nhn.nhn_provider import NhnProvider
class TestNhnProvider:
@patch.dict(
os.environ,
{
"NHN_USERNAME": "env_user",
"NHN_PASSWORD": "env_pass",
"NHN_TENANT_ID": "env_tenant",
},
)
@patch("prowler.providers.nhn.nhn_provider.load_and_validate_config_file")
@patch("requests.post")
def test_nhn_provider_init_success(self, mock_post, mock_load_config):
"""
Test a successful initialization of NhnProvider
with valid username/password/tenant_id and a Keystone token response = 200.
"""
# 1) Mock load_and_validate_config_file to avoid reading real config file
mock_load_config.return_value = {}
# 2) Mock the requests.post to simulate a successful token response
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
"access": {"token": {"id": "fake_keystone_token"}}
}
mock_post.return_value = mock_response
# 3) Create provider
provider = NhnProvider(
username="test_user",
password="test_pass",
tenant_id="test_tenant",
)
# 4) Assertions
assert provider._token == "fake_keystone_token"
assert provider.session is not None
assert provider.session.headers["X-Auth-Token"] == "fake_keystone_token"
@patch.dict(os.environ, {}, clear=True)
@patch(
"prowler.providers.nhn.nhn_provider.load_and_validate_config_file",
return_value={},
)
def test_nhn_provider_init_missing_args(self, mock_load_config):
"""
Test initialization when username/password/tenant_id is missing => ValueError
"""
with pytest.raises(ValueError) as exc_info:
NhnProvider(username="", password="secret", tenant_id="tenant")
assert "requires username, password and tenant_id" in str(exc_info.value)
@patch(
"prowler.providers.nhn.nhn_provider.load_and_validate_config_file",
return_value={},
)
@patch("requests.post")
def test_nhn_provider_init_token_fail(self, mock_post, mock_load_config):
"""
Test the case where Keystone token request fails (non-200)
=> provider._session remains None
"""
mock_post.return_value.status_code = 401
mock_post.return_value.text = "Unauthorized"
with pytest.raises(ValueError) as exc_info:
NhnProvider(
username="test_user",
password="test_pass",
tenant_id="tenant123",
)
assert "Failed to get NHN token" in str(exc_info.value)
@patch("prowler.providers.nhn.nhn_provider.requests")
def test_test_connection_success(self, mock_requests):
"""
Test test_connection static method => success case
"""
# 1) Mock token success
mock_post_response = MagicMock()
mock_post_response.status_code = 200
mock_post_response.json.return_value = {
"access": {"token": {"id": "fake_keystone_token"}}
}
# 2) Mock /servers success
mock_get_response = MagicMock()
mock_get_response.status_code = 200
mock_requests.post.return_value = mock_post_response
mock_requests.get.return_value = mock_get_response
conn = NhnProvider.test_connection(
username="test_user",
password="test_pass",
tenant_id="tenant123",
raise_on_exception=True,
)
assert isinstance(conn, Connection)
assert conn.is_connected is True
assert conn.error is None
@patch("prowler.providers.nhn.nhn_provider.requests")
def test_test_connection_token_fail(self, mock_requests):
"""
Test test_connection => token request fails => returns Connection(error=...)
"""
mock_requests.post.return_value.status_code = 403
mock_requests.post.return_value.text = "Forbidden"
conn = NhnProvider.test_connection(
username="bad_user",
password="bad_pass",
tenant_id="tenant123",
raise_on_exception=False, # so we don't raise, we get Connection object
)
assert conn.is_connected is False
assert conn.error is not None
assert "Failed to get token" in str(conn.error)
@patch("prowler.providers.nhn.nhn_provider.requests")
def test_test_connection_servers_fail(self, mock_requests):
"""
Test test_connection => token OK, but /servers fails => returns Connection(error=...)
"""
# Keystone token success
mock_post_response = MagicMock()
mock_post_response.status_code = 200
mock_post_response.json.return_value = {
"access": {"token": {"id": "fake_keystone_token"}}
}
mock_requests.post.return_value = mock_post_response
# /servers fail
mock_get_response = MagicMock()
mock_get_response.status_code = 500
mock_get_response.text = "Internal Server Error"
mock_requests.get.return_value = mock_get_response
conn = NhnProvider.test_connection(
username="test_user",
password="test_pass",
tenant_id="tenant123",
raise_on_exception=False,
)
assert conn.is_connected is False
assert conn.error is not None
assert "/servers call failed" in str(conn.error)
@@ -0,0 +1,110 @@
from unittest import mock
from uuid import uuid4
from prowler.providers.nhn.services.compute.compute_service import Instance
from tests.providers.nhn.nhn_fixtures import set_mocked_nhn_provider
class Test_compute_instance_login_user:
def test_no_instances(self):
# 1) Make a MagicMock for compute_client
compute_client = mock.MagicMock()
compute_client.instances = []
# 2) Patch get_global_provider() to return a mocked NHN provider
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
# patch the 'compute_instance_login_user.compute_client' used in the check code
"prowler.providers.nhn.services.compute.compute_instance_login_user.compute_instance_login_user.compute_client",
new=compute_client,
),
):
# 3) Import the check code AFTER patching
from prowler.providers.nhn.services.compute.compute_instance_login_user.compute_instance_login_user import (
compute_instance_login_user,
)
# 4) Run the check
check = compute_instance_login_user()
result = check.execute()
# 5) Assertions
assert len(result) == 0 # no instances => no findings
def test_has_instance_non_admin_login(self):
# Make a MagicMock for compute_client
compute_client = mock.MagicMock()
# Suppose we have 1 instance with login_user=False => PASS expected
instance_id = str(uuid4())
instance_name = "testVM"
mock_instance = mock.MagicMock(spec=Instance)
mock_instance.id = instance_id
mock_instance.name = instance_name
mock_instance.login_user = False # => means not admin login
compute_client.instances = [mock_instance]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.compute.compute_instance_login_user.compute_instance_login_user.compute_client",
new=compute_client,
),
):
from prowler.providers.nhn.services.compute.compute_instance_login_user.compute_instance_login_user import (
compute_instance_login_user,
)
check = compute_instance_login_user()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert "has a appropriate login user" in result[0].status_extended
assert result[0].resource_name == instance_name
assert result[0].resource_id == instance_id
def test_has_instance_admin_login(self):
# Another scenario: instance with login_user=True => FAIL expected
compute_client = mock.MagicMock()
instance_id = str(uuid4())
instance_name = "rootVM"
mock_instance = mock.MagicMock(spec=Instance)
mock_instance.id = instance_id
mock_instance.name = instance_name
mock_instance.login_user = True # => admin or root user
compute_client.instances = [mock_instance]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.compute.compute_instance_login_user.compute_instance_login_user.compute_client",
new=compute_client,
),
):
from prowler.providers.nhn.services.compute.compute_instance_login_user.compute_instance_login_user import (
compute_instance_login_user,
)
check = compute_instance_login_user()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
"has an Administrative(admin/root) login user"
in result[0].status_extended
)
assert result[0].resource_name == instance_name
assert result[0].resource_id == instance_id
@@ -0,0 +1,107 @@
from unittest import mock
from uuid import uuid4
from prowler.providers.nhn.services.compute.compute_service import Instance
from tests.providers.nhn.nhn_fixtures import set_mocked_nhn_provider
class Test_compute_instance_public_ip:
def test_no_instances(self):
# 1) Make a MagicMock for compute_client
compute_client = mock.MagicMock()
compute_client.instances = []
# 2) Patch get_global_provider() to return a mocked NHN provider
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
# patch the 'compute_instance_public_ip.compute_client' used in the check code
"prowler.providers.nhn.services.compute.compute_instance_public_ip.compute_instance_public_ip.compute_client",
new=compute_client,
),
):
# 3) Import the check code AFTER patching
from prowler.providers.nhn.services.compute.compute_instance_public_ip.compute_instance_public_ip import (
compute_instance_public_ip,
)
# 4) Run the check
check = compute_instance_public_ip()
result = check.execute()
# 5) Assertions
assert len(result) == 0 # no instances => no findings
def test_has_instance_non_public_ip(self):
# Make a MagicMock for compute_client
compute_client = mock.MagicMock()
# Suppose we have 1 instance with public_ip=False => PASS expected
instance_id = str(uuid4())
instance_name = "testVM"
mock_instance = mock.MagicMock(spec=Instance)
mock_instance.id = instance_id
mock_instance.name = instance_name
mock_instance.public_ip = False # => means does not have public IP
compute_client.instances = [mock_instance]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.compute.compute_instance_public_ip.compute_instance_public_ip.compute_client",
new=compute_client,
),
):
from prowler.providers.nhn.services.compute.compute_instance_public_ip.compute_instance_public_ip import (
compute_instance_public_ip,
)
check = compute_instance_public_ip()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert "does not have a public IP" in result[0].status_extended
assert result[0].resource_name == instance_name
assert result[0].resource_id == instance_id
def test_has_instance_public_ip(self):
# Another scenario: instance with public_ip=True => FAIL expected
compute_client = mock.MagicMock()
instance_id = str(uuid4())
instance_name = "rootVM"
mock_instance = mock.MagicMock(spec=Instance)
mock_instance.id = instance_id
mock_instance.name = instance_name
mock_instance.public_ip = True # => means has public IP
compute_client.instances = [mock_instance]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.compute.compute_instance_public_ip.compute_instance_public_ip.compute_client",
new=compute_client,
),
):
from prowler.providers.nhn.services.compute.compute_instance_public_ip.compute_instance_public_ip import (
compute_instance_public_ip,
)
check = compute_instance_public_ip()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert "has a public IP" in result[0].status_extended
assert result[0].resource_name == instance_name
assert result[0].resource_id == instance_id
@@ -0,0 +1,108 @@
from unittest import mock
from uuid import uuid4
from prowler.providers.nhn.services.compute.compute_service import Instance
from tests.providers.nhn.nhn_fixtures import set_mocked_nhn_provider
class Test_compute_instance_security_groups:
def test_no_instances(self):
# 1) Make a MagicMock for compute_client
compute_client = mock.MagicMock()
compute_client.instances = []
# 2) Patch get_global_provider() to return a mocked NHN provider
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
# patch the 'compute_instance_security_groups.compute_client' used in the check code
"prowler.providers.nhn.services.compute.compute_instance_security_groups.compute_instance_security_groups.compute_client",
new=compute_client,
),
):
# 3) Import the check code AFTER patching
from prowler.providers.nhn.services.compute.compute_instance_security_groups.compute_instance_security_groups import (
compute_instance_security_groups,
)
# 4) Run the check
check = compute_instance_security_groups()
result = check.execute()
# 5) Assertions
assert len(result) == 0 # no instances => no findings
def test_has_instance_variety_security_groups(self):
# Make a MagicMock for compute_client
compute_client = mock.MagicMock()
# Suppose we have 1 instance with security_groups=False => PASS expected
instance_id = str(uuid4())
instance_name = "testVM"
mock_instance = mock.MagicMock(spec=Instance)
mock_instance.id = instance_id
mock_instance.name = instance_name
mock_instance.security_groups = False # => means has variety of security groups
compute_client.instances = [mock_instance]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.compute.compute_instance_security_groups.compute_instance_security_groups.compute_client",
new=compute_client,
),
):
from prowler.providers.nhn.services.compute.compute_instance_security_groups.compute_instance_security_groups import (
compute_instance_security_groups,
)
check = compute_instance_security_groups()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert "has a variety of security groups" in result[0].status_extended
assert result[0].resource_name == instance_name
assert result[0].resource_id == instance_id
def test_has_instance_security_groups(self):
# Another scenario: instance with security_groups=True => FAIL expected
compute_client = mock.MagicMock()
instance_id = str(uuid4())
instance_name = "rootVM"
mock_instance = mock.MagicMock(spec=Instance)
mock_instance.id = instance_id
mock_instance.name = instance_name
mock_instance.security_groups = (
True # => means has only the default security group
)
compute_client.instances = [mock_instance]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.compute.compute_instance_security_groups.compute_instance_security_groups.compute_client",
new=compute_client,
),
):
from prowler.providers.nhn.services.compute.compute_instance_security_groups.compute_instance_security_groups import (
compute_instance_security_groups,
)
check = compute_instance_security_groups()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert "has only the default security group" in result[0].status_extended
assert result[0].resource_name == instance_name
assert result[0].resource_id == instance_id
@@ -0,0 +1,100 @@
from unittest.mock import MagicMock, patch
from prowler.providers.nhn.services.compute.compute_service import NHNComputeService
from tests.providers.nhn.nhn_fixtures import set_mocked_nhn_provider
class TestNHNComputeService:
@patch("prowler.providers.nhn.services.compute.compute_service.logger")
def test_compute_service_basic(self, mock_logger):
"""
Test that NHNComputeService properly calls _list_servers(),
_get_server_detail() for each server, and populates self.instances.
"""
# create a mocked NHN Provider
provider = set_mocked_nhn_provider(
username="testUser",
password="testPass",
tenant_id="tenant123",
)
# define mocked responses
mocked_response_servers = MagicMock()
mocked_response_servers.status_code = 200
mocked_response_servers.json.return_value = {
"servers": [
{"id": "server1", "name": "myserver1"},
{"id": "server2", "name": "myserver2"},
]
}
mocked_response_server1 = MagicMock()
mocked_response_server1.status_code = 200
mocked_response_server1.json.return_value = {
"server": {
"addresses": {
"vpc1": [
{"OS-EXT-IPS:type": "floating"},
]
},
"security_groups": [{"name": "default"}],
"metadata": {"login_username": "root"},
}
}
mocked_response_server2 = MagicMock()
mocked_response_server2.status_code = 200
mocked_response_server2.json.return_value = {
"server": {
"addresses": {
"vpc1": [
{"OS-EXT-IPS:type": "fixed"},
]
},
"security_groups": [{"name": "default"}, {"name": "other-sg"}],
"metadata": {"login_username": "regularuser"},
}
}
def get_side_effect(url, timeout=10):
print(f"Called with timeout={timeout}")
if (
"/v2/tenant123/servers" in url
and not url.endswith("server1")
and not url.endswith("server2")
):
return mocked_response_servers
elif url.endswith("server1"):
return mocked_response_server1
elif url.endswith("server2"):
return mocked_response_server2
else:
mock_404 = MagicMock()
mock_404.status_code = 404
mock_404.text = "Not Found"
return mock_404
provider.session.get.side_effect = get_side_effect
# create NHNComputeService, which internally calls _get_instances()
compute_service = NHNComputeService(provider)
assert len(compute_service.instances) == 2
# first instance
inst1 = compute_service.instances[0]
assert inst1.id == "server1"
assert inst1.name == "myserver1"
assert inst1.public_ip is True
assert inst1.security_groups is True
assert inst1.login_user is True
# second instance
inst2 = compute_service.instances[1]
assert inst2.id == "server2"
assert inst2.name == "myserver2"
assert inst2.public_ip is False
assert inst2.security_groups is False
assert inst2.login_user is False
mock_logger.error.assert_not_called()
@@ -0,0 +1,98 @@
from unittest.mock import MagicMock, patch
from prowler.providers.nhn.services.network.network_service import NHNNetworkService
from tests.providers.nhn.nhn_fixtures import set_mocked_nhn_provider
class TestNHNNetworkService:
@patch("prowler.providers.nhn.services.network.network_service.logger")
def test_network_service_basic(self, mock_logger):
"""
Test that NHNNetworkService correctly calls _list_vpcs(),
_get_vpc_detail() for each VPC, and populates self.networks and self.subnets.
"""
# create a mocked NHN Provider
provider = set_mocked_nhn_provider(
username="testUser",
password="testPass",
tenant_id="tenant123",
)
# define mocked responses for VPCs and Subnets
mocked_response_vpcs = MagicMock()
mocked_response_vpcs.status_code = 200
mocked_response_vpcs.json.return_value = {
"vpcs": [
{"id": "vpc1", "name": "myvpc1"},
{"id": "vpc2", "name": "myvpc2"},
]
}
mocked_response_vpc1 = MagicMock()
mocked_response_vpc1.status_code = 200
mocked_response_vpc1.json.return_value = {
"vpc": {
"routingtables": [],
"subnets": [
{"name": "subnet1", "router:external": True, "enable_dhcp": False},
],
}
}
mocked_response_vpc2 = MagicMock()
mocked_response_vpc2.status_code = 200
mocked_response_vpc2.json.return_value = {
"vpc": {
"routingtables": [{"id": "rt1"}],
"subnets": [
{"name": "subnet2", "router:external": False, "enable_dhcp": True},
],
}
}
def get_side_effect(url, timeout=10):
print(f"Called with timeout={timeout}")
if (
"/v2.0/vpcs" in url
and not url.endswith("vpc1")
and not url.endswith("vpc2")
):
return mocked_response_vpcs
elif url.endswith("vpc1"):
return mocked_response_vpc1
elif url.endswith("vpc2"):
return mocked_response_vpc2
else:
mock_404 = MagicMock()
mock_404.status_code = 404
mock_404.text = "Not Found"
return mock_404
provider.session.get.side_effect = get_side_effect
# create NHNNetworkService, which internally calls _get_networks() and _get_subnets()
network_service = NHNNetworkService(provider)
assert len(network_service.networks) == 2
# first network
net1 = network_service.networks[0]
assert net1.id == "vpc1"
assert net1.name == "myvpc1"
assert net1.empty_routingtables is True
assert len(net1.subnets) == 1
assert net1.subnets[0].name == "subnet1"
assert net1.subnets[0].external_router is True
assert net1.subnets[0].enable_dhcp is False
# second network
net2 = network_service.networks[1]
assert net2.id == "vpc2"
assert net2.name == "myvpc2"
assert net2.empty_routingtables is False # Assuming there's a routing table
assert len(net2.subnets) == 1
assert net2.subnets[0].name == "subnet2"
assert net2.subnets[0].external_router is False
assert net2.subnets[0].enable_dhcp is True
mock_logger.error.assert_not_called()
@@ -0,0 +1,107 @@
from unittest import mock
from uuid import uuid4
from prowler.providers.nhn.services.network.network_service import Network
from tests.providers.nhn.nhn_fixtures import set_mocked_nhn_provider
class Test_vpc_has_empty_routingtables:
def test_no_networks(self):
# 1) Make a MagicMock for network_client
network_client = mock.MagicMock()
network_client.networks = []
# 2) Patch get_global_provider() to return a mocked NHN provider
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
# patch the 'network_empty_routingtables.network_client' used in the check code
"prowler.providers.nhn.services.network.network_vpc_has_empty_routingtables.network_vpc_has_empty_routingtables.network_client",
new=network_client,
),
):
# 3) Import the check code AFTER patching
from prowler.providers.nhn.services.network.network_vpc_has_empty_routingtables.network_vpc_has_empty_routingtables import (
network_vpc_has_empty_routingtables,
)
# 4) Run the check
check = network_vpc_has_empty_routingtables()
result = check.execute()
# 5) Assertions
assert len(result) == 0 # no networks => no findings
def test_vpc_has_empty_routingtables(self):
# Make a MagicMock for network_client
network_client = mock.MagicMock()
# Suppose we have 1 network with empty_routingtables=True => FAIL expected
network_id = str(uuid4())
network_name = "testNetwork"
mock_network = mock.MagicMock(spec=Network)
mock_network.id = network_id
mock_network.name = network_name
mock_network.empty_routingtables = True
network_client.networks = [mock_network]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.network.network_vpc_has_empty_routingtables.network_vpc_has_empty_routingtables.network_client",
new=network_client,
),
):
from prowler.providers.nhn.services.network.network_vpc_has_empty_routingtables.network_vpc_has_empty_routingtables import (
network_vpc_has_empty_routingtables,
)
check = network_vpc_has_empty_routingtables()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert "has empty routingtables" in result[0].status_extended
assert result[0].resource_name == network_name
assert result[0].resource_id == network_id
def test_vpc_does_not_have_empty_routingtables(self):
# Another scenario: network with empty_routingtables=False => PASS expected
network_client = mock.MagicMock()
network_id = str(uuid4())
network_name = "testNetwork"
mock_network = mock.MagicMock(spec=Network)
mock_network.id = network_id
mock_network.name = network_name
mock_network.empty_routingtables = False
network_client.networks = [mock_network]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.network.network_vpc_has_empty_routingtables.network_vpc_has_empty_routingtables.network_client",
new=network_client,
),
):
from prowler.providers.nhn.services.network.network_vpc_has_empty_routingtables.network_vpc_has_empty_routingtables import (
network_vpc_has_empty_routingtables,
)
check = network_vpc_has_empty_routingtables()
result = check.execute()
assert len(result) == 0
assert result[0].status == "PASS"
assert "dose not have empty routingtables" in result[0].status_extended
assert result[0].resource_name == network_name
assert result[0].resource_id == network_id
@@ -0,0 +1,113 @@
from unittest import mock
from uuid import uuid4
from prowler.providers.nhn.services.network.network_service import Network, Subnet
from tests.providers.nhn.nhn_fixtures import set_mocked_nhn_provider
class Test_network_vpc_subnet_enable_dhcp:
def test_no_networks(self):
# 1) Make a MagicMock for network_client
network_client = mock.MagicMock()
network_client.networks = []
# 2) Patch get_global_provider() to return a mocked NHN provider
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
# patch the 'network_vpc_subnet_enable_dhcp.network_client' used in the check code
"prowler.providers.nhn.services.network.network_vpc_subnet_enable_dhcp.network_vpc_subnet_enable_dhcp.network_client",
new=network_client,
),
):
# 3) Import the check code AFTER patching
from prowler.providers.nhn.services.network.network_vpc_subnet_enable_dhcp.network_vpc_subnet_enable_dhcp import (
network_vpc_subnet_enable_dhcp,
)
# 4) Run the check
check = network_vpc_subnet_enable_dhcp()
result = check.execute()
# 5) Assertions
assert len(result) == 0 # no networks => no findings
def test_vpc_subnet_enable_dhcp(self):
# Make a MagicMock for network_client
network_client = mock.MagicMock()
# Suppose we have 1 network with enable_dhcp=True => FAIL expected
network_id = str(uuid4())
network_name = "testNetwork"
mock_network = mock.MagicMock(spec=Network)
mock_network.id = network_id
mock_network.name = network_name
mock_subnet = mock.MagicMock(spec=Subnet)
mock_subnet.name = "subnet1"
mock_subnet.enable_dhcp = True
mock_network.subnets = [mock_subnet]
network_client.networks = [mock_network]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.network.network_vpc_subnet_enable_dhcp.network_vpc_subnet_enable_dhcp.network_client",
new=network_client,
),
):
from prowler.providers.nhn.services.network.network_vpc_subnet_enable_dhcp.network_vpc_subnet_enable_dhcp import (
network_vpc_subnet_enable_dhcp,
)
check = network_vpc_subnet_enable_dhcp()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert "has DHCP enabled" in result[0].status_extended
assert result[0].resource_name == network_name
assert result[0].resource_id == network_id
def test_vpc_subnet_unable_dhcp(self):
# Another scenario: network with enable_dhcp=False => PASS expected
network_client = mock.MagicMock()
network_id = str(uuid4())
network_name = "testNetwork"
mock_network = mock.MagicMock(spec=Network)
mock_network.id = network_id
mock_network.name = network_name
mock_subnet = mock.MagicMock(spec=Subnet)
mock_subnet.name = "subnet1"
mock_subnet.enable_dhcp = False
mock_network.subnets = [mock_subnet]
network_client.networks = [mock_network]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.network.network_vpc_subnet_enable_dhcp.network_vpc_subnet_enable_dhcp.network_client",
new=network_client,
),
):
from prowler.providers.nhn.services.network.network_vpc_subnet_enable_dhcp.network_vpc_subnet_enable_dhcp import (
network_vpc_subnet_enable_dhcp,
)
check = network_vpc_subnet_enable_dhcp()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert "does not have DHCP enabled" in result[0].status_extended
assert result[0].resource_name == network_name
assert result[0].resource_id == network_id
@@ -0,0 +1,104 @@
from unittest import mock
from uuid import uuid4
from prowler.providers.nhn.services.network.network_service import Network, Subnet
from tests.providers.nhn.nhn_fixtures import set_mocked_nhn_provider
class Test_network_vpc_subnet_has_external_router:
def test_no_networks(self):
network_client = mock.MagicMock()
network_client.networks = []
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.network.network_vpc_subnet_has_external_router.network_vpc_subnet_has_external_router.network_client",
new=network_client,
),
):
from prowler.providers.nhn.services.network.network_vpc_subnet_has_external_router.network_vpc_subnet_has_external_router import (
network_vpc_subnet_has_external_router,
)
check = network_vpc_subnet_has_external_router()
result = check.execute()
assert len(result) == 0
def test_vpc_subnet_has_external_router(self):
network_client = mock.MagicMock()
network_id = str(uuid4())
network_name = "testNetwork"
mock_network = mock.MagicMock(spec=Network)
mock_network.id = network_id
mock_network.name = network_name
mock_subnet = mock.MagicMock(spec=Subnet)
mock_subnet.name = "subnet1"
mock_subnet.external_router = True
mock_network.subnets = [mock_subnet]
network_client.networks = [mock_network]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.network.network_vpc_subnet_has_external_router.network_vpc_subnet_has_external_router.network_client",
new=network_client,
),
):
from prowler.providers.nhn.services.network.network_vpc_subnet_has_external_router.network_vpc_subnet_has_external_router import (
network_vpc_subnet_has_external_router,
)
check = network_vpc_subnet_has_external_router()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert "has external router" in result[0].status_extended
assert result[0].resource_id == network_id
assert result[0].resource_name == network_name
def test_vpc_subnet_no_external_router(self):
network_client = mock.MagicMock()
network_id = str(uuid4())
network_name = "testNetwork"
mock_network = mock.MagicMock(spec=Network)
mock_network.id = network_id
mock_network.name = network_name
mock_subnet = mock.MagicMock(spec=Subnet)
mock_subnet.name = "subnet1"
mock_subnet.external_router = False
mock_network.subnets = [mock_subnet]
network_client.networks = [mock_network]
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_nhn_provider(),
),
mock.patch(
"prowler.providers.nhn.services.network.network_vpc_subnet_has_external_router.network_vpc_subnet_has_external_router.network_client",
new=network_client,
),
):
from prowler.providers.nhn.services.network.network_vpc_subnet_has_external_router.network_vpc_subnet_has_external_router import (
network_vpc_subnet_has_external_router,
)
check = network_vpc_subnet_has_external_router()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert "no external router" in result[0].status_extended
assert result[0].resource_id == network_id
assert result[0].resource_name == network_name