def login_handler(request): """ HTTP Request handler function for user login / logout requests """ session = ET.Element('session') if request.POST: action = request.POST['action'] if action == 'login': username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None and user.is_active: # Correct password, and the user is marked "active" login(request, user) session.text = username else: return HttpResponse(Response.error('login', 'Authentication Failed')) else: try: if request.session.session_key is not None and request.session.session_key != '': session_dir = ServerSettings.session_path(request.session.session_key) if os.path.exists(session_dir): logging.debug('Cleaning ' + session_dir) shutil.rmtree(session_dir) logout(request) except: logging.exception("Failed") else: logging.debug('Logout success!!') return HttpResponse(Response.success(action, 'ok', session)) return HttpResponse(Response.error('unknown', 'Invalid request!!'))
def login_handler(request): """ HTTP Request handler function for user login / logout requests """ session = ET.Element('session') if request.POST: action = request.POST['action'] if action == 'login': username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None and user.is_active: # Correct password, and the user is marked "active" login(request, user) session.text = username else: return HttpResponse(Response.error('login', 'Authentication Failed')) else: try: if request.session.session_key is not None and request.session.session_key != '': session_dir = ServerSettings.session_path(request.session.session_key) if os.path.exists(session_dir): logging.debug('Cleaning ' + session_dir) shutil.rmtree(session_dir) logout(request) except Exception as ex: print(ex.__doc__) print(ex.message) logging.debug('Login success') return HttpResponse(Response.success(action, 'ok', session)) return HttpResponse(Response.error(action, 'Invalid Request'))
def login_handler(request): """ HTTP Request handler function for user login / logout requests """ if request.POST: action = request.POST['action'] if action == 'login': username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None and user.is_active: # Correct password, and the user is marked "active" login(request, user) else: return HttpResponse(Response.error('login', 'Authentication Failed')) else: username = '' try: if request.session.session_key is not None and request.session.session_key != '': session_dir = ServerSettings.session_path(request.session.session_key) if os.path.exists(session_dir): logger.debug('Cleaning ' + session_dir) shutil.rmtree(session_dir) logout(request) except: logger.exception("Failed") else: logger.debug('Logout success!!') session = get_session_config(username) return HttpResponse(Response.success(action, 'ok', session)) return HttpResponse(Response.error('unknown', 'Invalid request!!'))
def commit_files(user, session): """ Moves compiled yang moudles to user's yang directory """ directory = ServerSettings.session_path(session) if not os.path.exists(directory): logging.error('Session storage %s does not exist' % directory) return False, None yangdst = ServerSettings.yang_path(user) cxmldst = ServerSettings.cxml_path(user) count = 0 if not os.path.exists(yangdst): logging.debug('Created ' + yangdst) os.makedirs(yangdst) if not os.path.exists(cxmldst): logging.debug('Created ' + cxmldst) os.makedirs(cxmldst) modules = ET.Element('modules') for cxmlpath in glob.glob(os.path.join(directory, '*.xml')): basename = os.path.basename(cxmlpath) if basename == 'dependencies.xml': continue base = os.path.splitext(basename)[0] yang_src_path = os.path.join(directory, base + '.yang') yang_dst_path = os.path.join(yangdst, base + '.yang') cxml_dst_path = os.path.join(cxmldst, base + '.xml') logging.debug('Committing ' + yang_src_path) if os.path.exists(yang_src_path): logging.debug('Commit ' + yang_dst_path) _clean_oldfiles(yangdst, base) _clean_oldfiles(cxmldst, base) os.rename(yang_src_path, yang_dst_path) os.rename(cxmlpath, cxml_dst_path) module = ET.Element('module') module.text = base + '.yang' modules.append(module) count += 1 # There is a update in yang modules, delete existing dependency file # so that it will be recompiled next time if count > 0: session_d = os.path.join(directory, 'dependencies.xml') if os.path.exists(session_d): logging.debug('Moving dependency file ...') os.rename(session_d, os.path.join(yangdst, 'dependencies.xml')) else: logging.debug('Compiling user dependency ...') Compiler.compile_pyimport(user) # added module might affect existing module, recompile them _compile_dependecies(user, [m.text for m in modules], None) logging.debug('Committed ' + str(count) + ' file(s)') return True, modules
def upload_handler(request): """ HTTP Request handler function to upload yang models """ mode = request.GET.get('mode', '') logging.debug(request.method + ':Received upload request .. ' + mode) if not request.user.is_authenticated(): logging.warning('User must be logged in !!') return HttpResponse(Response.error(mode, 'Unauthorized')) if not ServerSettings.user_aware(): if not request.user.has_perm('explorer.delete_yangmodel') or \ not request.user.has_perm('explorer.change_yangmodel'): logging.warning('Unauthorized upload request .. ') return HttpResponse(Response.error(mode, 'User does not have permission to upload !!')) if request.method == 'POST': # create a temporary storage for this session directory = ServerSettings.session_path(request.session.session_key) _file = Uploader.upload_file(request.FILES['Filedata'], directory) if _file is not None: module = ET.Element('module') module.text = _file rval = Response.success('upload', 'ok', xml=module) logging.debug(rval) return HttpResponse(rval) return HttpResponse(Response.error('upload', 'Failed to upload')) elif request.method == 'GET': if mode == 'sync': filename = request.GET.get('file', '') index = request.GET.get('index', '') logging.info('Received sync request for ' + filename + ', index ' + index) success, response = Uploader.sync_file(request.user.username, request.session.session_key, filename, index) if success: return HttpResponse(Response.success(mode, 'ok')) return HttpResponse(Response.error(mode, 'compilation failed', xml=response)) elif mode == 'commit': success, modules = Uploader.commit_files(request.user.username, request.session.session_key) if success: return HttpResponse(Response.success('commit', 'ok', modules)) elif mode == 'init': success, modules = Uploader.get_upload_files(request.user.username, request.session.session_key) if success: return HttpResponse(Response.success(mode, 'ok', modules)) elif mode == 'clear': success, modules = Uploader.clear_upload_files(request.user.username, request.session.session_key) if success: return HttpResponse(Response.success(mode, 'ok', modules)) return HttpResponse(Response.error(mode, 'failed')) return render_to_response('upload.html')
def get_dependencies(username, modules, session): """ return dependencies for given yang models """ session_dir = '' logging.debug("get_dependencies: Target Modules " + str(modules)) if session is not None: session_dir = ServerSettings.session_path(session) dfile = os.path.join(session_dir, 'dependencies.xml') else: dfile = os.path.join(ServerSettings.yang_path(username), 'dependencies.xml') if not os.path.exists(dfile): logging.error('get_dependencies: dependency file %s missing!!', dfile) return [] if session_dir: session_files = [os.path.basename(_file) for _file in glob.glob(os.path.join(session_dir, '*.yang'))] yang_path = ServerSettings.yang_path(username) yang_files = [os.path.basename(_file) for _file in glob.glob(os.path.join(yang_path, '*.yang'))] dmodules = Set([]) dgraph = DYGraph(dfile) for m in modules: module = dgraph.dependency_module(m) if module is None: continue for name in module.imports: dmodules.add(name) for name in module.includes: dmodules.add(name) for name in module.depends: dmodules.add(name) dmodules_list = list(dmodules) deplist = [] for _file in dmodules_list: # prefer freshly uploaded files if session_dir: depfile = _find_matching(_file, session_dir, session_files) else: depfile = _find_matching(_file, yang_path, yang_files) if depfile is not None: deplist.append(depfile) else: logging.warning("get_dependencies: Dependency (%s) not satisfied, compilation will fail !!" % _file) logging.debug("get_dependencies: Computed " + str(deplist)) return deplist
def clear_upload_files(user, session): """ Delete uploaded yang files which are not committed """ directory = ServerSettings.session_path(session) if not os.path.exists(directory): logging.debug('Session storage %s does not exist' % directory) return False, None modules = ET.Element('modules') for _file in glob.glob(os.path.join(directory, '*')): os.remove(_file) return True, modules
def clear_upload_files(user, session): """ Delete uploaded yang files which are not committed """ directory = ServerSettings.session_path(session) if not os.path.exists(directory): logging.error('Session storage %s does not exist' % directory) return (False, None) modules = ET.Element('modules') for _file in glob.glob(os.path.join(directory, '*')): os.remove(_file) return (True, modules)
def sync_file(user, session, filename, index): """ Compile yang module """ if index == '0': logging.debug('Compiling session dependency ...') (rc, msg) = Compiler.compile_pyimport(user, session) if not rc: return rc, msg _file = os.path.join(ServerSettings.session_path(session), filename) if os.path.exists(_file): (rc, msgs) = Compiler.compile_cxml(user, session, _file) else: logging.error('sync_file: File %s not found ' % filename) (rc, msgs) = (False, None) return rc, msgs
def sync_file(user, session, filename, index): """ Compile yang module """ if index == '0': logging.debug('Compiling session dependency ...') (rc, msg) = Compiler.compile_pyimport(user, session) if not rc: return (rc, msg) _file = os.path.join(ServerSettings.session_path(session), filename) if os.path.exists(_file): (rc, msgs) = Compiler.compile_cxml(user, session, _file) else: logging.error('sync_file: File %s not found ' % filename) (rc, msgs) = (False, None) return (rc, msgs)
def get_upload_files(user, session): """ Get the list of uploaded yang files which are not committed """ modules = ET.Element('modules') directory = ServerSettings.session_path(session) if not os.path.exists(directory): logging.error('Session storage %s does not exist' % directory) return (True, modules) for _file in glob.glob(os.path.join(directory, '*.yang')): module = ET.Element('module') module.text = os.path.basename(_file) modules.append(module) return (True, modules)
def get_upload_files(user, session): """ Get the list of uploaded yang files which are not committed """ modules = ET.Element('modules') directory = ServerSettings.session_path(session) if not os.path.exists(directory): logging.error('Session storage %s does not exist' % directory) return True, modules for _file in glob.glob(os.path.join(directory, '*.yang')): module = ET.Element('module') module.text = os.path.basename(_file) modules.append(module) return True, modules
def compile_pyimport(username, session=None): """ Compile yang model and return tuple (boolean, list-of-errors) """ plugins = os.path.join(settings.BASE_DIR, 'explorer', 'plugins') if not os.path.exists(plugins): logging.error('CXML Plugin directory is missing .. !!') return False, None if subprocess.call(['which', 'pyang']) != 0: logging.error( 'Could not find pyang compiler, please install pyang .. !!') return False, None logging.debug('Rebuilding dependencies for user %s' % username) # build include path includes = [ServerSettings.yang_path(username)] if session is not None: session_dir = ServerSettings.session_path(session) if not os.path.exists(session_dir): logging.error( 'compile_pyimport: Session directory %s not found !!', session_dir) return False, ["Session error !!"] includes.append(session_dir) depfile = os.path.join(session_dir, 'dependencies.xml') else: depfile = os.path.join(includes[0], 'dependencies.xml') target_yangs = [] for yang_dir in includes: for _file in glob.glob(os.path.join(yang_dir, '*.yang')): target_yangs.append(_file) if not target_yangs: logging.debug('compile_pyimport: No yang file found !!') return True, ET.Element('messages') command = [ 'pyang', '-f', 'pyimport', '--ignore-error', '--plugindir', 'explorer/plugins', '-p' ] command += [':'.join(includes)] command += target_yangs return Compiler.invoke_compile(command, depfile)
def create_session_storage(session): """ Create session storage directory for storing session private files Args: session: session id for user Returns: None """ directory = ServerSettings.session_path(session) try: if not os.path.exists(directory): logging.debug('Creating session storage ..') os.makedirs(directory) if not os.path.exists(directory): logging.error('Failed to create session storage ..') return None except: return None return directory
def compile_pyimport(username, session=None): ''' Compile yang model and return tuple (boolean, list-of-errors) ''' plugins = os.path.join(settings.BASE_DIR, 'explorer', 'plugins') if not os.path.exists(plugins): logging.error('CXML Plugin directory is missing .. !!') return (False, None) if subprocess.call(['which', 'pyang']) != 0: logging.error('Could not find pyang compiler, please install pyang .. !!') return (False, None) logging.debug('Rebuilding dependencies for user %s' % username) # build include path includes = [ServerSettings.yang_path(username)] if session is not None: session_dir = ServerSettings.session_path(session) if not os.path.exists(session_dir): logging.error('compile_pyimport: Session directory %s not found !!', session_dir) return (False, ["Session error !!"]) includes.append(session_dir) depfile = os.path.join(session_dir, 'dependencies.xml') else: depfile = os.path.join(includes[0], 'dependencies.xml') target_yangs = [] for yang_dir in includes: for _file in glob.glob(os.path.join(yang_dir, '*.yang')): target_yangs.append(_file) if not target_yangs: logging.debug('compile_pyimport: No yang file found !!') return (True, ET.Element('messages')) command = ['pyang', '-f', 'pyimport', '--plugindir', 'explorer/plugins', '-p'] command += [':'.join(includes)] command += target_yangs return Compiler.invoke_compile(command, depfile)
def compile_pyimport(username, session=None): """ Compile yang model and return tuple (boolean, list-of-errors) """ plugins = os.path.join(settings.BASE_DIR, "explorer", "plugins") if not os.path.exists(plugins): logging.error("CXML Plugin directory is missing .. !!") return False, None if subprocess.call(["which", "pyang"]) != 0: logging.error("Could not find pyang compiler, please install pyang .. !!") return False, None logging.debug("Rebuilding dependencies for user %s" % username) # build include path includes = [ServerSettings.yang_path(username)] if session is not None: session_dir = ServerSettings.session_path(session) if not os.path.exists(session_dir): logging.error("compile_pyimport: Session directory %s not found !!", session_dir) return False, ["Session error !!"] includes.append(session_dir) depfile = os.path.join(session_dir, "dependencies.xml") else: depfile = os.path.join(includes[0], "dependencies.xml") target_yangs = [] for yang_dir in includes: for _file in glob.glob(os.path.join(yang_dir, "*.yang")): target_yangs.append(_file) if not target_yangs: logging.debug("compile_pyimport: No yang file found !!") return True, ET.Element("messages") command = ["pyang", "-f", "pyimport", "--plugindir", "explorer/plugins", "-p"] command += [":".join(includes)] command += target_yangs return Compiler.invoke_compile(command, depfile)
def compile_cxml(username, session, filename): """ Compile yang model and return tuple (boolean, list-of-errors) """ logging.debug("Compiling %s .. !!" % filename) plugins = os.path.join(settings.BASE_DIR, "explorer", "plugins") if not os.path.exists(plugins): logging.error("CXML Plugin directory is missing .. !!") return False, None if subprocess.call(["which", "pyang"]) != 0: logging.error("Could not find pyang compiler, please install pyang .. !!") return False, None basename = os.path.basename(filename) modulename = basename.split(".")[0].strip() session_dir = "" if session is not None: session_dir = ServerSettings.session_path(session) if not os.path.exists(session_dir): logging.error("compile_cxml: Session directory %s not found !!", session_dir) return False, ["Session error !!"] yangfile = os.path.join(session_dir, modulename + ".yang") cxmlfile = os.path.join(session_dir, modulename + ".xml") else: yangfile = os.path.join(ServerSettings.yang_path(username), modulename + ".yang") cxmlfile = os.path.join(ServerSettings.cxml_path(username), modulename + ".xml") # Verify if yang file exists if not os.path.exists(yangfile): logging.debug("compile_cxml: " + yangfile + " not found !!") return False, ["Yang module %s not found on server !!" % modulename] command = ["pyang", "-f", "cxml", "--plugindir", "explorer/plugins", "-p"] # include path for pyang compilation includes = ServerSettings.yang_path(username) if session_dir: includes += ":" + session_dir command.append(includes) # include dependent models command += Compiler.get_dependencies(username, [filename], session) # finally add target module command.append(yangfile) # create a callback to handle empty output def empty_callback(outfile): module = os.path.basename(outfile) module = module.split(".")[0] module = module.split("@")[0] node = ET.Element("node") node.set("name", module) node.set("type", "module") with open(outfile, "w") as fd: fd.write(ET.tostring(node)) logging.debug("compile_cxml: Empty output from pyang, created default cxml!!") return Compiler.invoke_compile(command, cxmlfile, empty_callback)
def get_dependencies(username, modules, session): """ return dependencies for given yang models """ session_dir = '' logging.debug("get_dependencies: Target Modules " + str(modules)) if session is not None: session_dir = ServerSettings.session_path(session) dfile = os.path.join(session_dir, 'dependencies.xml') else: dfile = os.path.join(ServerSettings.yang_path(username), 'dependencies.xml') if not os.path.exists(dfile): logging.error('get_dependencies: dependency file %s missing!!', dfile) return [] if session_dir: session_files = [ os.path.basename(_file) for _file in glob.glob(os.path.join(session_dir, '*.yang')) ] yang_path = ServerSettings.yang_path(username) yang_files = [ os.path.basename(_file) for _file in glob.glob(os.path.join(yang_path, '*.yang')) ] dmodules = Set([]) dgraph = DYGraph(dfile) for m in modules: module = dgraph.dependency_module(m) if module is None: continue for name in module.imports: dmodules.add(name) for name in module.includes: dmodules.add(name) for name in module.depends: dmodules.add(name) dmodules_list = list(dmodules) deplist = [] for _file in dmodules_list: # prefer freshly uploaded files if session_dir: depfile = _find_matching(_file, session_dir, session_files) else: depfile = _find_matching(_file, yang_path, yang_files) if depfile is not None: deplist.append(depfile) else: logging.warning( "get_dependencies: Dependency (%s) not satisfied, compilation may fail !!" % _file) logging.debug("get_dependencies: Computed " + str(deplist)) return deplist
def compile_cxml(username, session, filename): ''' Compile yang model and return tuple (boolean, list-of-errors) ''' logging.debug('Compiling %s .. !!' % filename) plugins = os.path.join(settings.BASE_DIR, 'explorer', 'plugins') if not os.path.exists(plugins): logging.error('CXML Plugin directory is missing .. !!') return (False, None) if subprocess.call(['which', 'pyang']) != 0: logging.error('Could not find pyang compiler, please install pyang .. !!') return (False, None) basename = os.path.basename(filename) modulename = basename.split('.')[0].strip() session_dir = '' if session is not None: session_dir = ServerSettings.session_path(session) if not os.path.exists(session_dir): logging.error('compile_cxml: Session directory %s not found !!', session_dir) return (False, ["Session error !!"]) yangfile = os.path.join(session_dir, modulename + '.yang') cxmlfile = os.path.join(session_dir, modulename + '.xml') else: yangfile = os.path.join(ServerSettings.yang_path(username), modulename + '.yang') cxmlfile = os.path.join(ServerSettings.cxml_path(username), modulename + '.xml') # Verify if yang file exists if not os.path.exists(yangfile): logging.debug("compile_cxml: " + yangfile + ' not found !!') return (False, ["Yang module %s not found on server !!" % modulename]) command = ['pyang', '-f', 'cxml', '--plugindir', 'explorer/plugins', '-p'] # include path for pyang compilation includes = ServerSettings.yang_path(username) if session_dir: includes += ':' + session_dir command.append(includes) # include dependent models command += Compiler.get_dependencies(username, [filename], session) # finally add target module command.append(yangfile) # create a callback to handle empty output def empty_callback(outfile): module = os.path.basename(outfile) module = module.split('.')[0] module = module.split('@')[0] node = ET.Element('node') node.set('name', module) node.set('type', 'module') with open(outfile, 'w') as fd: fd.write(ET.tostring(node)) logging.debug('compile_cxml: Empty output from pyang, created default cxml!!') return Compiler.invoke_compile(command, cxmlfile, empty_callback)
def compile_cxml(username, session, filename): """ Compile yang model and return tuple (boolean, list-of-errors) """ logging.debug('Compiling %s .. !!' % filename) plugins = os.path.join(settings.BASE_DIR, 'explorer', 'plugins') if not os.path.exists(plugins): logging.error('CXML Plugin directory is missing .. !!') return False, None if subprocess.call(['which', 'pyang']) != 0: logging.error( 'Could not find pyang compiler, please install pyang .. !!') return False, None basename = os.path.basename(filename) modulename = basename.split('.yang')[0].strip() session_dir = '' if session is not None: session_dir = ServerSettings.session_path(session) if not os.path.exists(session_dir): logging.error( 'compile_cxml: Session directory %s not found !!', session_dir) return False, ["Session error !!"] yangfile = os.path.join(session_dir, modulename + '.yang') cxmlfile = os.path.join(session_dir, modulename + '.xml') else: yangfile = os.path.join(ServerSettings.yang_path(username), modulename + '.yang') cxmlfile = os.path.join(ServerSettings.cxml_path(username), modulename + '.xml') # Verify if yang file exists if not os.path.exists(yangfile): logging.debug("compile_cxml: " + yangfile + ' not found !!') return False, [ "Yang module %s not found on server !!" % modulename ] command = [ 'pyang', '-f', 'cxml', '--ignore-error', '--plugindir', 'explorer/plugins', '-p' ] # include path for pyang compilation includes = ServerSettings.yang_path(username) if session_dir: includes += ':' + session_dir command.append(includes) # include dependent models command += Compiler.get_dependencies(username, [filename], session) # finally add target module command.append(yangfile) # create a callback to handle empty output def empty_callback(outfile): module = os.path.basename(outfile) module = module.split('.')[0] module = module.split('@')[0] node = ET.Element('node') node.set('name', module) node.set('type', 'module') with open(outfile, 'w') as fd: fd.write(ET.tostring(node)) logging.debug( 'compile_cxml: Empty output from pyang, created default cxml!!' ) return Compiler.invoke_compile(command, cxmlfile, empty_callback)