From 61ef9441fcbc48b6a3aa636674a1f8cad5ff2e16 Mon Sep 17 00:00:00 2001 From: SDK Generator Bot Date: Fri, 6 Feb 2026 10:22:53 +0000 Subject: [PATCH] Generate cdn --- services/cdn/oas_commit | 1 + services/cdn/src/stackit/cdn/__init__.py | 8 ++ .../cdn/src/stackit/cdn/models/__init__.py | 4 + services/cdn/src/stackit/cdn/models/config.py | 7 + .../src/stackit/cdn/models/config_patch.py | 7 + .../cdn/models/create_distribution_payload.py | 7 + .../src/stackit/cdn/models/match_condition.py | 37 +++++ .../cdn/src/stackit/cdn/models/matcher.py | 93 ++++++++++++ .../src/stackit/cdn/models/redirect_config.py | 98 +++++++++++++ .../src/stackit/cdn/models/redirect_rule.py | 135 ++++++++++++++++++ .../src/stackit/cdn/models/status_error.py | 3 +- 11 files changed, 399 insertions(+), 1 deletion(-) create mode 100644 services/cdn/oas_commit create mode 100644 services/cdn/src/stackit/cdn/models/match_condition.py create mode 100644 services/cdn/src/stackit/cdn/models/matcher.py create mode 100644 services/cdn/src/stackit/cdn/models/redirect_config.py create mode 100644 services/cdn/src/stackit/cdn/models/redirect_rule.py diff --git a/services/cdn/oas_commit b/services/cdn/oas_commit new file mode 100644 index 00000000..edde3197 --- /dev/null +++ b/services/cdn/oas_commit @@ -0,0 +1 @@ +aac517d76702c25b3af67f78bde9e2bd2f758537 diff --git a/services/cdn/src/stackit/cdn/__init__.py b/services/cdn/src/stackit/cdn/__init__.py index c5b67297..c3aae32e 100644 --- a/services/cdn/src/stackit/cdn/__init__.py +++ b/services/cdn/src/stackit/cdn/__init__.py @@ -75,6 +75,8 @@ "LokiLogSinkCreate", "LokiLogSinkCredentials", "LokiLogSinkPatch", + "MatchCondition", + "Matcher", "Optimizer", "OptimizerPatch", "PatchDistributionPayload", @@ -86,6 +88,8 @@ "PutCustomDomainPayloadCertificate", "PutCustomDomainResponse", "PutCustomDomainResponseCertificate", + "RedirectConfig", + "RedirectRule", "Region", "StatusError", "WAFRuleAction", @@ -231,6 +235,8 @@ LokiLogSinkCredentials as LokiLogSinkCredentials, ) from stackit.cdn.models.loki_log_sink_patch import LokiLogSinkPatch as LokiLogSinkPatch +from stackit.cdn.models.match_condition import MatchCondition as MatchCondition +from stackit.cdn.models.matcher import Matcher as Matcher from stackit.cdn.models.optimizer import Optimizer as Optimizer from stackit.cdn.models.optimizer_patch import OptimizerPatch as OptimizerPatch from stackit.cdn.models.patch_distribution_payload import ( @@ -260,6 +266,8 @@ from stackit.cdn.models.put_custom_domain_response_certificate import ( PutCustomDomainResponseCertificate as PutCustomDomainResponseCertificate, ) +from stackit.cdn.models.redirect_config import RedirectConfig as RedirectConfig +from stackit.cdn.models.redirect_rule import RedirectRule as RedirectRule from stackit.cdn.models.region import Region as Region from stackit.cdn.models.status_error import StatusError as StatusError from stackit.cdn.models.waf_config import WafConfig as WafConfig diff --git a/services/cdn/src/stackit/cdn/models/__init__.py b/services/cdn/src/stackit/cdn/models/__init__.py index 01810655..4c2c90b4 100644 --- a/services/cdn/src/stackit/cdn/models/__init__.py +++ b/services/cdn/src/stackit/cdn/models/__init__.py @@ -85,6 +85,8 @@ from stackit.cdn.models.loki_log_sink_create import LokiLogSinkCreate from stackit.cdn.models.loki_log_sink_credentials import LokiLogSinkCredentials from stackit.cdn.models.loki_log_sink_patch import LokiLogSinkPatch +from stackit.cdn.models.match_condition import MatchCondition +from stackit.cdn.models.matcher import Matcher from stackit.cdn.models.optimizer import Optimizer from stackit.cdn.models.optimizer_patch import OptimizerPatch from stackit.cdn.models.patch_distribution_payload import PatchDistributionPayload @@ -104,6 +106,8 @@ from stackit.cdn.models.put_custom_domain_response_certificate import ( PutCustomDomainResponseCertificate, ) +from stackit.cdn.models.redirect_config import RedirectConfig +from stackit.cdn.models.redirect_rule import RedirectRule from stackit.cdn.models.region import Region from stackit.cdn.models.status_error import StatusError from stackit.cdn.models.waf_config import WafConfig diff --git a/services/cdn/src/stackit/cdn/models/config.py b/services/cdn/src/stackit/cdn/models/config.py index 2feb1995..0da37475 100644 --- a/services/cdn/src/stackit/cdn/models/config.py +++ b/services/cdn/src/stackit/cdn/models/config.py @@ -23,6 +23,7 @@ from stackit.cdn.models.config_backend import ConfigBackend from stackit.cdn.models.loki_log_sink import LokiLogSink from stackit.cdn.models.optimizer import Optimizer +from stackit.cdn.models.redirect_config import RedirectConfig from stackit.cdn.models.region import Region from stackit.cdn.models.waf_config import WafConfig @@ -53,6 +54,7 @@ class Config(BaseModel): alias="monthlyLimitBytes", ) optimizer: Optional[Optimizer] = None + redirects: Optional[RedirectConfig] = None regions: Annotated[List[Region], Field(min_length=1)] waf: WafConfig __properties: ClassVar[List[str]] = [ @@ -63,6 +65,7 @@ class Config(BaseModel): "logSink", "monthlyLimitBytes", "optimizer", + "redirects", "regions", "waf", ] @@ -113,6 +116,9 @@ def to_dict(self) -> Dict[str, Any]: # override the default output from pydantic by calling `to_dict()` of optimizer if self.optimizer: _dict["optimizer"] = self.optimizer.to_dict() + # override the default output from pydantic by calling `to_dict()` of redirects + if self.redirects: + _dict["redirects"] = self.redirects.to_dict() # override the default output from pydantic by calling `to_dict()` of waf if self.waf: _dict["waf"] = self.waf.to_dict() @@ -146,6 +152,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "logSink": LokiLogSink.from_dict(obj["logSink"]) if obj.get("logSink") is not None else None, "monthlyLimitBytes": obj.get("monthlyLimitBytes"), "optimizer": Optimizer.from_dict(obj["optimizer"]) if obj.get("optimizer") is not None else None, + "redirects": RedirectConfig.from_dict(obj["redirects"]) if obj.get("redirects") is not None else None, "regions": obj.get("regions"), "waf": WafConfig.from_dict(obj["waf"]) if obj.get("waf") is not None else None, } diff --git a/services/cdn/src/stackit/cdn/models/config_patch.py b/services/cdn/src/stackit/cdn/models/config_patch.py index 8eab45e3..5ca32461 100644 --- a/services/cdn/src/stackit/cdn/models/config_patch.py +++ b/services/cdn/src/stackit/cdn/models/config_patch.py @@ -23,6 +23,7 @@ from stackit.cdn.models.config_patch_backend import ConfigPatchBackend from stackit.cdn.models.loki_log_sink_patch import LokiLogSinkPatch from stackit.cdn.models.optimizer_patch import OptimizerPatch +from stackit.cdn.models.redirect_config import RedirectConfig from stackit.cdn.models.region import Region from stackit.cdn.models.waf_config_patch import WafConfigPatch @@ -55,6 +56,7 @@ class ConfigPatch(BaseModel): alias="monthlyLimitBytes", ) optimizer: Optional[OptimizerPatch] = None + redirects: Optional[RedirectConfig] = None regions: Optional[Annotated[List[Region], Field(min_length=1)]] = None waf: Optional[WafConfigPatch] = None __properties: ClassVar[List[str]] = [ @@ -65,6 +67,7 @@ class ConfigPatch(BaseModel): "logSink", "monthlyLimitBytes", "optimizer", + "redirects", "regions", "waf", ] @@ -115,6 +118,9 @@ def to_dict(self) -> Dict[str, Any]: # override the default output from pydantic by calling `to_dict()` of optimizer if self.optimizer: _dict["optimizer"] = self.optimizer.to_dict() + # override the default output from pydantic by calling `to_dict()` of redirects + if self.redirects: + _dict["redirects"] = self.redirects.to_dict() # override the default output from pydantic by calling `to_dict()` of waf if self.waf: _dict["waf"] = self.waf.to_dict() @@ -153,6 +159,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "logSink": LokiLogSinkPatch.from_dict(obj["logSink"]) if obj.get("logSink") is not None else None, "monthlyLimitBytes": obj.get("monthlyLimitBytes"), "optimizer": OptimizerPatch.from_dict(obj["optimizer"]) if obj.get("optimizer") is not None else None, + "redirects": RedirectConfig.from_dict(obj["redirects"]) if obj.get("redirects") is not None else None, "regions": obj.get("regions"), "waf": WafConfigPatch.from_dict(obj["waf"]) if obj.get("waf") is not None else None, } diff --git a/services/cdn/src/stackit/cdn/models/create_distribution_payload.py b/services/cdn/src/stackit/cdn/models/create_distribution_payload.py index be8bafde..724fa9c4 100644 --- a/services/cdn/src/stackit/cdn/models/create_distribution_payload.py +++ b/services/cdn/src/stackit/cdn/models/create_distribution_payload.py @@ -25,6 +25,7 @@ ) from stackit.cdn.models.loki_log_sink_create import LokiLogSinkCreate from stackit.cdn.models.optimizer import Optimizer +from stackit.cdn.models.redirect_config import RedirectConfig from stackit.cdn.models.region import Region from stackit.cdn.models.waf_config import WafConfig @@ -62,6 +63,7 @@ class CreateDistributionPayload(BaseModel): alias="monthlyLimitBytes", ) optimizer: Optional[Optimizer] = None + redirects: Optional[RedirectConfig] = None regions: Annotated[List[Region], Field(min_length=1)] = Field( description="Define in which regions you would like your content to be cached. " ) @@ -75,6 +77,7 @@ class CreateDistributionPayload(BaseModel): "logSink", "monthlyLimitBytes", "optimizer", + "redirects", "regions", "waf", ] @@ -125,6 +128,9 @@ def to_dict(self) -> Dict[str, Any]: # override the default output from pydantic by calling `to_dict()` of optimizer if self.optimizer: _dict["optimizer"] = self.optimizer.to_dict() + # override the default output from pydantic by calling `to_dict()` of redirects + if self.redirects: + _dict["redirects"] = self.redirects.to_dict() # override the default output from pydantic by calling `to_dict()` of waf if self.waf: _dict["waf"] = self.waf.to_dict() @@ -153,6 +159,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "logSink": LokiLogSinkCreate.from_dict(obj["logSink"]) if obj.get("logSink") is not None else None, "monthlyLimitBytes": obj.get("monthlyLimitBytes"), "optimizer": Optimizer.from_dict(obj["optimizer"]) if obj.get("optimizer") is not None else None, + "redirects": RedirectConfig.from_dict(obj["redirects"]) if obj.get("redirects") is not None else None, "regions": obj.get("regions"), "waf": WafConfig.from_dict(obj["waf"]) if obj.get("waf") is not None else None, } diff --git a/services/cdn/src/stackit/cdn/models/match_condition.py b/services/cdn/src/stackit/cdn/models/match_condition.py new file mode 100644 index 00000000..4f2fec0b --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/match_condition.py @@ -0,0 +1,37 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +from enum import Enum + +from typing_extensions import Self + + +class MatchCondition(str, Enum): + """ + Defines how multiple matchers within this rule are combined (ALL, ANY, NONE). Defaults to ANY. + """ + + """ + allowed enum values + """ + ANY = "ANY" + ALL = "ALL" + NONE = "NONE" + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of MatchCondition from a JSON string""" + return cls(json.loads(json_str)) diff --git a/services/cdn/src/stackit/cdn/models/matcher.py b/services/cdn/src/stackit/cdn/models/matcher.py new file mode 100644 index 00000000..1e8fc82c --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/matcher.py @@ -0,0 +1,93 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing_extensions import Annotated, Self + +from stackit.cdn.models.match_condition import MatchCondition + + +class Matcher(BaseModel): + """ + A matcher containing a list of string values to compare against the request path. + """ # noqa: E501 + + value_match_condition: Optional[MatchCondition] = Field(default=MatchCondition.ANY, alias="valueMatchCondition") + values: Annotated[List[StrictStr], Field(min_length=1)] = Field( + description='A list of glob patterns to match against the request path. At least one value is required. Examples: "/shop/*" or "*/img/*"' + ) + __properties: ClassVar[List[str]] = ["valueMatchCondition", "values"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of Matcher from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of Matcher from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "valueMatchCondition": ( + obj.get("valueMatchCondition") if obj.get("valueMatchCondition") is not None else MatchCondition.ANY + ), + "values": obj.get("values"), + } + ) + return _obj diff --git a/services/cdn/src/stackit/cdn/models/redirect_config.py b/services/cdn/src/stackit/cdn/models/redirect_config.py new file mode 100644 index 00000000..8f529803 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/redirect_config.py @@ -0,0 +1,98 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import BaseModel, ConfigDict, Field +from typing_extensions import Self + +from stackit.cdn.models.redirect_rule import RedirectRule + + +class RedirectConfig(BaseModel): + """ + A wrapper for a list of redirect rules that allows for redirect settings on a distribution. + """ # noqa: E501 + + rules: Optional[List[RedirectRule]] = Field( + default=None, description="A list of redirect rules. The order of rules matters for evaluation." + ) + __properties: ClassVar[List[str]] = ["rules"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RedirectConfig from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in rules (list) + _items = [] + if self.rules: + for _item in self.rules: + if _item: + _items.append(_item.to_dict()) + _dict["rules"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RedirectConfig from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "rules": ( + [RedirectRule.from_dict(_item) for _item in obj["rules"]] if obj.get("rules") is not None else None + ) + } + ) + return _obj diff --git a/services/cdn/src/stackit/cdn/models/redirect_rule.py b/services/cdn/src/stackit/cdn/models/redirect_rule.py new file mode 100644 index 00000000..5e79b090 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/redirect_rule.py @@ -0,0 +1,135 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +from typing import Any, ClassVar, Dict, List, Optional, Set + +from pydantic import ( + BaseModel, + ConfigDict, + Field, + StrictBool, + StrictStr, + field_validator, +) +from typing_extensions import Annotated, Self + +from stackit.cdn.models.match_condition import MatchCondition +from stackit.cdn.models.matcher import Matcher + + +class RedirectRule(BaseModel): + """ + A single redirect rule defining a source pattern and a target URL. + """ # noqa: E501 + + description: Optional[StrictStr] = Field(default=None, description="An optional description for the redirect rule.") + enabled: Optional[StrictBool] = Field(default=True, description="A toggle to enable or disable the redirect rule.") + matchers: Annotated[List[Matcher], Field(min_length=1)] = Field( + description="A list of matchers that define when this rule should apply. At least one matcher is required." + ) + rule_match_condition: Optional[MatchCondition] = Field(default=MatchCondition.ANY, alias="ruleMatchCondition") + status_code: Annotated[int, Field(le=399, strict=True, ge=300)] = Field( + description="The HTTP status code for the redirect. Must be one of 301, 302, 303, 307, or 308.", + alias="statusCode", + ) + target_url: StrictStr = Field(description="The target URL to redirect to. Must be a valid URI.", alias="targetUrl") + __properties: ClassVar[List[str]] = [ + "description", + "enabled", + "matchers", + "ruleMatchCondition", + "statusCode", + "targetUrl", + ] + + @field_validator("status_code") + def status_code_validate_enum(cls, value): + """Validates the enum""" + if value not in set([301, 302, 303, 307, 308]): + raise ValueError("must be one of enum values (301, 302, 303, 307, 308)") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RedirectRule from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in matchers (list) + _items = [] + if self.matchers: + for _item in self.matchers: + if _item: + _items.append(_item.to_dict()) + _dict["matchers"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RedirectRule from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "description": obj.get("description"), + "enabled": obj.get("enabled") if obj.get("enabled") is not None else True, + "matchers": ( + [Matcher.from_dict(_item) for _item in obj["matchers"]] if obj.get("matchers") is not None else None + ), + "ruleMatchCondition": ( + obj.get("ruleMatchCondition") if obj.get("ruleMatchCondition") is not None else MatchCondition.ANY + ), + "statusCode": obj.get("statusCode"), + "targetUrl": obj.get("targetUrl"), + } + ) + return _obj diff --git a/services/cdn/src/stackit/cdn/models/status_error.py b/services/cdn/src/stackit/cdn/models/status_error.py index 7951d701..dd236efe 100644 --- a/services/cdn/src/stackit/cdn/models/status_error.py +++ b/services/cdn/src/stackit/cdn/models/status_error.py @@ -48,10 +48,11 @@ def key_validate_enum(cls, value): "CUSTOM_DOMAIN_ALREADY_IN_USE", "PUBLIC_BETA_QUOTA_REACHED", "LOG_SINK_INSTANCE_UNAVAILABLE", + "EXTERNAL_QUOTA_REACHED", ] ): raise ValueError( - "must be one of enum values ('UNKNOWN', 'CUSTOM_DOMAIN_CNAME_MISSING', 'CUSTOM_DOMAIN_ALREADY_IN_USE', 'PUBLIC_BETA_QUOTA_REACHED', 'LOG_SINK_INSTANCE_UNAVAILABLE')" + "must be one of enum values ('UNKNOWN', 'CUSTOM_DOMAIN_CNAME_MISSING', 'CUSTOM_DOMAIN_ALREADY_IN_USE', 'PUBLIC_BETA_QUOTA_REACHED', 'LOG_SINK_INSTANCE_UNAVAILABLE', 'EXTERNAL_QUOTA_REACHED')" ) return value