From 6b246eb8a5ad6a246ae0c8255133325684cf374d Mon Sep 17 00:00:00 2001 From: scaleway-bot Date: Sun, 28 Sep 2025 11:11:21 +0000 Subject: [PATCH] feat: update generated APIs --- .../audit_trail/v1alpha1/__init__.py | 18 +- .../audit_trail/v1alpha1/api.py | 57 ++++++ .../audit_trail/v1alpha1/marshalling.py | 192 ++++++++++++++---- .../audit_trail/v1alpha1/types.py | 80 ++++++-- .../scaleway_async/tem/v1alpha1/__init__.py | 6 + .../tem/v1alpha1/marshalling.py | 90 ++++++++ .../scaleway_async/tem/v1alpha1/types.py | 54 +++++ .../scaleway/audit_trail/v1alpha1/__init__.py | 18 +- scaleway/scaleway/audit_trail/v1alpha1/api.py | 57 ++++++ .../audit_trail/v1alpha1/marshalling.py | 192 ++++++++++++++---- .../scaleway/audit_trail/v1alpha1/types.py | 80 ++++++-- scaleway/scaleway/tem/v1alpha1/__init__.py | 6 + scaleway/scaleway/tem/v1alpha1/marshalling.py | 90 ++++++++ scaleway/scaleway/tem/v1alpha1/types.py | 54 +++++ 14 files changed, 882 insertions(+), 112 deletions(-) diff --git a/scaleway-async/scaleway_async/audit_trail/v1alpha1/__init__.py b/scaleway-async/scaleway_async/audit_trail/v1alpha1/__init__.py index 6c6bc7b5d..04afd89e3 100644 --- a/scaleway-async/scaleway_async/audit_trail/v1alpha1/__init__.py +++ b/scaleway-async/scaleway_async/audit_trail/v1alpha1/__init__.py @@ -6,8 +6,10 @@ from .types import AuthenticationEventOrigin from .types import AuthenticationEventResult from .types import ListAuthenticationEventsRequestOrderBy +from .types import ListCombinedEventsRequestOrderBy from .types import ListEventsRequestOrderBy from .types import ResourceType +from .types import SystemEventKind from .types import AccountOrganizationInfo from .types import AccountProjectInfo from .types import AccountUserInfo @@ -32,13 +34,16 @@ from .types import SecretManagerSecretVersionInfo from .types import Resource from .types import EventPrincipal -from .types import EventSystem -from .types import ProductService from .types import AuthenticationEvent from .types import Event +from .types import SystemEvent +from .types import ProductService +from .types import ListCombinedEventsResponseCombinedEvent from .types import Product from .types import ListAuthenticationEventsRequest from .types import ListAuthenticationEventsResponse +from .types import ListCombinedEventsRequest +from .types import ListCombinedEventsResponse from .types import ListEventsRequest from .types import ListEventsResponse from .types import ListProductsRequest @@ -52,8 +57,10 @@ "AuthenticationEventOrigin", "AuthenticationEventResult", "ListAuthenticationEventsRequestOrderBy", + "ListCombinedEventsRequestOrderBy", "ListEventsRequestOrderBy", "ResourceType", + "SystemEventKind", "AccountOrganizationInfo", "AccountProjectInfo", "AccountUserInfo", @@ -78,13 +85,16 @@ "SecretManagerSecretVersionInfo", "Resource", "EventPrincipal", - "EventSystem", - "ProductService", "AuthenticationEvent", "Event", + "SystemEvent", + "ProductService", + "ListCombinedEventsResponseCombinedEvent", "Product", "ListAuthenticationEventsRequest", "ListAuthenticationEventsResponse", + "ListCombinedEventsRequest", + "ListCombinedEventsResponse", "ListEventsRequest", "ListEventsResponse", "ListProductsRequest", diff --git a/scaleway-async/scaleway_async/audit_trail/v1alpha1/api.py b/scaleway-async/scaleway_async/audit_trail/v1alpha1/api.py index d2a29e596..a05cc66b0 100644 --- a/scaleway-async/scaleway_async/audit_trail/v1alpha1/api.py +++ b/scaleway-async/scaleway_async/audit_trail/v1alpha1/api.py @@ -13,14 +13,17 @@ ) from .types import ( ListAuthenticationEventsRequestOrderBy, + ListCombinedEventsRequestOrderBy, ListEventsRequestOrderBy, ResourceType, ListAuthenticationEventsResponse, + ListCombinedEventsResponse, ListEventsResponse, ListProductsResponse, ) from .marshalling import ( unmarshal_ListAuthenticationEventsResponse, + unmarshal_ListCombinedEventsResponse, unmarshal_ListEventsResponse, unmarshal_ListProductsResponse, ) @@ -158,6 +161,60 @@ async def list_authentication_events( self._throw_on_error(res) return unmarshal_ListAuthenticationEventsResponse(res.json()) + async def list_combined_events( + self, + *, + region: Optional[ScwRegion] = None, + organization_id: Optional[str] = None, + project_id: Optional[str] = None, + resource_type: Optional[ResourceType] = None, + recorded_after: Optional[datetime] = None, + recorded_before: Optional[datetime] = None, + order_by: Optional[ListCombinedEventsRequestOrderBy] = None, + page_size: Optional[int] = None, + page_token: Optional[str] = None, + ) -> ListCombinedEventsResponse: + """ + :param region: Region to target. If none is passed will use default region from the config. + :param organization_id: + :param project_id: + :param resource_type: + :param recorded_after: + :param recorded_before: + :param order_by: + :param page_size: + :param page_token: + :return: :class:`ListCombinedEventsResponse ` + + Usage: + :: + + result = await api.list_combined_events() + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + + res = self._request( + "GET", + f"/audit-trail/v1alpha1/regions/{param_region}/combined-events", + params={ + "order_by": order_by, + "organization_id": organization_id + or self.client.default_organization_id, + "page_size": page_size or self.client.default_page_size, + "page_token": page_token, + "project_id": project_id or self.client.default_project_id, + "recorded_after": recorded_after, + "recorded_before": recorded_before, + "resource_type": resource_type, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListCombinedEventsResponse(res.json()) + async def list_products( self, *, diff --git a/scaleway-async/scaleway_async/audit_trail/v1alpha1/marshalling.py b/scaleway-async/scaleway_async/audit_trail/v1alpha1/marshalling.py index 4d9781e54..8c6d6fcb7 100644 --- a/scaleway-async/scaleway_async/audit_trail/v1alpha1/marshalling.py +++ b/scaleway-async/scaleway_async/audit_trail/v1alpha1/marshalling.py @@ -36,8 +36,10 @@ AuthenticationEvent, ListAuthenticationEventsResponse, EventPrincipal, - EventSystem, Event, + SystemEvent, + ListCombinedEventsResponseCombinedEvent, + ListCombinedEventsResponse, ListEventsResponse, ProductService, Product, @@ -802,23 +804,6 @@ def unmarshal_EventPrincipal(data: Any) -> EventPrincipal: return EventPrincipal(**args) -def unmarshal_EventSystem(data: Any) -> EventSystem: - if not isinstance(data, dict): - raise TypeError( - "Unmarshalling the type 'EventSystem' failed as data isn't a dictionary." - ) - - args: dict[str, Any] = {} - - field = data.get("name", None) - if field is not None: - args["name"] = field - else: - args["name"] = None - - return EventSystem(**args) - - def unmarshal_Event(data: Any) -> Event: if not isinstance(data, dict): raise TypeError( @@ -857,18 +842,6 @@ def unmarshal_Event(data: Any) -> Event: else: args["product_name"] = None - field = data.get("service_name", None) - if field is not None: - args["service_name"] = field - else: - args["service_name"] = None - - field = data.get("method_name", None) - if field is not None: - args["method_name"] = field - else: - args["method_name"] = None - field = data.get("recorded_at", None) if field is not None: args["recorded_at"] = ( @@ -883,6 +856,30 @@ def unmarshal_Event(data: Any) -> Event: else: args["principal"] = None + field = data.get("project_id", None) + if field is not None: + args["project_id"] = field + else: + args["project_id"] = None + + field = data.get("user_agent", None) + if field is not None: + args["user_agent"] = field + else: + args["user_agent"] = None + + field = data.get("service_name", None) + if field is not None: + args["service_name"] = field + else: + args["service_name"] = None + + field = data.get("method_name", None) + if field is not None: + args["method_name"] = field + else: + args["method_name"] = None + field = data.get("resources", None) if field is not None: args["resources"] = ( @@ -903,11 +900,80 @@ def unmarshal_Event(data: Any) -> Event: else: args["status_code"] = 0 - field = data.get("system", None) + field = data.get("request_body", None) if field is not None: - args["system"] = unmarshal_EventSystem(field) + args["request_body"] = field else: - args["system"] = None + args["request_body"] = {} + + return Event(**args) + + +def unmarshal_SystemEvent(data: Any) -> SystemEvent: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'SystemEvent' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("locality", None) + if field is not None: + args["locality"] = field + else: + args["locality"] = None + + field = data.get("organization_id", None) + if field is not None: + args["organization_id"] = field + else: + args["organization_id"] = None + + field = data.get("source", None) + if field is not None: + args["source"] = field + else: + args["source"] = None + + field = data.get("system_name", None) + if field is not None: + args["system_name"] = field + else: + args["system_name"] = None + + field = data.get("resources", None) + if field is not None: + args["resources"] = ( + [unmarshal_Resource(v) for v in field] if field is not None else None + ) + else: + args["resources"] = None + + field = data.get("kind", None) + if field is not None: + args["kind"] = field + else: + args["kind"] = None + + field = data.get("product_name", None) + if field is not None: + args["product_name"] = field + else: + args["product_name"] = None + + field = data.get("recorded_at", None) + if field is not None: + args["recorded_at"] = ( + parser.isoparse(field) if isinstance(field, str) else field + ) + else: + args["recorded_at"] = None field = data.get("project_id", None) if field is not None: @@ -915,19 +981,65 @@ def unmarshal_Event(data: Any) -> Event: else: args["project_id"] = None - field = data.get("user_agent", None) + return SystemEvent(**args) + + +def unmarshal_ListCombinedEventsResponseCombinedEvent( + data: Any, +) -> ListCombinedEventsResponseCombinedEvent: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListCombinedEventsResponseCombinedEvent' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("api", None) if field is not None: - args["user_agent"] = field + args["api"] = unmarshal_Event(field) else: - args["user_agent"] = None + args["api"] = None - field = data.get("request_body", None) + field = data.get("auth", None) if field is not None: - args["request_body"] = field + args["auth"] = unmarshal_AuthenticationEvent(field) else: - args["request_body"] = {} + args["auth"] = None - return Event(**args) + field = data.get("system", None) + if field is not None: + args["system"] = unmarshal_SystemEvent(field) + else: + args["system"] = None + + return ListCombinedEventsResponseCombinedEvent(**args) + + +def unmarshal_ListCombinedEventsResponse(data: Any) -> ListCombinedEventsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListCombinedEventsResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("events", None) + if field is not None: + args["events"] = ( + [unmarshal_ListCombinedEventsResponseCombinedEvent(v) for v in field] + if field is not None + else None + ) + else: + args["events"] = None + + field = data.get("next_page_token", None) + if field is not None: + args["next_page_token"] = field + else: + args["next_page_token"] = None + + return ListCombinedEventsResponse(**args) def unmarshal_ListEventsResponse(data: Any) -> ListEventsResponse: diff --git a/scaleway-async/scaleway_async/audit_trail/v1alpha1/types.py b/scaleway-async/scaleway_async/audit_trail/v1alpha1/types.py index f0df3a94c..df31b4686 100644 --- a/scaleway-async/scaleway_async/audit_trail/v1alpha1/types.py +++ b/scaleway-async/scaleway_async/audit_trail/v1alpha1/types.py @@ -73,6 +73,14 @@ def __str__(self) -> str: return str(self.value) +class ListCombinedEventsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + RECORDED_AT_DESC = "recorded_at_desc" + RECORDED_AT_ASC = "recorded_at_asc" + + def __str__(self) -> str: + return str(self.value) + + class ListEventsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): RECORDED_AT_DESC = "recorded_at_desc" RECORDED_AT_ASC = "recorded_at_asc" @@ -131,6 +139,15 @@ def __str__(self) -> str: return str(self.value) +class SystemEventKind(str, Enum, metaclass=StrEnumMeta): + UNKNOWN_KIND = "unknown_kind" + CRON = "cron" + NOTIFICATION = "notification" + + def __str__(self) -> str: + return str(self.value) + + @dataclass class AccountOrganizationInfo: pass @@ -316,17 +333,6 @@ class EventPrincipal: id: str -@dataclass -class EventSystem: - name: str - - -@dataclass -class ProductService: - name: str - methods: list[str] - - @dataclass class AuthenticationEvent: id: str @@ -468,7 +474,34 @@ class Event: principal: Optional[EventPrincipal] = None - system: Optional[EventSystem] = None + +@dataclass +class SystemEvent: + id: str + locality: str + organization_id: str + source: str + system_name: str + resources: list[Resource] + kind: SystemEventKind + product_name: str + recorded_at: Optional[datetime] = None + project_id: Optional[str] = None + + +@dataclass +class ProductService: + name: str + methods: list[str] + + +@dataclass +class ListCombinedEventsResponseCombinedEvent: + api: Optional[Event] = None + + auth: Optional[AuthenticationEvent] = None + + system: Optional[SystemEvent] = None @dataclass @@ -510,6 +543,29 @@ class ListAuthenticationEventsResponse: next_page_token: Optional[str] = None +@dataclass +class ListCombinedEventsRequest: + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + organization_id: Optional[str] = None + project_id: Optional[str] = None + resource_type: Optional[ResourceType] = None + recorded_after: Optional[datetime] = None + recorded_before: Optional[datetime] = None + order_by: Optional[ListCombinedEventsRequestOrderBy] = None + page_size: Optional[int] = None + page_token: Optional[str] = None + + +@dataclass +class ListCombinedEventsResponse: + events: list[ListCombinedEventsResponseCombinedEvent] + next_page_token: Optional[str] = None + + @dataclass class ListEventsRequest: region: Optional[ScwRegion] = None diff --git a/scaleway-async/scaleway_async/tem/v1alpha1/__init__.py b/scaleway-async/scaleway_async/tem/v1alpha1/__init__.py index fa7383134..1a7203950 100644 --- a/scaleway-async/scaleway_async/tem/v1alpha1/__init__.py +++ b/scaleway-async/scaleway_async/tem/v1alpha1/__init__.py @@ -19,7 +19,10 @@ from .types import ProjectSettingsPeriodicReportFrequency from .types import WebhookEventStatus from .types import WebhookEventType +from .types import DomainRecordsDKIM from .types import DomainRecordsDMARC +from .types import DomainRecordsMX +from .types import DomainRecordsSPF from .types import EmailTry from .types import DomainRecords from .types import DomainReputation @@ -106,7 +109,10 @@ "ProjectSettingsPeriodicReportFrequency", "WebhookEventStatus", "WebhookEventType", + "DomainRecordsDKIM", "DomainRecordsDMARC", + "DomainRecordsMX", + "DomainRecordsSPF", "EmailTry", "DomainRecords", "DomainReputation", diff --git a/scaleway-async/scaleway_async/tem/v1alpha1/marshalling.py b/scaleway-async/scaleway_async/tem/v1alpha1/marshalling.py index a3d9aeb45..491d43ee2 100644 --- a/scaleway-async/scaleway_async/tem/v1alpha1/marshalling.py +++ b/scaleway-async/scaleway_async/tem/v1alpha1/marshalling.py @@ -21,7 +21,10 @@ WebhookEventType, EmailTry, Email, + DomainRecordsDKIM, DomainRecordsDMARC, + DomainRecordsMX, + DomainRecordsSPF, DomainRecords, DomainReputation, DomainStatistics, @@ -205,6 +208,29 @@ def unmarshal_Email(data: Any) -> Email: return Email(**args) +def unmarshal_DomainRecordsDKIM(data: Any) -> DomainRecordsDKIM: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'DomainRecordsDKIM' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("name", None) + if field is not None: + args["name"] = field + else: + args["name"] = None + + field = data.get("value", None) + if field is not None: + args["value"] = field + else: + args["value"] = None + + return DomainRecordsDKIM(**args) + + def unmarshal_DomainRecordsDMARC(data: Any) -> DomainRecordsDMARC: if not isinstance(data, dict): raise TypeError( @@ -228,6 +254,52 @@ def unmarshal_DomainRecordsDMARC(data: Any) -> DomainRecordsDMARC: return DomainRecordsDMARC(**args) +def unmarshal_DomainRecordsMX(data: Any) -> DomainRecordsMX: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'DomainRecordsMX' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("name", None) + if field is not None: + args["name"] = field + else: + args["name"] = None + + field = data.get("value", None) + if field is not None: + args["value"] = field + else: + args["value"] = None + + return DomainRecordsMX(**args) + + +def unmarshal_DomainRecordsSPF(data: Any) -> DomainRecordsSPF: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'DomainRecordsSPF' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("name", None) + if field is not None: + args["name"] = field + else: + args["name"] = None + + field = data.get("value", None) + if field is not None: + args["value"] = field + else: + args["value"] = None + + return DomainRecordsSPF(**args) + + def unmarshal_DomainRecords(data: Any) -> DomainRecords: if not isinstance(data, dict): raise TypeError( @@ -242,6 +314,24 @@ def unmarshal_DomainRecords(data: Any) -> DomainRecords: else: args["dmarc"] = None + field = data.get("dkim", None) + if field is not None: + args["dkim"] = unmarshal_DomainRecordsDKIM(field) + else: + args["dkim"] = None + + field = data.get("spf", None) + if field is not None: + args["spf"] = unmarshal_DomainRecordsSPF(field) + else: + args["spf"] = None + + field = data.get("mx", None) + if field is not None: + args["mx"] = unmarshal_DomainRecordsMX(field) + else: + args["mx"] = None + return DomainRecords(**args) diff --git a/scaleway-async/scaleway_async/tem/v1alpha1/types.py b/scaleway-async/scaleway_async/tem/v1alpha1/types.py index 5b58cb41d..f1cfe51bb 100644 --- a/scaleway-async/scaleway_async/tem/v1alpha1/types.py +++ b/scaleway-async/scaleway_async/tem/v1alpha1/types.py @@ -205,6 +205,19 @@ def __str__(self) -> str: return str(self.value) +@dataclass +class DomainRecordsDKIM: + name: str + """ + Name of the DKIM TXT record. + """ + + value: str + """ + Value of the DKIM TXT record. + """ + + @dataclass class DomainRecordsDMARC: name: str @@ -218,6 +231,32 @@ class DomainRecordsDMARC: """ +@dataclass +class DomainRecordsMX: + name: str + """ + Name of the MX record. + """ + + value: str + """ + Value of the MX record. + """ + + +@dataclass +class DomainRecordsSPF: + name: str + """ + Name of the SPF TXT record. + """ + + value: str + """ + Value of the SPF TXT record. + """ + + @dataclass class EmailTry: rank: int @@ -248,6 +287,21 @@ class DomainRecords: DMARC TXT record specification. """ + dkim: Optional[DomainRecordsDKIM] = None + """ + DKIM TXT record specification. + """ + + spf: Optional[DomainRecordsSPF] = None + """ + SPF TXT record specification. + """ + + mx: Optional[DomainRecordsMX] = None + """ + MX record specification. + """ + @dataclass class DomainReputation: diff --git a/scaleway/scaleway/audit_trail/v1alpha1/__init__.py b/scaleway/scaleway/audit_trail/v1alpha1/__init__.py index 6c6bc7b5d..04afd89e3 100644 --- a/scaleway/scaleway/audit_trail/v1alpha1/__init__.py +++ b/scaleway/scaleway/audit_trail/v1alpha1/__init__.py @@ -6,8 +6,10 @@ from .types import AuthenticationEventOrigin from .types import AuthenticationEventResult from .types import ListAuthenticationEventsRequestOrderBy +from .types import ListCombinedEventsRequestOrderBy from .types import ListEventsRequestOrderBy from .types import ResourceType +from .types import SystemEventKind from .types import AccountOrganizationInfo from .types import AccountProjectInfo from .types import AccountUserInfo @@ -32,13 +34,16 @@ from .types import SecretManagerSecretVersionInfo from .types import Resource from .types import EventPrincipal -from .types import EventSystem -from .types import ProductService from .types import AuthenticationEvent from .types import Event +from .types import SystemEvent +from .types import ProductService +from .types import ListCombinedEventsResponseCombinedEvent from .types import Product from .types import ListAuthenticationEventsRequest from .types import ListAuthenticationEventsResponse +from .types import ListCombinedEventsRequest +from .types import ListCombinedEventsResponse from .types import ListEventsRequest from .types import ListEventsResponse from .types import ListProductsRequest @@ -52,8 +57,10 @@ "AuthenticationEventOrigin", "AuthenticationEventResult", "ListAuthenticationEventsRequestOrderBy", + "ListCombinedEventsRequestOrderBy", "ListEventsRequestOrderBy", "ResourceType", + "SystemEventKind", "AccountOrganizationInfo", "AccountProjectInfo", "AccountUserInfo", @@ -78,13 +85,16 @@ "SecretManagerSecretVersionInfo", "Resource", "EventPrincipal", - "EventSystem", - "ProductService", "AuthenticationEvent", "Event", + "SystemEvent", + "ProductService", + "ListCombinedEventsResponseCombinedEvent", "Product", "ListAuthenticationEventsRequest", "ListAuthenticationEventsResponse", + "ListCombinedEventsRequest", + "ListCombinedEventsResponse", "ListEventsRequest", "ListEventsResponse", "ListProductsRequest", diff --git a/scaleway/scaleway/audit_trail/v1alpha1/api.py b/scaleway/scaleway/audit_trail/v1alpha1/api.py index 3507cd93b..e4198824d 100644 --- a/scaleway/scaleway/audit_trail/v1alpha1/api.py +++ b/scaleway/scaleway/audit_trail/v1alpha1/api.py @@ -13,14 +13,17 @@ ) from .types import ( ListAuthenticationEventsRequestOrderBy, + ListCombinedEventsRequestOrderBy, ListEventsRequestOrderBy, ResourceType, ListAuthenticationEventsResponse, + ListCombinedEventsResponse, ListEventsResponse, ListProductsResponse, ) from .marshalling import ( unmarshal_ListAuthenticationEventsResponse, + unmarshal_ListCombinedEventsResponse, unmarshal_ListEventsResponse, unmarshal_ListProductsResponse, ) @@ -158,6 +161,60 @@ def list_authentication_events( self._throw_on_error(res) return unmarshal_ListAuthenticationEventsResponse(res.json()) + def list_combined_events( + self, + *, + region: Optional[ScwRegion] = None, + organization_id: Optional[str] = None, + project_id: Optional[str] = None, + resource_type: Optional[ResourceType] = None, + recorded_after: Optional[datetime] = None, + recorded_before: Optional[datetime] = None, + order_by: Optional[ListCombinedEventsRequestOrderBy] = None, + page_size: Optional[int] = None, + page_token: Optional[str] = None, + ) -> ListCombinedEventsResponse: + """ + :param region: Region to target. If none is passed will use default region from the config. + :param organization_id: + :param project_id: + :param resource_type: + :param recorded_after: + :param recorded_before: + :param order_by: + :param page_size: + :param page_token: + :return: :class:`ListCombinedEventsResponse ` + + Usage: + :: + + result = api.list_combined_events() + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + + res = self._request( + "GET", + f"/audit-trail/v1alpha1/regions/{param_region}/combined-events", + params={ + "order_by": order_by, + "organization_id": organization_id + or self.client.default_organization_id, + "page_size": page_size or self.client.default_page_size, + "page_token": page_token, + "project_id": project_id or self.client.default_project_id, + "recorded_after": recorded_after, + "recorded_before": recorded_before, + "resource_type": resource_type, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListCombinedEventsResponse(res.json()) + def list_products( self, *, diff --git a/scaleway/scaleway/audit_trail/v1alpha1/marshalling.py b/scaleway/scaleway/audit_trail/v1alpha1/marshalling.py index 4d9781e54..8c6d6fcb7 100644 --- a/scaleway/scaleway/audit_trail/v1alpha1/marshalling.py +++ b/scaleway/scaleway/audit_trail/v1alpha1/marshalling.py @@ -36,8 +36,10 @@ AuthenticationEvent, ListAuthenticationEventsResponse, EventPrincipal, - EventSystem, Event, + SystemEvent, + ListCombinedEventsResponseCombinedEvent, + ListCombinedEventsResponse, ListEventsResponse, ProductService, Product, @@ -802,23 +804,6 @@ def unmarshal_EventPrincipal(data: Any) -> EventPrincipal: return EventPrincipal(**args) -def unmarshal_EventSystem(data: Any) -> EventSystem: - if not isinstance(data, dict): - raise TypeError( - "Unmarshalling the type 'EventSystem' failed as data isn't a dictionary." - ) - - args: dict[str, Any] = {} - - field = data.get("name", None) - if field is not None: - args["name"] = field - else: - args["name"] = None - - return EventSystem(**args) - - def unmarshal_Event(data: Any) -> Event: if not isinstance(data, dict): raise TypeError( @@ -857,18 +842,6 @@ def unmarshal_Event(data: Any) -> Event: else: args["product_name"] = None - field = data.get("service_name", None) - if field is not None: - args["service_name"] = field - else: - args["service_name"] = None - - field = data.get("method_name", None) - if field is not None: - args["method_name"] = field - else: - args["method_name"] = None - field = data.get("recorded_at", None) if field is not None: args["recorded_at"] = ( @@ -883,6 +856,30 @@ def unmarshal_Event(data: Any) -> Event: else: args["principal"] = None + field = data.get("project_id", None) + if field is not None: + args["project_id"] = field + else: + args["project_id"] = None + + field = data.get("user_agent", None) + if field is not None: + args["user_agent"] = field + else: + args["user_agent"] = None + + field = data.get("service_name", None) + if field is not None: + args["service_name"] = field + else: + args["service_name"] = None + + field = data.get("method_name", None) + if field is not None: + args["method_name"] = field + else: + args["method_name"] = None + field = data.get("resources", None) if field is not None: args["resources"] = ( @@ -903,11 +900,80 @@ def unmarshal_Event(data: Any) -> Event: else: args["status_code"] = 0 - field = data.get("system", None) + field = data.get("request_body", None) if field is not None: - args["system"] = unmarshal_EventSystem(field) + args["request_body"] = field else: - args["system"] = None + args["request_body"] = {} + + return Event(**args) + + +def unmarshal_SystemEvent(data: Any) -> SystemEvent: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'SystemEvent' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + else: + args["id"] = None + + field = data.get("locality", None) + if field is not None: + args["locality"] = field + else: + args["locality"] = None + + field = data.get("organization_id", None) + if field is not None: + args["organization_id"] = field + else: + args["organization_id"] = None + + field = data.get("source", None) + if field is not None: + args["source"] = field + else: + args["source"] = None + + field = data.get("system_name", None) + if field is not None: + args["system_name"] = field + else: + args["system_name"] = None + + field = data.get("resources", None) + if field is not None: + args["resources"] = ( + [unmarshal_Resource(v) for v in field] if field is not None else None + ) + else: + args["resources"] = None + + field = data.get("kind", None) + if field is not None: + args["kind"] = field + else: + args["kind"] = None + + field = data.get("product_name", None) + if field is not None: + args["product_name"] = field + else: + args["product_name"] = None + + field = data.get("recorded_at", None) + if field is not None: + args["recorded_at"] = ( + parser.isoparse(field) if isinstance(field, str) else field + ) + else: + args["recorded_at"] = None field = data.get("project_id", None) if field is not None: @@ -915,19 +981,65 @@ def unmarshal_Event(data: Any) -> Event: else: args["project_id"] = None - field = data.get("user_agent", None) + return SystemEvent(**args) + + +def unmarshal_ListCombinedEventsResponseCombinedEvent( + data: Any, +) -> ListCombinedEventsResponseCombinedEvent: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListCombinedEventsResponseCombinedEvent' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("api", None) if field is not None: - args["user_agent"] = field + args["api"] = unmarshal_Event(field) else: - args["user_agent"] = None + args["api"] = None - field = data.get("request_body", None) + field = data.get("auth", None) if field is not None: - args["request_body"] = field + args["auth"] = unmarshal_AuthenticationEvent(field) else: - args["request_body"] = {} + args["auth"] = None - return Event(**args) + field = data.get("system", None) + if field is not None: + args["system"] = unmarshal_SystemEvent(field) + else: + args["system"] = None + + return ListCombinedEventsResponseCombinedEvent(**args) + + +def unmarshal_ListCombinedEventsResponse(data: Any) -> ListCombinedEventsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListCombinedEventsResponse' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("events", None) + if field is not None: + args["events"] = ( + [unmarshal_ListCombinedEventsResponseCombinedEvent(v) for v in field] + if field is not None + else None + ) + else: + args["events"] = None + + field = data.get("next_page_token", None) + if field is not None: + args["next_page_token"] = field + else: + args["next_page_token"] = None + + return ListCombinedEventsResponse(**args) def unmarshal_ListEventsResponse(data: Any) -> ListEventsResponse: diff --git a/scaleway/scaleway/audit_trail/v1alpha1/types.py b/scaleway/scaleway/audit_trail/v1alpha1/types.py index f0df3a94c..df31b4686 100644 --- a/scaleway/scaleway/audit_trail/v1alpha1/types.py +++ b/scaleway/scaleway/audit_trail/v1alpha1/types.py @@ -73,6 +73,14 @@ def __str__(self) -> str: return str(self.value) +class ListCombinedEventsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + RECORDED_AT_DESC = "recorded_at_desc" + RECORDED_AT_ASC = "recorded_at_asc" + + def __str__(self) -> str: + return str(self.value) + + class ListEventsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): RECORDED_AT_DESC = "recorded_at_desc" RECORDED_AT_ASC = "recorded_at_asc" @@ -131,6 +139,15 @@ def __str__(self) -> str: return str(self.value) +class SystemEventKind(str, Enum, metaclass=StrEnumMeta): + UNKNOWN_KIND = "unknown_kind" + CRON = "cron" + NOTIFICATION = "notification" + + def __str__(self) -> str: + return str(self.value) + + @dataclass class AccountOrganizationInfo: pass @@ -316,17 +333,6 @@ class EventPrincipal: id: str -@dataclass -class EventSystem: - name: str - - -@dataclass -class ProductService: - name: str - methods: list[str] - - @dataclass class AuthenticationEvent: id: str @@ -468,7 +474,34 @@ class Event: principal: Optional[EventPrincipal] = None - system: Optional[EventSystem] = None + +@dataclass +class SystemEvent: + id: str + locality: str + organization_id: str + source: str + system_name: str + resources: list[Resource] + kind: SystemEventKind + product_name: str + recorded_at: Optional[datetime] = None + project_id: Optional[str] = None + + +@dataclass +class ProductService: + name: str + methods: list[str] + + +@dataclass +class ListCombinedEventsResponseCombinedEvent: + api: Optional[Event] = None + + auth: Optional[AuthenticationEvent] = None + + system: Optional[SystemEvent] = None @dataclass @@ -510,6 +543,29 @@ class ListAuthenticationEventsResponse: next_page_token: Optional[str] = None +@dataclass +class ListCombinedEventsRequest: + region: Optional[ScwRegion] = None + """ + Region to target. If none is passed will use default region from the config. + """ + + organization_id: Optional[str] = None + project_id: Optional[str] = None + resource_type: Optional[ResourceType] = None + recorded_after: Optional[datetime] = None + recorded_before: Optional[datetime] = None + order_by: Optional[ListCombinedEventsRequestOrderBy] = None + page_size: Optional[int] = None + page_token: Optional[str] = None + + +@dataclass +class ListCombinedEventsResponse: + events: list[ListCombinedEventsResponseCombinedEvent] + next_page_token: Optional[str] = None + + @dataclass class ListEventsRequest: region: Optional[ScwRegion] = None diff --git a/scaleway/scaleway/tem/v1alpha1/__init__.py b/scaleway/scaleway/tem/v1alpha1/__init__.py index fa7383134..1a7203950 100644 --- a/scaleway/scaleway/tem/v1alpha1/__init__.py +++ b/scaleway/scaleway/tem/v1alpha1/__init__.py @@ -19,7 +19,10 @@ from .types import ProjectSettingsPeriodicReportFrequency from .types import WebhookEventStatus from .types import WebhookEventType +from .types import DomainRecordsDKIM from .types import DomainRecordsDMARC +from .types import DomainRecordsMX +from .types import DomainRecordsSPF from .types import EmailTry from .types import DomainRecords from .types import DomainReputation @@ -106,7 +109,10 @@ "ProjectSettingsPeriodicReportFrequency", "WebhookEventStatus", "WebhookEventType", + "DomainRecordsDKIM", "DomainRecordsDMARC", + "DomainRecordsMX", + "DomainRecordsSPF", "EmailTry", "DomainRecords", "DomainReputation", diff --git a/scaleway/scaleway/tem/v1alpha1/marshalling.py b/scaleway/scaleway/tem/v1alpha1/marshalling.py index a3d9aeb45..491d43ee2 100644 --- a/scaleway/scaleway/tem/v1alpha1/marshalling.py +++ b/scaleway/scaleway/tem/v1alpha1/marshalling.py @@ -21,7 +21,10 @@ WebhookEventType, EmailTry, Email, + DomainRecordsDKIM, DomainRecordsDMARC, + DomainRecordsMX, + DomainRecordsSPF, DomainRecords, DomainReputation, DomainStatistics, @@ -205,6 +208,29 @@ def unmarshal_Email(data: Any) -> Email: return Email(**args) +def unmarshal_DomainRecordsDKIM(data: Any) -> DomainRecordsDKIM: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'DomainRecordsDKIM' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("name", None) + if field is not None: + args["name"] = field + else: + args["name"] = None + + field = data.get("value", None) + if field is not None: + args["value"] = field + else: + args["value"] = None + + return DomainRecordsDKIM(**args) + + def unmarshal_DomainRecordsDMARC(data: Any) -> DomainRecordsDMARC: if not isinstance(data, dict): raise TypeError( @@ -228,6 +254,52 @@ def unmarshal_DomainRecordsDMARC(data: Any) -> DomainRecordsDMARC: return DomainRecordsDMARC(**args) +def unmarshal_DomainRecordsMX(data: Any) -> DomainRecordsMX: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'DomainRecordsMX' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("name", None) + if field is not None: + args["name"] = field + else: + args["name"] = None + + field = data.get("value", None) + if field is not None: + args["value"] = field + else: + args["value"] = None + + return DomainRecordsMX(**args) + + +def unmarshal_DomainRecordsSPF(data: Any) -> DomainRecordsSPF: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'DomainRecordsSPF' failed as data isn't a dictionary." + ) + + args: dict[str, Any] = {} + + field = data.get("name", None) + if field is not None: + args["name"] = field + else: + args["name"] = None + + field = data.get("value", None) + if field is not None: + args["value"] = field + else: + args["value"] = None + + return DomainRecordsSPF(**args) + + def unmarshal_DomainRecords(data: Any) -> DomainRecords: if not isinstance(data, dict): raise TypeError( @@ -242,6 +314,24 @@ def unmarshal_DomainRecords(data: Any) -> DomainRecords: else: args["dmarc"] = None + field = data.get("dkim", None) + if field is not None: + args["dkim"] = unmarshal_DomainRecordsDKIM(field) + else: + args["dkim"] = None + + field = data.get("spf", None) + if field is not None: + args["spf"] = unmarshal_DomainRecordsSPF(field) + else: + args["spf"] = None + + field = data.get("mx", None) + if field is not None: + args["mx"] = unmarshal_DomainRecordsMX(field) + else: + args["mx"] = None + return DomainRecords(**args) diff --git a/scaleway/scaleway/tem/v1alpha1/types.py b/scaleway/scaleway/tem/v1alpha1/types.py index 5b58cb41d..f1cfe51bb 100644 --- a/scaleway/scaleway/tem/v1alpha1/types.py +++ b/scaleway/scaleway/tem/v1alpha1/types.py @@ -205,6 +205,19 @@ def __str__(self) -> str: return str(self.value) +@dataclass +class DomainRecordsDKIM: + name: str + """ + Name of the DKIM TXT record. + """ + + value: str + """ + Value of the DKIM TXT record. + """ + + @dataclass class DomainRecordsDMARC: name: str @@ -218,6 +231,32 @@ class DomainRecordsDMARC: """ +@dataclass +class DomainRecordsMX: + name: str + """ + Name of the MX record. + """ + + value: str + """ + Value of the MX record. + """ + + +@dataclass +class DomainRecordsSPF: + name: str + """ + Name of the SPF TXT record. + """ + + value: str + """ + Value of the SPF TXT record. + """ + + @dataclass class EmailTry: rank: int @@ -248,6 +287,21 @@ class DomainRecords: DMARC TXT record specification. """ + dkim: Optional[DomainRecordsDKIM] = None + """ + DKIM TXT record specification. + """ + + spf: Optional[DomainRecordsSPF] = None + """ + SPF TXT record specification. + """ + + mx: Optional[DomainRecordsMX] = None + """ + MX record specification. + """ + @dataclass class DomainReputation: