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()
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()
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()
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()
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()
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
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()
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()
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()
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()