Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: gslib/commands/web.py

Issue 698893003: Update checked in version of gsutil to version 4.6 (Closed) Base URL: http://dart.googlecode.com/svn/third_party/gsutil/
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gslib/commands/versioning.py ('k') | gslib/copy_helper.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 website configuration command for buckets."""
16
17 from __future__ import absolute_import
14 18
15 import getopt 19 import getopt
16 import sys 20 import sys
17 21
18 from gslib.command import Command 22 from gslib.command import Command
19 from gslib.command import COMMAND_NAME 23 from gslib.cs_api_map import ApiSelector
20 from gslib.command import COMMAND_NAME_ALIASES
21 from gslib.command import FILE_URIS_OK
22 from gslib.command import MAX_ARGS
23 from gslib.command import MIN_ARGS
24 from gslib.command import PROVIDER_URIS_OK
25 from gslib.command import SUPPORTED_SUB_ARGS
26 from gslib.command import URIS_START_ARG
27 from gslib.exception import CommandException 24 from gslib.exception import CommandException
28 from gslib.help_provider import CreateHelpText 25 from gslib.help_provider import CreateHelpText
29 from gslib.help_provider import HELP_NAME 26 from gslib.third_party.storage_apitools import encoding as encoding
30 from gslib.help_provider import HELP_NAME_ALIASES 27 from gslib.third_party.storage_apitools import storage_v1_messages as apitools_m essages
31 from gslib.help_provider import HELP_ONE_LINE_SUMMARY
32 from gslib.help_provider import HELP_TEXT
33 from gslib.help_provider import HelpType
34 from gslib.help_provider import HELP_TYPE
35 from gslib.help_provider import SUBCOMMAND_HELP_TEXT
36 from gslib.util import NO_MAX 28 from gslib.util import NO_MAX
37 from gslib.util import UnaryDictToXml
38 from xml.dom.minidom import parseString as XmlParseString
39 29
40 30
41 _SET_SYNOPSIS = """ 31 _SET_SYNOPSIS = """
42 gsutil web set [-m main_page_suffix] [-e error_page] bucket_uri... 32 gsutil web set [-m main_page_suffix] [-e error_page] bucket_url...
43 """ 33 """
44 34
45 _GET_SYNOPSIS = """ 35 _GET_SYNOPSIS = """
46 gsutil web get bucket_uri 36 gsutil web get bucket_url
47 """ 37 """
48 38
49 _SYNOPSIS = _SET_SYNOPSIS + _GET_SYNOPSIS.lstrip('\n') 39 _SYNOPSIS = _SET_SYNOPSIS + _GET_SYNOPSIS.lstrip('\n')
50 40
51 _SET_DESCRIPTION = """ 41 _SET_DESCRIPTION = """
52 <B>SET</B> 42 <B>SET</B>
53 The "gsutil web set" command will allow you to set Website Configuration 43 The "gsutil web set" command will allow you to configure or disable
54 on your bucket(s). The "set" sub-command has the following options: 44 Website Configuration on your bucket(s). The "set" sub-command has the
45 following options (leave both options blank to disable):
55 46
56 <B>SET OPTIONS</B> 47 <B>SET OPTIONS</B>
57 -m <index.html> Specifies the object name to serve when a bucket 48 -m <index.html> Specifies the object name to serve when a bucket
58 listing is requested via the CNAME alias to 49 listing is requested via the CNAME alias to
59 c.storage.googleapis.com. 50 c.storage.googleapis.com.
60 51
61 -e <404.html> Specifies the error page to serve when a request is made 52 -e <404.html> Specifies the error page to serve when a request is made
62 for a non-existent object via the CNAME alias to 53 for a non-existent object via the CNAME alias to
63 c.storage.googleapis.com. 54 c.storage.googleapis.com.
64 55
65 """ 56 """
66 57
67 _GET_DESCRIPTION = """ 58 _GET_DESCRIPTION = """
68 <B>GET</B> 59 <B>GET</B>
69 The "gsutil web get" command will gets the web semantics configuration for 60 The "gsutil web get" command will gets the web semantics configuration for
70 a bucket and displays an XML representation of the configuration. 61 a bucket and displays a JSON representation of the configuration.
71 62
72 In Google Cloud Storage, this would look like: 63 In Google Cloud Storage, this would look like:
73 64
74 <?xml version="1.0" ?> 65 {
75 <WebsiteConfiguration> 66 "notFoundPage": "404.html",
76 <MainPageSuffix> 67 "mainPageSuffix": "index.html"
77 index.html 68 }
78 </MainPageSuffix>
79 <NotFoundPage>
80 404.html
81 </NotFoundPage>
82 </WebsiteConfiguration>
83 69
84 """ 70 """
85 71
86 _DESCRIPTION = """ 72 _DESCRIPTION = """
87 The Website Configuration feature enables you to configure a Google Cloud 73 The Website Configuration feature enables you to configure a Google Cloud
88 Storage bucket to behave like a static website. This means requests made via a 74 Storage bucket to behave like a static website. This means requests made via a
89 domain-named bucket aliased using a Domain Name System "CNAME" to 75 domain-named bucket aliased using a Domain Name System "CNAME" to
90 c.storage.googleapis.com will work like any other website, i.e., a GET to the 76 c.storage.googleapis.com will work like any other website, i.e., a GET to the
91 bucket will serve the configured "main" page instead of the usual bucket 77 bucket will serve the configured "main" page instead of the usual bucket
92 listing and a GET for a non-existent object will serve the configured error 78 listing and a GET for a non-existent object will serve the configured error
(...skipping 26 matching lines...) Expand all
119 via the CNAME alias, you can continue to use "gsutil ls" to list the bucket 105 via the CNAME alias, you can continue to use "gsutil ls" to list the bucket
120 and get the normal bucket listing (rather than the main page). 106 and get the normal bucket listing (rather than the main page).
121 107
122 2. The main_page_suffix applies to each subdirectory of the bucket. For 108 2. The main_page_suffix applies to each subdirectory of the bucket. For
123 example, with the main_page_suffix configured to be index.html, a GET 109 example, with the main_page_suffix configured to be index.html, a GET
124 request for http://example.com would retrieve 110 request for http://example.com would retrieve
125 http://example.com/index.html, and a GET request for 111 http://example.com/index.html, and a GET request for
126 http://example.com/photos would retrieve 112 http://example.com/photos would retrieve
127 http://example.com/photos/index.html. 113 http://example.com/photos/index.html.
128 114
129 2. There is just one 404.html page: For example, a GET request for 115 3. There is just one 404.html page: For example, a GET request for
130 http://example.com/photos/missing would retrieve 116 http://example.com/photos/missing would retrieve
131 http://example.com/404.html, not http://example.com/photos/404.html. 117 http://example.com/404.html, not http://example.com/photos/404.html.
132 118
133 3. For additional details see 119 4. For additional details see
134 https://developers.google.com/storage/docs/website-configuration. 120 https://developers.google.com/storage/docs/website-configuration.
135 121
136 The web command has two sub-commands: 122 The web command has two sub-commands:
137 """ + _SET_DESCRIPTION + _GET_DESCRIPTION 123 """ + _SET_DESCRIPTION + _GET_DESCRIPTION
138 124
139 _detailed_help_text = CreateHelpText(_SYNOPSIS, _DESCRIPTION) 125 _DETAILED_HELP_TEXT = CreateHelpText(_SYNOPSIS, _DESCRIPTION)
140 126
141 _get_help_text = CreateHelpText(_GET_SYNOPSIS, _GET_DESCRIPTION) 127 _get_help_text = CreateHelpText(_GET_SYNOPSIS, _GET_DESCRIPTION)
142 _set_help_text = CreateHelpText(_SET_SYNOPSIS, _SET_DESCRIPTION) 128 _set_help_text = CreateHelpText(_SET_SYNOPSIS, _SET_DESCRIPTION)
143 129
144 130
145 def BuildGSWebConfig(main_page_suffix=None, not_found_page=None):
146 config_body_l = ['<WebsiteConfiguration>']
147 if main_page_suffix:
148 config_body_l.append('<MainPageSuffix>%s</MainPageSuffix>' %
149 main_page_suffix)
150 if not_found_page:
151 config_body_l.append('<NotFoundPage>%s</NotFoundPage>' %
152 not_found_page)
153 config_body_l.append('</WebsiteConfiguration>')
154 return "".join(config_body_l)
155
156 def BuildS3WebConfig(main_page_suffix=None, error_page=None):
157 config_body_l = ['<WebsiteConfiguration xmlns="http://s3.amazonaws.com/doc/200 6-03-01/">']
158 if not main_page_suffix:
159 raise CommandException('S3 requires main page / index document')
160 config_body_l.append('<IndexDocument><Suffix>%s</Suffix></IndexDocument>' %
161 main_page_suffix)
162 if error_page:
163 config_body_l.append('<ErrorDocument><Key>%s</Key></ErrorDocument>' %
164 error_page)
165 config_body_l.append('</WebsiteConfiguration>')
166 return "".join(config_body_l)
167
168 class WebCommand(Command): 131 class WebCommand(Command):
169 """Implementation of gsutil web command.""" 132 """Implementation of gsutil web command."""
170 133
171 # Command specification (processed by parent class). 134 # Command specification. See base class for documentation.
172 command_spec = { 135 command_spec = Command.CreateCommandSpec(
173 # Name of command. 136 'web',
174 COMMAND_NAME : 'web', 137 command_name_aliases=['setwebcfg', 'getwebcfg'],
175 # List of command name aliases. 138 min_args=2,
176 COMMAND_NAME_ALIASES : ['setwebcfg', 'getwebcfg'], 139 max_args=NO_MAX,
177 # Min number of args required by this command. 140 supported_sub_args='m:e:',
178 MIN_ARGS : 2, 141 file_url_ok=False,
179 # Max number of args required by this command, or NO_MAX. 142 provider_url_ok=False,
180 MAX_ARGS : NO_MAX, 143 urls_start_arg=1,
181 # Getopt-style string specifying acceptable sub args. 144 gs_api_support=[ApiSelector.XML, ApiSelector.JSON],
182 SUPPORTED_SUB_ARGS : 'm:e:', 145 gs_default_api=ApiSelector.JSON,
183 # True if file URIs acceptable for this command. 146 )
184 FILE_URIS_OK : False, 147 # Help specification. See help_provider.py for documentation.
185 # True if provider-only URIs acceptable for this command. 148 help_spec = Command.HelpSpec(
186 PROVIDER_URIS_OK : False, 149 help_name='web',
187 # Index in args of first URI arg. 150 help_name_aliases=['getwebcfg', 'setwebcfg'],
188 URIS_START_ARG : 1, 151 help_type='command_help',
189 } 152 help_one_line_summary=(
190 help_spec = { 153 'Set a main page and/or error page for one or more buckets'),
191 # Name of command or auxiliary help info for which this help applies. 154 help_text=_DETAILED_HELP_TEXT,
192 HELP_NAME : 'web', 155 subcommand_help_text={'get': _get_help_text, 'set': _set_help_text},
193 # List of help name aliases. 156 )
194 HELP_NAME_ALIASES : ['getwebcfg', 'setwebcfg'], 157
195 # Type of help)
196 HELP_TYPE : HelpType.COMMAND_HELP,
197 # One line summary of this help.
198 HELP_ONE_LINE_SUMMARY : 'Set a main page and/or error page for one or more b uckets',
199 # The full help text.
200 HELP_TEXT : _detailed_help_text,
201 # Help text for sub-commands.
202 SUBCOMMAND_HELP_TEXT : {'get' : _get_help_text,
203 'set' : _set_help_text},
204 }
205
206 def _GetWeb(self): 158 def _GetWeb(self):
207 uri_args = self.args 159 """Gets website configuration for a bucket."""
160 bucket_url, bucket_metadata = self.GetSingleBucketUrlFromArg(
161 self.args[0], bucket_fields=['website'])
208 162
209 # Iterate over URIs, expanding wildcards, and getting the website 163 if bucket_url.scheme == 's3':
210 # configuration on each. 164 sys.stdout.write(self.gsutil_api.XmlPassThroughGetWebsite(
211 some_matched = False 165 bucket_url, provider=bucket_url.scheme))
212 for uri_str in uri_args: 166 else:
213 for blr in self.WildcardIterator(uri_str): 167 if bucket_metadata.website and (bucket_metadata.website.mainPageSuffix or
214 uri = blr.GetUri() 168 bucket_metadata.website.notFoundPage):
215 if not uri.names_bucket(): 169 sys.stdout.write(str(encoding.MessageToJson(
216 raise CommandException('URI %s must name a bucket for the %s command' 170 bucket_metadata.website)) + '\n')
217 % (uri, self.command_name)) 171 else:
218 some_matched = True 172 sys.stdout.write('%s has no website configuration.\n' % bucket_url)
219 sys.stderr.write('Getting website config on %s...\n' % uri) 173
220 web_config_xml = UnaryDictToXml(uri.get_website_config()) 174 return 0
221 sys.stdout.write(XmlParseString(web_config_xml).toprettyxml())
222 if not some_matched:
223 raise CommandException('No URIs matched')
224 175
225 def _SetWeb(self): 176 def _SetWeb(self):
177 """Sets website configuration for a bucket."""
226 main_page_suffix = None 178 main_page_suffix = None
227 error_page = None 179 error_page = None
228 if self.sub_opts: 180 if self.sub_opts:
229 for o, a in self.sub_opts: 181 for o, a in self.sub_opts:
230 if o == '-m': 182 if o == '-m':
231 main_page_suffix = a 183 main_page_suffix = a
232 elif o == '-e': 184 elif o == '-e':
233 error_page = a 185 error_page = a
234 186
235 uri_args = self.args 187 url_args = self.args
236 188
237 # Iterate over URIs, expanding wildcards, and setting the website 189 website = apitools_messages.Bucket.WebsiteValue(
190 mainPageSuffix=main_page_suffix, notFoundPage=error_page)
191
192 # Iterate over URLs, expanding wildcards and setting the website
238 # configuration on each. 193 # configuration on each.
239 some_matched = False 194 some_matched = False
240 for uri_str in uri_args: 195 for url_str in url_args:
241 for blr in self.WildcardIterator(uri_str): 196 bucket_iter = self.GetBucketUrlIterFromArg(url_str, bucket_fields=['id'])
242 uri = blr.GetUri() 197 for blr in bucket_iter:
243 if not uri.names_bucket(): 198 url = blr.storage_url
244 raise CommandException('URI %s must name a bucket for the %s command'
245 % (str(uri), self.command_name))
246 some_matched = True 199 some_matched = True
247 self.logger.info('Setting website config on %s...', uri) 200 self.logger.info('Setting website configuration on %s...', blr)
248 uri.set_website_config(main_page_suffix, error_page) 201 bucket_metadata = apitools_messages.Bucket(website=website)
202 self.gsutil_api.PatchBucket(url.bucket_name, bucket_metadata,
203 provider=url.scheme, fields=['id'])
249 if not some_matched: 204 if not some_matched:
250 raise CommandException('No URIs matched') 205 raise CommandException('No URLs matched')
206 return 0
251 207
252 # Command entry point.
253 def RunCommand(self): 208 def RunCommand(self):
209 """Command entry point for the web command."""
254 action_subcommand = self.args.pop(0) 210 action_subcommand = self.args.pop(0)
255 (self.sub_opts, self.args) = getopt.getopt(self.args, 211 self.sub_opts, self.args = getopt.getopt(
256 self.command_spec[SUPPORTED_SUB_ARGS]) 212 self.args, self.command_spec.supported_sub_args)
257 self.CheckArguments() 213 self.CheckArguments()
258 if action_subcommand == 'get': 214 if action_subcommand == 'get':
259 func = self._GetWeb 215 func = self._GetWeb
260 elif action_subcommand == 'set': 216 elif action_subcommand == 'set':
261 func = self._SetWeb 217 func = self._SetWeb
262 else: 218 else:
263 raise CommandException(('Invalid subcommand "%s" for the %s command.\n' 219 raise CommandException(('Invalid subcommand "%s" for the %s command.\n'
264 'See "gsutil help web".') % 220 'See "gsutil help web".') %
265 (action_subcommand, self.command_name)) 221 (action_subcommand, self.command_name))
266 func() 222 return func()
267 return 0
OLDNEW
« no previous file with comments | « gslib/commands/versioning.py ('k') | gslib/copy_helper.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698