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