diff --git a/scaleway-async/scaleway_async/secret/v1beta1/__init__.py b/scaleway-async/scaleway_async/secret/v1beta1/__init__.py index b55546b45..531ccc836 100644 --- a/scaleway-async/scaleway_async/secret/v1beta1/__init__.py +++ b/scaleway-async/scaleway_async/secret/v1beta1/__init__.py @@ -39,6 +39,8 @@ from .types import ListTagsRequest from .types import ListTagsResponse from .types import ProtectSecretRequest +from .types import RestoreSecretRequest +from .types import RestoreSecretVersionRequest from .types import SSHKey from .types import UnprotectSecretRequest from .types import UpdateSecretRequest @@ -85,6 +87,8 @@ "ListTagsRequest", "ListTagsResponse", "ProtectSecretRequest", + "RestoreSecretRequest", + "RestoreSecretVersionRequest", "SSHKey", "UnprotectSecretRequest", "UpdateSecretRequest", diff --git a/scaleway-async/scaleway_async/secret/v1beta1/api.py b/scaleway-async/scaleway_async/secret/v1beta1/api.py index 43d9cc8dd..47fef12c0 100644 --- a/scaleway-async/scaleway_async/secret/v1beta1/api.py +++ b/scaleway-async/scaleway_async/secret/v1beta1/api.py @@ -253,6 +253,7 @@ async def list_secrets( path: Optional[str] = None, ephemeral: Optional[bool] = None, type_: Optional[SecretType] = None, + scheduled_for_deletion: Optional[bool] = None, ) -> ListSecretsResponse: """ List secrets. @@ -268,6 +269,7 @@ async def list_secrets( :param path: Filter by exact path (optional). :param ephemeral: Filter by ephemeral / not ephemeral (optional). :param type_: Filter by secret type (optional). + :param scheduled_for_deletion: Filter by whether the secret was scheduled for deletion / not scheduled for deletion (optional). :return: :class:`ListSecretsResponse ` Usage: @@ -293,6 +295,7 @@ async def list_secrets( "page_size": page_size or self.client.default_page_size, "path": path, "project_id": project_id or self.client.default_project_id, + "scheduled_for_deletion": scheduled_for_deletion, "tags": tags, "type": type_, }, @@ -315,6 +318,7 @@ async def list_secrets_all( path: Optional[str] = None, ephemeral: Optional[bool] = None, type_: Optional[SecretType] = None, + scheduled_for_deletion: Optional[bool] = None, ) -> List[Secret]: """ List secrets. @@ -330,6 +334,7 @@ async def list_secrets_all( :param path: Filter by exact path (optional). :param ephemeral: Filter by ephemeral / not ephemeral (optional). :param type_: Filter by secret type (optional). + :param scheduled_for_deletion: Filter by whether the secret was scheduled for deletion / not scheduled for deletion (optional). :return: :class:`List[Secret] ` Usage: @@ -354,6 +359,7 @@ async def list_secrets_all( "path": path, "ephemeral": ephemeral, "type_": type_, + "scheduled_for_deletion": scheduled_for_deletion, }, ) @@ -1120,3 +1126,77 @@ async def list_secret_types_all( "page_size": page_size, }, ) + + async def restore_secret_version( + self, + *, + secret_id: str, + revision: str, + region: Optional[ScwRegion] = None, + ) -> SecretVersion: + """ + Restore a version. + Restore a secret's version specified by the `region`, `secret_id` and `revision` parameters. + :param secret_id: + :param revision: + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`SecretVersion ` + + Usage: + :: + + result = await api.restore_secret_version( + secret_id="example", + revision="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_secret_id = validate_path_param("secret_id", secret_id) + param_revision = validate_path_param("revision", revision) + + res = self._request( + "POST", + f"/secret-manager/v1beta1/regions/{param_region}/secrets/{param_secret_id}/versions/{param_revision}/restore", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_SecretVersion(res.json()) + + async def restore_secret( + self, + *, + secret_id: str, + region: Optional[ScwRegion] = None, + ) -> Secret: + """ + Restore a secret. + Restore a secret and all its versions scheduled for deletion specified by the `region` and `secret_id` parameters. + :param secret_id: + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`Secret ` + + Usage: + :: + + result = await api.restore_secret( + secret_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_secret_id = validate_path_param("secret_id", secret_id) + + res = self._request( + "POST", + f"/secret-manager/v1beta1/regions/{param_region}/secrets/{param_secret_id}/restore", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_Secret(res.json()) diff --git a/scaleway-async/scaleway_async/secret/v1beta1/marshalling.py b/scaleway-async/scaleway_async/secret/v1beta1/marshalling.py index 699110e53..bf3e70c02 100644 --- a/scaleway-async/scaleway_async/secret/v1beta1/marshalling.py +++ b/scaleway-async/scaleway_async/secret/v1beta1/marshalling.py @@ -110,6 +110,14 @@ def unmarshal_SecretVersion(data: Any) -> SecretVersion: else: args["ephemeral_properties"] = None + field = data.get("deletion_requested_at", None) + if field is not None: + args["deletion_requested_at"] = ( + parser.isoparse(field) if isinstance(field, str) else field + ) + else: + args["deletion_requested_at"] = None + return SecretVersion(**args) @@ -220,6 +228,14 @@ def unmarshal_Secret(data: Any) -> Secret: else: args["ephemeral_policy"] = None + field = data.get("deletion_requested_at", None) + if field is not None: + args["deletion_requested_at"] = ( + parser.isoparse(field) if isinstance(field, str) else field + ) + else: + args["deletion_requested_at"] = None + return Secret(**args) diff --git a/scaleway-async/scaleway_async/secret/v1beta1/types.py b/scaleway-async/scaleway_async/secret/v1beta1/types.py index 1b9fff0a7..338eaefd0 100644 --- a/scaleway-async/scaleway_async/secret/v1beta1/types.py +++ b/scaleway-async/scaleway_async/secret/v1beta1/types.py @@ -83,6 +83,7 @@ class SecretVersionStatus(str, Enum, metaclass=StrEnumMeta): ENABLED = "enabled" DISABLED = "disabled" DELETED = "deleted" + SCHEDULED_FOR_DELETION = "scheduled_for_deletion" def __str__(self) -> str: return str(self.value) @@ -174,6 +175,7 @@ class SecretVersion: * `unknown_status`: the version is in an invalid state. * `enabled`: the version is accessible. * `disabled`: the version is not accessible but can be enabled. +* `scheduled_for_deletion`: the version is scheduled for deletion. It will be deleted in 7 days. * `deleted`: the version is permanently deleted. It is not possible to recover it. """ @@ -207,6 +209,11 @@ class SecretVersion: Returns the version's expiration date, whether it expires after being accessed once, and the action to perform (disable or delete) once the version expires. """ + deletion_requested_at: Optional[datetime] + """ + Returns the time at which deletion was requested. + """ + @dataclass class Secret: @@ -291,6 +298,11 @@ class Secret: (Optional.) Policy that defines whether/when a secret's versions expire. By default, the policy is applied to all the secret's versions. """ + deletion_requested_at: Optional[datetime] + """ + Returns the time at which deletion was requested. + """ + @dataclass class AccessSecretVersionByPathRequest: @@ -792,6 +804,11 @@ class ListSecretsRequest: Filter by secret type (optional). """ + scheduled_for_deletion: Optional[bool] + """ + Filter by whether the secret was scheduled for deletion / not scheduled for deletion (optional). + """ + @dataclass class ListSecretsResponse: @@ -849,6 +866,28 @@ class ProtectSecretRequest: """ +@dataclass +class RestoreSecretRequest: + secret_id: str + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + +@dataclass +class RestoreSecretVersionRequest: + secret_id: str + + revision: str + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + @dataclass class SSHKey: ssh_private_key: str diff --git a/scaleway/scaleway/secret/v1beta1/__init__.py b/scaleway/scaleway/secret/v1beta1/__init__.py index b55546b45..531ccc836 100644 --- a/scaleway/scaleway/secret/v1beta1/__init__.py +++ b/scaleway/scaleway/secret/v1beta1/__init__.py @@ -39,6 +39,8 @@ from .types import ListTagsRequest from .types import ListTagsResponse from .types import ProtectSecretRequest +from .types import RestoreSecretRequest +from .types import RestoreSecretVersionRequest from .types import SSHKey from .types import UnprotectSecretRequest from .types import UpdateSecretRequest @@ -85,6 +87,8 @@ "ListTagsRequest", "ListTagsResponse", "ProtectSecretRequest", + "RestoreSecretRequest", + "RestoreSecretVersionRequest", "SSHKey", "UnprotectSecretRequest", "UpdateSecretRequest", diff --git a/scaleway/scaleway/secret/v1beta1/api.py b/scaleway/scaleway/secret/v1beta1/api.py index 894ae2ae9..9605f8654 100644 --- a/scaleway/scaleway/secret/v1beta1/api.py +++ b/scaleway/scaleway/secret/v1beta1/api.py @@ -253,6 +253,7 @@ def list_secrets( path: Optional[str] = None, ephemeral: Optional[bool] = None, type_: Optional[SecretType] = None, + scheduled_for_deletion: Optional[bool] = None, ) -> ListSecretsResponse: """ List secrets. @@ -268,6 +269,7 @@ def list_secrets( :param path: Filter by exact path (optional). :param ephemeral: Filter by ephemeral / not ephemeral (optional). :param type_: Filter by secret type (optional). + :param scheduled_for_deletion: Filter by whether the secret was scheduled for deletion / not scheduled for deletion (optional). :return: :class:`ListSecretsResponse ` Usage: @@ -293,6 +295,7 @@ def list_secrets( "page_size": page_size or self.client.default_page_size, "path": path, "project_id": project_id or self.client.default_project_id, + "scheduled_for_deletion": scheduled_for_deletion, "tags": tags, "type": type_, }, @@ -315,6 +318,7 @@ def list_secrets_all( path: Optional[str] = None, ephemeral: Optional[bool] = None, type_: Optional[SecretType] = None, + scheduled_for_deletion: Optional[bool] = None, ) -> List[Secret]: """ List secrets. @@ -330,6 +334,7 @@ def list_secrets_all( :param path: Filter by exact path (optional). :param ephemeral: Filter by ephemeral / not ephemeral (optional). :param type_: Filter by secret type (optional). + :param scheduled_for_deletion: Filter by whether the secret was scheduled for deletion / not scheduled for deletion (optional). :return: :class:`List[Secret] ` Usage: @@ -354,6 +359,7 @@ def list_secrets_all( "path": path, "ephemeral": ephemeral, "type_": type_, + "scheduled_for_deletion": scheduled_for_deletion, }, ) @@ -1120,3 +1126,77 @@ def list_secret_types_all( "page_size": page_size, }, ) + + def restore_secret_version( + self, + *, + secret_id: str, + revision: str, + region: Optional[ScwRegion] = None, + ) -> SecretVersion: + """ + Restore a version. + Restore a secret's version specified by the `region`, `secret_id` and `revision` parameters. + :param secret_id: + :param revision: + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`SecretVersion ` + + Usage: + :: + + result = api.restore_secret_version( + secret_id="example", + revision="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_secret_id = validate_path_param("secret_id", secret_id) + param_revision = validate_path_param("revision", revision) + + res = self._request( + "POST", + f"/secret-manager/v1beta1/regions/{param_region}/secrets/{param_secret_id}/versions/{param_revision}/restore", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_SecretVersion(res.json()) + + def restore_secret( + self, + *, + secret_id: str, + region: Optional[ScwRegion] = None, + ) -> Secret: + """ + Restore a secret. + Restore a secret and all its versions scheduled for deletion specified by the `region` and `secret_id` parameters. + :param secret_id: + :param region: Region to target. If none is passed will use default region from the config. + :return: :class:`Secret ` + + Usage: + :: + + result = api.restore_secret( + secret_id="example", + ) + """ + + param_region = validate_path_param( + "region", region or self.client.default_region + ) + param_secret_id = validate_path_param("secret_id", secret_id) + + res = self._request( + "POST", + f"/secret-manager/v1beta1/regions/{param_region}/secrets/{param_secret_id}/restore", + body={}, + ) + + self._throw_on_error(res) + return unmarshal_Secret(res.json()) diff --git a/scaleway/scaleway/secret/v1beta1/marshalling.py b/scaleway/scaleway/secret/v1beta1/marshalling.py index 699110e53..bf3e70c02 100644 --- a/scaleway/scaleway/secret/v1beta1/marshalling.py +++ b/scaleway/scaleway/secret/v1beta1/marshalling.py @@ -110,6 +110,14 @@ def unmarshal_SecretVersion(data: Any) -> SecretVersion: else: args["ephemeral_properties"] = None + field = data.get("deletion_requested_at", None) + if field is not None: + args["deletion_requested_at"] = ( + parser.isoparse(field) if isinstance(field, str) else field + ) + else: + args["deletion_requested_at"] = None + return SecretVersion(**args) @@ -220,6 +228,14 @@ def unmarshal_Secret(data: Any) -> Secret: else: args["ephemeral_policy"] = None + field = data.get("deletion_requested_at", None) + if field is not None: + args["deletion_requested_at"] = ( + parser.isoparse(field) if isinstance(field, str) else field + ) + else: + args["deletion_requested_at"] = None + return Secret(**args) diff --git a/scaleway/scaleway/secret/v1beta1/types.py b/scaleway/scaleway/secret/v1beta1/types.py index 1b9fff0a7..338eaefd0 100644 --- a/scaleway/scaleway/secret/v1beta1/types.py +++ b/scaleway/scaleway/secret/v1beta1/types.py @@ -83,6 +83,7 @@ class SecretVersionStatus(str, Enum, metaclass=StrEnumMeta): ENABLED = "enabled" DISABLED = "disabled" DELETED = "deleted" + SCHEDULED_FOR_DELETION = "scheduled_for_deletion" def __str__(self) -> str: return str(self.value) @@ -174,6 +175,7 @@ class SecretVersion: * `unknown_status`: the version is in an invalid state. * `enabled`: the version is accessible. * `disabled`: the version is not accessible but can be enabled. +* `scheduled_for_deletion`: the version is scheduled for deletion. It will be deleted in 7 days. * `deleted`: the version is permanently deleted. It is not possible to recover it. """ @@ -207,6 +209,11 @@ class SecretVersion: Returns the version's expiration date, whether it expires after being accessed once, and the action to perform (disable or delete) once the version expires. """ + deletion_requested_at: Optional[datetime] + """ + Returns the time at which deletion was requested. + """ + @dataclass class Secret: @@ -291,6 +298,11 @@ class Secret: (Optional.) Policy that defines whether/when a secret's versions expire. By default, the policy is applied to all the secret's versions. """ + deletion_requested_at: Optional[datetime] + """ + Returns the time at which deletion was requested. + """ + @dataclass class AccessSecretVersionByPathRequest: @@ -792,6 +804,11 @@ class ListSecretsRequest: Filter by secret type (optional). """ + scheduled_for_deletion: Optional[bool] + """ + Filter by whether the secret was scheduled for deletion / not scheduled for deletion (optional). + """ + @dataclass class ListSecretsResponse: @@ -849,6 +866,28 @@ class ProtectSecretRequest: """ +@dataclass +class RestoreSecretRequest: + secret_id: str + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + +@dataclass +class RestoreSecretVersionRequest: + secret_id: str + + revision: str + + region: Optional[ScwRegion] + """ + Region to target. If none is passed will use default region from the config. + """ + + @dataclass class SSHKey: ssh_private_key: str