diff --git a/lib/hawat/blueprints/networks/__init__.py b/lib/hawat/blueprints/networks/__init__.py index 9282752c68cd9920e0903c309f47ee2d0a9a4131..d3d7c3b195336b2b8b325cc174d2873b6a3b004c 100644 --- a/lib/hawat/blueprints/networks/__init__.py +++ b/lib/hawat/blueprints/networks/__init__.py @@ -29,8 +29,10 @@ import flask_principal from flask_babel import gettext, lazy_gettext from sqlalchemy import or_ +from sqlalchemy import text from mentat.datatype.sqldb import NetworkModel, GroupModel, ItemChangeLogModel +from mentat.datatype.internal import t_net import hawat.acl import hawat.menu @@ -110,14 +112,17 @@ class ListView(HTMLMixin, SQLAlchemyMixin, ItemListView): def build_query(query, model, form_args): # Adjust query based on text search string. if 'search' in form_args and form_args['search']: - query = query \ - .filter( - or_( - model.netname.like('%{}%'.format(form_args['search'])), - model.network.like('%{}%'.format(form_args['search'])), - model.description.like('%{}%'.format(form_args['search'])), + try: + net = t_net(form_args['search']) + query = query.filter(text("network >>= '{}'".format(str(net)))) + except ValueError: + query = query \ + .filter( + or_( + model.netname.like('%{}%'.format(form_args['search'])), + model.description.like('%{}%'.format(form_args['search'])) + ) ) - ) # Adjust query based on lower time boudary selection. if 'dt_from' in form_args and form_args['dt_from']: query = query.filter(model.createtime >= form_args['dt_from']) diff --git a/lib/hawat/migrations/versions/4fea3df63b55_convert_networks_to_ip4r_type.py b/lib/hawat/migrations/versions/4fea3df63b55_convert_networks_to_ip4r_type.py new file mode 100644 index 0000000000000000000000000000000000000000..9dad0c8c1ef0d8ba5eda169a0c77ac10e4715a92 --- /dev/null +++ b/lib/hawat/migrations/versions/4fea3df63b55_convert_networks_to_ip4r_type.py @@ -0,0 +1,24 @@ +"""Convert networks to ip4r type + +Revision ID: 4fea3df63b55 +Revises: 1c380ebe027e +Create Date: 2022-09-26 11:32:08.296165 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '4fea3df63b55' +down_revision = '1c380ebe027e' +branch_labels = None +depends_on = None + + +def upgrade(): + op.execute("ALTER TABLE networks ALTER COLUMN network TYPE iprange USING network::iprange") + + +def downgrade(): + op.execute("ALTER TABLE networks ALTER COLUMN network TYPE varchar") diff --git a/lib/mentat/datatype/sqldb.py b/lib/mentat/datatype/sqldb.py index 6735983e2ca74fa882da8ab66b9c32ecd03dc3fc..f003ed0de94a03720a6b37b8c378b14e01c4254c 100644 --- a/lib/mentat/datatype/sqldb.py +++ b/lib/mentat/datatype/sqldb.py @@ -66,6 +66,7 @@ from sqlalchemy.ext.declarative import declarative_base, declared_attr from sqlalchemy.schema import DropTable from sqlalchemy.ext.compiler import compiles from sqlalchemy.orm import validates +import sqlalchemy.types as types from werkzeug.security import generate_password_hash, check_password_hash @@ -441,6 +442,23 @@ def groupmodel_from_typeddict(structure, defaults = None): return sqlobj +class iprange(types.UserDefinedType): + cache_ok = True + + def get_col_spec(self, **kw): + return "iprange" + + def bind_processor(self, dialect): + def process(value): + return value + return process + + def result_processor(self, dialect, coltype): + def process(value): + return value + return process + + class NetworkModel(MODEL): """ Class representing network records objects within the SQL database mapped to @@ -453,7 +471,7 @@ class NetworkModel(MODEL): netname = sqlalchemy.Column(sqlalchemy.String(250), nullable = False) source = sqlalchemy.Column(sqlalchemy.String(50), nullable = False) - network = sqlalchemy.Column(sqlalchemy.String, nullable = False) + network = sqlalchemy.Column(iprange, nullable = False) description = sqlalchemy.Column(sqlalchemy.String) rank = sqlalchemy.Column(sqlalchemy.Integer) is_base = sqlalchemy.Column(sqlalchemy.Boolean, nullable = False, default = False) diff --git a/lib/mentat/datatype/test_sqldb.py b/lib/mentat/datatype/test_sqldb.py index 6c96f52ee5422c3118a563954ab27d929867ad7c..37d459d6e43ee69ecb75ef7b62374b7dba81775e 100644 --- a/lib/mentat/datatype/test_sqldb.py +++ b/lib/mentat/datatype/test_sqldb.py @@ -315,7 +315,7 @@ class TestMentatDatatypeSqldb(unittest.TestCase): for net in result.networks: self.assertTrue(net.netname in ['NET1','NET2','NET3','NET4']) self.assertTrue(net.source == 'manual') - self.assertTrue(net.network in ['192.168.0.0/24','10.0.0.0/8','::1/128','2001:ff::/64']) + self.assertTrue(net.network in ['192.168.0.0/24','10.0.0.0/8','::1','2001:ff::/64']) result = self.session.query(NetworkModel).filter(NetworkModel.netname == 'NET1').one() self.assertEqual(repr(result), "<Network(netname='NET1',network='192.168.0.0/24')>")