diff --git a/b2/_internal/console_tool.py b/b2/_internal/console_tool.py index 50c0fd74..03601841 100644 --- a/b2/_internal/console_tool.py +++ b/b2/_internal/console_tool.py @@ -3525,7 +3525,74 @@ def execute_operation(self, local_file, bucket, threads, **kwargs): return file_version -class UpdateFileLegalHold(FileIdAndOptionalFileNameMixin, Command): +class FileUpdateBase(B2URIFileArgMixin, LegalHoldMixin, Command): + """ + {LegalHoldMixin} + + Retention: + + Setting file retention settings requires the **writeFileRetentions** capability, and only works in bucket + with fileLockEnabled=true. Providing a ``retention-mode`` other than ``none`` requires providing ``retainUntil``, + which has to be a future timestamp in the form of an integer representing milliseconds since epoch. + + If a file already is in governance mode, disabling retention or shortening it's period requires providing + ``--bypass-governance``. + + If a file already is in compliance mode, disabling retention or shortening it's period is impossible. + + In both cases prolonging the retention period is possible. Changing from governance to compliance is also supported. + + {FILE_RETENTION_COMPATIBILITY_WARNING} + + Requires capability: + + - **readFiles** + """ + + @classmethod + def _setup_parser(cls, parser): + super()._setup_parser(parser) + + add_normalized_argument( + parser, + '--file-retention-mode', + default=None, + choices=(RetentionMode.COMPLIANCE.value, RetentionMode.GOVERNANCE.value, 'none') + ) + add_normalized_argument( + parser, + '--retain-until', + type=parse_millis_from_float_timestamp, + metavar='TIMESTAMP', + default=None + ) + add_normalized_argument(parser, '--bypass-governance', action='store_true', default=False) + + def _run(self, args): + b2_uri = self.get_b2_uri_from_arg(args) + file_version = self.api.get_file_info_by_uri(b2_uri) + + if args.legal_hold is not None: + self.api.update_file_legal_hold( + file_version.id_, file_version.file_name, LegalHold(args.legal_hold) + ) + + if args.file_retention_mode is not None: + if args.file_retention_mode == 'none': + file_retention = FileRetentionSetting(RetentionMode.NONE) + else: + file_retention = FileRetentionSetting( + RetentionMode(args.file_retention_mode), args.retain_until + ) + + self.api.update_file_retention( + file_version.id_, file_version.file_name, file_retention, args.bypass_governance + ) + + return 0 + + +class UpdateFileLegalHoldBase(FileIdAndOptionalFileNameMixin, Command): """ Only works in buckets with fileLockEnabled=true. @@ -3550,7 +3617,7 @@ def _run(self, args): return 0 -class UpdateFileRetention(FileIdAndOptionalFileNameMixin, Command): +class UpdateFileRetentionBase(FileIdAndOptionalFileNameMixin, Command): """ Only works in buckets with fileLockEnabled=true. Providing a ``retention-mode`` other than ``none`` requires providing ``retainUntil``, which has to be a future timestamp in the form of an integer representing milliseconds @@ -4931,6 +4998,12 @@ class FileHide(FileHideBase): COMMAND_NAME = 'hide' +@File.subcommands_registry.register +class FileUpdate(FileUpdateBase): + __doc__ = FileUpdateBase.__doc__ + COMMAND_NAME = 'update' + + class FileInfo2(CmdReplacedByMixin, B2URIFileArgMixin, FileInfoBase): __doc__ = FileInfoBase.__doc__ replaced_by_cmd = (File, FileInfo) @@ -4993,6 +5066,16 @@ class HideFile(CmdReplacedByMixin, FileHideBase): replaced_by_cmd = (File, FileHide) +class UpdateFileLegalHold(CmdReplacedByMixin, UpdateFileLegalHoldBase): + __doc__ = UpdateFileLegalHoldBase.__doc__ + replaced_by_cmd = (File, FileUpdate) + + +class UpdateFileRetention(CmdReplacedByMixin, UpdateFileRetentionBase): + __doc__ = UpdateFileRetentionBase.__doc__ + replaced_by_cmd = (File, FileUpdate) + + class ConsoleTool: """ Implements the commands available in the B2 command-line tool diff --git a/changelog.d/+command-file.added.md b/changelog.d/+command-file.added.md index 71b2be3d..31eeba6b 100644 --- a/changelog.d/+command-file.added.md +++ b/changelog.d/+command-file.added.md @@ -1 +1 @@ -Add `file {info|url|cat|upload|download|copy-by-id|hide}` commands. \ No newline at end of file +Add `file {info|url|cat|upload|download|copy-by-id|hide|update}` commands. \ No newline at end of file diff --git a/changelog.d/+command-file.deprecated.md b/changelog.d/+command-file.deprecated.md index 6d0a284e..baad1025 100644 --- a/changelog.d/+command-file.deprecated.md +++ b/changelog.d/+command-file.deprecated.md @@ -1 +1 @@ -Deprecated `file-info`, `get-url`, `cat`, `upload-file`, `download-file`, `copy-file-by-id` and `hide-file`, use `file {info|url|cat|upload|download|copy-by-id|hide}` instead. \ No newline at end of file +Deprecated `file-info`, `get-url`, `cat`, `upload-file`, `download-file`, `copy-file-by-id`, `hide-file`, `update-file-legal-hold` and `update-file-retention`, use `file {info|url|cat|upload|download|copy-by-id|hide|update}` instead. \ No newline at end of file