Source code for cobbler.templates.jinja

"""
Template functionality that is tied to Jinja2.
"""

# pyright: strict, reportPossiblyUnboundVariable=false

from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Tuple

import yaml

from cobbler.templates import BaseTemplateProvider

try:
    import jinja2

    JINJA2_AVAILABLE = True
except ModuleNotFoundError:
    JINJA2_AVAILABLE = False  # type: ignore[reportConstantRedefinition]


if TYPE_CHECKING:
    from cobbler.api import CobblerAPI

if JINJA2_AVAILABLE:

[docs] class CobblerJinjaLoader(jinja2.BaseLoader): """ Custom Jinja template loader that allows loading templates from the CobblerAPI. """ def __init__(self, cobbler_api: "CobblerAPI") -> None: """ Constructor :param cobbler_api: The CobblerAPI object to search for templates. """ self.cobbler_api = cobbler_api
[docs] def get_source( self, environment: "jinja2.Environment", template: str ) -> Tuple[str, Optional[str], Optional[Callable[[], bool]]]: search_result = self.cobbler_api.find_template(False, False, name=template) if search_result is None or isinstance(search_result, list): raise jinja2.TemplateNotFound(template) return search_result.content, search_result.name, None
[docs] def toyaml(data: Any) -> str: """ Function which is registred as a custom Jinja filter and allows convering arbitrary data into YAML. """ return yaml.dump(data).rstrip("\n")
[docs] class JinjaTemplateProvider(BaseTemplateProvider): """ Provides support for the Jinja2 template language to Cobbler. See: https://jinja.palletsprojects.com/en/3.1.x/ """ template_language = "jinja" def __init__(self, api: "CobblerAPI"): super().__init__(api) if JINJA2_AVAILABLE: self.jinja2_env = jinja2.Environment(loader=CobblerJinjaLoader(self.api)) self.jinja2_env.filters["any"] = any # type: ignore self.jinja2_env.filters["all"] = all # type: ignore self.jinja2_env.filters["toyaml"] = toyaml # type: ignore @property def template_type_available(self) -> bool: return JINJA2_AVAILABLE @property def template_file_extension(self) -> str: return "jinja"
[docs] def render(self, raw_data: str, search_table: Dict[str, Any]) -> str: if not JINJA2_AVAILABLE: return "" try: template = self.jinja2_env.from_string(raw_data) data_out = template.render(search_table) except Exception as exc: self.logger.warning("errors were encountered rendering the template") self.logger.warning(str(exc)) data_out = "# EXCEPTION OCCURRED DURING JINJA2 TEMPLATE PROCESSING\n" return data_out