예제 #1
0
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!!'))
예제 #2
0
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'))
예제 #3
0
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!!'))
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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')
예제 #7
0
    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
예제 #8
0
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
예제 #9
0
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)
예제 #10
0
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
예제 #11
0
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)
예제 #12
0
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)
예제 #13
0
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
예제 #14
0
    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)
예제 #15
0
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
예제 #16
0
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
예제 #17
0
    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)
예제 #18
0
    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)
예제 #19
0
    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)
예제 #20
0
    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
예제 #21
0
    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)
예제 #22
0
    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)