rostran/core/conditions.py (68 lines of code) (raw):

from rostran.core.exceptions import InvalidTemplateCondition, InvalidTemplateConditions from rostran.core.utils import sorted_data class Condition: CONDITION_FUNCS = ("Fn::And", "Fn::Or", "Fn::Not", "Fn::Equals") def __init__(self, name, value): self.name = name self.value = value @classmethod def initialize(cls, name: str, value: dict): condition = cls(name, value) condition.validate() return condition def validate(self): if not isinstance(self.name, str): raise InvalidTemplateCondition( name=self.name, reason=f"The type should be str", ) if not isinstance(self.value, dict): raise InvalidTemplateCondition( name=self.name, reason=f"The type of value ({self.value}) should be dict", ) # validate value key for key, value in self.value.items(): if not isinstance(key, str): raise InvalidTemplateCondition( name=f"{self.name}.{key}", reason=f"The type should be str", ) if key not in self.CONDITION_FUNCS: raise InvalidTemplateCondition( name=self.name, reason=f"Condition function {key} is not supported. Allowed functions: {self.CONDITION_FUNCS}", ) if not isinstance(value, (dict, list)): raise InvalidTemplateCondition( name=f"{self.name}.{key}", reason=f"The type of value ({self.value}) should be dict or list", ) def as_dict(self, format=False): data = {self.name: self.value} if format: data[self.name] = sorted_data(self.value) return data class Conditions(dict): @classmethod def initialize(cls, data: dict): if not isinstance(data, dict): raise InvalidTemplateConditions( reason=f"The type of data ({data}) should be dict" ) conditions = cls() for name, value in data.items(): condition = Condition.initialize(name, value) conditions.add(condition) return conditions def add(self, condition: Condition): self[condition.name] = condition def as_dict(self, format=False) -> dict: data = {} keys = self.keys() if format: keys = sorted_data(keys) for key in keys: condition: Condition = self[key] if condition.value is not None: data.update(condition.as_dict(format)) return data