Source code for saf.plugins

# Copyright 2021-2023 VMware, Inc.
# SPDX-License-Identifier: Apache-2.0
"""
Salt Analytics Framework Plugins Support.
"""
from __future__ import annotations

import contextlib
import logging
import pathlib
import types
from typing import Generator
from typing import TypeVar

from salt.utils import entrypoints

log = logging.getLogger(__name__)


PACKAGE_ROOT = pathlib.Path(__file__).resolve().parent

PLT = TypeVar("PLT", bound="PluginsList")


[docs]class PluginsList: """ Plugins manager. """ _instance = None def __init__(self: PLT) -> None: self.collectors: dict[str, types.ModuleType] = {} self.processors: dict[str, types.ModuleType] = {} self.forwarders: dict[str, types.ModuleType] = {} self.load_plugins()
[docs] def __repr__(self: PLT) -> str: """ Return a printable representation of the class instance. """ return ( f"<{self.__class__.__name__} collectors={list(self.collectors)} " f"processors={list(self.processors)} forwarders={list(self.forwarders)}>" )
[docs] @staticmethod def instance() -> PluginsList: """ Return the cached instance of the plugins listing. If it doesn't exist yet, a new instance is created and cached. """ if PluginsList._instance is None: PluginsList._instance = PluginsList() return PluginsList._instance
[docs] def load_plugins(self: PLT) -> None: """ Load the available salt analytics framework plugins. """ for name, listing in ( ("collect", self.collectors), ("process", self.processors), ("forward", self.forwarders), ): for entry_point in entrypoints.iter_entry_points(f"saf.{name}"): log.debug("Loading salt analytics framework collect plugin from %s", entry_point) with catch_entry_points_exception(entry_point) as ctx: module = entry_point.load() if ctx.exception_caught: continue listing[entry_point.name] = module
[docs]@contextlib.contextmanager def catch_entry_points_exception(entry_point: str) -> Generator[types.SimpleNamespace, None, None]: """ Context manager to catch exceptions while loading entry points. """ context = types.SimpleNamespace(exception_caught=False) try: yield context except Exception: context.exception_caught = True entry_point_details = entrypoints.name_and_version_from_entry_point(entry_point) log.exception( "Error processing Salt Analytics Framework Plugin %s(version: %s)", entry_point_details.name, entry_point_details.version, )