• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
17from __future__ import absolute_import
18
19from gslib.command import Command
20from gslib.command_argument import CommandArgument
21from gslib.cs_api_map import ApiSelector
22from gslib.exception import CommandException
23from gslib.help_provider import CreateHelpText
24from gslib.third_party.storage_apitools import storage_v1_messages as apitools_messages
25from 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
65class 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