mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-08-20 05:35:41 +02:00
58 lines
3.1 KiB
Python
58 lines
3.1 KiB
Python
# This file is Copyright 2019 Volatility Foundation and licensed under the Volatility Software License 1.0
|
|
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
|
|
#
|
|
"""An automagic module to use configuration data to configure and then
|
|
construct classes that fulfill the descendants of a :class:`~volatility.framewo
|
|
rk.interfaces.configuration.ConfigurableInterface`."""
|
|
|
|
import logging
|
|
from typing import List
|
|
|
|
from volatility.framework import constants
|
|
from volatility.framework import interfaces
|
|
|
|
vollog = logging.getLogger(__name__)
|
|
|
|
|
|
class ConstructionMagic(interfaces.automagic.AutomagicInterface):
|
|
"""Constructs underlying layers.
|
|
|
|
Class to run through the requirement tree of the :class:`~volatility.framework.interfaces.configuration.ConfigurableInterface`
|
|
and from the bottom of the tree upwards, attempt to construct all
|
|
:class:`~volatility.framework.interfaces.configuration.ConstructableRequirementInterface` based classes.
|
|
|
|
:warning: This `automagic` should run first to allow existing configurations to have been constructed for use by later automagic
|
|
"""
|
|
priority = 0
|
|
|
|
def __call__(self,
|
|
context: interfaces.context.ContextInterface,
|
|
config_path: str,
|
|
requirement: interfaces.configuration.RequirementInterface,
|
|
progress_callback = None,
|
|
optional = False) -> List[str]:
|
|
result = [] # type: List[str]
|
|
if requirement.unsatisfied(context, config_path):
|
|
# Having called validate at the top level tells us both that we need to dig deeper
|
|
# but also ensures that TranslationLayerRequirements have got the correct subrequirements if their class is populated
|
|
|
|
subreq_config_path = interfaces.configuration.path_join(config_path, requirement.name)
|
|
for subreq in requirement.requirements.values():
|
|
try:
|
|
self(context, subreq_config_path, subreq, optional = optional or subreq.optional)
|
|
except Exception as e:
|
|
# We don't really care if this fails, it tends to mean the configuration isn't complete for that item
|
|
vollog.log(constants.LOGLEVEL_VVVV, "Construction Exception occurred: {}".format(e))
|
|
invalid = subreq.unsatisfied(context, subreq_config_path)
|
|
# We want to traverse optional paths, so don't check until we've tried to validate
|
|
# We also don't want to emit a debug message when a parent is optional, hence the optional parameter
|
|
if invalid and not (optional or subreq.optional):
|
|
vollog.log(constants.LOGLEVEL_V, "Failed on requirement: {}".format(subreq_config_path))
|
|
result.append(interfaces.configuration.path_join(subreq_config_path, subreq.name))
|
|
if result:
|
|
return result
|
|
elif isinstance(requirement, interfaces.configuration.ConstructableRequirementInterface):
|
|
# We know all the subrequirements are filled, so let's populate
|
|
requirement.construct(context, config_path)
|
|
return []
|