Esempio n. 1
0
    def _PatchIamHelperInternal(self,
                                storage_url,
                                bindings_tuples,
                                thread_state=None):

        policy = self.GetIamHelper(storage_url, thread_state=thread_state)
        (etag, bindings) = (policy.etag, policy.bindings)

        # Create a backup which is untainted by any references to the original
        # bindings.
        orig_bindings = list(bindings)

        for (is_grant, diff) in bindings_tuples:
            bindings = PatchBindings(bindings, BindingsTuple(is_grant, diff))

        if IsEqualBindings(bindings, orig_bindings):
            self.logger.info('No changes made to %s', storage_url)
            return

        policy = apitools_messages.Policy(bindings=bindings, etag=etag)

        # We explicitly wish for etag mismatches to raise an error and allow this
        # function to error out, so we are bypassing the exception handling offered
        # by IamCommand.SetIamHelper in lieu of our own handling (@Retry).
        self._SetIamHelperInternal(storage_url,
                                   policy,
                                   thread_state=thread_state)
Esempio n. 2
0
File: iam.py Progetto: vjeffz/gsutil
    def _PatchIamHelperInternal(self,
                                storage_url,
                                bindings_tuples,
                                thread_state=None):

        policy = self.GetIamHelper(storage_url, thread_state=thread_state)
        (etag, bindings) = (policy.etag, policy.bindings)

        # If any of the bindings have conditions present, raise an exception.
        # See the docstring for the IamChOnResourceWithConditionsException class
        # for more details on why we raise this exception.
        for binding in bindings:
            if binding.condition:
                message = 'Could not patch IAM policy for %s.' % storage_url
                message += '\n'
                message += '\n'.join(
                    textwrap.wrap(
                        'The resource had conditions present in its IAM policy bindings, '
                        'which is not supported by "iam ch". %s' %
                        IAM_CH_CONDITIONS_WORKAROUND_MSG))
                raise IamChOnResourceWithConditionsException(message)

        # Create a backup which is untainted by any references to the original
        # bindings.
        orig_bindings = list(bindings)

        for (is_grant, diff) in bindings_tuples:
            bindings = PatchBindings(bindings, BindingsTuple(is_grant, diff))

        if IsEqualBindings(bindings, orig_bindings):
            self.logger.info('No changes made to %s', storage_url)
            return

        policy = apitools_messages.Policy(bindings=bindings, etag=etag)

        # We explicitly wish for etag mismatches to raise an error and allow this
        # function to error out, so we are bypassing the exception handling offered
        # by IamCommand.SetIamHelper in lieu of our own handling (@Retry).
        self._SetIamHelperInternal(storage_url,
                                   policy,
                                   thread_state=thread_state)
Esempio n. 3
0
    def _SetIam(self):
        """Set IAM policy for given wildcards on the command line."""

        self.continue_on_error = False
        self.recursion_requested = False
        self.all_versions = False
        if self.sub_opts:
            for o, unused_a in self.sub_opts:
                if o in ['-r', '-R']:
                    self.recursion_requested = True
                elif o == '-f':
                    self.continue_on_error = True
                elif o == '-a':
                    self.all_versions = True
                else:
                    self.RaiseInvalidArgumentException()

        file_url = self.args[0]
        patterns = self.args[1:]

        # Load the IAM policy file and raise error if the file is invalid JSON or
        # does not exist.
        try:
            with open(file_url, 'r') as fp:
                bindings = json.loads(fp.read())
        except (IOError, ValueError):
            raise ArgumentException('Invalid IAM policy file "%s".' % file_url)

        policy = apitools_messages.Policy(bindings=bindings)

        self.everything_set_okay = True

        # This list of wildcard strings will be handled by NameExpansionIterator.
        threaded_wildcards = []

        for pattern in patterns:
            surl = StorageUrlFromString(pattern)
            if surl.IsBucket():
                if self.recursion_requested:
                    surl.object_name = '*'
                    threaded_wildcards.append(surl.url_string)
                else:
                    self.SetIamHelper(surl, policy)
            else:
                threaded_wildcards.append(surl.url_string)

        # N.B.: If threaded_wildcards contains a non-existent bucket
        # (e.g. ["gs://non-existent", "gs://existent"]), NameExpansionIterator
        # will raise an exception in iter.next. This halts all iteration, even
        # when -f is set. This behavior is also evident in acl set. This behavior
        # also appears for any exception that will be raised when iterating over
        # wildcard expansions (access denied if bucket cannot be listed, etc.).
        if threaded_wildcards:
            name_expansion_iterator = NameExpansionIterator(
                self.command_name,
                self.debug,
                self.logger,
                self.gsutil_api,
                threaded_wildcards,
                self.recursion_requested,
                all_versions=self.all_versions,
                continue_on_error=self.continue_on_error
                or self.parallel_operations,
                bucket_listing_fields=['name'])

            seek_ahead_iterator = SeekAheadNameExpansionIterator(
                self.command_name,
                self.debug,
                self.GetSeekAheadGsutilApi(),
                threaded_wildcards,
                self.recursion_requested,
                all_versions=self.all_versions)

            # We cannot curry policy along due to a Python2.6 bug; see comments in
            # IamCommand._PatchIam for more information.
            policy_it = itertools.repeat(protojson.encode_message(policy))
            self.Apply(_SetIamWrapper,
                       itertools.izip(policy_it, name_expansion_iterator),
                       _SetIamExceptionHandler,
                       fail_on_error=not self.continue_on_error,
                       seek_ahead_iterator=seek_ahead_iterator)

            self.everything_set_okay &= not GetFailureCount() > 0

        # TODO: Add an error counter for files and objects.
        if not self.everything_set_okay:
            raise CommandException('Some IAM policies could not be set.')