From 2c010a9c81806a381af86f62231fbda2f8b0a863 Mon Sep 17 00:00:00 2001 From: SDK Generator Bot Date: Wed, 8 Oct 2025 09:47:33 +0000 Subject: [PATCH] Generate cdn --- services/cdn/src/stackit/cdn/__init__.py | 26 ++ .../cdn/src/stackit/cdn/api/default_api.py | 300 ++++++++++++++++++ .../cdn/src/stackit/cdn/models/__init__.py | 10 + 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/distribution.py | 7 + .../stackit/cdn/models/distribution_waf.py | 124 ++++++++ .../models/list_waf_collections_response.py | 98 ++++++ .../cdn/src/stackit/cdn/models/waf_config.py | 91 ++++++ .../stackit/cdn/models/waf_config_patch.py | 85 +++++ .../cdn/src/stackit/cdn/models/waf_mode.py | 37 +++ .../cdn/src/stackit/cdn/models/waf_rule.py | 85 +++++ .../stackit/cdn/models/waf_rule_collection.py | 102 ++++++ .../src/stackit/cdn/models/waf_rule_group.py | 98 ++++++ .../cdn/models/waf_status_rule_block.py | 81 +++++ .../cdn/src/stackit/cdn/models/waf_type.py | 36 +++ 17 files changed, 1201 insertions(+) create mode 100644 services/cdn/src/stackit/cdn/models/distribution_waf.py create mode 100644 services/cdn/src/stackit/cdn/models/list_waf_collections_response.py create mode 100644 services/cdn/src/stackit/cdn/models/waf_config.py create mode 100644 services/cdn/src/stackit/cdn/models/waf_config_patch.py create mode 100644 services/cdn/src/stackit/cdn/models/waf_mode.py create mode 100644 services/cdn/src/stackit/cdn/models/waf_rule.py create mode 100644 services/cdn/src/stackit/cdn/models/waf_rule_collection.py create mode 100644 services/cdn/src/stackit/cdn/models/waf_rule_group.py create mode 100644 services/cdn/src/stackit/cdn/models/waf_status_rule_block.py create mode 100644 services/cdn/src/stackit/cdn/models/waf_type.py diff --git a/services/cdn/src/stackit/cdn/__init__.py b/services/cdn/src/stackit/cdn/__init__.py index 5c6e0dfba..6478c7022 100644 --- a/services/cdn/src/stackit/cdn/__init__.py +++ b/services/cdn/src/stackit/cdn/__init__.py @@ -40,6 +40,7 @@ "DistributionStatisticsRecord", "DistributionStatisticsRecordEntry", "DistributionStatisticsRecordRegions", + "DistributionWaf", "Domain", "DomainStatus", "ErrorDetails", @@ -59,6 +60,7 @@ "HttpBackend", "HttpBackendPatch", "ListDistributionsResponse", + "ListWAFCollectionsResponse", "LokiLogSink", "Optimizer", "OptimizerPatch", @@ -74,6 +76,14 @@ "PutCustomDomainResponseCertificate", "Region", "StatusError", + "WAFRule", + "WAFRuleCollection", + "WAFRuleGroup", + "WAFStatusRuleBlock", + "WafConfig", + "WafConfigPatch", + "WafMode", + "WafType", ] # import apis into sdk package @@ -119,6 +129,7 @@ from stackit.cdn.models.distribution_statistics_record_regions import ( DistributionStatisticsRecordRegions as DistributionStatisticsRecordRegions, ) +from stackit.cdn.models.distribution_waf import DistributionWaf as DistributionWaf from stackit.cdn.models.domain import Domain as Domain from stackit.cdn.models.domain_status import DomainStatus as DomainStatus from stackit.cdn.models.error_details import ErrorDetails as ErrorDetails @@ -164,6 +175,9 @@ from stackit.cdn.models.list_distributions_response import ( ListDistributionsResponse as ListDistributionsResponse, ) +from stackit.cdn.models.list_waf_collections_response import ( + ListWAFCollectionsResponse as ListWAFCollectionsResponse, +) from stackit.cdn.models.loki_log_sink import LokiLogSink as LokiLogSink from stackit.cdn.models.optimizer import Optimizer as Optimizer from stackit.cdn.models.optimizer_patch import OptimizerPatch as OptimizerPatch @@ -197,3 +211,15 @@ ) 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 +from stackit.cdn.models.waf_config_patch import WafConfigPatch as WafConfigPatch +from stackit.cdn.models.waf_mode import WafMode as WafMode +from stackit.cdn.models.waf_rule import WAFRule as WAFRule +from stackit.cdn.models.waf_rule_collection import ( + WAFRuleCollection as WAFRuleCollection, +) +from stackit.cdn.models.waf_rule_group import WAFRuleGroup as WAFRuleGroup +from stackit.cdn.models.waf_status_rule_block import ( + WAFStatusRuleBlock as WAFStatusRuleBlock, +) +from stackit.cdn.models.waf_type import WafType as WafType diff --git a/services/cdn/src/stackit/cdn/api/default_api.py b/services/cdn/src/stackit/cdn/api/default_api.py index b5e2172ab..5e31fce69 100644 --- a/services/cdn/src/stackit/cdn/api/default_api.py +++ b/services/cdn/src/stackit/cdn/api/default_api.py @@ -41,6 +41,7 @@ ) from stackit.cdn.models.get_statistics_response import GetStatisticsResponse from stackit.cdn.models.list_distributions_response import ListDistributionsResponse +from stackit.cdn.models.list_waf_collections_response import ListWAFCollectionsResponse from stackit.cdn.models.patch_distribution_payload import PatchDistributionPayload from stackit.cdn.models.patch_distribution_response import PatchDistributionResponse from stackit.cdn.models.purge_cache_payload import PurgeCachePayload @@ -1694,6 +1695,12 @@ def get_distribution( self, project_id: Annotated[StrictStr, Field(description="Your STACKIT Project ID")], distribution_id: StrictStr, + with_waf_status: Annotated[ + Optional[StrictBool], + Field( + description="If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules." + ), + ] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -1712,6 +1719,8 @@ def get_distribution( :type project_id: str :param distribution_id: (required) :type distribution_id: str + :param with_waf_status: If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules. + :type with_waf_status: bool :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -1737,6 +1746,7 @@ def get_distribution( _param = self._get_distribution_serialize( project_id=project_id, distribution_id=distribution_id, + with_waf_status=with_waf_status, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -1762,6 +1772,12 @@ def get_distribution_with_http_info( self, project_id: Annotated[StrictStr, Field(description="Your STACKIT Project ID")], distribution_id: StrictStr, + with_waf_status: Annotated[ + Optional[StrictBool], + Field( + description="If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules." + ), + ] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -1780,6 +1796,8 @@ def get_distribution_with_http_info( :type project_id: str :param distribution_id: (required) :type distribution_id: str + :param with_waf_status: If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules. + :type with_waf_status: bool :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -1805,6 +1823,7 @@ def get_distribution_with_http_info( _param = self._get_distribution_serialize( project_id=project_id, distribution_id=distribution_id, + with_waf_status=with_waf_status, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -1830,6 +1849,12 @@ def get_distribution_without_preload_content( self, project_id: Annotated[StrictStr, Field(description="Your STACKIT Project ID")], distribution_id: StrictStr, + with_waf_status: Annotated[ + Optional[StrictBool], + Field( + description="If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules." + ), + ] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -1848,6 +1873,8 @@ def get_distribution_without_preload_content( :type project_id: str :param distribution_id: (required) :type distribution_id: str + :param with_waf_status: If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules. + :type with_waf_status: bool :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -1873,6 +1900,7 @@ def get_distribution_without_preload_content( _param = self._get_distribution_serialize( project_id=project_id, distribution_id=distribution_id, + with_waf_status=with_waf_status, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -1893,6 +1921,7 @@ def _get_distribution_serialize( self, project_id, distribution_id, + with_waf_status, _request_auth, _content_type, _headers, @@ -1916,6 +1945,10 @@ def _get_distribution_serialize( if distribution_id is not None: _path_params["distributionId"] = distribution_id # process the query parameters + if with_waf_status is not None: + + _query_params.append(("withWafStatus", with_waf_status)) + # process the header parameters # process the form parameters # process the body parameter @@ -3122,6 +3155,12 @@ def list_distributions( description="Quantifies how many distributions should be returned on this page. Must be a natural number between 1 and 100 (inclusive) " ), ] = None, + with_waf_status: Annotated[ + Optional[StrictBool], + Field( + description="If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules." + ), + ] = None, page_identifier: Annotated[ Optional[StrictStr], Field( @@ -3153,6 +3192,8 @@ def list_distributions( :type project_id: str :param page_size: Quantifies how many distributions should be returned on this page. Must be a natural number between 1 and 100 (inclusive) :type page_size: int + :param with_waf_status: If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules. + :type with_waf_status: bool :param page_identifier: Identifier is returned by the previous response and is used to request the next page. As the `pageIdentifier` encodes an element, inserts during pagination will *not* shift the result. So a scenario like: - Start listing first page - Insert new element - Start listing second page will *never* result in an element from the first page to get \"pushed\" to the second page, like it could occur with basic limit + offset pagination. The identifier should be treated as an opaque string and never modified. Only pass values returned by the API. :type page_identifier: str :param sort_by: The following sort options exist. We default to `createdAt` - `id` - Sort by distribution ID using String comparison - `updatedAt` - Sort by when the distribution configuration was last modified, for example by changing the regions or response headers - `createdAt` - Sort by when the distribution was initially created. - `originUrl` - Sort by originURL using String comparison - `status` - Sort by distribution status, using String comparison - `originUrlRelated` - The origin URL is segmented and reversed before sorting. E.g. `www.example.com` is converted to `com.example.www` for sorting. This way, distributions pointing to the same domain trees are grouped next to each other. @@ -3184,6 +3225,7 @@ def list_distributions( _param = self._list_distributions_serialize( project_id=project_id, page_size=page_size, + with_waf_status=with_waf_status, page_identifier=page_identifier, sort_by=sort_by, sort_order=sort_order, @@ -3216,6 +3258,12 @@ def list_distributions_with_http_info( description="Quantifies how many distributions should be returned on this page. Must be a natural number between 1 and 100 (inclusive) " ), ] = None, + with_waf_status: Annotated[ + Optional[StrictBool], + Field( + description="If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules." + ), + ] = None, page_identifier: Annotated[ Optional[StrictStr], Field( @@ -3247,6 +3295,8 @@ def list_distributions_with_http_info( :type project_id: str :param page_size: Quantifies how many distributions should be returned on this page. Must be a natural number between 1 and 100 (inclusive) :type page_size: int + :param with_waf_status: If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules. + :type with_waf_status: bool :param page_identifier: Identifier is returned by the previous response and is used to request the next page. As the `pageIdentifier` encodes an element, inserts during pagination will *not* shift the result. So a scenario like: - Start listing first page - Insert new element - Start listing second page will *never* result in an element from the first page to get \"pushed\" to the second page, like it could occur with basic limit + offset pagination. The identifier should be treated as an opaque string and never modified. Only pass values returned by the API. :type page_identifier: str :param sort_by: The following sort options exist. We default to `createdAt` - `id` - Sort by distribution ID using String comparison - `updatedAt` - Sort by when the distribution configuration was last modified, for example by changing the regions or response headers - `createdAt` - Sort by when the distribution was initially created. - `originUrl` - Sort by originURL using String comparison - `status` - Sort by distribution status, using String comparison - `originUrlRelated` - The origin URL is segmented and reversed before sorting. E.g. `www.example.com` is converted to `com.example.www` for sorting. This way, distributions pointing to the same domain trees are grouped next to each other. @@ -3278,6 +3328,7 @@ def list_distributions_with_http_info( _param = self._list_distributions_serialize( project_id=project_id, page_size=page_size, + with_waf_status=with_waf_status, page_identifier=page_identifier, sort_by=sort_by, sort_order=sort_order, @@ -3310,6 +3361,12 @@ def list_distributions_without_preload_content( description="Quantifies how many distributions should be returned on this page. Must be a natural number between 1 and 100 (inclusive) " ), ] = None, + with_waf_status: Annotated[ + Optional[StrictBool], + Field( + description="If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules." + ), + ] = None, page_identifier: Annotated[ Optional[StrictStr], Field( @@ -3341,6 +3398,8 @@ def list_distributions_without_preload_content( :type project_id: str :param page_size: Quantifies how many distributions should be returned on this page. Must be a natural number between 1 and 100 (inclusive) :type page_size: int + :param with_waf_status: If set, the top level of a distribution contains a `waf` property, which defines the status of the waf. This includes a list of all resolved rules. + :type with_waf_status: bool :param page_identifier: Identifier is returned by the previous response and is used to request the next page. As the `pageIdentifier` encodes an element, inserts during pagination will *not* shift the result. So a scenario like: - Start listing first page - Insert new element - Start listing second page will *never* result in an element from the first page to get \"pushed\" to the second page, like it could occur with basic limit + offset pagination. The identifier should be treated as an opaque string and never modified. Only pass values returned by the API. :type page_identifier: str :param sort_by: The following sort options exist. We default to `createdAt` - `id` - Sort by distribution ID using String comparison - `updatedAt` - Sort by when the distribution configuration was last modified, for example by changing the regions or response headers - `createdAt` - Sort by when the distribution was initially created. - `originUrl` - Sort by originURL using String comparison - `status` - Sort by distribution status, using String comparison - `originUrlRelated` - The origin URL is segmented and reversed before sorting. E.g. `www.example.com` is converted to `com.example.www` for sorting. This way, distributions pointing to the same domain trees are grouped next to each other. @@ -3372,6 +3431,7 @@ def list_distributions_without_preload_content( _param = self._list_distributions_serialize( project_id=project_id, page_size=page_size, + with_waf_status=with_waf_status, page_identifier=page_identifier, sort_by=sort_by, sort_order=sort_order, @@ -3394,6 +3454,7 @@ def _list_distributions_serialize( self, project_id, page_size, + with_waf_status, page_identifier, sort_by, sort_order, @@ -3422,6 +3483,10 @@ def _list_distributions_serialize( _query_params.append(("pageSize", page_size)) + if with_waf_status is not None: + + _query_params.append(("withWafStatus", with_waf_status)) + if page_identifier is not None: _query_params.append(("pageIdentifier", page_identifier)) @@ -3460,6 +3525,241 @@ def _list_distributions_serialize( _request_auth=_request_auth, ) + @validate_call + def list_waf_collections( + self, + project_id: Annotated[StrictStr, Field(description="Your STACKIT Project ID")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ListWAFCollectionsResponse: + """List all WAF rule collections of the project + + Returns all WAF rule collections available to the project + + :param project_id: Your STACKIT Project ID (required) + :type project_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_waf_collections_serialize( + project_id=project_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListWAFCollectionsResponse", + "401": "str", + "422": "GenericJSONResponse", + "500": "GenericJSONResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + @validate_call + def list_waf_collections_with_http_info( + self, + project_id: Annotated[StrictStr, Field(description="Your STACKIT Project ID")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ListWAFCollectionsResponse]: + """List all WAF rule collections of the project + + Returns all WAF rule collections available to the project + + :param project_id: Your STACKIT Project ID (required) + :type project_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_waf_collections_serialize( + project_id=project_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListWAFCollectionsResponse", + "401": "str", + "422": "GenericJSONResponse", + "500": "GenericJSONResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + @validate_call + def list_waf_collections_without_preload_content( + self, + project_id: Annotated[StrictStr, Field(description="Your STACKIT Project ID")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List all WAF rule collections of the project + + Returns all WAF rule collections available to the project + + :param project_id: Your STACKIT Project ID (required) + :type project_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_waf_collections_serialize( + project_id=project_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "ListWAFCollectionsResponse", + "401": "str", + "422": "GenericJSONResponse", + "500": "GenericJSONResponse", + } + response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + return response_data.response + + def _list_waf_collections_serialize( + self, + project_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = {} + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if project_id is not None: + _path_params["projectId"] = project_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + # set the HTTP header `Accept` + if "Accept" not in _header_params: + _header_params["Accept"] = self.api_client.select_header_accept(["application/json", "text/plain"]) + + # authentication setting + _auth_settings: List[str] = [] + + return self.api_client.param_serialize( + method="GET", + resource_path="/v1beta/projects/{projectId}/waf/collections", + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth, + ) + @validate_call def patch_distribution( self, diff --git a/services/cdn/src/stackit/cdn/models/__init__.py b/services/cdn/src/stackit/cdn/models/__init__.py index 0f332fc83..7d4409f37 100644 --- a/services/cdn/src/stackit/cdn/models/__init__.py +++ b/services/cdn/src/stackit/cdn/models/__init__.py @@ -32,6 +32,7 @@ from stackit.cdn.models.distribution_statistics_record_regions import ( DistributionStatisticsRecordRegions, ) +from stackit.cdn.models.distribution_waf import DistributionWaf from stackit.cdn.models.domain import Domain from stackit.cdn.models.domain_status import DomainStatus from stackit.cdn.models.error_details import ErrorDetails @@ -63,6 +64,7 @@ from stackit.cdn.models.http_backend import HttpBackend from stackit.cdn.models.http_backend_patch import HttpBackendPatch from stackit.cdn.models.list_distributions_response import ListDistributionsResponse +from stackit.cdn.models.list_waf_collections_response import ListWAFCollectionsResponse from stackit.cdn.models.loki_log_sink import LokiLogSink from stackit.cdn.models.optimizer import Optimizer from stackit.cdn.models.optimizer_patch import OptimizerPatch @@ -86,3 +88,11 @@ ) from stackit.cdn.models.region import Region from stackit.cdn.models.status_error import StatusError +from stackit.cdn.models.waf_config import WafConfig +from stackit.cdn.models.waf_config_patch import WafConfigPatch +from stackit.cdn.models.waf_mode import WafMode +from stackit.cdn.models.waf_rule import WAFRule +from stackit.cdn.models.waf_rule_collection import WAFRuleCollection +from stackit.cdn.models.waf_rule_group import WAFRuleGroup +from stackit.cdn.models.waf_status_rule_block import WAFStatusRuleBlock +from stackit.cdn.models.waf_type import WafType diff --git a/services/cdn/src/stackit/cdn/models/config.py b/services/cdn/src/stackit/cdn/models/config.py index f570e172b..64ccf8f2c 100644 --- a/services/cdn/src/stackit/cdn/models/config.py +++ b/services/cdn/src/stackit/cdn/models/config.py @@ -24,6 +24,7 @@ from stackit.cdn.models.loki_log_sink import LokiLogSink from stackit.cdn.models.optimizer import Optimizer from stackit.cdn.models.region import Region +from stackit.cdn.models.waf_config import WafConfig class Config(BaseModel): @@ -53,6 +54,7 @@ class Config(BaseModel): ) optimizer: Optional[Optimizer] = None regions: Annotated[List[Region], Field(min_length=1)] + waf: WafConfig __properties: ClassVar[List[str]] = [ "backend", "blockedCountries", @@ -62,6 +64,7 @@ class Config(BaseModel): "monthlyLimitBytes", "optimizer", "regions", + "waf", ] model_config = ConfigDict( @@ -110,6 +113,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 waf + if self.waf: + _dict["waf"] = self.waf.to_dict() # set to None if default_cache_duration (nullable) is None # and model_fields_set contains the field if self.default_cache_duration is None and "default_cache_duration" in self.model_fields_set: @@ -141,6 +147,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "monthlyLimitBytes": obj.get("monthlyLimitBytes"), "optimizer": Optimizer.from_dict(obj["optimizer"]) if obj.get("optimizer") is not None else None, "regions": obj.get("regions"), + "waf": WafConfig.from_dict(obj["waf"]) if obj.get("waf") is not None else None, } ) return _obj diff --git a/services/cdn/src/stackit/cdn/models/config_patch.py b/services/cdn/src/stackit/cdn/models/config_patch.py index 05ead0ea2..bc99927b8 100644 --- a/services/cdn/src/stackit/cdn/models/config_patch.py +++ b/services/cdn/src/stackit/cdn/models/config_patch.py @@ -24,6 +24,7 @@ from stackit.cdn.models.optimizer_patch import OptimizerPatch from stackit.cdn.models.patch_loki_log_sink import PatchLokiLogSink from stackit.cdn.models.region import Region +from stackit.cdn.models.waf_config_patch import WafConfigPatch class ConfigPatch(BaseModel): @@ -55,6 +56,7 @@ class ConfigPatch(BaseModel): ) optimizer: Optional[OptimizerPatch] = None regions: Optional[Annotated[List[Region], Field(min_length=1)]] = None + waf: Optional[WafConfigPatch] = None __properties: ClassVar[List[str]] = [ "backend", "blockedCountries", @@ -64,6 +66,7 @@ class ConfigPatch(BaseModel): "monthlyLimitBytes", "optimizer", "regions", + "waf", ] model_config = ConfigDict( @@ -112,6 +115,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 waf + if self.waf: + _dict["waf"] = self.waf.to_dict() # set to None if default_cache_duration (nullable) is None # and model_fields_set contains the field if self.default_cache_duration is None and "default_cache_duration" in self.model_fields_set: @@ -148,6 +154,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "monthlyLimitBytes": obj.get("monthlyLimitBytes"), "optimizer": OptimizerPatch.from_dict(obj["optimizer"]) if obj.get("optimizer") is not None else None, "regions": obj.get("regions"), + "waf": WafConfigPatch.from_dict(obj["waf"]) if obj.get("waf") is not None else None, } ) return _obj 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 58a1e7d92..243e9d4d0 100644 --- a/services/cdn/src/stackit/cdn/models/create_distribution_payload.py +++ b/services/cdn/src/stackit/cdn/models/create_distribution_payload.py @@ -23,6 +23,7 @@ from stackit.cdn.models.optimizer import Optimizer from stackit.cdn.models.patch_loki_log_sink import PatchLokiLogSink from stackit.cdn.models.region import Region +from stackit.cdn.models.waf_config import WafConfig class CreateDistributionPayload(BaseModel): @@ -73,6 +74,7 @@ class CreateDistributionPayload(BaseModel): regions: Annotated[List[Region], Field(min_length=1)] = Field( description="Define in which regions you would like your content to be cached. " ) + waf: Optional[WafConfig] = None __properties: ClassVar[List[str]] = [ "blockedCountries", "blockedIPs", @@ -85,6 +87,7 @@ class CreateDistributionPayload(BaseModel): "originRequestHeaders", "originUrl", "regions", + "waf", ] model_config = ConfigDict( @@ -130,6 +133,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 waf + if self.waf: + _dict["waf"] = self.waf.to_dict() return _dict @classmethod @@ -154,6 +160,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "originRequestHeaders": obj.get("originRequestHeaders"), "originUrl": obj.get("originUrl"), "regions": obj.get("regions"), + "waf": WafConfig.from_dict(obj["waf"]) if obj.get("waf") is not None else None, } ) return _obj diff --git a/services/cdn/src/stackit/cdn/models/distribution.py b/services/cdn/src/stackit/cdn/models/distribution.py index 1ad303dd3..88092b613 100644 --- a/services/cdn/src/stackit/cdn/models/distribution.py +++ b/services/cdn/src/stackit/cdn/models/distribution.py @@ -22,6 +22,7 @@ from typing_extensions import Annotated, Self from stackit.cdn.models.config import Config +from stackit.cdn.models.distribution_waf import DistributionWaf from stackit.cdn.models.domain import Domain from stackit.cdn.models.status_error import StatusError @@ -49,6 +50,7 @@ class Distribution(BaseModel): description="RFC3339 string which returns the last time the distribution configuration was modified. ", alias="updatedAt", ) + waf: Optional[DistributionWaf] = None __properties: ClassVar[List[str]] = [ "config", "createdAt", @@ -58,6 +60,7 @@ class Distribution(BaseModel): "projectId", "status", "updatedAt", + "waf", ] @field_validator("status") @@ -121,6 +124,9 @@ def to_dict(self) -> Dict[str, Any]: if _item: _items.append(_item.to_dict()) _dict["errors"] = _items + # override the default output from pydantic by calling `to_dict()` of waf + if self.waf: + _dict["waf"] = self.waf.to_dict() return _dict @classmethod @@ -146,6 +152,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "projectId": obj.get("projectId"), "status": obj.get("status"), "updatedAt": obj.get("updatedAt"), + "waf": DistributionWaf.from_dict(obj["waf"]) if obj.get("waf") is not None else None, } ) return _obj diff --git a/services/cdn/src/stackit/cdn/models/distribution_waf.py b/services/cdn/src/stackit/cdn/models/distribution_waf.py new file mode 100644 index 000000000..c6c631342 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/distribution_waf.py @@ -0,0 +1,124 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1beta.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.waf_status_rule_block import WAFStatusRuleBlock + + +class DistributionWaf(BaseModel): + """ + For this property to be present two pre-conditions must be met: - the WAF was enabled at least once - the query parameter ?withWafStatus is truthy This property contains the waf Status. At this point in time, this contains all resolved rules. Rules are split into 3 groups: - enabledRules - logOnlyRules - disabledRules **Do note that the global waf mode (Disabled, LogOnly, Enabled) is *NOT* reflected in this list!** + """ # noqa: E501 + + disabled_rules: List[WAFStatusRuleBlock] = Field(alias="disabledRules") + enabled_rules: List[WAFStatusRuleBlock] = Field(alias="enabledRules") + log_only_rules: List[WAFStatusRuleBlock] = Field(alias="logOnlyRules") + __properties: ClassVar[List[str]] = ["disabledRules", "enabledRules", "logOnlyRules"] + + 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 DistributionWaf 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 disabled_rules (list) + _items = [] + if self.disabled_rules: + for _item in self.disabled_rules: + if _item: + _items.append(_item.to_dict()) + _dict["disabledRules"] = _items + # override the default output from pydantic by calling `to_dict()` of each item in enabled_rules (list) + _items = [] + if self.enabled_rules: + for _item in self.enabled_rules: + if _item: + _items.append(_item.to_dict()) + _dict["enabledRules"] = _items + # override the default output from pydantic by calling `to_dict()` of each item in log_only_rules (list) + _items = [] + if self.log_only_rules: + for _item in self.log_only_rules: + if _item: + _items.append(_item.to_dict()) + _dict["logOnlyRules"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of DistributionWaf from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "disabledRules": ( + [WAFStatusRuleBlock.from_dict(_item) for _item in obj["disabledRules"]] + if obj.get("disabledRules") is not None + else None + ), + "enabledRules": ( + [WAFStatusRuleBlock.from_dict(_item) for _item in obj["enabledRules"]] + if obj.get("enabledRules") is not None + else None + ), + "logOnlyRules": ( + [WAFStatusRuleBlock.from_dict(_item) for _item in obj["logOnlyRules"]] + if obj.get("logOnlyRules") is not None + else None + ), + } + ) + return _obj diff --git a/services/cdn/src/stackit/cdn/models/list_waf_collections_response.py b/services/cdn/src/stackit/cdn/models/list_waf_collections_response.py new file mode 100644 index 000000000..eb81ba028 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/list_waf_collections_response.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: 1beta.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 +from typing_extensions import Self + +from stackit.cdn.models.waf_rule_collection import WAFRuleCollection + + +class ListWAFCollectionsResponse(BaseModel): + """ + ListWAFCollectionsResponse + """ # noqa: E501 + + collections: List[WAFRuleCollection] + __properties: ClassVar[List[str]] = ["collections"] + + 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 ListWAFCollectionsResponse 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 collections (list) + _items = [] + if self.collections: + for _item in self.collections: + if _item: + _items.append(_item.to_dict()) + _dict["collections"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ListWAFCollectionsResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "collections": ( + [WAFRuleCollection.from_dict(_item) for _item in obj["collections"]] + if obj.get("collections") is not None + else None + ) + } + ) + return _obj diff --git a/services/cdn/src/stackit/cdn/models/waf_config.py b/services/cdn/src/stackit/cdn/models/waf_config.py new file mode 100644 index 000000000..830d93768 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/waf_config.py @@ -0,0 +1,91 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1beta.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 Self + +from stackit.cdn.models.waf_mode import WafMode +from stackit.cdn.models.waf_type import WafType + + +class WafConfig(BaseModel): + """ + Configuration of the WAF of a distribution + """ # noqa: E501 + + enabled_rule_ids: List[StrictStr] = Field( + description="IDs of the WAF rules that are **explicitly** enabled for this distribution. If this rule is in a disabled / log Only RuleGroup or Collection, it will be enabled regardless as `enabledRuleIds` overrides those in specificity. Do note that rules can also be enabled because a Rulegroup or Collection is enabled. **DO NOT** use this property to find all active rules. Instead, pass `?withWafStatus=true` as a query parameter to `GetDistribution` or `ListDistributions`. This will expose the `waf` Property on distribution Level. From there you can `$.waf.enabledRules.map(e => e.id)` to get a list of all enabled rules. ", + alias="enabledRuleIds", + ) + mode: WafMode + type: WafType + __properties: ClassVar[List[str]] = ["enabledRuleIds", "mode", "type"] + + 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 WafConfig 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 WafConfig from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + {"enabledRuleIds": obj.get("enabledRuleIds"), "mode": obj.get("mode"), "type": obj.get("type")} + ) + return _obj diff --git a/services/cdn/src/stackit/cdn/models/waf_config_patch.py b/services/cdn/src/stackit/cdn/models/waf_config_patch.py new file mode 100644 index 000000000..6235b7722 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/waf_config_patch.py @@ -0,0 +1,85 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1beta.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 +from typing_extensions import Self + +from stackit.cdn.models.waf_mode import WafMode +from stackit.cdn.models.waf_type import WafType + + +class WafConfigPatch(BaseModel): + """ + WafConfigPatch + """ # noqa: E501 + + mode: Optional[WafMode] = None + type: Optional[WafType] = None + __properties: ClassVar[List[str]] = ["mode", "type"] + + 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 WafConfigPatch 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 WafConfigPatch from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"mode": obj.get("mode"), "type": obj.get("type")}) + return _obj diff --git a/services/cdn/src/stackit/cdn/models/waf_mode.py b/services/cdn/src/stackit/cdn/models/waf_mode.py new file mode 100644 index 000000000..7e7b41c78 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/waf_mode.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: 1beta.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 WafMode(str, Enum): + """ + WafMode + """ + + """ + allowed enum values + """ + DISABLED = "DISABLED" + ENABLED = "ENABLED" + LOG_ONLY = "LOG_ONLY" + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of WafMode from a JSON string""" + return cls(json.loads(json_str)) diff --git a/services/cdn/src/stackit/cdn/models/waf_rule.py b/services/cdn/src/stackit/cdn/models/waf_rule.py new file mode 100644 index 000000000..910b4fd63 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/waf_rule.py @@ -0,0 +1,85 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1beta.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 Self + + +class WAFRule(BaseModel): + """ + WAFRule + """ # noqa: E501 + + code: Optional[StrictStr] = Field( + default=None, description="Optional CoreRuleSet rule ID in case this is a CRS rule" + ) + description: Dict[str, StrictStr] = Field(description="LocalizedString is a map from language to string value") + id: StrictStr + __properties: ClassVar[List[str]] = ["code", "description", "id"] + + 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 WAFRule 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 WAFRule from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"code": obj.get("code"), "description": obj.get("description"), "id": obj.get("id")}) + return _obj diff --git a/services/cdn/src/stackit/cdn/models/waf_rule_collection.py b/services/cdn/src/stackit/cdn/models/waf_rule_collection.py new file mode 100644 index 000000000..3e5c48b93 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/waf_rule_collection.py @@ -0,0 +1,102 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1beta.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 Self + +from stackit.cdn.models.waf_rule_group import WAFRuleGroup + + +class WAFRuleCollection(BaseModel): + """ + WAFRuleCollection + """ # noqa: E501 + + groups: List[WAFRuleGroup] + id: StrictStr + name: Dict[str, StrictStr] = Field(description="LocalizedString is a map from language to string value") + __properties: ClassVar[List[str]] = ["groups", "id", "name"] + + 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 WAFRuleCollection 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 groups (list) + _items = [] + if self.groups: + for _item in self.groups: + if _item: + _items.append(_item.to_dict()) + _dict["groups"] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of WAFRuleCollection from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "groups": ( + [WAFRuleGroup.from_dict(_item) for _item in obj["groups"]] + if obj.get("groups") is not None + else None + ), + "id": obj.get("id"), + "name": obj.get("name"), + } + ) + return _obj diff --git a/services/cdn/src/stackit/cdn/models/waf_rule_group.py b/services/cdn/src/stackit/cdn/models/waf_rule_group.py new file mode 100644 index 000000000..904931ac7 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/waf_rule_group.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: 1beta.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 Self + +from stackit.cdn.models.waf_rule import WAFRule + + +class WAFRuleGroup(BaseModel): + """ + WAFRuleGroup + """ # noqa: E501 + + description: Dict[str, StrictStr] = Field(description="LocalizedString is a map from language to string value") + name: Dict[str, StrictStr] = Field(description="LocalizedString is a map from language to string value") + rules: List[WAFRule] + __properties: ClassVar[List[str]] = ["description", "name", "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 WAFRuleGroup 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 WAFRuleGroup 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"), + "name": obj.get("name"), + "rules": [WAFRule.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/waf_status_rule_block.py b/services/cdn/src/stackit/cdn/models/waf_status_rule_block.py new file mode 100644 index 000000000..ad8f0e277 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/waf_status_rule_block.py @@ -0,0 +1,81 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1beta.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 Self + + +class WAFStatusRuleBlock(BaseModel): + """ + WAFStatusRuleBlock + """ # noqa: E501 + + id: StrictStr = Field(description="Specifies the ID of the Rule.") + __properties: ClassVar[List[str]] = ["id"] + + 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 WAFStatusRuleBlock 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 WAFStatusRuleBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({"id": obj.get("id")}) + return _obj diff --git a/services/cdn/src/stackit/cdn/models/waf_type.py b/services/cdn/src/stackit/cdn/models/waf_type.py new file mode 100644 index 000000000..33bd06d94 --- /dev/null +++ b/services/cdn/src/stackit/cdn/models/waf_type.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +""" + CDN API + + API used to create and manage your CDN distributions. + + The version of the OpenAPI document: 1beta.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 WafType(str, Enum): + """ + Enable or disable the Premium WAF. Do note that enabling the Premium WAF will cause additional fees. Some features are gated behind the Premium WAF, like additional, **premium-only rules** and the ability to create **custom rules** (not yet implemented) + """ + + """ + allowed enum values + """ + FREE = "FREE" + PREMIUM = "PREMIUM" + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of WafType from a JSON string""" + return cls(json.loads(json_str))