class FakeCommandWithNestedArguments(object): subcommand_name = 'event' subcommand_subname = 'set' # Matches the number of CommandArguments in argparse_arguments below. num_args = 2 command_spec = Command.CreateCommandSpec('FakeCommandWithNestedArguments', argparse_arguments={ subcommand_name: { subcommand_subname: [ CommandArgument('arg1'), CommandArgument('arg2'), ] } })
class FakeCommandWithInvalidCompleter(Command): """Command with an invalid completer on an argument.""" command_spec = Command.CreateCommandSpec( 'fake1', argparse_arguments=[CommandArgument('arg', completer='BAD')]) help_spec = Command.HelpSpec(help_name='fake1', help_name_aliases=[], help_type='command_help', help_one_line_summary='fake command for tests', help_text='fake command for tests', subcommand_help_text={}) def __init__(self): pass
class BucketPolicyOnlyCommand(Command): """Implements the gsutil bucketpolicyonly command.""" command_spec = Command.CreateCommandSpec( 'bucketpolicyonly', usage_synopsis=_SYNOPSIS, min_args=2, max_args=NO_MAX, supported_sub_args='', file_url_ok=False, provider_url_ok=False, urls_start_arg=2, gs_api_support=[ApiSelector.JSON], gs_default_api=ApiSelector.JSON, argparse_arguments={ 'get': [CommandArgument.MakeNCloudURLsArgument(1),], 'set': [ CommandArgument('mode', choices=['on', 'off']), CommandArgument.MakeZeroOrMoreCloudBucketURLsArgument() ], }) # Help specification. See help_provider.py for documentation. help_spec = Command.HelpSpec( help_name='bucketpolicyonly', help_name_aliases=[], help_type='command_help', help_one_line_summary='Configure uniform bucket-level access', help_text=_DETAILED_HELP_TEXT, subcommand_help_text={ 'get': _get_help_text, 'set': _set_help_text, }, ) def _ValidateBucketListingRefAndReturnBucketName(self, blr): if blr.storage_url.scheme != 'gs': raise CommandException( 'The %s command can only be used with gs:// bucket URLs.' % self.command_name) def _GetBucketPolicyOnly(self, blr): """Gets the Bucket Policy Only setting for a bucket.""" self._ValidateBucketListingRefAndReturnBucketName(blr) bucket_url = blr.storage_url bucket_metadata = self.gsutil_api.GetBucket(bucket_url.bucket_name, fields=['iamConfiguration'], provider=bucket_url.scheme) iam_config = bucket_metadata.iamConfiguration bucket_policy_only = iam_config.bucketPolicyOnly fields = { 'bucket': str(bucket_url).rstrip('/'), 'enabled': bucket_policy_only.enabled } locked_time_line = '' if bucket_policy_only.lockedTime: fields['locked_time'] = bucket_policy_only.lockedTime locked_time_line = ' LockedTime: {locked_time}\n' if bucket_policy_only: print(('Bucket Policy Only setting for {bucket}:\n' ' Enabled: {enabled}\n' + locked_time_line).format(**fields)) def _SetBucketPolicyOnly(self, blr, setting_arg): """Sets the Bucket Policy Only setting for a bucket on or off.""" self._ValidateBucketListingRefAndReturnBucketName(blr) bucket_url = blr.storage_url iam_config = IamConfigurationValue() iam_config.bucketPolicyOnly = BucketPolicyOnlyValue() iam_config.bucketPolicyOnly.enabled = (setting_arg == 'on') bucket_metadata = apitools_messages.Bucket(iamConfiguration=iam_config) setting_verb = 'Enabling' if setting_arg == 'on' else 'Disabling' print('%s Bucket Policy Only for %s...' % (setting_verb, str(bucket_url).rstrip('/'))) self.gsutil_api.PatchBucket(bucket_url.bucket_name, bucket_metadata, fields=['iamConfiguration'], provider=bucket_url.scheme) return 0 def _BucketPolicyOnly(self): """Handles bucketpolicyonly command on a Cloud Storage bucket.""" subcommand = self.args.pop(0) if subcommand not in ('get', 'set'): raise CommandException('bucketpolicyonly only supports get|set') subcommand_func = None subcommand_args = [] setting_arg = None if subcommand == 'get': subcommand_func = self._GetBucketPolicyOnly elif subcommand == 'set': subcommand_func = self._SetBucketPolicyOnly setting_arg = self.args.pop(0) InsistOnOrOff(setting_arg, 'Only on and off values allowed for set option') subcommand_args.append(setting_arg) # Iterate over bucket args, performing the specified subsubcommand. some_matched = False url_args = self.args if not url_args: self.RaiseWrongNumberOfArgumentsException() for url_str in url_args: # Throws a CommandException if the argument is not a bucket. bucket_iter = self.GetBucketUrlIterFromArg(url_str) for bucket_listing_ref in bucket_iter: some_matched = True subcommand_func(bucket_listing_ref, *subcommand_args) if not some_matched: raise CommandException(NO_URLS_MATCHED_TARGET % list(url_args)) return 0 def RunCommand(self): """Command entry point for the bucketpolicyonly command.""" if self.gsutil_api.GetApiSelector(provider='gs') != ApiSelector.JSON: raise CommandException('\n'.join( textwrap.wrap( 'The "%s" command can only be used with the Cloud Storage JSON API.' % self.command_name))) action_subcommand = self.args[0] self.ParseSubOpts(check_args=True) if action_subcommand == 'get' or action_subcommand == 'set': metrics.LogCommandParams(sub_opts=self.sub_opts) metrics.LogCommandParams(subcommands=[action_subcommand]) self._BucketPolicyOnly() else: raise CommandException('Invalid subcommand "%s", use get|set instead.' % action_subcommand)
class LoggingCommand(Command): """Implementation of gsutil logging command.""" # Command specification. See base class for documentation. command_spec = Command.CreateCommandSpec( 'logging', command_name_aliases=['disablelogging', 'enablelogging', 'getlogging'], usage_synopsis=_SYNOPSIS, min_args=2, max_args=NO_MAX, supported_sub_args='b:o:', file_url_ok=False, provider_url_ok=False, urls_start_arg=0, gs_api_support=[ApiSelector.XML, ApiSelector.JSON], gs_default_api=ApiSelector.JSON, argparse_arguments=[ CommandArgument('mode', choices=['on', 'off']), CommandArgument.MakeZeroOrMoreCloudBucketURLsArgument() ] ) # Help specification. See help_provider.py for documentation. help_spec = Command.HelpSpec( help_name='logging', help_name_aliases=['loggingconfig', 'logs', 'log', 'getlogging', 'enablelogging', 'disablelogging'], help_type='command_help', help_one_line_summary='Configure or retrieve logging on buckets', help_text=_DETAILED_HELP_TEXT, subcommand_help_text={'get': _get_help_text, 'set': _set_help_text}, ) def _Get(self): """Gets logging configuration for a bucket.""" bucket_url, bucket_metadata = self.GetSingleBucketUrlFromArg( self.args[0], bucket_fields=['logging']) if bucket_url.scheme == 's3': sys.stdout.write(self.gsutil_api.XmlPassThroughGetLogging( bucket_url, provider=bucket_url.scheme)) else: if (bucket_metadata.logging and bucket_metadata.logging.logBucket and bucket_metadata.logging.logObjectPrefix): sys.stdout.write(str(encoding.MessageToJson( bucket_metadata.logging)) + '\n') else: sys.stdout.write('%s has no logging configuration.\n' % bucket_url) return 0 def _Enable(self): """Enables logging configuration for a bucket.""" # Disallow multi-provider 'logging set on' calls, because the schemas # differ. if not UrlsAreForSingleProvider(self.args): raise CommandException('"logging set on" command spanning providers not ' 'allowed.') target_bucket_url = None target_prefix = None for opt, opt_arg in self.sub_opts: if opt == '-b': target_bucket_url = StorageUrlFromString(opt_arg) if opt == '-o': target_prefix = opt_arg if not target_bucket_url: raise CommandException('"logging set on" requires \'-b <log_bucket>\' ' 'option') if not target_bucket_url.IsBucket(): raise CommandException('-b option must specify a bucket URL.') # Iterate over URLs, expanding wildcards and setting logging on each. some_matched = False for url_str in self.args: bucket_iter = self.GetBucketUrlIterFromArg(url_str, bucket_fields=['id']) for blr in bucket_iter: url = blr.storage_url some_matched = True self.logger.info('Enabling logging on %s...', blr) logging = apitools_messages.Bucket.LoggingValue( logBucket=target_bucket_url.bucket_name, logObjectPrefix=target_prefix or url.bucket_name) bucket_metadata = apitools_messages.Bucket(logging=logging) self.gsutil_api.PatchBucket(url.bucket_name, bucket_metadata, provider=url.scheme, fields=['id']) if not some_matched: raise CommandException(NO_URLS_MATCHED_TARGET % list(self.args)) return 0 def _Disable(self): """Disables logging configuration for a bucket.""" # Iterate over URLs, expanding wildcards, and disabling logging on each. some_matched = False for url_str in self.args: bucket_iter = self.GetBucketUrlIterFromArg(url_str, bucket_fields=['id']) for blr in bucket_iter: url = blr.storage_url some_matched = True self.logger.info('Disabling logging on %s...', blr) logging = apitools_messages.Bucket.LoggingValue() bucket_metadata = apitools_messages.Bucket(logging=logging) self.gsutil_api.PatchBucket(url.bucket_name, bucket_metadata, provider=url.scheme, fields=['id']) if not some_matched: raise CommandException(NO_URLS_MATCHED_TARGET % list(self.args)) return 0 def RunCommand(self): """Command entry point for the logging command.""" # Parse the subcommand and alias for the new logging command. action_subcommand = self.args.pop(0) if action_subcommand == 'get': func = self._Get elif action_subcommand == 'set': state_subcommand = self.args.pop(0) if not self.args: self.RaiseWrongNumberOfArgumentsException() if state_subcommand == 'on': func = self._Enable elif state_subcommand == 'off': func = self._Disable else: raise CommandException(( 'Invalid subcommand "%s" for the "%s %s" command.\n' 'See "gsutil help logging".') % ( state_subcommand, self.command_name, action_subcommand)) else: raise CommandException(('Invalid subcommand "%s" for the %s command.\n' 'See "gsutil help logging".') % (action_subcommand, self.command_name)) self.ParseSubOpts(check_args=True) func() return 0
class PapCommand(Command): """Implements the gsutil pap command.""" command_spec = Command.CreateCommandSpec( 'pap', command_name_aliases=['publicaccessprevention'], usage_synopsis=_SYNOPSIS, min_args=2, max_args=NO_MAX, supported_sub_args='', file_url_ok=False, provider_url_ok=False, urls_start_arg=2, gs_api_support=[ApiSelector.JSON], gs_default_api=ApiSelector.JSON, argparse_arguments={ 'get': [ CommandArgument.MakeNCloudURLsArgument(1), ], 'set': [ CommandArgument('mode', choices=['enforced', 'inherited']), CommandArgument.MakeZeroOrMoreCloudBucketURLsArgument() ], }) # Help specification. See help_provider.py for documentation. help_spec = Command.HelpSpec( help_name='pap', help_name_aliases=['publicaccessprevention'], help_type='command_help', help_one_line_summary='Configure public access prevention', help_text=_DETAILED_HELP_TEXT, subcommand_help_text={ 'get': _get_help_text, 'set': _set_help_text, }, ) def _ValidateBucketListingRefAndReturnBucketName(self, blr): if blr.storage_url.scheme != 'gs': raise CommandException( 'The %s command can only be used with gs:// bucket URLs.' % self.command_name) def _GetPublicAccessPrevention(self, blr): """Gets the public access prevention setting for a bucket.""" bucket_url = blr.storage_url bucket_metadata = self.gsutil_api.GetBucket( bucket_url.bucket_name, fields=['iamConfiguration'], provider=bucket_url.scheme) iam_config = bucket_metadata.iamConfiguration public_access_prevention = iam_config.publicAccessPrevention or 'inherited' bucket = str(bucket_url).rstrip('/') print('%s: %s' % (bucket, public_access_prevention)) def _SetPublicAccessPrevention(self, blr, setting_arg): """Sets the Public Access Prevention setting for a bucket enforced or inherited.""" bucket_url = blr.storage_url iam_config = IamConfigurationValue() iam_config.publicAccessPrevention = setting_arg bucket_metadata = apitools_messages.Bucket(iamConfiguration=iam_config) print('Setting Public Access Prevention %s for %s' % (setting_arg, str(bucket_url).rstrip('/'))) self.gsutil_api.PatchBucket(bucket_url.bucket_name, bucket_metadata, fields=['iamConfiguration'], provider=bucket_url.scheme) return 0 def _Pap(self): """Handles pap command on Cloud Storage buckets.""" subcommand = self.args.pop(0) if subcommand not in ('get', 'set'): raise CommandException('pap only supports get|set') subcommand_func = None subcommand_args = [] setting_arg = None if subcommand == 'get': subcommand_func = self._GetPublicAccessPrevention elif subcommand == 'set': subcommand_func = self._SetPublicAccessPrevention setting_arg = self.args.pop(0) subcommand_args.append(setting_arg) if self.gsutil_api.GetApiSelector('gs') != ApiSelector.JSON: raise CommandException('\n'.join( textwrap.wrap( ('The "%s" command can only be with the Cloud Storage ' 'JSON API.') % self.command_name))) # Iterate over bucket args, performing the specified subsubcommand. some_matched = False url_args = self.args if not url_args: self.RaiseWrongNumberOfArgumentsException() for url_str in url_args: # Throws a CommandException if the argument is not a bucket. bucket_iter = self.GetBucketUrlIterFromArg(url_str) for bucket_listing_ref in bucket_iter: if self.gsutil_api.GetApiSelector( bucket_listing_ref.storage_url.scheme ) != ApiSelector.JSON: raise CommandException('\n'.join( textwrap.wrap( ('The "%s" command can only be used for GCS ' 'Buckets.') % self.command_name))) some_matched = True subcommand_func(bucket_listing_ref, *subcommand_args) if not some_matched: raise CommandException(NO_URLS_MATCHED_TARGET % list(url_args)) return 0 def RunCommand(self): """Command entry point for the pap command.""" action_subcommand = self.args[0] self.ParseSubOpts(check_args=True) if action_subcommand == 'get' or action_subcommand == 'set': metrics.LogCommandParams(sub_opts=self.sub_opts) metrics.LogCommandParams(subcommands=[action_subcommand]) self._Pap() else: raise CommandException( 'Invalid subcommand "%s", use get|set instead.' % action_subcommand)
class VersioningCommand(Command): """Implementation of gsutil versioning command.""" # Command specification. See base class for documentation. command_spec = Command.CreateCommandSpec( 'versioning', command_name_aliases=['setversioning', 'getversioning'], usage_synopsis=_SYNOPSIS, min_args=2, max_args=NO_MAX, supported_sub_args='', file_url_ok=False, provider_url_ok=False, urls_start_arg=2, gs_api_support=[ApiSelector.XML, ApiSelector.JSON], gs_default_api=ApiSelector.JSON, argparse_arguments={ 'set': [ CommandArgument('mode', choices=['on', 'off']), CommandArgument.MakeZeroOrMoreCloudBucketURLsArgument() ], 'get': [ CommandArgument.MakeZeroOrMoreCloudBucketURLsArgument() ] } ) # Help specification. See help_provider.py for documentation. help_spec = Command.HelpSpec( help_name='versioning', help_name_aliases=['getversioning', 'setversioning'], help_type='command_help', help_one_line_summary=( 'Enable or suspend versioning for one or more buckets'), help_text=_DETAILED_HELP_TEXT, subcommand_help_text={'get': _get_help_text, 'set': _set_help_text}, ) def _CalculateUrlsStartArg(self): if not self.args: self.RaiseWrongNumberOfArgumentsException() if self.args[0].lower() == 'set': return 2 else: return 1 def _SetVersioning(self): """Gets versioning configuration for a bucket.""" versioning_arg = self.args[0].lower() if versioning_arg not in ('on', 'off'): raise CommandException('Argument to "%s set" must be either <on|off>' % (self.command_name)) url_args = self.args[1:] if not url_args: self.RaiseWrongNumberOfArgumentsException() # Iterate over URLs, expanding wildcards and set the versioning # configuration on each. some_matched = False for url_str in url_args: bucket_iter = self.GetBucketUrlIterFromArg(url_str, bucket_fields=['id']) for blr in bucket_iter: url = blr.storage_url some_matched = True bucket_metadata = apitools_messages.Bucket( versioning=apitools_messages.Bucket.VersioningValue()) if versioning_arg == 'on': self.logger.info('Enabling versioning for %s...', url) bucket_metadata.versioning.enabled = True else: self.logger.info('Suspending versioning for %s...', url) bucket_metadata.versioning.enabled = False self.gsutil_api.PatchBucket(url.bucket_name, bucket_metadata, provider=url.scheme, fields=['id']) if not some_matched: raise CommandException(NO_URLS_MATCHED_TARGET % list(url_args)) def _GetVersioning(self): """Gets versioning configuration for one or more buckets.""" url_args = self.args # Iterate over URLs, expanding wildcards and getting the versioning # configuration on each. some_matched = False for url_str in url_args: bucket_iter = self.GetBucketUrlIterFromArg(url_str, bucket_fields=['versioning']) for blr in bucket_iter: some_matched = True if blr.root_object.versioning and blr.root_object.versioning.enabled: print('%s: Enabled' % blr.url_string.rstrip('/')) else: print('%s: Suspended' % blr.url_string.rstrip('/')) if not some_matched: raise CommandException(NO_URLS_MATCHED_TARGET % list(url_args)) def RunCommand(self): """Command entry point for the versioning command.""" action_subcommand = self.args.pop(0) if action_subcommand == 'get': func = self._GetVersioning metrics.LogCommandParams(subcommands=[action_subcommand]) elif action_subcommand == 'set': func = self._SetVersioning versioning_arg = self.args[0].lower() if versioning_arg in ('on', 'off'): metrics.LogCommandParams( subcommands=[action_subcommand, versioning_arg]) else: raise CommandException(( 'Invalid subcommand "%s" for the %s command.\n' 'See "gsutil help %s".') % ( action_subcommand, self.command_name, self.command_name)) func() return 0