Source code for cobbler.items.abstract.item_group

"""
"ItemGroup" is the abstract base class for groups of items.

Changelog:
    * V3.4.0 (unreleased):
        * Initial creation of the class
"""

# SPDX-License-Identifier: GPL-2.0-or-later
# SPDX-FileCopyrightText: Enno Gotthold <enno.gotthold@suse.com>

from abc import ABC
from typing import TYPE_CHECKING, Any, List, Type

from cobbler import enums
from cobbler.items.abstract.inheritable_item import InheritableItem

if TYPE_CHECKING:
    from cobbler.api import CobblerAPI

    LazyProperty = property
else:
    from cobbler.decorator import LazyProperty


[docs] class ItemGroup(InheritableItem, ABC): """ Abstract class for item groups in Cobbler. """ TYPE_NAME = "item_group_abstract" COLLECTION_TYPE = "item_groups" def __init__(self, api: "CobblerAPI", *args: Any, **kwargs: Any): """ Constructor. :param api: The Cobbler API object. """ super().__init__(api) # Prevent attempts to clear the to_dict cache before the object is initialized. self._has_initialized = False self._members: List[str] = [] if len(kwargs) > 0: self.from_dict(kwargs) def _resolve(self, property_name: List[str]) -> Any: settings_name = property_name[-1] if property_name[-1] == "owners": settings_name = "default_ownership" raw_value = self.__get_raw_value(self, property_name) if raw_value == enums.VALUE_INHERITED: return getattr(self.api.settings(), settings_name) else: return raw_value def _resolve_enum( self, property_name: List[str], enum_type: Type[enums.ConvertableEnum] ) -> Any: # The DistroGroup doesn't have any enum types that need resolving. return None def _resolve_list(self, property_name: List[str]) -> List[Any]: """ Resolves and merges a list property from the current object, its parent, and global settings. :param property_name: The list of strings that represent the names of the attributes/properties to travel to the target attribute. :returns: The list with all values blended together. """ property_name_raw = property_name.copy() property_name_raw[-1] = "_" + property_name_raw[-1] attribute_value = self.__get_raw_value(self, property_name_raw) settings = self.api.settings() merged_list: List[Any] = [] parent = self.parent if self.parent is None: parent = self.get_conceptual_parent() # type: ignore try: merged_list.extend(self.__get_raw_value(parent, property_name)) except AttributeError: # Does not have the requested attribute pass if hasattr(settings, property_name[-1]): merged_list.extend(getattr(settings, property_name[-1])) if attribute_value != enums.VALUE_INHERITED: merged_list.extend(attribute_value) return merged_list def __get_raw_value(self, obj: Any, property_name: List[str]) -> Any: """ Retrieves the raw value of a nested attribute from an object using a list of property names. :returns: The raw value of the property. :raises AttributeError: In case the property doesn't have the requested attribute. """ if hasattr(obj, f"_{property_name[0]}"): property_key = property_name.pop(0) if len(property_name) > 0: return self.__get_raw_value(getattr(obj, property_key), property_name) return getattr(obj, f"_{property_key}") raise AttributeError( f'Could not retrieve "{property_name[0]}" with obj "{obj}!' ) @LazyProperty def members(self) -> List[str]: """ :getter: The members of this group. :setter: Set the members of this group. """ return self._members @members.setter def members(self, value: List[str]) -> None: """ Set the members of this item group. :param value: A list of string uids representing the members of the group. """ if not isinstance(value, list): # pyright: ignore[reportUnnecessaryIsInstance] raise TypeError("members must be a list") for member in value: if not isinstance( member, str ): # pyright: ignore[reportUnnecessaryIsInstance] raise TypeError("All members must be of type string") self._members = value