Commit 2dcc48f6 authored by gj4210's avatar gj4210 👽
Browse files

Merge branch 'new_interface' of git.scc.kit.edu:scc-net/net-suite/net-suite into new_interface

parents ae8e6d86 6c600738
[submodule "net_suite/modules/dhcp_leases"]
path = net_suite/modules/dhcp_leases
url = git@git.scc.kit.edu:scc-net/net-suite/net-suite-dhcp_leases.git
[submodule "net_suite/modules/dnsvs"]
path = net_suite/modules/dnsvs
url = git@git.scc.kit.edu:scc-net/net-suite/net-suite-dnsvs.git
[submodule "net_suite/modules/macfinder"]
path = net_suite/modules/macfinder
url = git@git.scc.kit.edu:scc-net/net-suite/net-suite-macfinder.git
......
......@@ -28,8 +28,7 @@ LOGIN_URL = 'login_api.login'
# LOGIN_URL = 'login_db.login'
# moduels ans their 'mountpoints'
MODULES = [{'mod': 'net_suite.modules.dnsvs', 'url': '/dnsvs'}]
DEFAULT_URL = 'dnsvs.vs'
MODULES = []
MINIDHCPVS_DB = 'mac_addrs'
MINIDHCPVS_USER = 'lease_reader'
......
......@@ -10,7 +10,7 @@ import sys
import os
import inspect
import subprocess
from .model import DBObject, MetaDBObject, Transaction
from .model import DBObject, MetaDBObject
import importlib
import kitnet.lib.netdd
import kitnet.lib.host_oper_mode_data
......@@ -44,10 +44,6 @@ class ModMetaData(object):
self.is_tool = is_tool
def my_finalize(thing):
return thing if thing is not None else ''
class CustomJSONEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, DBObject):
......@@ -58,8 +54,6 @@ class CustomJSONEncoder(JSONEncoder):
return str(obj)
elif isinstance(obj, ModMetaData):
return {k: v for (k, v) in obj.__dict__.items() if 'func' not in k}
elif isinstance(obj, Transaction):
return {k:v for (k,v) in obj.__dict__.items() if not callable(v)}
elif isinstance(obj, kitnet.lib.host_oper_mode_data.Loader):
return {'is_devel': obj.OP_ENV_IS_DEVEL, 'is_prod': obj.OP_ENV_IS_PROD, 'is_test': obj.OP_ENV_IS_TEST,
'mode': obj.OP_ENV_MODE}
......@@ -70,27 +64,11 @@ class CustomJSONEncoder(JSONEncoder):
class MyApp(Flask):
def __init__(self):
Flask.__init__(self, __name__)
self.jinja_loader = jinja2.ChoiceLoader([
self.jinja_loader,
jinja2.PrefixLoader({}, delimiter="/")
])
def create_global_jinja_loader(self):
return self.jinja_loader
def register_blueprint(self, **kwargs):
Flask.register_blueprint(self, **kwargs)
self.jinja_loader.loaders[1].mapping[kwargs['blueprint'].name] = kwargs['blueprint'].jinja_loader
pass
# Define the WSGI application object
app = MyApp()
app.jinja_env.add_extension('jinja2.ext.do')
app = MyApp(__name__)
app.json_encoder = CustomJSONEncoder
Compress(app)
Breadcrumbs(app=app)
app.wsgi_app = SessionMiddleware(app.wsgi_app, session_opts)
# ldap_helper = kitnet.lib.idmldap.Helper(kitnet.lib.idmldap.CfgLdr())
......@@ -98,16 +76,6 @@ app.wsgi_app = SessionMiddleware(app.wsgi_app, session_opts)
db = PostgreSQL()
db_conn = db.connect()
app.jinja_env.finalize = my_finalize
def resolve_menu(menu_dict):
for k, v in menu_dict.items():
if type(v) is dict:
resolve_menu(v)
else:
menu_dict[k] = url_for(v)
def get_git_version(path):
try:
......@@ -118,7 +86,6 @@ def get_git_version(path):
return 'unknown'
MENU = collections.OrderedDict()
VERSION = get_git_version(__file__)
MODS = list()
......@@ -134,12 +101,6 @@ def load_mods():
app.register_blueprint(blueprint=getattr(mod, m['mod'].split('.')[-1]),
url_prefix='{prefix}{url}'.format(prefix='/tools' if mod.METADATA.is_tool else '',
url=m['url']))
if not mod.METADATA.is_tool:
MENU.update(mod.MENU)
else:
if 'Tools' not in MENU:
MENU['Tools'] = dict()
MENU['Tools'].update(mod.MENU)
def update_and_load_datadict():
......@@ -158,32 +119,9 @@ def finalize_init():
db_conn.close()
@app.context_processor
def inject_colnames():
return dict(colnames=colnames)
@app.route('/api/colnames')
def api_colnames():
return jsonify(colnames)
@app.context_processor
def inject_date():
return dict(date=datetime.datetime.now())
_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')
@app.template_filter()
@evalcontextfilter
def nl2br(eval_ctx, value):
result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n') \
for p in _paragraph_re.split(escape(value)))
if eval_ctx.autoescape:
result = Markup(result)
return result
from . import views
from .model import *
from flask import render_template
class DBAction(object):
def __init__(self, transaction_sql, params_dict, name, ref_link=None):
self.transaction_sql = transaction_sql
self.reindexed_sql = None
self.name = name
self.params_dict = params_dict
self.ref_link = ref_link
self.last_error = None
def render(self):
return render_template('transactions/generic.html', name=self.name, ref_link=self.ref_link)
class AddAction(DBAction):
def __init__(self, transaction_sql, params_dict, name=None, type=None):
super().__init__(transaction_sql=transaction_sql, params_dict=params_dict, name=name, ref_link=None)
self.type = type
def render(self):
return render_template('transactions/add.html', name=self.name, add_type=self.type)
class DeleteAction(DBAction):
def __init__(self, transaction_sql, params_dict, name=None, type=None):
super().__init__(transaction_sql=transaction_sql, params_dict=params_dict, name=name, ref_link=None)
self.type = type
def render(self):
return render_template('transactions/delete.html', name=self.name, add_type=self.type)
class EditAction(DBAction):
def __init__(self, transaction_sql, params_dict, name=None, type=None):
super().__init__(transaction_sql=transaction_sql, params_dict=params_dict, name=name, ref_link=None)
self.type = type
def render(self):
return render_template('transactions/edit.html', name=self.name, add_type=self.type)
class DeleteRecordAction(DeleteAction):
def __init__(self, rr_data, inttype, fqdn):
stmts = [{'name': 'fqdn', 'old_value': fqdn},
{'name': 'data', 'old_value': rr_data},
{'name': 'inttype', 'old_value': inttype}]
query = """
'dns',
'record',
'delete',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict, type='RR', name=rr_data)
self.rr_data = rr_data
self.inttype = inttype
self.fqdn = fqdn
def render(self):
return render_template('transactions/delete_record.html', rr_data=self.rr_data, inttype=self.inttype,
fqdn=self.fqdn)
class AddRecordAction(DeleteAction):
def __init__(self, with_description, rr_data, inttype, fqdn, fqdn_description):
stmts = [{'name': 'fqdn', 'new_value': fqdn},
{'name': 'data', 'new_value': rr_data},
{'name': 'inttype', 'new_value': inttype}]
if with_description:
stmts.append({'name': 'fqdn_description', 'new_value': fqdn_description})
query = """
'dns',
'record',
'create',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict, type='RR', name=rr_data)
self.rr_data = rr_data
self.inttype = inttype
self.fqdn = fqdn
def render(self):
return render_template('transactions/add_record.html', rr_data=self.rr_data, inttype=self.inttype,
fqdn=self.fqdn)
class EditRecordAction(EditAction):
def __init__(self, old_rr_data, new_rr_data, old_inttype, new_inttype, old_fqdn, new_fqdn):
stmts = [{'name': 'fqdn', 'old_value': old_fqdn, 'new_value': new_fqdn},
{'name': 'data', 'old_value': old_rr_data,
'new_value': new_rr_data},
{'name': 'inttype', 'old_value': old_inttype.name, 'new_value': new_inttype},
]
query = """
'dns',
'record',
'update',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict)
self.old_rr_data = old_rr_data
self.new_rr_data = new_rr_data
self.new_inttype = new_inttype
self.old_fqdn = old_fqdn
self.new_fqdn = new_fqdn # currently not used
self.old_inttype = old_inttype
self.rectype = old_inttype.name.split(',')[-1]
def render(self):
return render_template('transactions/edit_record.html', old_inttype=self.old_inttype,
new_inttype=self.new_inttype, new_rr_data=self.new_rr_data, old_rr_data=self.old_rr_data,
fqdn=self.old_fqdn, rectype=self.rectype)
class AddMgrsAction(AddAction):
def __init__(self, mgrs, area):
stmts = [{'name': 'mgr_login_name_list', 'new_value': mgrs},
{'name': 'range_name', 'old_value': area.print_name}]
query = """
'dns',
'mgr2range',
'bulk_update',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict)
self.area = area
self.mgrs = mgrs
def render(self):
return render_template('transactions/add_mgrs.html', mgrs=self.mgrs, area=self.area)
class DeleteMgrsAction(DeleteAction):
def __init__(self, mgrs, area):
stmts = [{'name': 'mgr_login_name_list', 'old_value': mgrs},
{'name': 'range_name', 'old_value': area.print_name}]
query = """
'dns',
'mgr2range',
'bulk_update',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict)
self.area = area
self.mgrs = mgrs
def render(self):
return render_template('transactions/del_mgrs.html', mgrs=self.mgrs, area=self.area)
class DeleteFQDNAction(DeleteAction):
def __init__(self, fqdn, force_del_ref_records=False, do_del_pqdn=False, inttype=None):
stmts = [
{'name': 'value', 'old_value': fqdn},
{'name': 'force_del_ref_records', 'old_value': force_del_ref_records},
{'name': 'do_del_pqdn', 'old_value': do_del_pqdn},
]
query = """
'dns',
'fqdn',
'delete',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict)
self.force_del_ref_records = force_del_ref_records
self.do_del_pqdn = do_del_pqdn
self.fqdn = fqdn
self.inttype = inttype
def render(self):
return render_template('transactions/delete_fqdn.html', fqdn=self.fqdn,
inttype=self.inttype, do_del_pqdn=self.do_del_pqdn,
force_del_ref_records=self.force_del_ref_records)
class AddFQDNAction(AddAction):
def __init__(self, fqdn, description, inttype):
stmts = [
{'name': 'description', 'new_value': description},
{'name': 'inttype', 'new_value': inttype},
{'name': 'value', 'new_value': fqdn},
]
query = """
'dns',
'fqdn',
'create',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict)
self.fqdn = fqdn
self.description = description
self.inttype = inttype
def render(self):
return render_template('transactions/add_fqdn.html', fqdn=self.fqdn, description=self.description,
inttype=self.inttype)
class EditFQDNAction(EditAction):
def __init__(self, old_fqdn, new_description, old_description, new_fqdn=None, old_inttype=None, new_inttype=None):
if new_inttype == old_inttype == new_fqdn and old_inttype is None:
stmts = [
{'name': 'value', 'old_value': old_fqdn, 'new_value': old_fqdn}, # FIXME if net-suite#91 is fixed
{'name': 'description', 'new_value': new_description}
]
new_fqdn = old_fqdn
old_inttype = new_inttype
else:
stmts = [
{'name': 'description', 'new_value': new_description},
{'name': 'inttype', 'new_value': new_inttype},
{'name': 'value', 'old_value': old_fqdn, 'new_value': new_fqdn},
]
query = """
'dns',
'fqdn',
'update',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict)
self.old_fqdn = old_fqdn
self.new_fqdn = new_fqdn
self.old_description = old_description if not old_description == '' else None
self.new_description = new_description if not old_description == '' else None
self.old_inttype = old_inttype
self.new_inttype = new_inttype
def render(self):
return render_template('transactions/edit_fqdn.html', old_fqdn=self.old_fqdn, new_fqdn=self.new_fqdn,
old_description=self.old_description, new_description=self.new_description,
old_inttype=self.old_inttype, new_inttype=self.new_inttype)
class DeleteDomainsAction(DeleteAction):
def __init__(self, domains, area):
stmts = [{'name': 'fqdn_value_list', 'old_value': domains},
{'name': 'range_name', 'old_value': area.print_name}]
query = """
'dns',
'domain2range',
'bulk_update',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict)
self.domains = domains
self.area = area
def render(self):
return render_template('transactions/delete_domains.html', area=self.area, domains=self.domains)
class AddDomainsAction(AddAction):
def __init__(self, domains, area):
stmts = [{'name': 'fqdn_value_list', 'new_value': domains},
{'name': 'range_name', 'old_value': area.print_name}]
query = """
'dns',
'domain2range',
'bulk_update',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict)
self.domains = domains
self.area = area
def render(self):
return render_template('transactions/add_domains.html', area=self.area, domains=self.domains)
class EditAreaDescriptionAction(EditAction):
def __init__(self, area, new_description):
stmts = [{'name': 'description', 'new_value': new_description},
{'name': 'name', 'old_value': area.print_name}]
query = """
'dns',
'range',
'update',
{stmts}::json[],
'{{}}'
"""
params_dict = {'stmts': [json.dumps(s) for s in stmts]}
super().__init__(transaction_sql=query, params_dict=params_dict)
self.area = area
self.new_description = new_description
def render(self):
return render_template('transactions/edit_area_description.html', area=self.area,
new_description=self.new_description)
import datetime
import json
import dns.name
from .actions import *
import postgresql
import ipaddress
import requests
class BooleanSearchFilter(object):
def __init__(self, name, default, form_name):
......@@ -82,92 +83,6 @@ class RRType(MetaDBObject):
return [RRType(**r) for r in rr_types]
class Transaction(object):
def __init__(self):
self.plan = list()
def add_action(self, action):
if action is not None:
self.plan.append(action)
def execute(self, db, connection, login_name, dry_run=False):
if len(self.plan) == 0:
return
params_dict = {'login_name': login_name, 'dry': dry_run}
prefix = 0
for p in self.plan: # reindex placeholder to avoid conflicts
p.last_error = None
keys = [str(prefix) + k for k in p.params_dict.keys()]
p.reindexed_sql = p.transaction_sql.format(
**{k: '{' + v + '}' for k, v in list(zip(p.params_dict.keys(), keys))})
params_dict.update({k: v for k, v in list(zip(keys, p.params_dict.values()))})
prefix += 1
query = """
select wapi.data_importer(
in_login_name => {{login_name}},
in_version_name => 'release',
in_stmt_list => array[{stmts}],
in_report_stmt_pos => true,
in_is_dry_mode => {{dry}}
);
""".format(
stmts=',\n'.join(['row({})::wapi.imp_ta_stmt_rec_type'.format(p.reindexed_sql) for p in self.plan]))
params_dict = self.__nullify_rec(params_dict)
try:
db.execute(connection, query.replace('{}', '{{}}'), params_dict)
except postgresql.exceptions.Exception as e:
if 'hint' not in e.details:
raise e
err = json.loads(e.details['hint'])
packs = err['user_params_list']
for p in packs:
if p['fpkg'] == 'wapi' and p['fname'] == 'exec_data_importer':
for param in p['kv_list']:
if param['wapi_name'] == 'pos':
self.plan[int(param['val_wi']) - 1].last_error = err
break
break
raise e
def __nullify_rec(self, p):
if p is None:
return None
if type(p) == list:
for i in range(len(p)):
if p[i] == '':
p[i] = None
else:
p[i] = self.__nullify_rec(p[i])
return p
elif type(p) == dict:
for k, v in p.items():
if v == '':
p[k] = None
else:
p[k] = self.__nullify_rec(v)
return p
else:
try:
data = json.loads(p)
p = json.dumps(self.__nullify_rec(data))
except:
if p == '':
return None
return p
def swap(self, old, new):
tmp = self.plan[new]
self.plan[new] = self.plan[old]
self.plan[old] = tmp
def delete(self, index):
del self.plan[index]
def save(self, name, db, connection, login_name): # TODO
raise NotImplementedError()
class EVLogEntry(DBObject):
TABLE = 'v_evlog_dflt_top_n'
......@@ -597,21 +512,6 @@ class DBNetArea(DBObject, NetArea):
{'range': self.key_nr})
return [DNSAddr(**r) for r in res]
def delete_domains(self, domains):
return DeleteDomainsAction(domains=domains, area=self)
def add_domains(self, domains):
return AddDomainsAction(domains=domains, area=self)
def remove_mgrs(self, mgrs):
return DeleteMgrsAction(area=self, mgrs=mgrs)
def add_mgrs(self, mgrs):
return AddMgrsAction(mgrs=mgrs, area=self)
def update_description(self, description):
return EditAreaDescriptionAction(area=self, new_description=description)
@staticmethod
def get_area_utilization(db, connection, login, areas):
rest = dict()
......@@ -695,26 +595,6 @@ class RR(MetaDBObject):
return None
return {'NTree': NTree(**_marshal_dict(res[0], NTree)), 'rr': RR(**_marshal_dict(res[0], RR))}
def update_rr(self, old_fqdn, new_fqdn, rr_data, rr_data_unref, inttype):
rr = str(rr_data_unref + ' ' + rr_data) if rr_data_unref != '' else rr_data
if rr == self.rr_data and inttype == self.inttype.name and old_fqdn == new_fqdn:
return None
return EditRecordAction(new_rr_data=rr, old_inttype=self.inttype, new_inttype=inttype, new_fqdn=new_fqdn,
old_fqdn=old_fqdn,
old_rr_data=self.rr_data)