Island: Add a Machine model

This commit is contained in:
Mike Salvatore 2022-08-18 08:49:51 -04:00
parent 09474ac1fe
commit a4a4613a66
4 changed files with 172 additions and 0 deletions

View File

@ -9,3 +9,4 @@ from .pba_results import PbaResults
from monkey_island.cc.models.report.report import Report
from .simulation import Simulation, SimulationSchema, IslandMode
from .user_credentials import UserCredentials
from .machine import Machine

View File

@ -0,0 +1,17 @@
from ipaddress import IPv4Interface
from typing import Optional, Sequence
from pydantic import Field, PositiveInt
from common import OperatingSystems
from .base_models import MutableBaseModel
class Machine(MutableBaseModel):
id: PositiveInt = Field(..., allow_mutation=False)
node_id: Optional[PositiveInt]
network_interfaces: Sequence[IPv4Interface]
operating_system: OperatingSystems
operating_system_version: str
hostname: str

View File

@ -0,0 +1,153 @@
import uuid
from ipaddress import IPv4Interface
from types import MappingProxyType
import pytest
from common import OperatingSystems
from monkey_island.cc.models import Machine
MACHINE_OBJECT_DICT = MappingProxyType(
{
"id": 1,
"node_id": uuid.getnode(),
"network_interfaces": [IPv4Interface("10.0.0.1/24"), IPv4Interface("192.168.5.32/16")],
"operating_system": OperatingSystems.WINDOWS,
"operating_system_version": "eXtra Problems",
"hostname": "my.host",
}
)
MACHINE_SIMPLE_DICT = MappingProxyType(
{
"id": 1,
"node_id": uuid.getnode(),
"network_interfaces": ["10.0.0.1/24", "192.168.5.32/16"],
"operating_system": "windows",
"operating_system_version": "eXtra Problems",
"hostname": "my.host",
}
)
def test_constructor():
# Raises exception_on_failure
Machine(**MACHINE_OBJECT_DICT)
def test_from_dict():
# Raises exception_on_failure
Machine(**MACHINE_SIMPLE_DICT)
def test_to_dict():
m = Machine(**MACHINE_OBJECT_DICT)
assert m.dict(simplify=True) == dict(MACHINE_SIMPLE_DICT)
@pytest.mark.parametrize(
"key, value",
[
("id", "not-an-int"),
("node_id", "not-an-int"),
("network_interfaces", "not-a-list"),
("operating_system", 2.1),
("operating_system", "bsd"),
("operating_system_version", {}),
("hostname", []),
],
)
def test_construct_invalid_field__type_error(key, value):
invalid_type_dict = MACHINE_SIMPLE_DICT.copy()
invalid_type_dict[key] = value
with pytest.raises(TypeError):
Machine(**invalid_type_dict)
@pytest.mark.parametrize(
"key, value",
[
("id", -1),
("node_id", 0),
("network_interfaces", [1, "stuff", 3]),
("network_interfaces", ["10.0.0.1/16", 2, []]),
],
)
def test_construct_invalid_field__value_error(key, value):
invalid_type_dict = MACHINE_SIMPLE_DICT.copy()
invalid_type_dict[key] = value
with pytest.raises(ValueError):
Machine(**invalid_type_dict)
def test_construct__extra_fields_forbidden():
extra_field_dict = MACHINE_SIMPLE_DICT.copy()
extra_field_dict["extra_field"] = 99 # red balloons
with pytest.raises(ValueError):
Machine(**extra_field_dict)
def test_id_immutable():
m = Machine(**MACHINE_OBJECT_DICT)
with pytest.raises(TypeError):
m.id = 2
@pytest.mark.parametrize("node_id", [None, 1, 100])
def test_node_id_set_valid_value(node_id):
m = Machine(**MACHINE_OBJECT_DICT)
# Raises exception_on_failure
m.node_id = node_id
def test_node_id_validate_on_set():
m = Machine(**MACHINE_OBJECT_DICT)
with pytest.raises(ValueError):
m.node_id = -50
def test_network_interfaces_set_valid_value():
m = Machine(**MACHINE_OBJECT_DICT)
# Raises exception_on_failure
m.network_interfaces = [IPv4Interface("172.1.2.3/24")]
def test_network_interfaces_set_invalid_value():
m = Machine(**MACHINE_OBJECT_DICT)
with pytest.raises(ValueError):
m.network_interfaces = [IPv4Interface("172.1.2.3/24"), None]
def test_operating_system_set_valid_value():
m = Machine(**MACHINE_OBJECT_DICT)
# Raises exception_on_failure
m.operating_system = OperatingSystems.LINUX
def test_operating_system_set_invalid_value():
m = Machine(**MACHINE_OBJECT_DICT)
with pytest.raises(ValueError):
m.operating_system = "MacOS"
def test_set_operating_system_version():
m = Machine(**MACHINE_OBJECT_DICT)
# Raises exception_on_failure
m.operating_system_version = "1234"
def test_set_hostname():
m = Machine(**MACHINE_OBJECT_DICT)
# Raises exception_on_failure
m.operating_system_version = "wopr"

View File

@ -209,6 +209,7 @@ _serialize_credentials # unused method (monkey/common/credentials/credentials:6
# Models
_make_simulation # unused method (monkey/monkey_island/cc/models/simulation.py:19
operating_system_version
# TODO DELETE AFTER RESOURCE REFACTORING