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 cxml_path(username, modulename): _dir = ServerSettings.cxml_path(username) modules = [os.path.basename(_file) for _file in glob.glob(os.path.join(_dir, '*.xml'))] for module in modules: if module == modulename + '.xml': return os.path.join(_dir, module) if module.startswith(modulename + '@'): return os.path.join(_dir, module) return None
def test_04_upload_handler(self): """ Verify upload_handler API in views.py """ # 1. Login to django server response = self.chrome.post('/explorer/login/', {'username': '******', 'password': '******', 'action': 'login'}) self.assertTrue(response.status_code == 200) # 2. Intialize upload request response = self.chrome.get('/explorer/upload', {'mode' : 'init'}) self.assertTrue(response.status_code == 200) self.assertTrue('ok' in response.content) # Get path to upload file curr = os.getcwd() pathlist = curr.split('/') while pathlist[-1] != 'yang-explorer': pathlist.pop() pathlist.append('default-models') root = '/'.join(pathlist) # 3. Upload file content filelist = ['ietf-inet-types.yang', 'ietf-yang-types.yang', '*****@*****.**'] for _file in filelist: with open(os.path.join(root, _file), 'r') as fp: response = self.chrome.post('/explorer/upload-add', {'Filedata' : fp}) self.assertTrue(response.status_code == 200) self.assertTrue('ok' in response.content) f = response.content.split('<module>')[1].split('</module>')[0] self.upload_files.append(f.strip()) # 4. Compile file for _file in self.upload_files: response = self.chrome.get('/explorer/upload', {'mode':'sync', 'file': _file}) self.assertTrue(response.status_code == 200) self.assertTrue('ok' in response.content) # 5. Commit file response = self.chrome.get('/explorer/upload', {'mode':'commit'}) self.assertTrue(response.status_code == 200) self.assertTrue('ok' in response.content) # logout response = self.chrome.post('/explorer/login/', {'username': '******', 'password': '******', 'action': 'logout'}) self.assertTrue(response.status_code == 200) self.assertTrue('ok' in response.content) # Verify that files are actually uploaded yang_path = ServerSettings.yang_path('demo') cxml_path = ServerSettings.cxml_path('demo') for _file in self.upload_files: # check if yang file is uploaded self.assertTrue(os.path.exists(os.path.join(yang_path, _file))) # check if xml file is created xml_name = _file.split('.yang')[0] + '.xml' self.assertTrue(os.path.exists(os.path.join(cxml_path, xml_name))) print("Test: upload_handler PASSED")
def is_browsable(username, module): cxml_path = os.path.join(ServerSettings.cxml_path(username), module + '.xml') browsable = False if os.path.exists(cxml_path): try: root = ET.parse(cxml_path).getroot() if root.find('node'): browsable = True except: logger.error('is_browsable: Exception in parse -> ' + cxml_path) return browsable
def is_browsable(username, module): cxml_path = os.path.join(ServerSettings.cxml_path(username), module + '.xml') browsable = False if os.path.exists(cxml_path): try: root = ET.parse(cxml_path).getroot() if root.find('node'): browsable = True except: logging.error('is_browsable: Excption in parse -> ' + cxml_path) return browsable
def get_modulelist(username): """ Return list of modules available to user """ users = User.objects.filter(username=username) if not users: logger.warning("ModuleAdmin.admin_action: Invalid user " + username) return [] modules = [] files = glob.glob(os.path.join(ServerSettings.cxml_path(username), '*.xml')) for _file in files: module = os.path.basename(_file).split('.xml')[0] if UserProfile.objects.filter(user=users[0], module=module).exists(): modules.append(module) return modules
def get_modulelist(username): ''' Return list of modules available to user ''' users = User.objects.filter(username=username) if not users: logging.debug("ModuleAdmin.admin_action: Inavlid user " + username) return [] modules = [] files = glob.glob(os.path.join(ServerSettings.cxml_path(username), '*.xml')) for _file in files: module = os.path.basename(_file).split('.xml')[0] if UserProfile.objects.filter(user=users[0], module=module).exists(): modules.append(module) return modules
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)
def test_05_admin_handler(self): """ Verify admin handler functionality """ # 1. Login to django server response = self.chrome.post('/explorer/login/', {'username': '******', 'password': '******', 'action': 'login'}) self.assertTrue(response.status_code == 200) # 2 Subscribe invalid module modules = ET.Element('modules') module = ET.Element('module') module.text = '*****@*****.**' modules.append(module) response = self.chrome.get('/explorer/admin', {'action':'subscribe', 'payload': ET.tostring(modules)}) self.assertTrue(response.status_code == 200) print response.content self.assertTrue('error' in response.content) self.assertTrue('not a main module' in response.content) # 2 Subscribe valid module module.text = '*****@*****.**' response = self.chrome.get('/explorer/admin', {'action':'subscribe', 'payload': ET.tostring(modules)}) self.assertTrue(response.status_code == 200) print response.content self.assertTrue('ok' in response.content) # 3. Verify that returned list correct subscription modulelist = ET.fromstring(response.content).find('modulelist') found = False for m in modulelist: if m.text == '*****@*****.**': found = True self.assertTrue(m.get('subscribed', 'false') == 'true') self.assertTrue(found) # 4. Un-Subscribe ietf-interfaces response = self.chrome.get('/explorer/admin', {'action':'unsubscribe', 'payload': ET.tostring(modules)}) self.assertTrue(response.status_code == 200) print response.content self.assertTrue('ok' in response.content) # 5. Verify that returned list correct subscription modulelist = ET.fromstring(response.content).find('modulelist') found = False for m in modulelist: if m.text == '*****@*****.**': found = True self.assertFalse(m.get('subscribed', 'false') == 'true') self.assertTrue(found) module.text = '*****@*****.**' response = self.chrome.get('/explorer/admin', {'action':'delete', 'payload': ET.tostring(modules)}) self.assertTrue(response.status_code == 200) print response.content self.assertTrue('ok' in response.content) # 6. Verify delete modulelist = ET.fromstring(response.content).find('modulelist') found = False for m in modulelist: self.assertTrue(m.text != '*****@*****.**') _file = module.text yang_path = ServerSettings.yang_path('demo') cxml_path = ServerSettings.cxml_path('demo') # check if yang file is deleted self.assertFalse(os.path.exists(os.path.join(yang_path, _file))) # check if xml file is deleted xml_name = _file.split('.yang')[0] + '.xml' self.assertFalse(os.path.exists(os.path.join(cxml_path, xml_name))) print("Test: admin_handler PASSED")
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)