Mini Shell
import asyncio
import logging
from defence360agent import utils
from defence360agent.contracts import messages, plugins
logger = logging.getLogger(__name__)
class IDSAwareMessageSink(plugins.MessageSink):
"""A message sink that accepts messages taking into account the
current IDS (strategy).
"""
STRATEGY = None # no IDS preference by default
@plugins.expect(messages.MessageType.StrategyChange)
async def on_strategy_change(self, message):
"""De/activate the plugin on strategy change if necessary."""
# - activate sink if it has no IDS preference
# - activate sink if it can work with the current IDS (as
# indicated by STRATEGY)
# - deactivate sink if it can't work with the current IDS
if self.STRATEGY is None or message.strategy == self.STRATEGY:
if not self.is_active():
try:
await self.activate()
except asyncio.CancelledError:
raise
except Exception:
logger.exception("Failed to activate %r plugin", self)
utils.fail_agent_service()
else:
logger.info("Plugin %r is activated", self)
elif self.is_active():
try:
await self.deactivate()
except (Exception, asyncio.CancelledError):
logger.exception("Failed to deactivate %r plugin", self)
utils.fail_agent_service()
else:
logger.info("Plugin %r is deactivated", self)
async def process_message(self, message):
if self.is_active() or isinstance(
message, messages.MessageType.StrategyChange
):
return await super().process_message(message)
async def shutdown(self):
if self.is_active():
try:
await self.deactivate()
except (Exception, asyncio.CancelledError):
logger.exception("Failed to deactivate %r plugin", self)
# NOTE: don't propagate errors on shutdown
else:
logger.info("Plugin %r is deactivated", self)
return await super().shutdown()
async def activate(self):
"""This method will be called for plugins with specified strategy
when this strategy becomes active.
"""
self._mark_as_active()
async def deactivate(self):
"""This method will be called for plugins with specified strategy
when this strategy becomes inactive.
"""
self._mark_as_inactive()
def is_active(self):
"""Indicates if plugin is active."""
return getattr(self, "_is_active", False)
def _mark_as_active(self):
self._is_active = True
def _mark_as_inactive(self):
self._is_active = False