Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / telemetry / third_party / gsutilz / gslib / commands / lifecycle.py
blob02146dd300bfcea64fee2b0689af677ebf681fa1
1 # -*- coding: utf-8 -*-
2 # Copyright 2013 Google Inc. All Rights Reserved.
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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 lifecycle configuration command for GCS buckets."""
17 from __future__ import absolute_import
19 import sys
21 from gslib.command import Command
22 from gslib.command_argument import CommandArgument
23 from gslib.cs_api_map import ApiSelector
24 from gslib.exception import CommandException
25 from gslib.help_provider import CreateHelpText
26 from gslib.third_party.storage_apitools import storage_v1_messages as apitools_messages
27 from gslib.translation_helper import LifecycleTranslation
28 from gslib.util import NO_MAX
29 from gslib.util import UrlsAreForSingleProvider
32 _GET_SYNOPSIS = """
33 gsutil lifecycle get url
34 """
36 _SET_SYNOPSIS = """
37 gsutil lifecycle set config-json-file url...
38 """
40 _SYNOPSIS = _GET_SYNOPSIS + _SET_SYNOPSIS.lstrip('\n') + '\n'
42 _GET_DESCRIPTION = """
43 <B>GET</B>
44 Gets the lifecycle configuration for a given bucket. You can get the
45 lifecycle configuration for only one bucket at a time. The output can be
46 redirected into a file, edited and then updated via the set sub-command.
48 """
50 _SET_DESCRIPTION = """
51 <B>SET</B>
52 Sets the lifecycle configuration on one or more buckets. The config-json-file
53 specified on the command line should be a path to a local file containing
54 the lifecycle configuration JSON document.
56 """
58 _DESCRIPTION = """
59 The lifecycle command can be used to get or set lifecycle management policies
60 for the given bucket(s). This command is supported for buckets only, not
61 objects. For more information on object lifecycle management, please see the
62 `developer guide <https://developers.google.com/storage/docs/lifecycle>`_.
64 The lifecycle command has two sub-commands:
65 """ + _GET_DESCRIPTION + _SET_DESCRIPTION + """
66 <B>EXAMPLES</B>
67 The following lifecycle configuration JSON document specifies that all objects
68 in this bucket that are more than 365 days old will be deleted automatically:
71 "rule":
74 "action": {"type": "Delete"},
75 "condition": {"age": 365}
80 The following (empty) lifecycle configuration JSON document removes all
81 lifecycle configuration for a bucket:
85 """
87 _DETAILED_HELP_TEXT = CreateHelpText(_SYNOPSIS, _DESCRIPTION)
89 _get_help_text = CreateHelpText(_GET_SYNOPSIS, _GET_DESCRIPTION)
90 _set_help_text = CreateHelpText(_SET_SYNOPSIS, _SET_DESCRIPTION)
93 class LifecycleCommand(Command):
94 """Implementation of gsutil lifecycle command."""
96 # Command specification. See base class for documentation.
97 command_spec = Command.CreateCommandSpec(
98 'lifecycle',
99 command_name_aliases=['lifecycleconfig'],
100 usage_synopsis=_SYNOPSIS,
101 min_args=2,
102 max_args=NO_MAX,
103 supported_sub_args='',
104 file_url_ok=True,
105 provider_url_ok=False,
106 urls_start_arg=1,
107 gs_api_support=[ApiSelector.XML, ApiSelector.JSON],
108 gs_default_api=ApiSelector.JSON,
109 argparse_arguments={
110 'set': [
111 CommandArgument.MakeNFileURLsArgument(1),
112 CommandArgument.MakeZeroOrMoreCloudBucketURLsArgument()
114 'get': [
115 CommandArgument.MakeNCloudBucketURLsArgument(1)
119 # Help specification. See help_provider.py for documentation.
120 help_spec = Command.HelpSpec(
121 help_name='lifecycle',
122 help_name_aliases=['getlifecycle', 'setlifecycle'],
123 help_type='command_help',
124 help_one_line_summary=(
125 'Get or set lifecycle configuration for a bucket'),
126 help_text=_DETAILED_HELP_TEXT,
127 subcommand_help_text={'get': _get_help_text, 'set': _set_help_text},
130 def _SetLifecycleConfig(self):
131 """Sets lifecycle configuration for a Google Cloud Storage bucket."""
132 lifecycle_arg = self.args[0]
133 url_args = self.args[1:]
134 # Disallow multi-provider 'lifecycle set' requests.
135 if not UrlsAreForSingleProvider(url_args):
136 raise CommandException('"%s" command spanning providers not allowed.' %
137 self.command_name)
139 # Open, read and parse file containing JSON document.
140 lifecycle_file = open(lifecycle_arg, 'r')
141 lifecycle_txt = lifecycle_file.read()
142 lifecycle_file.close()
144 # Iterate over URLs, expanding wildcards and setting the lifecycle on each.
145 some_matched = False
146 for url_str in url_args:
147 bucket_iter = self.GetBucketUrlIterFromArg(url_str,
148 bucket_fields=['lifecycle'])
149 for blr in bucket_iter:
150 url = blr.storage_url
151 some_matched = True
152 self.logger.info('Setting lifecycle configuration on %s...', blr)
153 if url.scheme == 's3':
154 self.gsutil_api.XmlPassThroughSetLifecycle(
155 lifecycle_txt, url, provider=url.scheme)
156 else:
157 lifecycle = LifecycleTranslation.JsonLifecycleToMessage(lifecycle_txt)
158 bucket_metadata = apitools_messages.Bucket(lifecycle=lifecycle)
159 self.gsutil_api.PatchBucket(url.bucket_name, bucket_metadata,
160 provider=url.scheme, fields=['id'])
161 if not some_matched:
162 raise CommandException('No URLs matched')
163 return 0
165 def _GetLifecycleConfig(self):
166 """Gets lifecycle configuration for a Google Cloud Storage bucket."""
167 bucket_url, bucket_metadata = self.GetSingleBucketUrlFromArg(
168 self.args[0], bucket_fields=['lifecycle'])
170 if bucket_url.scheme == 's3':
171 sys.stdout.write(self.gsutil_api.XmlPassThroughGetLifecycle(
172 bucket_url, provider=bucket_url.scheme))
173 else:
174 if bucket_metadata.lifecycle and bucket_metadata.lifecycle.rule:
175 sys.stdout.write(LifecycleTranslation.JsonLifecycleFromMessage(
176 bucket_metadata.lifecycle))
177 else:
178 sys.stdout.write('%s has no lifecycle configuration.\n' % bucket_url)
180 return 0
182 def RunCommand(self):
183 """Command entry point for the lifecycle command."""
184 subcommand = self.args.pop(0)
185 if subcommand == 'get':
186 return self._GetLifecycleConfig()
187 elif subcommand == 'set':
188 return self._SetLifecycleConfig()
189 else:
190 raise CommandException('Invalid subcommand "%s" for the %s command.' %
191 (subcommand, self.command_name))