def fip_get_all_by_queries(queries): """Returns Floating IPs filtered by an array of queries. :param queries: array of queries "key op value" where op can be http://docs.sqlalchemy.org/en/rel_0_7/core/expression_api.html #sqlalchemy.sql.operators.ColumnOperators """ fips_query = model_query(models.FloatingIP, get_session()) oper = { '<': ['lt', lambda a, b: a >= b], '>': ['gt', lambda a, b: a <= b], '<=': ['le', lambda a, b: a > b], '>=': ['ge', lambda a, b: a < b], '==': ['eq', lambda a, b: a != b], '!=': ['ne', lambda a, b: a == b], } for query in queries: try: key, op, value = query.split(' ', 2) except ValueError: raise db_exc.BlazarDBInvalidFilter(query_filter=query) column = getattr(models.FloatingIP, key, None) if column is not None: if op == 'in': filt = column.in_(value.split(',')) else: if op in oper: op = oper[op][0] try: attr = [ e for e in ['%s', '%s_', '__%s__'] if hasattr(column, e % op) ][0] % op except IndexError: raise db_exc.BlazarDBInvalidFilterOperator( filter_operator=op) if value == 'null': value = None filt = getattr(column, attr)(value) fips_query = fips_query.filter(filt) else: raise db_exc.BlazarDBInvalidFilter(query_filter=query) return fips_query.all()
def host_get_all_by_queries(queries): """Returns hosts filtered by an array of queries. :param queries: array of queries "key op value" where op can be http://docs.sqlalchemy.org/en/rel_0_7/core/expression_api.html #sqlalchemy.sql.operators.ColumnOperators """ hosts_query = model_query(models.ComputeHost, get_session()) oper = { '<': ['lt', lambda a, b: a >= b], '>': ['gt', lambda a, b: a <= b], '<=': ['le', lambda a, b: a > b], '>=': ['ge', lambda a, b: a < b], '==': ['eq', lambda a, b: a != b], '!=': ['ne', lambda a, b: a == b], } hosts = [] for query in queries: try: key, op, value = query.split(' ', 2) except ValueError: raise db_exc.BlazarDBInvalidFilter(query_filter=query) column = getattr(models.ComputeHost, key, None) if column is not None: if op == 'in': filt = column.in_(value.split(',')) else: if op in oper: op = oper[op][0] try: attr = [ e for e in ['%s', '%s_', '__%s__'] if hasattr(column, e % op) ][0] % op except IndexError: raise db_exc.BlazarDBInvalidFilterOperator( filter_operator=op) if value == 'null': value = None filt = getattr(column, attr)(value) hosts_query = hosts_query.filter(filt) else: # looking for extra capabilities matches extra_filter = model_query( models.ComputeHostExtraCapability, get_session()).filter( models.ComputeHostExtraCapability.capability_name == key).all() if not extra_filter: raise db_exc.BlazarDBNotFound( id=key, model='ComputeHostExtraCapability') for host in extra_filter: if op in oper and oper[op][1](host.capability_value, value): hosts.append(host.computehost_id) elif op not in oper: msg = 'Operator %s for extra capabilities not implemented' raise NotImplementedError(msg % op) # We must also avoid selecting any host which doesn't have the # extra capability present. all_hosts = [h.id for h in hosts_query.all()] extra_filter_hosts = [h.computehost_id for h in extra_filter] hosts += [h for h in all_hosts if h not in extra_filter_hosts] return hosts_query.filter(~models.ComputeHost.id.in_(hosts)).all()