Esempio n. 1
0
    def on_post(self, keystone_id, **kwargs):

        project = res.get_or_create_project(keystone_id, self.project_repo)

        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start on_post...%s', data)

        new_container = models.Container(data)
        new_container.tenant_id = project.id

        # TODO(hgedikli): performance optimizations
        for secret_ref in new_container.container_secrets:
            secret = self.secret_repo.get(entity_id=secret_ref.secret_id,
                                          keystone_id=keystone_id,
                                          suppress_exception=True)
            if not secret:
                # This only partially localizes the error message and
                # doesn't localize secret_ref.name.
                pecan.abort(404, u._("Secret provided for '{0}' doesn't"
                                     " exist.").format(secret_ref.name))

        self.container_repo.create_from(new_container)

        pecan.response.status = 201
        pecan.response.headers['Location'] = '/containers/{0}'.format(
            new_container.id
        )
        url = hrefs.convert_container_to_href(new_container.id)
        return {'container_ref': url}
Esempio n. 2
0
    def on_patch(self, external_project_id, **kwargs):
        """Handles update of existing container acl requests.

        At least one container ACL needs to exist for update to proceed.
        In update, multiple operation ACL payload can be specified as
        mentioned in sample below. A specific ACL can be updated by its
        own id via ContainerACLController patch request.

        {
          "read":{
            "users":[
              "5ecb18f341894e94baca9e8c7b6a824a",
              "20b63d71f90848cf827ee48074f213b7",
              "c7753f8da8dc4fbea75730ab0b6e0ef4"
            ]
          },
          "write":{
            "users":[
              "5ecb18f341894e94baca9e8c7b6a824a"
            ],
            "project-access":false
          }
        }
        """
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start ContainerACLsController on_patch...%s', data)

        existing_acls_map = {
            acl.operation: acl
            for acl in self.container.container_acls
        }
        for operation in itertools.ifilter(lambda x: data.get(x),
                                           validators.ACL_OPERATIONS):
            project_access = data[operation].get('project-access')
            user_ids = data[operation].get('users')
            if operation in existing_acls_map:  # update if matching acl exists
                c_acl = existing_acls_map[operation]
                if project_access is not None:
                    c_acl.project_access = project_access
            else:
                c_acl = models.ContainerACL(self.container.id,
                                            operation=operation,
                                            project_access=project_access)
            self.acl_repo.create_or_replace_from(self.container,
                                                 container_acl=c_acl,
                                                 user_ids=user_ids)

        acl_ref = '{0}/acl'.format(
            hrefs.convert_container_to_href(self.container.id))
        return {'acl_ref': acl_ref}
Esempio n. 3
0
    def on_patch(self, external_project_id, **kwargs):
        """Handles update of existing container acl requests.

        At least one container ACL needs to exist for update to proceed.
        In update, multiple operation ACL payload can be specified as
        mentioned in sample below. A specific ACL can be updated by its
        own id via ContainerACLController patch request.

        {
          "read":{
            "users":[
              "5ecb18f341894e94baca9e8c7b6a824a",
              "20b63d71f90848cf827ee48074f213b7",
              "c7753f8da8dc4fbea75730ab0b6e0ef4"
            ]
          },
          "write":{
            "users":[
              "5ecb18f341894e94baca9e8c7b6a824a"
            ],
            "project-access":false
          }
        }
        """
        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start ContainerACLsController on_patch...%s', data)

        existing_acls_map = {acl.operation: acl for acl in
                             self.container.container_acls}
        for operation in six.moves.filter(lambda x: data.get(x),
                                          validators.ACL_OPERATIONS):
            project_access = data[operation].get('project-access')
            user_ids = data[operation].get('users')
            if operation in existing_acls_map:  # update if matching acl exists
                c_acl = existing_acls_map[operation]
                if project_access is not None:
                    c_acl.project_access = project_access
            else:
                c_acl = models.ContainerACL(self.container.id,
                                            operation=operation,
                                            project_access=project_access)
            self.acl_repo.create_or_replace_from(self.container,
                                                 container_acl=c_acl,
                                                 user_ids=user_ids)

        acl_ref = '{0}/acl'.format(
            hrefs.convert_container_to_href(self.container.id))
        return {'acl_ref': acl_ref}
Esempio n. 4
0
    def on_post(self, external_project_id, **kwargs):
        """Handles adding an existing secret to an existing container."""

        if self.container.type != 'generic':
            pecan.abort(400, u._("Only 'generic' containers can be modified."))

        data = api.load_body(pecan.request, validator=self.validator)

        name = data.get('name')
        secret_ref = data.get('secret_ref')
        secret_id = hrefs.get_secret_id_from_ref(secret_ref)

        secret = self.secret_repo.get(
            entity_id=secret_id,
            external_project_id=external_project_id,
            suppress_exception=True)
        if not secret:
            pecan.abort(404, u._("Secret provided doesn't exist."))

        found_container_secrets = list(
            filter(lambda cs: cs.secret_id == secret_id and cs.name == name,
                   self.container.container_secrets)
        )

        if found_container_secrets:
            pecan.abort(409, u._('Conflict. A secret with that name and ID is '
                                 'already stored in this container. The same '
                                 'secret can exist in a container as long as '
                                 'the name is unique.'))

        LOG.debug('Start container secret on_post...%s', secret_ref)
        new_container_secret = models.ContainerSecret()
        new_container_secret.container_id = self.container.id
        new_container_secret.name = name
        new_container_secret.secret_id = secret_id
        self.container_secret_repo.save(new_container_secret)

        url = hrefs.convert_container_to_href(self.container.id)
        LOG.debug(u._('URI to container is %s'), url)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url
        LOG.info(u._LI('Created a container secret for project: %s'),
                 external_project_id)

        return {'container_ref': url}
Esempio n. 5
0
    def on_post(self, external_project_id, **kwargs):
        """Handles adding an existing secret to an existing container."""

        if self.container.type != 'generic':
            pecan.abort(400, u._("Only 'generic' containers can be modified."))

        data = api.load_body(pecan.request, validator=self.validator)

        name = data.get('name')
        secret_ref = data.get('secret_ref')
        secret_id = hrefs.get_secret_id_from_ref(secret_ref)

        secret = self.secret_repo.get(
            entity_id=secret_id,
            external_project_id=external_project_id,
            suppress_exception=True)
        if not secret:
            pecan.abort(404, u._("Secret provided doesn't exist."))

        found_container_secrets = list(
            filter(lambda cs: cs.secret_id == secret_id and cs.name == name,
                   self.container.container_secrets)
        )

        if found_container_secrets:
            pecan.abort(409, u._('Conflict. A secret with that name and ID is '
                                 'already stored in this container. The same '
                                 'secret can exist in a container as long as '
                                 'the name is unique.'))

        LOG.debug('Start container secret on_post...%s', secret_ref)
        new_container_secret = models.ContainerSecret()
        new_container_secret.container_id = self.container.id
        new_container_secret.name = name
        new_container_secret.secret_id = secret_id
        self.container_secret_repo.save(new_container_secret)

        url = hrefs.convert_container_to_href(self.container.id)
        LOG.debug('URI to container is %s', url)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url
        LOG.info(u._LI('Created a container secret for project: %s'),
                 external_project_id)

        return {'container_ref': url}
Esempio n. 6
0
    def on_post(self, external_project_id, **kwargs):

        project = res.get_or_create_project(external_project_id)

        data = api.load_body(pecan.request, validator=self.validator)
        ctxt = controllers._get_barbican_context(pecan.request)
        if ctxt:  # in authenticated pipleline case, always use auth token user
            data['creator_id'] = ctxt.user

        self.quota_enforcer.enforce(project)

        LOG.debug('Start on_post...%s', data)

        new_container = models.Container(data)
        new_container.project_id = project.id

        # TODO(hgedikli): performance optimizations
        for secret_ref in new_container.container_secrets:
            secret = self.secret_repo.get(
                entity_id=secret_ref.secret_id,
                external_project_id=external_project_id,
                suppress_exception=True)
            if not secret:
                # This only partially localizes the error message and
                # doesn't localize secret_ref.name.
                pecan.abort(
                    404,
                    u._("Secret provided for '{secret_name}' doesn't "
                        "exist.").format(secret_name=secret_ref.name)
                )

        self.container_repo.create_from(new_container)

        url = hrefs.convert_container_to_href(new_container.id)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url
        LOG.info(u._LI('Created a container for project: %s'),
                 external_project_id)

        return {'container_ref': url}
Esempio n. 7
0
    def on_post(self, external_project_id, **kwargs):

        project = res.get_or_create_project(external_project_id)

        data = api.load_body(pecan.request, validator=self.validator)
        ctxt = controllers._get_barbican_context(pecan.request)
        if ctxt:  # in authenticated pipleline case, always use auth token user
            data['creator_id'] = ctxt.user

        self.quota_enforcer.enforce(project)

        LOG.debug('Start on_post...%s', data)

        new_container = models.Container(data)
        new_container.project_id = project.id

        # TODO(hgedikli): performance optimizations
        for secret_ref in new_container.container_secrets:
            secret = self.secret_repo.get(
                entity_id=secret_ref.secret_id,
                external_project_id=external_project_id,
                suppress_exception=True)
            if not secret:
                # This only partially localizes the error message and
                # doesn't localize secret_ref.name.
                pecan.abort(
                    404,
                    u._("Secret provided for '{secret_name}' doesn't "
                        "exist.").format(secret_name=secret_ref.name)
                )

        self.container_repo.create_from(new_container)

        url = hrefs.convert_container_to_href(new_container.id)

        pecan.response.status = 201
        pecan.response.headers['Location'] = url
        LOG.info(u._LI('Created a container for project: %s'),
                 external_project_id)

        return {'container_ref': url}
Esempio n. 8
0
    def on_put(self, external_project_id, **kwargs):
        """Handles update of existing container acl requests.

        Replaces existing container ACL(s) with input ACL(s) data. Existing
        ACL operation not specified in input are removed as part of update.
        For missing project-access in ACL, true is used as default.
        In update, multiple operation ACL payload can be specified as
        mentioned in sample below. A specific ACL can be updated by its
        own id via ContainerACLController patch request.

        {
          "read":{
            "users":[
              "5ecb18f341894e94baca9e8c7b6a824a",
              "20b63d71f90848cf827ee48074f213b7",
              "c7753f8da8dc4fbea75730ab0b6e0ef4"
            ]
          },
          "write":{
            "users":[
              "5ecb18f341894e94baca9e8c7b6a824a"
            ],
            "project-access":false
          }
        }

        Every container, by default, has an implicit ACL in case client has not
        defined an explicit ACL. That default ACL definition, DEFAULT_ACL,
        signifies that a container by default has project based access i.e.
        client with necessary roles on container project can access the
        container. That's why when ACL is added to a container, it always
        returns 200 (and not 201) indicating existence of implicit ACL on a
        container.
        """

        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start ContainerACLsController on_put...%s', data)

        existing_acls_map = {
            acl.operation: acl
            for acl in self.container.container_acls
        }
        for operation in itertools.ifilter(lambda x: data.get(x),
                                           validators.ACL_OPERATIONS):
            project_access = data[operation].get('project-access', True)
            user_ids = data[operation].get('users', [])
            if operation in existing_acls_map:  # update if matching acl exists
                c_acl = existing_acls_map.pop(operation)
                c_acl.project_access = project_access
            else:
                c_acl = models.ContainerACL(self.container.id,
                                            operation=operation,
                                            project_access=project_access)
            self.acl_repo.create_or_replace_from(self.container,
                                                 container_acl=c_acl,
                                                 user_ids=user_ids)
        # delete remaining existing acls as they are not present in input.
        for acl in six.itervalues(existing_acls_map):
            self.acl_repo.delete_entity_by_id(entity_id=acl.id,
                                              external_project_id=None)
        acl_ref = '{0}/acl'.format(
            hrefs.convert_container_to_href(self.container.id))
        return {'acl_ref': acl_ref}
Esempio n. 9
0
    def on_put(self, external_project_id, **kwargs):
        """Handles update of existing container acl requests.

        Replaces existing container ACL(s) with input ACL(s) data. Existing
        ACL operation not specified in input are removed as part of update.
        For missing project-access in ACL, true is used as default.
        In update, multiple operation ACL payload can be specified as
        mentioned in sample below. A specific ACL can be updated by its
        own id via ContainerACLController patch request.

        {
          "read":{
            "users":[
              "5ecb18f341894e94baca9e8c7b6a824a",
              "20b63d71f90848cf827ee48074f213b7",
              "c7753f8da8dc4fbea75730ab0b6e0ef4"
            ]
          },
          "write":{
            "users":[
              "5ecb18f341894e94baca9e8c7b6a824a"
            ],
            "project-access":false
          }
        }

        Every container, by default, has an implicit ACL in case client has not
        defined an explicit ACL. That default ACL definition, DEFAULT_ACL,
        signifies that a container by default has project based access i.e.
        client with necessary roles on container project can access the
        container. That's why when ACL is added to a container, it always
        returns 200 (and not 201) indicating existence of implicit ACL on a
        container.
        """

        data = api.load_body(pecan.request, validator=self.validator)
        LOG.debug('Start ContainerACLsController on_put...%s', data)

        existing_acls_map = {acl.operation: acl for acl in
                             self.container.container_acls}
        for operation in six.moves.filter(lambda x: data.get(x),
                                          validators.ACL_OPERATIONS):
            project_access = data[operation].get('project-access', True)
            user_ids = data[operation].get('users', [])
            if operation in existing_acls_map:  # update if matching acl exists
                c_acl = existing_acls_map.pop(operation)
                c_acl.project_access = project_access
            else:
                c_acl = models.ContainerACL(self.container.id,
                                            operation=operation,
                                            project_access=project_access)
            self.acl_repo.create_or_replace_from(self.container,
                                                 container_acl=c_acl,
                                                 user_ids=user_ids)
        # delete remaining existing acls as they are not present in input.
        for acl in existing_acls_map.values():
            self.acl_repo.delete_entity_by_id(entity_id=acl.id,
                                              external_project_id=None)
        acl_ref = '{0}/acl'.format(
            hrefs.convert_container_to_href(self.container.id))
        return {'acl_ref': acl_ref}