| OLD | NEW |
| 1 # -*- coding: utf-8 -*- |
| 1 # Copyright 2012 Google Inc. All Rights Reserved. | 2 # Copyright 2012 Google Inc. All Rights Reserved. |
| 2 # | 3 # |
| 3 # Licensed under the Apache License, Version 2.0 (the "License"); | 4 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 # you may not use this file except in compliance with the License. | 5 # you may not use this file except in compliance with the License. |
| 5 # You may obtain a copy of the License at | 6 # You may obtain a copy of the License at |
| 6 # | 7 # |
| 7 # http://www.apache.org/licenses/LICENSE-2.0 | 8 # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 # | 9 # |
| 9 # Unless required by applicable law or agreed to in writing, software | 10 # Unless required by applicable law or agreed to in writing, software |
| 10 # distributed under the License is distributed on an "AS IS" BASIS, | 11 # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 # See the License for the specific language governing permissions and | 13 # See the License for the specific language governing permissions and |
| 13 # limitations under the License. | 14 # limitations under the License. |
| 15 """Implementation of versioning configuration command for buckets.""" |
| 16 |
| 17 from __future__ import absolute_import |
| 14 | 18 |
| 15 from gslib.command import Command | 19 from gslib.command import Command |
| 16 from gslib.command import COMMAND_NAME | 20 from gslib.cs_api_map import ApiSelector |
| 17 from gslib.command import COMMAND_NAME_ALIASES | |
| 18 from gslib.command import FILE_URIS_OK | |
| 19 from gslib.command import MAX_ARGS | |
| 20 from gslib.command import MIN_ARGS | |
| 21 from gslib.command import PROVIDER_URIS_OK | |
| 22 from gslib.command import SUPPORTED_SUB_ARGS | |
| 23 from gslib.command import URIS_START_ARG | |
| 24 from gslib.exception import CommandException | 21 from gslib.exception import CommandException |
| 25 from gslib.help_provider import CreateHelpText | 22 from gslib.help_provider import CreateHelpText |
| 26 from gslib.help_provider import HELP_NAME | 23 from gslib.third_party.storage_apitools import storage_v1_messages as apitools_m
essages |
| 27 from gslib.help_provider import HELP_NAME_ALIASES | |
| 28 from gslib.help_provider import HELP_ONE_LINE_SUMMARY | |
| 29 from gslib.help_provider import HELP_TEXT | |
| 30 from gslib.help_provider import HelpType | |
| 31 from gslib.help_provider import HELP_TYPE | |
| 32 from gslib.help_provider import SUBCOMMAND_HELP_TEXT | |
| 33 from gslib.util import NO_MAX | 24 from gslib.util import NO_MAX |
| 34 | 25 |
| 35 | 26 |
| 36 _SET_SYNOPSIS = """ | 27 _SET_SYNOPSIS = """ |
| 37 gsutil versioning set [on|off] bucket_uri... | 28 gsutil versioning set [on|off] bucket_url... |
| 38 """ | 29 """ |
| 39 | 30 |
| 40 _GET_SYNOPSIS = """ | 31 _GET_SYNOPSIS = """ |
| 41 gsutil versioning get bucket_uri | 32 gsutil versioning get bucket_url... |
| 42 """ | 33 """ |
| 43 | 34 |
| 44 _SYNOPSIS = _SET_SYNOPSIS + _GET_SYNOPSIS.lstrip('\n') | 35 _SYNOPSIS = _SET_SYNOPSIS + _GET_SYNOPSIS.lstrip('\n') |
| 45 | 36 |
| 46 _SET_DESCRIPTION = """ | 37 _SET_DESCRIPTION = """ |
| 47 <B>SET</B> | 38 <B>SET</B> |
| 48 The "set" sub-command requires an additional sub-command, either "on" or | 39 The "set" sub-command requires an additional sub-command, either "on" or |
| 49 "off", which, respectively, will enable or disable versioning for the | 40 "off", which, respectively, will enable or disable versioning for the |
| 50 specified bucket(s). | 41 specified bucket(s). |
| 51 | 42 |
| 52 """ | 43 """ |
| 53 | 44 |
| 54 _GET_DESCRIPTION = """ | 45 _GET_DESCRIPTION = """ |
| 55 <B>GET</B> | 46 <B>GET</B> |
| 56 The "get" sub-command gets the versioning configuration for a | 47 The "get" sub-command gets the versioning configuration for a |
| 57 bucket and displays an XML representation of the configuration. | 48 bucket and displays whether or not it is enabled. |
| 58 | |
| 59 In Google Cloud Storage, this would look like: | |
| 60 | |
| 61 <?xml version="1.0" ?> | |
| 62 <VersioningConfiguration> | |
| 63 <Status> | |
| 64 Enabled | |
| 65 </Status> | |
| 66 </VersioningConfiguration> | |
| 67 | |
| 68 """ | 49 """ |
| 69 | 50 |
| 70 _DESCRIPTION = """ | 51 _DESCRIPTION = """ |
| 71 The Versioning Configuration feature enables you to configure a Google Cloud | 52 The Versioning Configuration feature enables you to configure a Google Cloud |
| 72 Storage bucket to keep old versions of objects. | 53 Storage bucket to keep old versions of objects. |
| 73 | 54 |
| 74 The gsutil versioning command has two sub-commands: | 55 The gsutil versioning command has two sub-commands: |
| 75 """ + _SET_DESCRIPTION + _GET_DESCRIPTION | 56 """ + _SET_DESCRIPTION + _GET_DESCRIPTION |
| 76 | 57 |
| 77 _detailed_help_text = CreateHelpText(_SYNOPSIS, _DESCRIPTION) | 58 _DETAILED_HELP_TEXT = CreateHelpText(_SYNOPSIS, _DESCRIPTION) |
| 78 | 59 |
| 79 _get_help_text = CreateHelpText(_GET_SYNOPSIS, _GET_DESCRIPTION) | 60 _get_help_text = CreateHelpText(_GET_SYNOPSIS, _GET_DESCRIPTION) |
| 80 _set_help_text = CreateHelpText(_SET_SYNOPSIS, _SET_DESCRIPTION) | 61 _set_help_text = CreateHelpText(_SET_SYNOPSIS, _SET_DESCRIPTION) |
| 81 | 62 |
| 63 |
| 82 class VersioningCommand(Command): | 64 class VersioningCommand(Command): |
| 83 """Implementation of gsutil versioning command.""" | 65 """Implementation of gsutil versioning command.""" |
| 84 | 66 |
| 85 # Command specification (processed by parent class). | 67 # Command specification. See base class for documentation. |
| 86 command_spec = { | 68 command_spec = Command.CreateCommandSpec( |
| 87 # Name of command. | 69 'versioning', |
| 88 COMMAND_NAME : 'versioning', | 70 command_name_aliases=['setversioning', 'getversioning'], |
| 89 # List of command name aliases. | 71 min_args=2, |
| 90 COMMAND_NAME_ALIASES : ['setversioning', 'getversioning'], | 72 max_args=NO_MAX, |
| 91 # Min number of args required by this command. | 73 supported_sub_args='', |
| 92 MIN_ARGS : 2, | 74 file_url_ok=False, |
| 93 # Max number of args required by this command, or NO_MAX. | 75 provider_url_ok=False, |
| 94 MAX_ARGS : NO_MAX, | 76 urls_start_arg=2, |
| 95 # Getopt-style string specifying acceptable sub args. | 77 gs_api_support=[ApiSelector.XML, ApiSelector.JSON], |
| 96 SUPPORTED_SUB_ARGS : '', | 78 gs_default_api=ApiSelector.JSON, |
| 97 # True if file URIs acceptable for this command. | 79 ) |
| 98 FILE_URIS_OK : False, | 80 # Help specification. See help_provider.py for documentation. |
| 99 # True if provider-only URIs acceptable for this command. | 81 help_spec = Command.HelpSpec( |
| 100 PROVIDER_URIS_OK : False, | 82 help_name='versioning', |
| 101 # Index in args of first URI arg. | 83 help_name_aliases=['getversioning', 'setversioning'], |
| 102 URIS_START_ARG : 2, | 84 help_type='command_help', |
| 103 } | 85 help_one_line_summary=( |
| 104 help_spec = { | 86 'Enable or suspend versioning for one or more buckets'), |
| 105 # Name of command or auxiliary help info for which this help applies. | 87 help_text=_DETAILED_HELP_TEXT, |
| 106 HELP_NAME : 'versioning', | 88 subcommand_help_text={'get': _get_help_text, 'set': _set_help_text}, |
| 107 # List of help name aliases. | 89 ) |
| 108 HELP_NAME_ALIASES : ['getversioning', 'setversioning'], | |
| 109 # Type of help) | |
| 110 HELP_TYPE : HelpType.COMMAND_HELP, | |
| 111 # One line summary of this help. | |
| 112 HELP_ONE_LINE_SUMMARY : 'Enable or suspend versioning for one or more ' | |
| 113 'buckets', | |
| 114 # The full help text. | |
| 115 HELP_TEXT : _detailed_help_text, | |
| 116 # Help text for sub-commands. | |
| 117 SUBCOMMAND_HELP_TEXT : {'get' : _get_help_text, | |
| 118 'set' : _set_help_text}, | |
| 119 } | |
| 120 | 90 |
| 121 def _CalculateUrisStartArg(self): | 91 def _CalculateUrlsStartArg(self): |
| 122 if not self.args: | 92 if not self.args: |
| 123 self._RaiseWrongNumberOfArgumentsException() | 93 self._RaiseWrongNumberOfArgumentsException() |
| 124 if (self.args[0].lower() == 'set'): | 94 if self.args[0].lower() == 'set': |
| 125 return 2 | 95 return 2 |
| 126 else: | 96 else: |
| 127 return 1 | 97 return 1 |
| 128 | 98 |
| 129 def _SetVersioning(self): | 99 def _SetVersioning(self): |
| 100 """Gets versioning configuration for a bucket.""" |
| 130 versioning_arg = self.args[0].lower() | 101 versioning_arg = self.args[0].lower() |
| 131 if not versioning_arg in ('on', 'off'): | 102 if versioning_arg not in ('on', 'off'): |
| 132 raise CommandException('Argument to "%s set" must be either [on|off]' | 103 raise CommandException('Argument to "%s set" must be either [on|off]' |
| 133 % (self.command_name)) | 104 % (self.command_name)) |
| 134 uri_args = self.args[1:] | 105 url_args = self.args[1:] |
| 135 if len(uri_args) == 0: | 106 if not url_args: |
| 136 self._RaiseWrongNumberOfArgumentsException() | 107 self._RaiseWrongNumberOfArgumentsException() |
| 137 | 108 |
| 138 # Iterate over URIs, expanding wildcards, and setting the website | 109 # Iterate over URLs, expanding wildcards and set the versioning |
| 139 # configuration on each. | 110 # configuration on each. |
| 140 some_matched = False | 111 some_matched = False |
| 141 for uri_str in uri_args: | 112 for url_str in url_args: |
| 142 for blr in self.WildcardIterator(uri_str): | 113 bucket_iter = self.GetBucketUrlIterFromArg(url_str, bucket_fields=['id']) |
| 143 uri = blr.GetUri() | 114 for blr in bucket_iter: |
| 144 if not uri.names_bucket(): | 115 url = blr.storage_url |
| 145 raise CommandException('URI %s must name a bucket for the %s command' | |
| 146 % (str(uri), self.command_name)) | |
| 147 some_matched = True | 116 some_matched = True |
| 117 bucket_metadata = apitools_messages.Bucket( |
| 118 versioning=apitools_messages.Bucket.VersioningValue()) |
| 148 if versioning_arg == 'on': | 119 if versioning_arg == 'on': |
| 149 self.logger.info('Enabling versioning for %s...', uri) | 120 self.logger.info('Enabling versioning for %s...', url) |
| 150 uri.configure_versioning(True) | 121 bucket_metadata.versioning.enabled = True |
| 151 else: | 122 else: |
| 152 self.logger.info('Suspending versioning for %s...', uri) | 123 self.logger.info('Suspending versioning for %s...', url) |
| 153 uri.configure_versioning(False) | 124 bucket_metadata.versioning.enabled = False |
| 125 self.gsutil_api.PatchBucket(url.bucket_name, bucket_metadata, |
| 126 provider=url.scheme, fields=['id']) |
| 154 if not some_matched: | 127 if not some_matched: |
| 155 raise CommandException('No URIs matched') | 128 raise CommandException('No URLs matched') |
| 156 | 129 |
| 157 def _GetVersioning(self): | 130 def _GetVersioning(self): |
| 158 uri_args = self.args | 131 """Gets versioning configuration for one or more buckets.""" |
| 132 url_args = self.args |
| 159 | 133 |
| 160 # Iterate over URIs, expanding wildcards, and getting the website | 134 # Iterate over URLs, expanding wildcards and getting the versioning |
| 161 # configuration on each. | 135 # configuration on each. |
| 162 some_matched = False | 136 some_matched = False |
| 163 for uri_str in uri_args: | 137 for url_str in url_args: |
| 164 for blr in self.WildcardIterator(uri_str): | 138 bucket_iter = self.GetBucketUrlIterFromArg(url_str, |
| 165 uri = blr.GetUri() | 139 bucket_fields=['versioning']) |
| 166 if not uri.names_bucket(): | 140 for blr in bucket_iter: |
| 167 raise CommandException('URI %s must name a bucket for the %s command' | |
| 168 % (str(uri), self.command_name)) | |
| 169 some_matched = True | 141 some_matched = True |
| 170 uri_str = '%s://%s' % (uri.scheme, uri.bucket_name) | 142 if blr.root_object.versioning and blr.root_object.versioning.enabled: |
| 171 if uri.get_versioning_config(): | 143 print '%s: Enabled' % blr.url_string.rstrip('/') |
| 172 print '%s: Enabled' % uri_str | |
| 173 else: | 144 else: |
| 174 print '%s: Suspended' % uri_str | 145 print '%s: Suspended' % blr.url_string.rstrip('/') |
| 175 if not some_matched: | 146 if not some_matched: |
| 176 raise CommandException('No URIs matched') | 147 raise CommandException('No URLs matched') |
| 177 | 148 |
| 178 # Command entry point. | |
| 179 def RunCommand(self): | 149 def RunCommand(self): |
| 150 """Command entry point for the versioning command.""" |
| 180 action_subcommand = self.args.pop(0) | 151 action_subcommand = self.args.pop(0) |
| 181 if action_subcommand == 'get': | 152 if action_subcommand == 'get': |
| 182 func = self._GetVersioning | 153 func = self._GetVersioning |
| 183 elif action_subcommand == 'set': | 154 elif action_subcommand == 'set': |
| 184 func = self._SetVersioning | 155 func = self._SetVersioning |
| 185 else: | 156 else: |
| 186 raise CommandException(( | 157 raise CommandException(( |
| 187 'Invalid subcommand "%s" for the %s command.\n' | 158 'Invalid subcommand "%s" for the %s command.\n' |
| 188 'See "gsutil help %s".') % | 159 'See "gsutil help %s".') % ( |
| 189 (action_subcommand, self.command_name, self.command_name)) | 160 action_subcommand, self.command_name, self.command_name)) |
| 190 func() | 161 func() |
| 191 return 0 | 162 return 0 |
| OLD | NEW |