From 5cb7f6ac49742fbe9c84509dab4d901d7fd6b7bd Mon Sep 17 00:00:00 2001 From: scaleway-bot Date: Thu, 7 Aug 2025 14:16:25 +0000 Subject: [PATCH] feat: update generated APIs --- .../scaleway_async/webhosting/v1/__init__.py | 42 +- .../scaleway_async/webhosting/v1/api.py | 309 ++++++++++++++ .../scaleway_async/webhosting/v1/content.py | 7 + .../webhosting/v1/marshalling.py | 322 ++++++++++++-- .../scaleway_async/webhosting/v1/types.py | 396 +++++++++++++++--- scaleway/scaleway/webhosting/v1/__init__.py | 42 +- scaleway/scaleway/webhosting/v1/api.py | 309 ++++++++++++++ scaleway/scaleway/webhosting/v1/content.py | 7 + .../scaleway/webhosting/v1/marshalling.py | 322 ++++++++++++-- scaleway/scaleway/webhosting/v1/types.py | 396 +++++++++++++++--- 10 files changed, 1990 insertions(+), 162 deletions(-) diff --git a/scaleway-async/scaleway_async/webhosting/v1/__init__.py b/scaleway-async/scaleway_async/webhosting/v1/__init__.py index 43df2e816..93b525663 100644 --- a/scaleway-async/scaleway_async/webhosting/v1/__init__.py +++ b/scaleway-async/scaleway_async/webhosting/v1/__init__.py @@ -1,5 +1,8 @@ # This file was automatically generated. DO NOT EDIT. # If you have any remark or suggestion do not hesitate to open an issue. +from .types import BackupItemType +from .types import BackupStatus +from .content import BACKUP_TRANSIENT_STATUSES from .types import DnsRecordStatus from .types import DnsRecordType from .types import DnsRecordsStatus @@ -13,6 +16,7 @@ from .types import DomainZoneOwner from .types import HostingStatus from .content import HOSTING_TRANSIENT_STATUSES +from .types import ListBackupsRequestOrderBy from .types import ListDatabaseUsersRequestOrderBy from .types import ListDatabasesRequestOrderBy from .types import ListFtpAccountsRequestOrderBy @@ -24,11 +28,14 @@ from .types import OfferOptionName from .types import OfferOptionWarning from .types import PlatformPlatformGroup +from .types import AutoConfigDomainDns from .types import PlatformControlPanelUrls +from .types import HostingDomainCustomDomain from .types import OfferOption from .types import PlatformControlPanel +from .types import BackupItem +from .types import HostingDomain from .types import CreateDatabaseRequestUser -from .types import AutoConfigDomainDns from .types import CreateHostingRequestDomainConfiguration from .types import OfferOptionRequest from .types import SyncDomainDnsRecordsRequestRecord @@ -37,6 +44,8 @@ from .types import HostingUser from .types import Offer from .types import Platform +from .types import BackupItemGroup +from .types import Backup from .types import ControlPanel from .types import DatabaseUser from .types import Database @@ -45,6 +54,11 @@ from .types import MailAccount from .types import Website from .types import DomainAvailability +from .types import BackupApiGetBackupRequest +from .types import BackupApiListBackupItemsRequest +from .types import BackupApiListBackupsRequest +from .types import BackupApiRestoreBackupItemsRequest +from .types import BackupApiRestoreBackupRequest from .types import CheckUserOwnsDomainResponse from .types import ControlPanelApiListControlPanelsRequest from .types import DatabaseApiAssignDatabaseUserRequest @@ -78,6 +92,8 @@ from .types import HostingApiListHostingsRequest from .types import HostingApiResetHostingPasswordRequest from .types import HostingApiUpdateHostingRequest +from .types import ListBackupItemsResponse +from .types import ListBackupsResponse from .types import ListControlPanelsResponse from .types import ListDatabaseUsersResponse from .types import ListDatabasesResponse @@ -93,9 +109,12 @@ from .types import OfferApiListOffersRequest from .types import ResetHostingPasswordResponse from .types import ResourceSummary +from .types import RestoreBackupItemsResponse +from .types import RestoreBackupResponse from .types import SearchDomainsResponse from .types import Session from .types import WebsiteApiListWebsitesRequest +from .api import WebhostingV1BackupAPI from .api import WebhostingV1ControlPanelAPI from .api import WebhostingV1DatabaseAPI from .api import WebhostingV1DnsAPI @@ -106,6 +125,9 @@ from .api import WebhostingV1WebsiteAPI __all__ = [ + "BackupItemType", + "BackupStatus", + "BACKUP_TRANSIENT_STATUSES", "DnsRecordStatus", "DnsRecordType", "DnsRecordsStatus", @@ -119,6 +141,7 @@ "DomainZoneOwner", "HostingStatus", "HOSTING_TRANSIENT_STATUSES", + "ListBackupsRequestOrderBy", "ListDatabaseUsersRequestOrderBy", "ListDatabasesRequestOrderBy", "ListFtpAccountsRequestOrderBy", @@ -130,11 +153,14 @@ "OfferOptionName", "OfferOptionWarning", "PlatformPlatformGroup", + "AutoConfigDomainDns", "PlatformControlPanelUrls", + "HostingDomainCustomDomain", "OfferOption", "PlatformControlPanel", + "BackupItem", + "HostingDomain", "CreateDatabaseRequestUser", - "AutoConfigDomainDns", "CreateHostingRequestDomainConfiguration", "OfferOptionRequest", "SyncDomainDnsRecordsRequestRecord", @@ -143,6 +169,8 @@ "HostingUser", "Offer", "Platform", + "BackupItemGroup", + "Backup", "ControlPanel", "DatabaseUser", "Database", @@ -151,6 +179,11 @@ "MailAccount", "Website", "DomainAvailability", + "BackupApiGetBackupRequest", + "BackupApiListBackupItemsRequest", + "BackupApiListBackupsRequest", + "BackupApiRestoreBackupItemsRequest", + "BackupApiRestoreBackupRequest", "CheckUserOwnsDomainResponse", "ControlPanelApiListControlPanelsRequest", "DatabaseApiAssignDatabaseUserRequest", @@ -184,6 +217,8 @@ "HostingApiListHostingsRequest", "HostingApiResetHostingPasswordRequest", "HostingApiUpdateHostingRequest", + "ListBackupItemsResponse", + "ListBackupsResponse", "ListControlPanelsResponse", "ListDatabaseUsersResponse", "ListDatabasesResponse", @@ -199,9 +234,12 @@ "OfferApiListOffersRequest", "ResetHostingPasswordResponse", "ResourceSummary", + "RestoreBackupItemsResponse", + "RestoreBackupResponse", "SearchDomainsResponse", "Session", "WebsiteApiListWebsitesRequest", + "WebhostingV1BackupAPI", "WebhostingV1ControlPanelAPI", "WebhostingV1DatabaseAPI", "WebhostingV1DnsAPI", diff --git a/scaleway-async/scaleway_async/webhosting/v1/api.py b/scaleway-async/scaleway_async/webhosting/v1/api.py index 0988b7377..3abdd7514 100644 --- a/scaleway-async/scaleway_async/webhosting/v1/api.py +++ b/scaleway-async/scaleway_async/webhosting/v1/api.py @@ -15,6 +15,7 @@ ) from .types import ( HostingStatus, + ListBackupsRequestOrderBy, ListDatabaseUsersRequestOrderBy, ListDatabasesRequestOrderBy, ListFtpAccountsRequestOrderBy, @@ -23,6 +24,8 @@ ListOffersRequestOrderBy, ListWebsitesRequestOrderBy, AutoConfigDomainDns, + Backup, + BackupApiRestoreBackupItemsRequest, CheckUserOwnsDomainResponse, ControlPanel, CreateDatabaseRequestUser, @@ -45,6 +48,8 @@ HostingApiCreateHostingRequest, HostingApiUpdateHostingRequest, HostingSummary, + ListBackupItemsResponse, + ListBackupsResponse, ListControlPanelsResponse, ListDatabaseUsersResponse, ListDatabasesResponse, @@ -61,16 +66,20 @@ OfferOptionRequest, ResetHostingPasswordResponse, ResourceSummary, + RestoreBackupItemsResponse, + RestoreBackupResponse, SearchDomainsResponse, Session, SyncDomainDnsRecordsRequestRecord, Website, ) from .content import ( + BACKUP_TRANSIENT_STATUSES, DOMAIN_TRANSIENT_STATUSES, HOSTING_TRANSIENT_STATUSES, ) from .marshalling import ( + unmarshal_Backup, unmarshal_DatabaseUser, unmarshal_Database, unmarshal_FtpAccount, @@ -79,6 +88,8 @@ unmarshal_DnsRecords, unmarshal_Domain, unmarshal_Hosting, + unmarshal_ListBackupItemsResponse, + unmarshal_ListBackupsResponse, unmarshal_ListControlPanelsResponse, unmarshal_ListDatabaseUsersResponse, unmarshal_ListDatabasesResponse, @@ -89,8 +100,11 @@ unmarshal_ListWebsitesResponse, unmarshal_ResetHostingPasswordResponse, unmarshal_ResourceSummary, + unmarshal_RestoreBackupItemsResponse, + unmarshal_RestoreBackupResponse, unmarshal_SearchDomainsResponse, unmarshal_Session, + marshal_BackupApiRestoreBackupItemsRequest, marshal_DatabaseApiAssignDatabaseUserRequest, marshal_DatabaseApiChangeDatabaseUserPasswordRequest, marshal_DatabaseApiCreateDatabaseRequest, @@ -111,6 +125,292 @@ ) +class WebhostingV1BackupAPI(API): + """ + This API allows you to list and restore backups for your cPanel and WordPress Web Hosting service. + """ + + async def list_backups( + self, + *, + hosting_id: str, + region: Optional[ScwRegion] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListBackupsRequestOrderBy] = None, + ) -> ListBackupsResponse: + """ + List all available backups for a hosting account. + :param hosting_id: UUID of the hosting account. + :param region: Region to target. If none is passed will use default region from the config. + :param page: Page number to retrieve. + :param page_size: Number of backups to return per page. + :param order_by: Order in which to return the list of backups. + :return: :class:`ListBackupsResponse ` + + Usage: + :: + + result = await api.list_backups( + hosting_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_hosting_id = validate_path_param("hosting_id", hosting_id) + + res = self._request( + "GET", + f"/webhosting/v1/regions/{param_region}/hostings/{param_hosting_id}/backups", + params={ + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListBackupsResponse(res.json()) + + async def list_backups_all( + self, + *, + hosting_id: str, + region: Optional[ScwRegion] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListBackupsRequestOrderBy] = None, + ) -> List[Backup]: + """ + List all available backups for a hosting account. + :param hosting_id: UUID of the hosting account. + :param region: Region to target. If none is passed will use default region from the config. + :param page: Page number to retrieve. + :param page_size: Number of backups to return per page. + :param order_by: Order in which to return the list of backups. + :return: :class:`List[Backup] ` + + Usage: + :: + + result = await api.list_backups_all( + hosting_id="example", + ) + """ + + return await fetch_all_pages_async( + type=ListBackupsResponse, + key="backups", + fetcher=self.list_backups, + args={ + "hosting_id": hosting_id, + "region": region, + "page": page, + "page_size": page_size, + "order_by": order_by, + }, + ) + + async def get_backup( + self, + *, + hosting_id: str, + backup_id: str, + region: Optional[ScwRegion] = None, + ) -> Backup: + """ + Get info about a backup specified by the backup ID. + :param hosting_id: UUID of the hosting account. + :param backup_id: ID of the backup to retrieve. + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`Backup ` + + Usage: + :: + + result = await api.get_backup( + hosting_id="example", + backup_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_hosting_id = validate_path_param("hosting_id", hosting_id) + param_backup_id = validate_path_param("backup_id", backup_id) + + res = self._request( + "GET", + f"/webhosting/v1/regions/{param_region}/hostings/{param_hosting_id}/backups/{param_backup_id}", + ) + + self._throw_on_error(res) + return unmarshal_Backup(res.json()) + + async def wait_for_backup( + self, + *, + hosting_id: str, + backup_id: str, + region: Optional[ScwRegion] = None, + options: Optional[WaitForOptions[Backup, Union[bool, Awaitable[bool]]]] = None, + ) -> Backup: + """ + Get info about a backup specified by the backup ID. + :param hosting_id: UUID of the hosting account. + :param backup_id: ID of the backup to retrieve. + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`Backup ` + + Usage: + :: + + result = await api.get_backup( + hosting_id="example", + backup_id="example", + ) + """ + + if not options: + options = WaitForOptions() + + if not options.stop: + options.stop = lambda res: res.status not in BACKUP_TRANSIENT_STATUSES + + return await wait_for_resource_async( + fetcher=self.get_backup, + options=options, + args={ + "hosting_id": hosting_id, + "backup_id": backup_id, + "region": region, + }, + ) + + async def restore_backup( + self, + *, + hosting_id: str, + backup_id: str, + region: Optional[ScwRegion] = None, + ) -> RestoreBackupResponse: + """ + Restore an entire backup to your hosting environment. + :param hosting_id: UUID of the hosting account. + :param backup_id: ID of the backup to fully restore. + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`RestoreBackupResponse ` + + Usage: + :: + + result = await api.restore_backup( + hosting_id="example", + backup_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_hosting_id = validate_path_param("hosting_id", hosting_id) + param_backup_id = validate_path_param("backup_id", backup_id) + + res = self._request( + "POST", + f"/webhosting/v1/regions/{param_region}/hostings/{param_hosting_id}/backups/{param_backup_id}/restore", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_RestoreBackupResponse(res.json()) + + async def list_backup_items( + self, + *, + hosting_id: str, + backup_id: str, + region: Optional[ScwRegion] = None, + ) -> ListBackupItemsResponse: + """ + List items within a specific backup, grouped by type. + :param hosting_id: UUID of the hosting account. + :param backup_id: ID of the backup to list items from. + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`ListBackupItemsResponse ` + + Usage: + :: + + result = await api.list_backup_items( + hosting_id="example", + backup_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_hosting_id = validate_path_param("hosting_id", hosting_id) + + res = self._request( + "GET", + f"/webhosting/v1/regions/{param_region}/hostings/{param_hosting_id}/backup-items", + params={ + "backup_id": backup_id, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListBackupItemsResponse(res.json()) + + async def restore_backup_items( + self, + *, + hosting_id: str, + region: Optional[ScwRegion] = None, + item_ids: Optional[List[str]] = None, + ) -> RestoreBackupItemsResponse: + """ + Restore specific items from a backup (e.g., a database or mailbox). + :param hosting_id: UUID of the hosting account. + :param region: Region to target. If none is passed will use default region from the config. + :param item_ids: List of backup item IDs to restore individually. + :return: :class:`RestoreBackupItemsResponse ` + + Usage: + :: + + result = await api.restore_backup_items( + hosting_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_hosting_id = validate_path_param("hosting_id", hosting_id) + + res = self._request( + "POST", + f"/webhosting/v1/regions/{param_region}/hostings/{param_hosting_id}/restore-backup-items", + body=marshal_BackupApiRestoreBackupItemsRequest( + BackupApiRestoreBackupItemsRequest( + hosting_id=hosting_id, + region=region, + item_ids=item_ids, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_RestoreBackupItemsResponse(res.json()) + + class WebhostingV1ControlPanelAPI(API): """ This API allows you to manage your Web Hosting services. @@ -1112,6 +1412,7 @@ async def create_hosting( region: Optional[ScwRegion] = None, project_id: Optional[str] = None, tags: Optional[List[str]] = None, + subdomain: Optional[str] = None, offer_options: Optional[List[OfferOptionRequest]] = None, language: Optional[StdLanguageCode] = None, domain_configuration: Optional[CreateHostingRequestDomainConfiguration] = None, @@ -1127,6 +1428,7 @@ async def create_hosting( :param region: Region to target. If none is passed will use default region from the config. :param project_id: ID of the Scaleway Project in which to create the Web Hosting plan. :param tags: List of tags for the Web Hosting plan. + :param subdomain: The name prefix to use as a free subdomain (for example, `mysite`) assigned to the Web Hosting plan. The full domain will be automatically created by adding it to the fixed base domain (e.g. `mysite.scw.site`). You do not need to include the base domain yourself. :param offer_options: List of the Web Hosting plan options IDs with their quantities. :param language: Default language for the control panel interface. :param domain_configuration: Indicates whether to update hosting domain name servers and DNS records for domains managed by Scaleway Elements (deprecated, use auto_config_domain_dns instead). @@ -1159,6 +1461,7 @@ async def create_hosting( region=region, project_id=project_id, tags=tags, + subdomain=subdomain, offer_options=offer_options, language=language, domain_configuration=domain_configuration, @@ -1185,6 +1488,7 @@ async def list_hostings( project_id: Optional[str] = None, organization_id: Optional[str] = None, control_panels: Optional[List[str]] = None, + subdomain: Optional[str] = None, ) -> ListHostingsResponse: """ List all Web Hosting plans. @@ -1199,6 +1503,7 @@ async def list_hostings( :param project_id: Project ID to filter for, only Web Hosting plans from this Project will be returned. :param organization_id: Organization ID to filter for, only Web Hosting plans from this Organization will be returned. :param control_panels: Name of the control panel to filter for, only Web Hosting plans from this control panel will be returned. + :param subdomain: Optional free subdomain linked to the Web Hosting plan. :return: :class:`ListHostingsResponse ` Usage: @@ -1224,6 +1529,7 @@ async def list_hostings( "page_size": page_size or self.client.default_page_size, "project_id": project_id or self.client.default_project_id, "statuses": statuses, + "subdomain": subdomain, "tags": tags, }, ) @@ -1244,6 +1550,7 @@ async def list_hostings_all( project_id: Optional[str] = None, organization_id: Optional[str] = None, control_panels: Optional[List[str]] = None, + subdomain: Optional[str] = None, ) -> List[HostingSummary]: """ List all Web Hosting plans. @@ -1258,6 +1565,7 @@ async def list_hostings_all( :param project_id: Project ID to filter for, only Web Hosting plans from this Project will be returned. :param organization_id: Organization ID to filter for, only Web Hosting plans from this Organization will be returned. :param control_panels: Name of the control panel to filter for, only Web Hosting plans from this control panel will be returned. + :param subdomain: Optional free subdomain linked to the Web Hosting plan. :return: :class:`List[HostingSummary] ` Usage: @@ -1281,6 +1589,7 @@ async def list_hostings_all( "project_id": project_id, "organization_id": organization_id, "control_panels": control_panels, + "subdomain": subdomain, }, ) diff --git a/scaleway-async/scaleway_async/webhosting/v1/content.py b/scaleway-async/scaleway_async/webhosting/v1/content.py index 895da5659..e77f5228b 100644 --- a/scaleway-async/scaleway_async/webhosting/v1/content.py +++ b/scaleway-async/scaleway_async/webhosting/v1/content.py @@ -3,11 +3,18 @@ from typing import List from .types import ( + BackupStatus, DomainAvailabilityStatus, DomainStatus, HostingStatus, ) +BACKUP_TRANSIENT_STATUSES: List[BackupStatus] = [ + BackupStatus.RESTORING, +] +""" +Lists transient statutes of the enum :class:`BackupStatus `. +""" DOMAIN_AVAILABILITY_TRANSIENT_STATUSES: List[DomainAvailabilityStatus] = [ DomainAvailabilityStatus.VALIDATING, ] diff --git a/scaleway-async/scaleway_async/webhosting/v1/marshalling.py b/scaleway-async/scaleway_async/webhosting/v1/marshalling.py index 901528da9..690db002d 100644 --- a/scaleway-async/scaleway_async/webhosting/v1/marshalling.py +++ b/scaleway-async/scaleway_async/webhosting/v1/marshalling.py @@ -16,6 +16,7 @@ DomainAction, DomainAvailabilityAction, DomainDnsAction, + Backup, DatabaseUser, Database, FtpAccount, @@ -27,12 +28,18 @@ DnsRecords, Domain, PlatformControlPanelUrls, + HostingDomainCustomDomain, OfferOption, PlatformControlPanel, + HostingDomain, HostingUser, Offer, Platform, Hosting, + BackupItem, + BackupItemGroup, + ListBackupItemsResponse, + ListBackupsResponse, ControlPanel, ListControlPanelsResponse, ListDatabaseUsersResponse, @@ -46,9 +53,12 @@ ListWebsitesResponse, ResetHostingPasswordResponse, ResourceSummary, + RestoreBackupItemsResponse, + RestoreBackupResponse, DomainAvailability, SearchDomainsResponse, Session, + BackupApiRestoreBackupItemsRequest, DatabaseApiAssignDatabaseUserRequest, DatabaseApiChangeDatabaseUserPasswordRequest, CreateDatabaseRequestUser, @@ -73,6 +83,39 @@ ) +def unmarshal_Backup(data: Any) -> Backup: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Backup' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + + field = data.get("size", None) + if field is not None: + args["size"] = field + + field = data.get("status", None) + if field is not None: + args["status"] = field + + field = data.get("total_items", None) + if field is not None: + args["total_items"] = field + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + return Backup(**args) + + def unmarshal_DatabaseUser(data: Any) -> DatabaseUser: if not isinstance(data, dict): raise TypeError( @@ -366,6 +409,35 @@ def unmarshal_PlatformControlPanelUrls(data: Any) -> PlatformControlPanelUrls: return PlatformControlPanelUrls(**args) +def unmarshal_HostingDomainCustomDomain(data: Any) -> HostingDomainCustomDomain: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'HostingDomainCustomDomain' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("domain", None) + if field is not None: + args["domain"] = field + + field = data.get("domain_status", None) + if field is not None: + args["domain_status"] = field + + field = data.get("dns_status", None) + if field is not None: + args["dns_status"] = field + + field = data.get("auto_config_domain_dns", None) + if field is not None: + args["auto_config_domain_dns"] = unmarshal_AutoConfigDomainDns(field) + else: + args["auto_config_domain_dns"] = None + + return HostingDomainCustomDomain(**args) + + def unmarshal_OfferOption(data: Any) -> OfferOption: if not isinstance(data, dict): raise TypeError( @@ -432,6 +504,27 @@ def unmarshal_PlatformControlPanel(data: Any) -> PlatformControlPanel: return PlatformControlPanel(**args) +def unmarshal_HostingDomain(data: Any) -> HostingDomain: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'HostingDomain' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("subdomain", None) + if field is not None: + args["subdomain"] = field + + field = data.get("custom_domain", None) + if field is not None: + args["custom_domain"] = unmarshal_HostingDomainCustomDomain(field) + else: + args["custom_domain"] = None + + return HostingDomain(**args) + + def unmarshal_HostingUser(data: Any) -> HostingUser: if not isinstance(data, dict): raise TypeError( @@ -571,18 +664,6 @@ def unmarshal_Hosting(data: Any) -> Hosting: if field is not None: args["status"] = field - field = data.get("domain", None) - if field is not None: - args["domain"] = field - - field = data.get("tags", None) - if field is not None: - args["tags"] = field - - field = data.get("ipv4", None) - if field is not None: - args["ipv4"] = field - field = data.get("updated_at", None) if field is not None: args["updated_at"] = parser.isoparse(field) if isinstance(field, str) else field @@ -595,17 +676,11 @@ def unmarshal_Hosting(data: Any) -> Hosting: else: args["created_at"] = None - field = data.get("protected", None) - if field is not None: - args["protected"] = field - - field = data.get("domain_status", None) - if field is not None: - args["domain_status"] = field - - field = data.get("region", None) + field = data.get("domain", None) if field is not None: - args["region"] = field + args["domain"] = field + else: + args["domain"] = None field = data.get("offer", None) if field is not None: @@ -619,6 +694,22 @@ def unmarshal_Hosting(data: Any) -> Hosting: else: args["platform"] = None + field = data.get("tags", None) + if field is not None: + args["tags"] = field + + field = data.get("ipv4", None) + if field is not None: + args["ipv4"] = field + + field = data.get("protected", None) + if field is not None: + args["protected"] = field + + field = data.get("region", None) + if field is not None: + args["region"] = field + field = data.get("dns_status", None) if field is not None: args["dns_status"] = field @@ -631,9 +722,121 @@ def unmarshal_Hosting(data: Any) -> Hosting: else: args["user"] = None + field = data.get("domain_status", None) + if field is not None: + args["domain_status"] = field + else: + args["domain_status"] = None + + field = data.get("domain_info", None) + if field is not None: + args["domain_info"] = unmarshal_HostingDomain(field) + else: + args["domain_info"] = None + return Hosting(**args) +def unmarshal_BackupItem(data: Any) -> BackupItem: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'BackupItem' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + + field = data.get("name", None) + if field is not None: + args["name"] = field + + field = data.get("type", None) + if field is not None: + args["type_"] = field + + field = data.get("size", None) + if field is not None: + args["size"] = field + + field = data.get("status", None) + if field is not None: + args["status"] = field + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + return BackupItem(**args) + + +def unmarshal_BackupItemGroup(data: Any) -> BackupItemGroup: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'BackupItemGroup' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("type", None) + if field is not None: + args["type_"] = field + + field = data.get("items", None) + if field is not None: + args["items"] = ( + [unmarshal_BackupItem(v) for v in field] if field is not None else None + ) + + return BackupItemGroup(**args) + + +def unmarshal_ListBackupItemsResponse(data: Any) -> ListBackupItemsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListBackupItemsResponse' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + + field = data.get("groups", None) + if field is not None: + args["groups"] = ( + [unmarshal_BackupItemGroup(v) for v in field] if field is not None else None + ) + + return ListBackupItemsResponse(**args) + + +def unmarshal_ListBackupsResponse(data: Any) -> ListBackupsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListBackupsResponse' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + + field = data.get("backups", None) + if field is not None: + args["backups"] = ( + [unmarshal_Backup(v) for v in field] if field is not None else None + ) + + return ListBackupsResponse(**args) + + def unmarshal_ControlPanel(data: Any) -> ControlPanel: if not isinstance(data, dict): raise TypeError( @@ -767,10 +970,6 @@ def unmarshal_HostingSummary(data: Any) -> HostingSummary: if field is not None: args["status"] = field - field = data.get("domain", None) - if field is not None: - args["domain"] = field - field = data.get("protected", None) if field is not None: args["protected"] = field @@ -779,10 +978,6 @@ def unmarshal_HostingSummary(data: Any) -> HostingSummary: if field is not None: args["offer_name"] = field - field = data.get("domain_status", None) - if field is not None: - args["domain_status"] = field - field = data.get("region", None) if field is not None: args["region"] = field @@ -799,12 +994,30 @@ def unmarshal_HostingSummary(data: Any) -> HostingSummary: else: args["updated_at"] = None + field = data.get("domain", None) + if field is not None: + args["domain"] = field + else: + args["domain"] = None + field = data.get("dns_status", None) if field is not None: args["dns_status"] = field else: args["dns_status"] = None + field = data.get("domain_status", None) + if field is not None: + args["domain_status"] = field + else: + args["domain_status"] = None + + field = data.get("domain_info", None) + if field is not None: + args["domain_info"] = unmarshal_HostingDomain(field) + else: + args["domain_info"] = None + return HostingSummary(**args) @@ -963,6 +1176,28 @@ def unmarshal_ResourceSummary(data: Any) -> ResourceSummary: return ResourceSummary(**args) +def unmarshal_RestoreBackupItemsResponse(data: Any) -> RestoreBackupItemsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'RestoreBackupItemsResponse' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + return RestoreBackupItemsResponse(**args) + + +def unmarshal_RestoreBackupResponse(data: Any) -> RestoreBackupResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'RestoreBackupResponse' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + return RestoreBackupResponse(**args) + + def unmarshal_DomainAvailability(data: Any) -> DomainAvailability: if not isinstance(data, dict): raise TypeError( @@ -1036,6 +1271,18 @@ def unmarshal_Session(data: Any) -> Session: return Session(**args) +def marshal_BackupApiRestoreBackupItemsRequest( + request: BackupApiRestoreBackupItemsRequest, + defaults: ProfileDefaults, +) -> Dict[str, Any]: + output: Dict[str, Any] = {} + + if request.item_ids is not None: + output["item_ids"] = request.item_ids + + return output + + def marshal_DatabaseApiAssignDatabaseUserRequest( request: DatabaseApiAssignDatabaseUserRequest, defaults: ProfileDefaults, @@ -1083,8 +1330,16 @@ def marshal_DatabaseApiCreateDatabaseRequest( output.update( resolve_one_of( [ - OneOfPossibility("new_user", request.new_user), - OneOfPossibility("existing_username", request.existing_username), + OneOfPossibility( + param="new_user", + value=request.new_user, + marshal_func=marshal_CreateDatabaseRequestUser, + ), + OneOfPossibility( + param="existing_username", + value=request.existing_username, + marshal_func=None, + ), ] ), ) @@ -1292,6 +1547,9 @@ def marshal_HostingApiCreateHostingRequest( if request.tags is not None: output["tags"] = request.tags + if request.subdomain is not None: + output["subdomain"] = request.subdomain + if request.offer_options is not None: output["offer_options"] = [ marshal_OfferOptionRequest(item, defaults) for item in request.offer_options diff --git a/scaleway-async/scaleway_async/webhosting/v1/types.py b/scaleway-async/scaleway_async/webhosting/v1/types.py index 9d80eb681..69b95f5df 100644 --- a/scaleway-async/scaleway_async/webhosting/v1/types.py +++ b/scaleway-async/scaleway_async/webhosting/v1/types.py @@ -20,6 +20,34 @@ ) +class BackupItemType(str, Enum, metaclass=StrEnumMeta): + UNKNOWN_BACKUP_ITEM_TYPE = "unknown_backup_item_type" + FULL = "full" + WEB = "web" + MAIL = "mail" + DB = "db" + DB_USER = "db_user" + FTP_USER = "ftp_user" + DNS_ZONE = "dns_zone" + CRON_JOB = "cron_job" + SSL_CERTIFICATE = "ssl_certificate" + + def __str__(self) -> str: + return str(self.value) + + +class BackupStatus(str, Enum, metaclass=StrEnumMeta): + UNKNOWN_BACKUP_STATUS = "unknown_backup_status" + ACTIVE = "active" + LOCKED = "locked" + DISABLED = "disabled" + DAMAGED = "damaged" + RESTORING = "restoring" + + def __str__(self) -> str: + return str(self.value) + + class DnsRecordStatus(str, Enum, metaclass=StrEnumMeta): UNKNOWN_STATUS = "unknown_status" VALID = "valid" @@ -131,6 +159,14 @@ def __str__(self) -> str: return str(self.value) +class ListBackupsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_DESC = "created_at_desc" + CREATED_AT_ASC = "created_at_asc" + + def __str__(self) -> str: + return str(self.value) + + class ListDatabaseUsersRequestOrderBy(str, Enum, metaclass=StrEnumMeta): USERNAME_ASC = "username_asc" USERNAME_DESC = "username_desc" @@ -232,6 +268,34 @@ def __str__(self) -> str: return str(self.value) +@dataclass +class AutoConfigDomainDns: + nameservers: bool + """ + Whether or not to synchronize domain nameservers. + """ + + web_records: bool + """ + Whether or not to synchronize web records. + """ + + mail_records: bool + """ + Whether or not to synchronize mail records. + """ + + all_records: bool + """ + Whether or not to synchronize all types of records. Takes priority over the other fields. + """ + + none: bool + """ + No automatic domain configuration. Users must configure their domain for the Web Hosting to work. + """ + + @dataclass class PlatformControlPanelUrls: dashboard: str @@ -245,6 +309,29 @@ class PlatformControlPanelUrls: """ +@dataclass +class HostingDomainCustomDomain: + domain: str + """ + Custom domain linked to the hosting plan. + """ + + domain_status: DomainStatus + """ + Status of the custom domain verification. + """ + + dns_status: DnsRecordsStatus + """ + Status of the DNS configuration for the custom domain. + """ + + auto_config_domain_dns: Optional[AutoConfigDomainDns] + """ + Indicates whether to auto-configure DNS for this domain. + """ + + @dataclass class OfferOption: id: str @@ -302,40 +389,58 @@ class PlatformControlPanel: @dataclass -class CreateDatabaseRequestUser: - username: str +class BackupItem: + id: str + """ + ID of the item. + """ - password: str + name: str + """ + Name of the item (e.g., `database name`, `email address`). + """ + type_: BackupItemType + """ + Type of the item (e.g., email, database, FTP). + """ -@dataclass -class AutoConfigDomainDns: - nameservers: bool + size: int """ - Whether or not to synchronize domain nameservers. + Size of the item in bytes. """ - web_records: bool + status: BackupStatus """ - Whether or not to synchronize web records. + Status of the item. Available values are `active`, `damaged`, and `restoring`. """ - mail_records: bool + created_at: Optional[datetime] """ - Whether or not to synchronize mail records. + Date and time at which this item was backed up. """ - all_records: bool + +@dataclass +class HostingDomain: + subdomain: str """ - Whether or not to synchronize all types of records. Takes priority over the other fields. + Optional free subdomain linked to the Web Hosting plan. """ - none: bool + custom_domain: Optional[HostingDomainCustomDomain] """ - No automatic domain configuration. Users must configure their domain for the Web Hosting to work. + Optional custom domain linked to the Web Hosting plan. """ +@dataclass +class CreateDatabaseRequestUser: + username: str + + password: str + + @dataclass class CreateHostingRequestDomainConfiguration: update_nameservers: bool @@ -527,6 +632,47 @@ class Platform: """ +@dataclass +class BackupItemGroup: + type_: BackupItemType + """ + Type of items (e.g., email, database, FTP). + """ + + items: List[BackupItem] + """ + List of individual backup items of this type. + """ + + +@dataclass +class Backup: + id: str + """ + ID of the backup. + """ + + size: int + """ + Total size of the backup in bytes. + """ + + status: BackupStatus + """ + Status of the backup. Available values are `active`, `locked`, and `restoring`. + """ + + total_items: int + """ + Total number of restorable items in the backup. + """ + + created_at: Optional[datetime] + """ + Creation date of the backup. + """ + + @dataclass class ControlPanel: name: str @@ -606,11 +752,6 @@ class HostingSummary: Status of the Web Hosting plan. """ - domain: str - """ - Main domain associated with the Web Hosting plan. - """ - protected: bool """ Whether the hosting is protected or not. @@ -621,11 +762,6 @@ class HostingSummary: Name of the active offer for the Web Hosting plan. """ - domain_status: DomainStatus - """ - Main domain status of the Web Hosting plan. - """ - region: ScwRegion """ Region where the Web Hosting plan is hosted. @@ -641,11 +777,26 @@ class HostingSummary: Date on which the Web Hosting plan was last updated. """ + domain: Optional[str] + """ + Main domain associated with the Web Hosting plan (deprecated, use domain_info). + """ + dns_status: Optional[DnsRecordsStatus] """ DNS status of the Web Hosting plan. """ + domain_status: Optional[DomainStatus] + """ + Main domain status of the Web Hosting plan. + """ + + domain_info: Optional[HostingDomain] + """ + Domain configuration block (subdomain, optional custom domain, and DNS settings). + """ + @dataclass class MailAccount: @@ -711,6 +862,106 @@ class DomainAvailability: """ +@dataclass +class BackupApiGetBackupRequest: + hosting_id: str + """ + UUID of the hosting account. + """ + + backup_id: str + """ + ID of the backup to retrieve. + """ + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + +@dataclass +class BackupApiListBackupItemsRequest: + hosting_id: str + """ + UUID of the hosting account. + """ + + backup_id: str + """ + ID of the backup to list items from. + """ + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + +@dataclass +class BackupApiListBackupsRequest: + hosting_id: str + """ + UUID of the hosting account. + """ + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + page: Optional[int] + """ + Page number to retrieve. + """ + + page_size: Optional[int] + """ + Number of backups to return per page. + """ + + order_by: Optional[ListBackupsRequestOrderBy] + """ + Order in which to return the list of backups. + """ + + +@dataclass +class BackupApiRestoreBackupItemsRequest: + hosting_id: str + """ + UUID of the hosting account. + """ + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + item_ids: Optional[List[str]] + """ + List of backup item IDs to restore individually. + """ + + +@dataclass +class BackupApiRestoreBackupRequest: + hosting_id: str + """ + UUID of the hosting account. + """ + + backup_id: str + """ + ID of the backup to fully restore. + """ + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + @dataclass class CheckUserOwnsDomainResponse: owns_domain: bool @@ -1274,39 +1525,44 @@ class Hosting: Status of the Web Hosting plan. """ - domain: str + updated_at: Optional[datetime] """ - Main domain associated with the Web Hosting plan. + Date on which the Web Hosting plan was last updated. """ - tags: List[str] + created_at: Optional[datetime] """ - List of tags associated with the Web Hosting plan. + Date on which the Web Hosting plan was created. """ - ipv4: str + domain: Optional[str] """ - Current IPv4 address of the hosting. + Main domain associated with the Web Hosting plan (deprecated, use domain_info). """ - updated_at: Optional[datetime] + offer: Optional[Offer] """ - Date on which the Web Hosting plan was last updated. + Details of the Web Hosting plan offer and options. """ - created_at: Optional[datetime] + platform: Optional[Platform] """ - Date on which the Web Hosting plan was created. + Details of the hosting platform. """ - protected: bool + tags: List[str] """ - Whether the hosting is protected or not. + List of tags associated with the Web Hosting plan. """ - domain_status: DomainStatus + ipv4: str """ - Main domain status of the Web Hosting plan. + Current IPv4 address of the hosting. + """ + + protected: bool + """ + Whether the hosting is protected or not. """ region: ScwRegion @@ -1314,24 +1570,24 @@ class Hosting: Region where the Web Hosting plan is hosted. """ - offer: Optional[Offer] + dns_status: Optional[DnsRecordsStatus] """ - Details of the Web Hosting plan offer and options. + DNS status of the Web Hosting plan (deprecated, use domain_info). """ - platform: Optional[Platform] + user: Optional[HostingUser] """ - Details of the hosting platform. + Details of the hosting user. """ - dns_status: Optional[DnsRecordsStatus] + domain_status: Optional[DomainStatus] """ - DNS status of the Web Hosting plan. + Main domain status of the Web Hosting plan (deprecated, use domain_info). """ - user: Optional[HostingUser] + domain_info: Optional[HostingDomain] """ - Details of the hosting user. + Domain configuration block (subdomain, optional custom domain, and DNS settings). """ @@ -1367,6 +1623,11 @@ class HostingApiCreateHostingRequest: List of tags for the Web Hosting plan. """ + subdomain: Optional[str] + """ + The name prefix to use as a free subdomain (for example, `mysite`) assigned to the Web Hosting plan. The full domain will be automatically created by adding it to the fixed base domain (e.g. `mysite.scw.site`). You do not need to include the base domain yourself. + """ + offer_options: Optional[List[OfferOptionRequest]] """ List of the Web Hosting plan options IDs with their quantities. @@ -1497,6 +1758,11 @@ class HostingApiListHostingsRequest: Name of the control panel to filter for, only Web Hosting plans from this control panel will be returned. """ + subdomain: Optional[str] + """ + Optional free subdomain linked to the Web Hosting plan. + """ + @dataclass class HostingApiResetHostingPasswordRequest: @@ -1549,6 +1815,32 @@ class HostingApiUpdateHostingRequest: """ +@dataclass +class ListBackupItemsResponse: + total_count: int + """ + Total number of backup item groups. + """ + + groups: List[BackupItemGroup] + """ + List of backup item groups categorized by type. + """ + + +@dataclass +class ListBackupsResponse: + total_count: int + """ + Total number of available backups. + """ + + backups: List[Backup] + """ + List of available backups. + """ + + @dataclass class ListControlPanelsResponse: total_count: int @@ -1834,6 +2126,16 @@ class ResourceSummary: """ +@dataclass +class RestoreBackupItemsResponse: + pass + + +@dataclass +class RestoreBackupResponse: + pass + + @dataclass class SearchDomainsResponse: domains_available: List[DomainAvailability] diff --git a/scaleway/scaleway/webhosting/v1/__init__.py b/scaleway/scaleway/webhosting/v1/__init__.py index 43df2e816..93b525663 100644 --- a/scaleway/scaleway/webhosting/v1/__init__.py +++ b/scaleway/scaleway/webhosting/v1/__init__.py @@ -1,5 +1,8 @@ # This file was automatically generated. DO NOT EDIT. # If you have any remark or suggestion do not hesitate to open an issue. +from .types import BackupItemType +from .types import BackupStatus +from .content import BACKUP_TRANSIENT_STATUSES from .types import DnsRecordStatus from .types import DnsRecordType from .types import DnsRecordsStatus @@ -13,6 +16,7 @@ from .types import DomainZoneOwner from .types import HostingStatus from .content import HOSTING_TRANSIENT_STATUSES +from .types import ListBackupsRequestOrderBy from .types import ListDatabaseUsersRequestOrderBy from .types import ListDatabasesRequestOrderBy from .types import ListFtpAccountsRequestOrderBy @@ -24,11 +28,14 @@ from .types import OfferOptionName from .types import OfferOptionWarning from .types import PlatformPlatformGroup +from .types import AutoConfigDomainDns from .types import PlatformControlPanelUrls +from .types import HostingDomainCustomDomain from .types import OfferOption from .types import PlatformControlPanel +from .types import BackupItem +from .types import HostingDomain from .types import CreateDatabaseRequestUser -from .types import AutoConfigDomainDns from .types import CreateHostingRequestDomainConfiguration from .types import OfferOptionRequest from .types import SyncDomainDnsRecordsRequestRecord @@ -37,6 +44,8 @@ from .types import HostingUser from .types import Offer from .types import Platform +from .types import BackupItemGroup +from .types import Backup from .types import ControlPanel from .types import DatabaseUser from .types import Database @@ -45,6 +54,11 @@ from .types import MailAccount from .types import Website from .types import DomainAvailability +from .types import BackupApiGetBackupRequest +from .types import BackupApiListBackupItemsRequest +from .types import BackupApiListBackupsRequest +from .types import BackupApiRestoreBackupItemsRequest +from .types import BackupApiRestoreBackupRequest from .types import CheckUserOwnsDomainResponse from .types import ControlPanelApiListControlPanelsRequest from .types import DatabaseApiAssignDatabaseUserRequest @@ -78,6 +92,8 @@ from .types import HostingApiListHostingsRequest from .types import HostingApiResetHostingPasswordRequest from .types import HostingApiUpdateHostingRequest +from .types import ListBackupItemsResponse +from .types import ListBackupsResponse from .types import ListControlPanelsResponse from .types import ListDatabaseUsersResponse from .types import ListDatabasesResponse @@ -93,9 +109,12 @@ from .types import OfferApiListOffersRequest from .types import ResetHostingPasswordResponse from .types import ResourceSummary +from .types import RestoreBackupItemsResponse +from .types import RestoreBackupResponse from .types import SearchDomainsResponse from .types import Session from .types import WebsiteApiListWebsitesRequest +from .api import WebhostingV1BackupAPI from .api import WebhostingV1ControlPanelAPI from .api import WebhostingV1DatabaseAPI from .api import WebhostingV1DnsAPI @@ -106,6 +125,9 @@ from .api import WebhostingV1WebsiteAPI __all__ = [ + "BackupItemType", + "BackupStatus", + "BACKUP_TRANSIENT_STATUSES", "DnsRecordStatus", "DnsRecordType", "DnsRecordsStatus", @@ -119,6 +141,7 @@ "DomainZoneOwner", "HostingStatus", "HOSTING_TRANSIENT_STATUSES", + "ListBackupsRequestOrderBy", "ListDatabaseUsersRequestOrderBy", "ListDatabasesRequestOrderBy", "ListFtpAccountsRequestOrderBy", @@ -130,11 +153,14 @@ "OfferOptionName", "OfferOptionWarning", "PlatformPlatformGroup", + "AutoConfigDomainDns", "PlatformControlPanelUrls", + "HostingDomainCustomDomain", "OfferOption", "PlatformControlPanel", + "BackupItem", + "HostingDomain", "CreateDatabaseRequestUser", - "AutoConfigDomainDns", "CreateHostingRequestDomainConfiguration", "OfferOptionRequest", "SyncDomainDnsRecordsRequestRecord", @@ -143,6 +169,8 @@ "HostingUser", "Offer", "Platform", + "BackupItemGroup", + "Backup", "ControlPanel", "DatabaseUser", "Database", @@ -151,6 +179,11 @@ "MailAccount", "Website", "DomainAvailability", + "BackupApiGetBackupRequest", + "BackupApiListBackupItemsRequest", + "BackupApiListBackupsRequest", + "BackupApiRestoreBackupItemsRequest", + "BackupApiRestoreBackupRequest", "CheckUserOwnsDomainResponse", "ControlPanelApiListControlPanelsRequest", "DatabaseApiAssignDatabaseUserRequest", @@ -184,6 +217,8 @@ "HostingApiListHostingsRequest", "HostingApiResetHostingPasswordRequest", "HostingApiUpdateHostingRequest", + "ListBackupItemsResponse", + "ListBackupsResponse", "ListControlPanelsResponse", "ListDatabaseUsersResponse", "ListDatabasesResponse", @@ -199,9 +234,12 @@ "OfferApiListOffersRequest", "ResetHostingPasswordResponse", "ResourceSummary", + "RestoreBackupItemsResponse", + "RestoreBackupResponse", "SearchDomainsResponse", "Session", "WebsiteApiListWebsitesRequest", + "WebhostingV1BackupAPI", "WebhostingV1ControlPanelAPI", "WebhostingV1DatabaseAPI", "WebhostingV1DnsAPI", diff --git a/scaleway/scaleway/webhosting/v1/api.py b/scaleway/scaleway/webhosting/v1/api.py index 7c925ee6e..aee6521ae 100644 --- a/scaleway/scaleway/webhosting/v1/api.py +++ b/scaleway/scaleway/webhosting/v1/api.py @@ -15,6 +15,7 @@ ) from .types import ( HostingStatus, + ListBackupsRequestOrderBy, ListDatabaseUsersRequestOrderBy, ListDatabasesRequestOrderBy, ListFtpAccountsRequestOrderBy, @@ -23,6 +24,8 @@ ListOffersRequestOrderBy, ListWebsitesRequestOrderBy, AutoConfigDomainDns, + Backup, + BackupApiRestoreBackupItemsRequest, CheckUserOwnsDomainResponse, ControlPanel, CreateDatabaseRequestUser, @@ -45,6 +48,8 @@ HostingApiCreateHostingRequest, HostingApiUpdateHostingRequest, HostingSummary, + ListBackupItemsResponse, + ListBackupsResponse, ListControlPanelsResponse, ListDatabaseUsersResponse, ListDatabasesResponse, @@ -61,16 +66,20 @@ OfferOptionRequest, ResetHostingPasswordResponse, ResourceSummary, + RestoreBackupItemsResponse, + RestoreBackupResponse, SearchDomainsResponse, Session, SyncDomainDnsRecordsRequestRecord, Website, ) from .content import ( + BACKUP_TRANSIENT_STATUSES, DOMAIN_TRANSIENT_STATUSES, HOSTING_TRANSIENT_STATUSES, ) from .marshalling import ( + unmarshal_Backup, unmarshal_DatabaseUser, unmarshal_Database, unmarshal_FtpAccount, @@ -79,6 +88,8 @@ unmarshal_DnsRecords, unmarshal_Domain, unmarshal_Hosting, + unmarshal_ListBackupItemsResponse, + unmarshal_ListBackupsResponse, unmarshal_ListControlPanelsResponse, unmarshal_ListDatabaseUsersResponse, unmarshal_ListDatabasesResponse, @@ -89,8 +100,11 @@ unmarshal_ListWebsitesResponse, unmarshal_ResetHostingPasswordResponse, unmarshal_ResourceSummary, + unmarshal_RestoreBackupItemsResponse, + unmarshal_RestoreBackupResponse, unmarshal_SearchDomainsResponse, unmarshal_Session, + marshal_BackupApiRestoreBackupItemsRequest, marshal_DatabaseApiAssignDatabaseUserRequest, marshal_DatabaseApiChangeDatabaseUserPasswordRequest, marshal_DatabaseApiCreateDatabaseRequest, @@ -111,6 +125,292 @@ ) +class WebhostingV1BackupAPI(API): + """ + This API allows you to list and restore backups for your cPanel and WordPress Web Hosting service. + """ + + def list_backups( + self, + *, + hosting_id: str, + region: Optional[ScwRegion] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListBackupsRequestOrderBy] = None, + ) -> ListBackupsResponse: + """ + List all available backups for a hosting account. + :param hosting_id: UUID of the hosting account. + :param region: Region to target. If none is passed will use default region from the config. + :param page: Page number to retrieve. + :param page_size: Number of backups to return per page. + :param order_by: Order in which to return the list of backups. + :return: :class:`ListBackupsResponse ` + + Usage: + :: + + result = api.list_backups( + hosting_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_hosting_id = validate_path_param("hosting_id", hosting_id) + + res = self._request( + "GET", + f"/webhosting/v1/regions/{param_region}/hostings/{param_hosting_id}/backups", + params={ + "order_by": order_by, + "page": page, + "page_size": page_size or self.client.default_page_size, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListBackupsResponse(res.json()) + + def list_backups_all( + self, + *, + hosting_id: str, + region: Optional[ScwRegion] = None, + page: Optional[int] = None, + page_size: Optional[int] = None, + order_by: Optional[ListBackupsRequestOrderBy] = None, + ) -> List[Backup]: + """ + List all available backups for a hosting account. + :param hosting_id: UUID of the hosting account. + :param region: Region to target. If none is passed will use default region from the config. + :param page: Page number to retrieve. + :param page_size: Number of backups to return per page. + :param order_by: Order in which to return the list of backups. + :return: :class:`List[Backup] ` + + Usage: + :: + + result = api.list_backups_all( + hosting_id="example", + ) + """ + + return fetch_all_pages( + type=ListBackupsResponse, + key="backups", + fetcher=self.list_backups, + args={ + "hosting_id": hosting_id, + "region": region, + "page": page, + "page_size": page_size, + "order_by": order_by, + }, + ) + + def get_backup( + self, + *, + hosting_id: str, + backup_id: str, + region: Optional[ScwRegion] = None, + ) -> Backup: + """ + Get info about a backup specified by the backup ID. + :param hosting_id: UUID of the hosting account. + :param backup_id: ID of the backup to retrieve. + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`Backup ` + + Usage: + :: + + result = api.get_backup( + hosting_id="example", + backup_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_hosting_id = validate_path_param("hosting_id", hosting_id) + param_backup_id = validate_path_param("backup_id", backup_id) + + res = self._request( + "GET", + f"/webhosting/v1/regions/{param_region}/hostings/{param_hosting_id}/backups/{param_backup_id}", + ) + + self._throw_on_error(res) + return unmarshal_Backup(res.json()) + + def wait_for_backup( + self, + *, + hosting_id: str, + backup_id: str, + region: Optional[ScwRegion] = None, + options: Optional[WaitForOptions[Backup, bool]] = None, + ) -> Backup: + """ + Get info about a backup specified by the backup ID. + :param hosting_id: UUID of the hosting account. + :param backup_id: ID of the backup to retrieve. + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`Backup ` + + Usage: + :: + + result = api.get_backup( + hosting_id="example", + backup_id="example", + ) + """ + + if not options: + options = WaitForOptions() + + if not options.stop: + options.stop = lambda res: res.status not in BACKUP_TRANSIENT_STATUSES + + return wait_for_resource( + fetcher=self.get_backup, + options=options, + args={ + "hosting_id": hosting_id, + "backup_id": backup_id, + "region": region, + }, + ) + + def restore_backup( + self, + *, + hosting_id: str, + backup_id: str, + region: Optional[ScwRegion] = None, + ) -> RestoreBackupResponse: + """ + Restore an entire backup to your hosting environment. + :param hosting_id: UUID of the hosting account. + :param backup_id: ID of the backup to fully restore. + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`RestoreBackupResponse ` + + Usage: + :: + + result = api.restore_backup( + hosting_id="example", + backup_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_hosting_id = validate_path_param("hosting_id", hosting_id) + param_backup_id = validate_path_param("backup_id", backup_id) + + res = self._request( + "POST", + f"/webhosting/v1/regions/{param_region}/hostings/{param_hosting_id}/backups/{param_backup_id}/restore", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_RestoreBackupResponse(res.json()) + + def list_backup_items( + self, + *, + hosting_id: str, + backup_id: str, + region: Optional[ScwRegion] = None, + ) -> ListBackupItemsResponse: + """ + List items within a specific backup, grouped by type. + :param hosting_id: UUID of the hosting account. + :param backup_id: ID of the backup to list items from. + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`ListBackupItemsResponse ` + + Usage: + :: + + result = api.list_backup_items( + hosting_id="example", + backup_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_hosting_id = validate_path_param("hosting_id", hosting_id) + + res = self._request( + "GET", + f"/webhosting/v1/regions/{param_region}/hostings/{param_hosting_id}/backup-items", + params={ + "backup_id": backup_id, + }, + ) + + self._throw_on_error(res) + return unmarshal_ListBackupItemsResponse(res.json()) + + def restore_backup_items( + self, + *, + hosting_id: str, + region: Optional[ScwRegion] = None, + item_ids: Optional[List[str]] = None, + ) -> RestoreBackupItemsResponse: + """ + Restore specific items from a backup (e.g., a database or mailbox). + :param hosting_id: UUID of the hosting account. + :param region: Region to target. If none is passed will use default region from the config. + :param item_ids: List of backup item IDs to restore individually. + :return: :class:`RestoreBackupItemsResponse ` + + Usage: + :: + + result = api.restore_backup_items( + hosting_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_hosting_id = validate_path_param("hosting_id", hosting_id) + + res = self._request( + "POST", + f"/webhosting/v1/regions/{param_region}/hostings/{param_hosting_id}/restore-backup-items", + body=marshal_BackupApiRestoreBackupItemsRequest( + BackupApiRestoreBackupItemsRequest( + hosting_id=hosting_id, + region=region, + item_ids=item_ids, + ), + self.client, + ), + ) + + self._throw_on_error(res) + return unmarshal_RestoreBackupItemsResponse(res.json()) + + class WebhostingV1ControlPanelAPI(API): """ This API allows you to manage your Web Hosting services. @@ -1112,6 +1412,7 @@ def create_hosting( region: Optional[ScwRegion] = None, project_id: Optional[str] = None, tags: Optional[List[str]] = None, + subdomain: Optional[str] = None, offer_options: Optional[List[OfferOptionRequest]] = None, language: Optional[StdLanguageCode] = None, domain_configuration: Optional[CreateHostingRequestDomainConfiguration] = None, @@ -1127,6 +1428,7 @@ def create_hosting( :param region: Region to target. If none is passed will use default region from the config. :param project_id: ID of the Scaleway Project in which to create the Web Hosting plan. :param tags: List of tags for the Web Hosting plan. + :param subdomain: The name prefix to use as a free subdomain (for example, `mysite`) assigned to the Web Hosting plan. The full domain will be automatically created by adding it to the fixed base domain (e.g. `mysite.scw.site`). You do not need to include the base domain yourself. :param offer_options: List of the Web Hosting plan options IDs with their quantities. :param language: Default language for the control panel interface. :param domain_configuration: Indicates whether to update hosting domain name servers and DNS records for domains managed by Scaleway Elements (deprecated, use auto_config_domain_dns instead). @@ -1159,6 +1461,7 @@ def create_hosting( region=region, project_id=project_id, tags=tags, + subdomain=subdomain, offer_options=offer_options, language=language, domain_configuration=domain_configuration, @@ -1185,6 +1488,7 @@ def list_hostings( project_id: Optional[str] = None, organization_id: Optional[str] = None, control_panels: Optional[List[str]] = None, + subdomain: Optional[str] = None, ) -> ListHostingsResponse: """ List all Web Hosting plans. @@ -1199,6 +1503,7 @@ def list_hostings( :param project_id: Project ID to filter for, only Web Hosting plans from this Project will be returned. :param organization_id: Organization ID to filter for, only Web Hosting plans from this Organization will be returned. :param control_panels: Name of the control panel to filter for, only Web Hosting plans from this control panel will be returned. + :param subdomain: Optional free subdomain linked to the Web Hosting plan. :return: :class:`ListHostingsResponse ` Usage: @@ -1224,6 +1529,7 @@ def list_hostings( "page_size": page_size or self.client.default_page_size, "project_id": project_id or self.client.default_project_id, "statuses": statuses, + "subdomain": subdomain, "tags": tags, }, ) @@ -1244,6 +1550,7 @@ def list_hostings_all( project_id: Optional[str] = None, organization_id: Optional[str] = None, control_panels: Optional[List[str]] = None, + subdomain: Optional[str] = None, ) -> List[HostingSummary]: """ List all Web Hosting plans. @@ -1258,6 +1565,7 @@ def list_hostings_all( :param project_id: Project ID to filter for, only Web Hosting plans from this Project will be returned. :param organization_id: Organization ID to filter for, only Web Hosting plans from this Organization will be returned. :param control_panels: Name of the control panel to filter for, only Web Hosting plans from this control panel will be returned. + :param subdomain: Optional free subdomain linked to the Web Hosting plan. :return: :class:`List[HostingSummary] ` Usage: @@ -1281,6 +1589,7 @@ def list_hostings_all( "project_id": project_id, "organization_id": organization_id, "control_panels": control_panels, + "subdomain": subdomain, }, ) diff --git a/scaleway/scaleway/webhosting/v1/content.py b/scaleway/scaleway/webhosting/v1/content.py index 895da5659..e77f5228b 100644 --- a/scaleway/scaleway/webhosting/v1/content.py +++ b/scaleway/scaleway/webhosting/v1/content.py @@ -3,11 +3,18 @@ from typing import List from .types import ( + BackupStatus, DomainAvailabilityStatus, DomainStatus, HostingStatus, ) +BACKUP_TRANSIENT_STATUSES: List[BackupStatus] = [ + BackupStatus.RESTORING, +] +""" +Lists transient statutes of the enum :class:`BackupStatus `. +""" DOMAIN_AVAILABILITY_TRANSIENT_STATUSES: List[DomainAvailabilityStatus] = [ DomainAvailabilityStatus.VALIDATING, ] diff --git a/scaleway/scaleway/webhosting/v1/marshalling.py b/scaleway/scaleway/webhosting/v1/marshalling.py index 901528da9..690db002d 100644 --- a/scaleway/scaleway/webhosting/v1/marshalling.py +++ b/scaleway/scaleway/webhosting/v1/marshalling.py @@ -16,6 +16,7 @@ DomainAction, DomainAvailabilityAction, DomainDnsAction, + Backup, DatabaseUser, Database, FtpAccount, @@ -27,12 +28,18 @@ DnsRecords, Domain, PlatformControlPanelUrls, + HostingDomainCustomDomain, OfferOption, PlatformControlPanel, + HostingDomain, HostingUser, Offer, Platform, Hosting, + BackupItem, + BackupItemGroup, + ListBackupItemsResponse, + ListBackupsResponse, ControlPanel, ListControlPanelsResponse, ListDatabaseUsersResponse, @@ -46,9 +53,12 @@ ListWebsitesResponse, ResetHostingPasswordResponse, ResourceSummary, + RestoreBackupItemsResponse, + RestoreBackupResponse, DomainAvailability, SearchDomainsResponse, Session, + BackupApiRestoreBackupItemsRequest, DatabaseApiAssignDatabaseUserRequest, DatabaseApiChangeDatabaseUserPasswordRequest, CreateDatabaseRequestUser, @@ -73,6 +83,39 @@ ) +def unmarshal_Backup(data: Any) -> Backup: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'Backup' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + + field = data.get("size", None) + if field is not None: + args["size"] = field + + field = data.get("status", None) + if field is not None: + args["status"] = field + + field = data.get("total_items", None) + if field is not None: + args["total_items"] = field + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + return Backup(**args) + + def unmarshal_DatabaseUser(data: Any) -> DatabaseUser: if not isinstance(data, dict): raise TypeError( @@ -366,6 +409,35 @@ def unmarshal_PlatformControlPanelUrls(data: Any) -> PlatformControlPanelUrls: return PlatformControlPanelUrls(**args) +def unmarshal_HostingDomainCustomDomain(data: Any) -> HostingDomainCustomDomain: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'HostingDomainCustomDomain' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("domain", None) + if field is not None: + args["domain"] = field + + field = data.get("domain_status", None) + if field is not None: + args["domain_status"] = field + + field = data.get("dns_status", None) + if field is not None: + args["dns_status"] = field + + field = data.get("auto_config_domain_dns", None) + if field is not None: + args["auto_config_domain_dns"] = unmarshal_AutoConfigDomainDns(field) + else: + args["auto_config_domain_dns"] = None + + return HostingDomainCustomDomain(**args) + + def unmarshal_OfferOption(data: Any) -> OfferOption: if not isinstance(data, dict): raise TypeError( @@ -432,6 +504,27 @@ def unmarshal_PlatformControlPanel(data: Any) -> PlatformControlPanel: return PlatformControlPanel(**args) +def unmarshal_HostingDomain(data: Any) -> HostingDomain: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'HostingDomain' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("subdomain", None) + if field is not None: + args["subdomain"] = field + + field = data.get("custom_domain", None) + if field is not None: + args["custom_domain"] = unmarshal_HostingDomainCustomDomain(field) + else: + args["custom_domain"] = None + + return HostingDomain(**args) + + def unmarshal_HostingUser(data: Any) -> HostingUser: if not isinstance(data, dict): raise TypeError( @@ -571,18 +664,6 @@ def unmarshal_Hosting(data: Any) -> Hosting: if field is not None: args["status"] = field - field = data.get("domain", None) - if field is not None: - args["domain"] = field - - field = data.get("tags", None) - if field is not None: - args["tags"] = field - - field = data.get("ipv4", None) - if field is not None: - args["ipv4"] = field - field = data.get("updated_at", None) if field is not None: args["updated_at"] = parser.isoparse(field) if isinstance(field, str) else field @@ -595,17 +676,11 @@ def unmarshal_Hosting(data: Any) -> Hosting: else: args["created_at"] = None - field = data.get("protected", None) - if field is not None: - args["protected"] = field - - field = data.get("domain_status", None) - if field is not None: - args["domain_status"] = field - - field = data.get("region", None) + field = data.get("domain", None) if field is not None: - args["region"] = field + args["domain"] = field + else: + args["domain"] = None field = data.get("offer", None) if field is not None: @@ -619,6 +694,22 @@ def unmarshal_Hosting(data: Any) -> Hosting: else: args["platform"] = None + field = data.get("tags", None) + if field is not None: + args["tags"] = field + + field = data.get("ipv4", None) + if field is not None: + args["ipv4"] = field + + field = data.get("protected", None) + if field is not None: + args["protected"] = field + + field = data.get("region", None) + if field is not None: + args["region"] = field + field = data.get("dns_status", None) if field is not None: args["dns_status"] = field @@ -631,9 +722,121 @@ def unmarshal_Hosting(data: Any) -> Hosting: else: args["user"] = None + field = data.get("domain_status", None) + if field is not None: + args["domain_status"] = field + else: + args["domain_status"] = None + + field = data.get("domain_info", None) + if field is not None: + args["domain_info"] = unmarshal_HostingDomain(field) + else: + args["domain_info"] = None + return Hosting(**args) +def unmarshal_BackupItem(data: Any) -> BackupItem: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'BackupItem' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("id", None) + if field is not None: + args["id"] = field + + field = data.get("name", None) + if field is not None: + args["name"] = field + + field = data.get("type", None) + if field is not None: + args["type_"] = field + + field = data.get("size", None) + if field is not None: + args["size"] = field + + field = data.get("status", None) + if field is not None: + args["status"] = field + + field = data.get("created_at", None) + if field is not None: + args["created_at"] = parser.isoparse(field) if isinstance(field, str) else field + else: + args["created_at"] = None + + return BackupItem(**args) + + +def unmarshal_BackupItemGroup(data: Any) -> BackupItemGroup: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'BackupItemGroup' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("type", None) + if field is not None: + args["type_"] = field + + field = data.get("items", None) + if field is not None: + args["items"] = ( + [unmarshal_BackupItem(v) for v in field] if field is not None else None + ) + + return BackupItemGroup(**args) + + +def unmarshal_ListBackupItemsResponse(data: Any) -> ListBackupItemsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListBackupItemsResponse' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + + field = data.get("groups", None) + if field is not None: + args["groups"] = ( + [unmarshal_BackupItemGroup(v) for v in field] if field is not None else None + ) + + return ListBackupItemsResponse(**args) + + +def unmarshal_ListBackupsResponse(data: Any) -> ListBackupsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'ListBackupsResponse' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + field = data.get("total_count", None) + if field is not None: + args["total_count"] = field + + field = data.get("backups", None) + if field is not None: + args["backups"] = ( + [unmarshal_Backup(v) for v in field] if field is not None else None + ) + + return ListBackupsResponse(**args) + + def unmarshal_ControlPanel(data: Any) -> ControlPanel: if not isinstance(data, dict): raise TypeError( @@ -767,10 +970,6 @@ def unmarshal_HostingSummary(data: Any) -> HostingSummary: if field is not None: args["status"] = field - field = data.get("domain", None) - if field is not None: - args["domain"] = field - field = data.get("protected", None) if field is not None: args["protected"] = field @@ -779,10 +978,6 @@ def unmarshal_HostingSummary(data: Any) -> HostingSummary: if field is not None: args["offer_name"] = field - field = data.get("domain_status", None) - if field is not None: - args["domain_status"] = field - field = data.get("region", None) if field is not None: args["region"] = field @@ -799,12 +994,30 @@ def unmarshal_HostingSummary(data: Any) -> HostingSummary: else: args["updated_at"] = None + field = data.get("domain", None) + if field is not None: + args["domain"] = field + else: + args["domain"] = None + field = data.get("dns_status", None) if field is not None: args["dns_status"] = field else: args["dns_status"] = None + field = data.get("domain_status", None) + if field is not None: + args["domain_status"] = field + else: + args["domain_status"] = None + + field = data.get("domain_info", None) + if field is not None: + args["domain_info"] = unmarshal_HostingDomain(field) + else: + args["domain_info"] = None + return HostingSummary(**args) @@ -963,6 +1176,28 @@ def unmarshal_ResourceSummary(data: Any) -> ResourceSummary: return ResourceSummary(**args) +def unmarshal_RestoreBackupItemsResponse(data: Any) -> RestoreBackupItemsResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'RestoreBackupItemsResponse' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + return RestoreBackupItemsResponse(**args) + + +def unmarshal_RestoreBackupResponse(data: Any) -> RestoreBackupResponse: + if not isinstance(data, dict): + raise TypeError( + "Unmarshalling the type 'RestoreBackupResponse' failed as data isn't a dictionary." + ) + + args: Dict[str, Any] = {} + + return RestoreBackupResponse(**args) + + def unmarshal_DomainAvailability(data: Any) -> DomainAvailability: if not isinstance(data, dict): raise TypeError( @@ -1036,6 +1271,18 @@ def unmarshal_Session(data: Any) -> Session: return Session(**args) +def marshal_BackupApiRestoreBackupItemsRequest( + request: BackupApiRestoreBackupItemsRequest, + defaults: ProfileDefaults, +) -> Dict[str, Any]: + output: Dict[str, Any] = {} + + if request.item_ids is not None: + output["item_ids"] = request.item_ids + + return output + + def marshal_DatabaseApiAssignDatabaseUserRequest( request: DatabaseApiAssignDatabaseUserRequest, defaults: ProfileDefaults, @@ -1083,8 +1330,16 @@ def marshal_DatabaseApiCreateDatabaseRequest( output.update( resolve_one_of( [ - OneOfPossibility("new_user", request.new_user), - OneOfPossibility("existing_username", request.existing_username), + OneOfPossibility( + param="new_user", + value=request.new_user, + marshal_func=marshal_CreateDatabaseRequestUser, + ), + OneOfPossibility( + param="existing_username", + value=request.existing_username, + marshal_func=None, + ), ] ), ) @@ -1292,6 +1547,9 @@ def marshal_HostingApiCreateHostingRequest( if request.tags is not None: output["tags"] = request.tags + if request.subdomain is not None: + output["subdomain"] = request.subdomain + if request.offer_options is not None: output["offer_options"] = [ marshal_OfferOptionRequest(item, defaults) for item in request.offer_options diff --git a/scaleway/scaleway/webhosting/v1/types.py b/scaleway/scaleway/webhosting/v1/types.py index 9d80eb681..69b95f5df 100644 --- a/scaleway/scaleway/webhosting/v1/types.py +++ b/scaleway/scaleway/webhosting/v1/types.py @@ -20,6 +20,34 @@ ) +class BackupItemType(str, Enum, metaclass=StrEnumMeta): + UNKNOWN_BACKUP_ITEM_TYPE = "unknown_backup_item_type" + FULL = "full" + WEB = "web" + MAIL = "mail" + DB = "db" + DB_USER = "db_user" + FTP_USER = "ftp_user" + DNS_ZONE = "dns_zone" + CRON_JOB = "cron_job" + SSL_CERTIFICATE = "ssl_certificate" + + def __str__(self) -> str: + return str(self.value) + + +class BackupStatus(str, Enum, metaclass=StrEnumMeta): + UNKNOWN_BACKUP_STATUS = "unknown_backup_status" + ACTIVE = "active" + LOCKED = "locked" + DISABLED = "disabled" + DAMAGED = "damaged" + RESTORING = "restoring" + + def __str__(self) -> str: + return str(self.value) + + class DnsRecordStatus(str, Enum, metaclass=StrEnumMeta): UNKNOWN_STATUS = "unknown_status" VALID = "valid" @@ -131,6 +159,14 @@ def __str__(self) -> str: return str(self.value) +class ListBackupsRequestOrderBy(str, Enum, metaclass=StrEnumMeta): + CREATED_AT_DESC = "created_at_desc" + CREATED_AT_ASC = "created_at_asc" + + def __str__(self) -> str: + return str(self.value) + + class ListDatabaseUsersRequestOrderBy(str, Enum, metaclass=StrEnumMeta): USERNAME_ASC = "username_asc" USERNAME_DESC = "username_desc" @@ -232,6 +268,34 @@ def __str__(self) -> str: return str(self.value) +@dataclass +class AutoConfigDomainDns: + nameservers: bool + """ + Whether or not to synchronize domain nameservers. + """ + + web_records: bool + """ + Whether or not to synchronize web records. + """ + + mail_records: bool + """ + Whether or not to synchronize mail records. + """ + + all_records: bool + """ + Whether or not to synchronize all types of records. Takes priority over the other fields. + """ + + none: bool + """ + No automatic domain configuration. Users must configure their domain for the Web Hosting to work. + """ + + @dataclass class PlatformControlPanelUrls: dashboard: str @@ -245,6 +309,29 @@ class PlatformControlPanelUrls: """ +@dataclass +class HostingDomainCustomDomain: + domain: str + """ + Custom domain linked to the hosting plan. + """ + + domain_status: DomainStatus + """ + Status of the custom domain verification. + """ + + dns_status: DnsRecordsStatus + """ + Status of the DNS configuration for the custom domain. + """ + + auto_config_domain_dns: Optional[AutoConfigDomainDns] + """ + Indicates whether to auto-configure DNS for this domain. + """ + + @dataclass class OfferOption: id: str @@ -302,40 +389,58 @@ class PlatformControlPanel: @dataclass -class CreateDatabaseRequestUser: - username: str +class BackupItem: + id: str + """ + ID of the item. + """ - password: str + name: str + """ + Name of the item (e.g., `database name`, `email address`). + """ + type_: BackupItemType + """ + Type of the item (e.g., email, database, FTP). + """ -@dataclass -class AutoConfigDomainDns: - nameservers: bool + size: int """ - Whether or not to synchronize domain nameservers. + Size of the item in bytes. """ - web_records: bool + status: BackupStatus """ - Whether or not to synchronize web records. + Status of the item. Available values are `active`, `damaged`, and `restoring`. """ - mail_records: bool + created_at: Optional[datetime] """ - Whether or not to synchronize mail records. + Date and time at which this item was backed up. """ - all_records: bool + +@dataclass +class HostingDomain: + subdomain: str """ - Whether or not to synchronize all types of records. Takes priority over the other fields. + Optional free subdomain linked to the Web Hosting plan. """ - none: bool + custom_domain: Optional[HostingDomainCustomDomain] """ - No automatic domain configuration. Users must configure their domain for the Web Hosting to work. + Optional custom domain linked to the Web Hosting plan. """ +@dataclass +class CreateDatabaseRequestUser: + username: str + + password: str + + @dataclass class CreateHostingRequestDomainConfiguration: update_nameservers: bool @@ -527,6 +632,47 @@ class Platform: """ +@dataclass +class BackupItemGroup: + type_: BackupItemType + """ + Type of items (e.g., email, database, FTP). + """ + + items: List[BackupItem] + """ + List of individual backup items of this type. + """ + + +@dataclass +class Backup: + id: str + """ + ID of the backup. + """ + + size: int + """ + Total size of the backup in bytes. + """ + + status: BackupStatus + """ + Status of the backup. Available values are `active`, `locked`, and `restoring`. + """ + + total_items: int + """ + Total number of restorable items in the backup. + """ + + created_at: Optional[datetime] + """ + Creation date of the backup. + """ + + @dataclass class ControlPanel: name: str @@ -606,11 +752,6 @@ class HostingSummary: Status of the Web Hosting plan. """ - domain: str - """ - Main domain associated with the Web Hosting plan. - """ - protected: bool """ Whether the hosting is protected or not. @@ -621,11 +762,6 @@ class HostingSummary: Name of the active offer for the Web Hosting plan. """ - domain_status: DomainStatus - """ - Main domain status of the Web Hosting plan. - """ - region: ScwRegion """ Region where the Web Hosting plan is hosted. @@ -641,11 +777,26 @@ class HostingSummary: Date on which the Web Hosting plan was last updated. """ + domain: Optional[str] + """ + Main domain associated with the Web Hosting plan (deprecated, use domain_info). + """ + dns_status: Optional[DnsRecordsStatus] """ DNS status of the Web Hosting plan. """ + domain_status: Optional[DomainStatus] + """ + Main domain status of the Web Hosting plan. + """ + + domain_info: Optional[HostingDomain] + """ + Domain configuration block (subdomain, optional custom domain, and DNS settings). + """ + @dataclass class MailAccount: @@ -711,6 +862,106 @@ class DomainAvailability: """ +@dataclass +class BackupApiGetBackupRequest: + hosting_id: str + """ + UUID of the hosting account. + """ + + backup_id: str + """ + ID of the backup to retrieve. + """ + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + +@dataclass +class BackupApiListBackupItemsRequest: + hosting_id: str + """ + UUID of the hosting account. + """ + + backup_id: str + """ + ID of the backup to list items from. + """ + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + +@dataclass +class BackupApiListBackupsRequest: + hosting_id: str + """ + UUID of the hosting account. + """ + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + page: Optional[int] + """ + Page number to retrieve. + """ + + page_size: Optional[int] + """ + Number of backups to return per page. + """ + + order_by: Optional[ListBackupsRequestOrderBy] + """ + Order in which to return the list of backups. + """ + + +@dataclass +class BackupApiRestoreBackupItemsRequest: + hosting_id: str + """ + UUID of the hosting account. + """ + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + item_ids: Optional[List[str]] + """ + List of backup item IDs to restore individually. + """ + + +@dataclass +class BackupApiRestoreBackupRequest: + hosting_id: str + """ + UUID of the hosting account. + """ + + backup_id: str + """ + ID of the backup to fully restore. + """ + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + @dataclass class CheckUserOwnsDomainResponse: owns_domain: bool @@ -1274,39 +1525,44 @@ class Hosting: Status of the Web Hosting plan. """ - domain: str + updated_at: Optional[datetime] """ - Main domain associated with the Web Hosting plan. + Date on which the Web Hosting plan was last updated. """ - tags: List[str] + created_at: Optional[datetime] """ - List of tags associated with the Web Hosting plan. + Date on which the Web Hosting plan was created. """ - ipv4: str + domain: Optional[str] """ - Current IPv4 address of the hosting. + Main domain associated with the Web Hosting plan (deprecated, use domain_info). """ - updated_at: Optional[datetime] + offer: Optional[Offer] """ - Date on which the Web Hosting plan was last updated. + Details of the Web Hosting plan offer and options. """ - created_at: Optional[datetime] + platform: Optional[Platform] """ - Date on which the Web Hosting plan was created. + Details of the hosting platform. """ - protected: bool + tags: List[str] """ - Whether the hosting is protected or not. + List of tags associated with the Web Hosting plan. """ - domain_status: DomainStatus + ipv4: str """ - Main domain status of the Web Hosting plan. + Current IPv4 address of the hosting. + """ + + protected: bool + """ + Whether the hosting is protected or not. """ region: ScwRegion @@ -1314,24 +1570,24 @@ class Hosting: Region where the Web Hosting plan is hosted. """ - offer: Optional[Offer] + dns_status: Optional[DnsRecordsStatus] """ - Details of the Web Hosting plan offer and options. + DNS status of the Web Hosting plan (deprecated, use domain_info). """ - platform: Optional[Platform] + user: Optional[HostingUser] """ - Details of the hosting platform. + Details of the hosting user. """ - dns_status: Optional[DnsRecordsStatus] + domain_status: Optional[DomainStatus] """ - DNS status of the Web Hosting plan. + Main domain status of the Web Hosting plan (deprecated, use domain_info). """ - user: Optional[HostingUser] + domain_info: Optional[HostingDomain] """ - Details of the hosting user. + Domain configuration block (subdomain, optional custom domain, and DNS settings). """ @@ -1367,6 +1623,11 @@ class HostingApiCreateHostingRequest: List of tags for the Web Hosting plan. """ + subdomain: Optional[str] + """ + The name prefix to use as a free subdomain (for example, `mysite`) assigned to the Web Hosting plan. The full domain will be automatically created by adding it to the fixed base domain (e.g. `mysite.scw.site`). You do not need to include the base domain yourself. + """ + offer_options: Optional[List[OfferOptionRequest]] """ List of the Web Hosting plan options IDs with their quantities. @@ -1497,6 +1758,11 @@ class HostingApiListHostingsRequest: Name of the control panel to filter for, only Web Hosting plans from this control panel will be returned. """ + subdomain: Optional[str] + """ + Optional free subdomain linked to the Web Hosting plan. + """ + @dataclass class HostingApiResetHostingPasswordRequest: @@ -1549,6 +1815,32 @@ class HostingApiUpdateHostingRequest: """ +@dataclass +class ListBackupItemsResponse: + total_count: int + """ + Total number of backup item groups. + """ + + groups: List[BackupItemGroup] + """ + List of backup item groups categorized by type. + """ + + +@dataclass +class ListBackupsResponse: + total_count: int + """ + Total number of available backups. + """ + + backups: List[Backup] + """ + List of available backups. + """ + + @dataclass class ListControlPanelsResponse: total_count: int @@ -1834,6 +2126,16 @@ class ResourceSummary: """ +@dataclass +class RestoreBackupItemsResponse: + pass + + +@dataclass +class RestoreBackupResponse: + pass + + @dataclass class SearchDomainsResponse: domains_available: List[DomainAvailability]