Ejemplo n.º 1
0
    def __call__(self):
        exclusive_start_table_name = (
            self.action_params.get(parser.Props.EXCLUSIVE_START_TABLE_NAME,
                                   None)
        )

        limit = self.action_params.get(parser.Props.LIMIT, None)

        try:
            table_names = (
                storage.list_tables(
                    self.context,
                    exclusive_start_table_name=exclusive_start_table_name,
                    limit=limit)
            )

            res = {parser.Props.TABLE_NAMES: table_names}

            if table_names and limit == len(table_names):
                res[parser.Props.LAST_EVALUATED_TABLE_NAME] = table_names[-1]

            return res
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 2
0
    def __call__(self):

        table_name = self.action_params.get(Props.TABLE_NAME, None)

        if not table_name:
            raise exception.ValidationException(
                message='Table name is not defined')

        try:
            table_meta = storage.describe_table(self.context, table_name)

            result = {
                Props.TABLE: {
                    Props.ATTRIBUTE_DEFINITIONS:
                    (Parser.format_attribute_definitions(
                        table_meta.schema.attribute_type_map)),
                    Props.CREATION_DATE_TIME:
                    0,
                    Props.ITEM_COUNT:
                    0,
                    Props.KEY_SCHEMA: (Parser.format_key_schema(
                        table_meta.schema.key_attributes)),
                    Props.PROVISIONED_THROUGHPUT:
                    (Values.PROVISIONED_THROUGHPUT_DUMMY),
                    Props.TABLE_NAME:
                    table_name,
                    Props.TABLE_STATUS:
                    (Parser.format_table_status(table_meta.status)),
                    Props.TABLE_SIZE_BYTES:
                    0
                }
            }

            if table_meta.schema.index_def_map:
                table_def = result[Props.TABLE]
                table_def[Props.LOCAL_SECONDARY_INDEXES] = (
                    Parser.format_local_secondary_indexes(
                        table_meta.schema.key_attributes[0],
                        table_meta.schema.index_def_map))
            return result

        except exception.TableNotExistsException as e:
            raise exception.ResourceNotFoundException(e.message)
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 3
0
    def __call__(self):

        table_name = self.action_params.get(Props.TABLE_NAME, None)

        try:
            table_meta = storage.describe_table(self.context, table_name)

            storage.delete_table(self.context, table_name)

            # TODO (isviridov): fill ITEM_COUNT, TABLE_SIZE_BYTES,
            # CREATION_DATE_TIME with real data
            return {
                Props.TABLE_DESCRIPTION: {
                    Props.ATTRIBUTE_DEFINITIONS: (
                        Parser.format_attribute_definitions(
                            table_meta.schema.attribute_type_map
                        )
                    ),
                    Props.CREATION_DATE_TIME: 0,
                    Props.ITEM_COUNT: 0,
                    Props.KEY_SCHEMA: (
                        Parser.format_key_schema(
                            table_meta.schema.key_attributes
                        )
                    ),
                    Props.LOCAL_SECONDARY_INDEXES: (
                        Parser.format_local_secondary_indexes(
                            table_meta.schema.key_attributes[0],
                            table_meta.schema.index_def_map
                        )
                    ),
                    Props.PROVISIONED_THROUGHPUT: (
                        Values.PROVISIONED_THROUGHPUT_DUMMY
                    ),
                    Props.TABLE_NAME: table_name,
                    Props.TABLE_STATUS: Parser.format_table_status(
                        table_meta.status
                    ),
                    Props.TABLE_SIZE_BYTES: 0
                }
            }
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 4
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # get attributes_to_get
            attributes_to_get = self.action_params.get(
                parser.Props.ATTRIBUTES_TO_GET, None)

            select_type = (models.SelectType.all()
                           if attributes_to_get is None else
                           models.AttributeToGet.specified(attributes_to_get))

            # parse key_attributes
            key_attributes = parser.Parser.parse_item_attributes(
                self.action_params[parser.Props.KEY])

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get  to schema expectation

            consistent_read = self.action_params.get(
                parser.Props.CONSISTENT_READ, False)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)

            # format conditions to get item
            indexed_condition_map = {
                name: [models.IndexedCondition.eq(value)]
                for name, value in key_attributes.iteritems()
            }
        except Exception:
            raise exception.ValidationException()

        try:
            # get item
            result = storage.select_item(self.context,
                                         table_name,
                                         indexed_condition_map,
                                         select_type=select_type,
                                         limit=2,
                                         consistent=consistent_read)

            # format response
            if result.count == 0:
                return {}

            assert result.count == 1

            response = {
                parser.Props.ITEM:
                parser.Parser.format_item_attributes(result.items[0])
            }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 5
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # parse expected item conditions
            expected_item_conditions = (
                parser.Parser.parse_expected_attribute_conditions(
                    self.action_params.get(parser.Props.EXPECTED, {})))

            # parse item
            key_attributes = parser.Parser.parse_item_attributes(
                self.action_params[parser.Props.KEY])

            # parse return_values param
            return_values = self.action_params.get(
                parser.Props.RETURN_VALUES, parser.Values.RETURN_VALUES_NONE)

            # parse return_item_collection_metrics
            return_item_collection_metrics = self.action_params.get(
                parser.Props.RETURN_ITEM_COLLECTION_METRICS,
                parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)
        except Exception:
            raise AWSValidationException()

        try:
            # put item
            result = storage.delete_item(
                self.context,
                table_name,
                key_attributes,
                expected_condition_map=expected_item_conditions)
        except AWSErrorResponseException as e:
            raise e
        except Exception:
            raise AWSErrorResponseException()

        if not result:
            raise AWSErrorResponseException()

        # format response
        response = {}

        try:
            if return_values != parser.Values.RETURN_VALUES_NONE:
                # TODO(dukhlov):
                # It is needed to return all deleted item attributes
                #
                response[parser.Props.ATTRIBUTES] = (
                    parser.Parser.format_item_attributes(key_attributes))

            if (return_item_collection_metrics !=
                    parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE):
                response[parser.Props.ITEM_COLLECTION_METRICS] = {
                    parser.Props.ITEM_COLLECTION_KEY: {
                        parser.Parser.format_item_attributes(
                            models.AttributeValue(models.ATTRIBUTE_TYPE_STRING,
                                                  "key"))
                    },
                    parser.Props.SIZE_ESTIMATED_RANGE_GB: [0]
                }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            return response
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 6
0
    def _authorize(self, req, auth_uri):
        # Read request signature and access id.
        # If we find X-Auth-User in the headers we ignore a key error
        # here so that we can use both authentication methods.
        # Returning here just means the user didn't supply AWS
        # authentication and we'll let the app try native keystone next.
        logger.info(_("Checking AWS credentials.."))

        signature = self._get_signature(req)
        if not signature:
            if 'X-Auth-User' in req.headers:
                return self.application
            elif 'X-Auth-Token' in req.headers:
                return self.application
            else:
                logger.info(_("No AWS Signature found."))
                raise exception.IncompleteSignatureException()

        access = self._get_access(req)
        if not access:
            if 'X-Auth-User' in req.headers:
                return self.application
            else:
                logger.info(_("No AWSAccessKeyId/Authorization Credential"))
                raise exception.IncompleteSignatureException()

        logger.info(_("AWS credentials found, checking against keystone."))

        if not auth_uri:
            logger.error(
                _("Ec2Token authorization failed, no auth_uri "
                  "specified in config file"))
            raise exception.AWSErrorResponseException(
                _('Service misconfigured'))
        # Make a copy of args for authentication and signature verification.
        auth_params = dict(req.params)
        # 'Signature' param Not part of authentication args
        auth_params.pop('Signature', None)

        # Authenticate the request.
        # AWS v4 authentication requires a hash of the body
        body_hash = hashlib.sha256(req.body).hexdigest()
        creds = {
            'ec2Credentials': {
                'access': access,
                'signature': signature,
                'host': req.host,
                'verb': req.method,
                'path': req.path,
                'params': auth_params,
                'headers': req.headers,
                'body_hash': body_hash
            }
        }
        creds_json = json.dumps(creds)
        headers = {'Content-Type': 'application/json'}

        keystone_ec2_uri = self._conf_get_keystone_ec2_uri(auth_uri)
        logger.info(_('Authenticating with %s') % keystone_ec2_uri)
        response = requests.post(keystone_ec2_uri,
                                 data=creds_json,
                                 headers=headers)
        result = response.json()
        try:
            token_id = result['access']['token']['id']
            tenant = result['access']['token']['tenant']['name']
            tenant_id = result['access']['token']['tenant']['id']
            logger.info(_("AWS authentication successful."))
        except (AttributeError, KeyError):
            logger.info(_("AWS authentication failure."))
            # Try to extract the reason for failure so we can return the
            # appropriate AWS error via raising an exception
            try:
                reason = result['error']['message']
            except KeyError:
                reason = None

            if reason == "EC2 access key not found.":
                raise exception.InvalidClientTokenIdError()
            elif reason == "EC2 signature not supplied.":
                raise exception.SignatureError()
            else:
                raise exception.AccessDeniedError()

        # Authenticated!
        ec2_creds = {
            'ec2Credentials': {
                'access': access,
                'signature': signature
            }
        }
        req.headers['X-Auth-EC2-Creds'] = json.dumps(ec2_creds)
        req.headers['X-Auth-Token'] = token_id
        req.headers['X-Tenant-Name'] = tenant
        req.headers['X-Tenant-Id'] = tenant_id
        req.headers['X-Auth-URL'] = auth_uri

        metadata = result['access'].get('metadata', {})
        roles = metadata.get('roles', [])
        req.headers['X-Roles'] = ','.join(roles)

        return self.application
Ejemplo n.º 7
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # parse expected item conditions
            expected_item_conditions = (
                parser.Parser.parse_expected_attribute_conditions(
                    self.action_params.get(parser.Props.EXPECTED, {})))

            #parse attribute updates
            attribute_updates = parser.Parser.parse_attribute_updates(
                self.action_params.get(parser.Props.ATTRIBUTE_UPDATES, {}))

            # parse key
            key_attributes = parser.Parser.parse_item_attributes(
                self.action_params[parser.Props.KEY])

            # parse return_values param
            return_values = self.action_params.get(
                parser.Props.RETURN_VALUES, parser.Values.RETURN_VALUES_NONE)

            # parse return_item_collection_metrics
            return_item_collection_metrics = self.action_params.get(
                parser.Props.RETURN_ITEM_COLLECTION_METRICS,
                parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)

            select_result = None

            indexed_condition_map_for_select = {
                name: models.IndexedCondition.eq(value)
                for name, value in key_attributes.iteritems()
            }
        except Exception:
            raise exception.ValidationException()

        try:
            if return_values in (parser.Values.RETURN_VALUES_UPDATED_OLD,
                                 parser.Values.RETURN_VALUES_ALL_OLD):

                select_result = storage.select_item(
                    self.context, table_name, indexed_condition_map_for_select)

            # update item
            result = storage.update_item(
                self.context,
                table_name,
                key_attribute_map=key_attributes,
                attribute_action_map=attribute_updates,
                expected_condition_map=expected_item_conditions)

            if not result:
                raise exception.AWSErrorResponseException()

            if return_values in (parser.Values.RETURN_VALUES_UPDATED_NEW,
                                 parser.Values.RETURN_VALUES_ALL_NEW):

                select_result = storage.select_item(
                    self.context, table_name, indexed_condition_map_for_select)

            # format response
            response = {}

            if return_values != parser.Values.RETURN_VALUES_NONE:
                response[parser.Props.ATTRIBUTES] = (
                    parser.Parser.format_item_attributes(
                        select_result.items[0]))

            if (return_item_collection_metrics !=
                    parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE):
                response[parser.Props.ITEM_COLLECTION_METRICS] = {
                    parser.Props.ITEM_COLLECTION_KEY: {
                        parser.Parser.format_item_attributes(
                            models.AttributeValue(models.ATTRIBUTE_TYPE_STRING,
                                                  "key"))
                    },
                    parser.Props.SIZE_ESTIMATED_RANGE_GB: [0]
                }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 8
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # parse select_type
            attributes_to_get = self.action_params.get(
                parser.Props.ATTRIBUTES_TO_GET, None)
            if attributes_to_get is not None:
                attributes_to_get = frozenset(attributes_to_get)

            select = self.action_params.get(parser.Props.SELECT, None)

            index_name = self.action_params.get(parser.Props.INDEX_NAME, None)

            select_type = parser.Parser.parse_select_type(
                select, attributes_to_get, index_name)

            # parse exclusive_start_key_attributes
            exclusive_start_key_attributes = self.action_params.get(
                parser.Props.EXCLUSIVE_START_KEY, None)
            if exclusive_start_key_attributes is not None:
                exclusive_start_key_attributes = (
                    parser.Parser.parse_item_attributes(
                        exclusive_start_key_attributes))

            # parse indexed_condition_map
            indexed_condition_map = parser.Parser.parse_attribute_conditions(
                self.action_params.get(parser.Props.KEY_CONDITIONS, None))

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get to schema expectation

            consistent_read = self.action_params.get(
                parser.Props.CONSISTENT_READ, False)

            limit = self.action_params.get(parser.Props.LIMIT, None)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)

            order_asc = self.action_params.get(parser.Props.SCAN_INDEX_FORWARD,
                                               None)

            order_type = (None if order_asc is None else models.ORDER_TYPE_ASC
                          if order_asc else models.ORDER_TYPE_DESC)
        except Exception:
            raise exception.ValidationException()

        try:
            # select item
            result = storage.select_item(
                self.context,
                table_name,
                indexed_condition_map,
                select_type=select_type,
                index_name=index_name,
                limit=limit,
                consistent=consistent_read,
                order_type=order_type,
                exclusive_start_key=exclusive_start_key_attributes)

            # format response
            if select_type.type == models.SelectType.SELECT_TYPE_COUNT:
                response = {parser.Props.COUNT: result.count}
            else:
                response = {
                    parser.Props.COUNT:
                    result.count,
                    parser.Props.ITEMS: [
                        parser.Parser.format_item_attributes(row)
                        for row in result.items
                    ]
                }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            if limit == result.count:
                response[parser.Props.LAST_EVALUATED_KEY] = (
                    parser.Parser.format_item_attributes(
                        result.last_evaluated_key))
            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 9
0
    def __call__(self):
        try:
            #TODO ikhudoshyn: table_name may be index name
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            attrs_to_get = self.action_params.get(
                parser.Props.ATTRIBUTES_TO_GET, None)

            select = self.action_params.get(parser.Props.SELECT, None)

            select_type = parser.Parser.parse_select_type(select, attrs_to_get)

            limit = self.action_params.get(parser.Props.LIMIT, None)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)

            exclusive_start_key = self.action_params.get(
                parser.Props.EXCLUSIVE_START_KEY, None)

            exclusive_start_key = parser.Parser.parse_item_attributes(
                exclusive_start_key) if exclusive_start_key else None

            scan_filter = self.action_params.get(parser.Props.SCAN_FILTER, {})

            condition_map = parser.Parser.parse_attribute_conditions(
                scan_filter)

            segment = self.action_params.get(parser.Props.SEGMENT, 0)
            total_segments = self.action_params.get(
                parser.Props.TOTAL_SEGMENTS, 1)

            assert segment < total_segments
        except Exception:
            raise exception.AWSErrorResponseException()

        try:
            result = storage.scan(self.context,
                                  table_name,
                                  condition_map,
                                  attributes_to_get=attrs_to_get,
                                  limit=limit,
                                  exclusive_start_key=exclusive_start_key)

            response = {
                parser.Props.COUNT: result.count,
                parser.Props.SCANNED_COUNT: result.scanned_count
            }

            if not select_type.is_count:
                response[parser.Props.ITEMS] = [
                    parser.Parser.format_item_attributes(row)
                    for row in result.items
                ]

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            if result.last_evaluated_key:
                response[parser.Props.LAST_EVALUATED_KEY] = (
                    parser.Parser.format_item_attributes(
                        result.last_evaluated_key))

            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
Ejemplo n.º 10
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            #parse table attributes
            attribute_definitions = parser.Parser.parse_attribute_definitions(
                self.action_params.get(parser.Props.ATTRIBUTE_DEFINITIONS, {})
            )

            #parse table key schema
            key_attrs = parser.Parser.parse_key_schema(
                self.action_params.get(parser.Props.KEY_SCHEMA, [])
            )

            #parse table indexed field list
            indexed_def_map = parser.Parser.parse_local_secondary_indexes(
                self.action_params.get(
                    parser.Props.LOCAL_SECONDARY_INDEXES, [])
            )

            #prepare table_schema structure
            table_schema = models.TableSchema(
                attribute_definitions, key_attrs, indexed_def_map
            )

        except Exception:
            raise exception.ValidationException()

        try:
            # creating table
            table_meta = storage.create_table(
                self.context, table_name, table_schema
            )

            result = {
                parser.Props.TABLE_DESCRIPTION: {
                    parser.Props.ATTRIBUTE_DEFINITIONS: (
                        parser.Parser.format_attribute_definitions(
                            table_meta.schema.attribute_type_map
                        )
                    ),
                    parser.Props.CREATION_DATE_TIME: 0,
                    parser.Props.ITEM_COUNT: 0,
                    parser.Props.KEY_SCHEMA: (
                        parser.Parser.format_key_schema(
                            table_meta.schema.key_attributes
                        )
                    ),
                    parser.Props.PROVISIONED_THROUGHPUT: (
                        parser.Values.PROVISIONED_THROUGHPUT_DUMMY
                    ),
                    parser.Props.TABLE_NAME: table_name,
                    parser.Props.TABLE_STATUS: (
                        parser.Parser.format_table_status(table_meta.status)
                    ),
                    parser.Props.TABLE_SIZE_BYTES: 0
                }
            }

            if table_meta.schema.index_def_map:
                table_def = result[parser.Props.TABLE_DESCRIPTION]
                table_def[parser.Props.LOCAL_SECONDARY_INDEXES] = (
                    parser.Parser.format_local_secondary_indexes(
                        table_meta.schema.key_attributes[0],
                        table_meta.schema.index_def_map
                    )
                )

            return result
        except exception.TableAlreadyExistsException:
            raise exception.ResourceInUseException()
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()