137 lines
4.4 KiB
Python
137 lines
4.4 KiB
Python
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
|
"""Actions for interacting with applications on network hosts."""
|
|
from abc import ABC
|
|
from typing import ClassVar
|
|
|
|
from primaite.game.agent.actions.abstract import AbstractAction
|
|
from primaite.interface.request import RequestFormat
|
|
|
|
__all__ = (
|
|
"NodeApplicationExecuteAction",
|
|
"NodeApplicationScanAction",
|
|
"NodeApplicationCloseAction",
|
|
"NodeApplicationFixAction",
|
|
"NodeApplicationInstallAction",
|
|
"NodeApplicationRemoveAction",
|
|
)
|
|
|
|
|
|
class NodeApplicationAbstractAction(AbstractAction, ABC):
|
|
"""
|
|
Base class for application actions.
|
|
|
|
Any action which applies to an application and uses node_name and application_name as its only two parameters can
|
|
inherit from this base class.
|
|
"""
|
|
|
|
class ConfigSchema(AbstractAction.ConfigSchema, ABC):
|
|
"""Base Configuration schema for Node Application actions."""
|
|
|
|
node_name: str
|
|
application_name: str
|
|
verb: ClassVar[str]
|
|
|
|
@classmethod
|
|
def form_request(cls, config: ConfigSchema) -> RequestFormat:
|
|
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
|
|
return [
|
|
"network",
|
|
"node",
|
|
config.node_name,
|
|
"application",
|
|
config.application_name,
|
|
config.verb,
|
|
]
|
|
|
|
|
|
class NodeApplicationExecuteAction(NodeApplicationAbstractAction, discriminator="node-application-execute"):
|
|
"""Action which executes an application."""
|
|
|
|
config: "NodeApplicationExecuteAction.ConfigSchema"
|
|
|
|
class ConfigSchema(NodeApplicationAbstractAction.ConfigSchema):
|
|
"""Configuration schema for NodeApplicationExecuteAction."""
|
|
|
|
verb: str = "execute"
|
|
|
|
|
|
class NodeApplicationScanAction(NodeApplicationAbstractAction, discriminator="node-application-scan"):
|
|
"""Action which scans an application."""
|
|
|
|
config: "NodeApplicationScanAction.ConfigSchema"
|
|
|
|
class ConfigSchema(NodeApplicationAbstractAction.ConfigSchema):
|
|
"""Configuration schema for NodeApplicationScanAction."""
|
|
|
|
verb: str = "scan"
|
|
|
|
|
|
class NodeApplicationCloseAction(NodeApplicationAbstractAction, discriminator="node-application-close"):
|
|
"""Action which closes an application."""
|
|
|
|
config: "NodeApplicationCloseAction.ConfigSchema"
|
|
|
|
class ConfigSchema(NodeApplicationAbstractAction.ConfigSchema):
|
|
"""Configuration schema for NodeApplicationCloseAction."""
|
|
|
|
verb: str = "close"
|
|
|
|
|
|
class NodeApplicationFixAction(NodeApplicationAbstractAction, discriminator="node-application-fix"):
|
|
"""Action which fixes an application."""
|
|
|
|
config: "NodeApplicationFixAction.ConfigSchema"
|
|
|
|
class ConfigSchema(NodeApplicationAbstractAction.ConfigSchema):
|
|
"""Configuration schema for NodeApplicationFixAction."""
|
|
|
|
verb: str = "fix"
|
|
|
|
|
|
class NodeApplicationInstallAction(NodeApplicationAbstractAction, discriminator="node-application-install"):
|
|
"""Action which installs an application."""
|
|
|
|
config: "NodeApplicationInstallAction.ConfigSchema"
|
|
|
|
class ConfigSchema(NodeApplicationAbstractAction.ConfigSchema):
|
|
"""Configuration schema for NodeApplicationInstallAction."""
|
|
|
|
verb: str = "install"
|
|
|
|
@classmethod
|
|
def form_request(cls, config: ConfigSchema) -> RequestFormat:
|
|
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
|
|
return [
|
|
"network",
|
|
"node",
|
|
config.node_name,
|
|
"software_manager",
|
|
"application",
|
|
config.verb,
|
|
config.application_name,
|
|
]
|
|
|
|
|
|
class NodeApplicationRemoveAction(NodeApplicationAbstractAction, discriminator="node-application-remove"):
|
|
"""Action which removes/uninstalls an application."""
|
|
|
|
config: "NodeApplicationRemoveAction.ConfigSchema"
|
|
|
|
class ConfigSchema(NodeApplicationAbstractAction.ConfigSchema):
|
|
"""Configuration schema for NodeApplicationRemoveAction."""
|
|
|
|
verb: str = "uninstall"
|
|
|
|
@classmethod
|
|
def form_request(cls, config: ConfigSchema) -> RequestFormat:
|
|
"""Return the action formatted as a request which can be ingested by the PrimAITE simulation."""
|
|
return [
|
|
"network",
|
|
"node",
|
|
config.node_name,
|
|
"software_manager",
|
|
"application",
|
|
config.verb,
|
|
config.application_name,
|
|
]
|