Ejemplo n.º 1
0
    def __init__(self, yin_path, yin_file, model_dir, verbose=False):
        """
        YANG model initializer

        :param: yin_path (string) Directory path to the location of the YIN file (and python file)
        :param: yin_file (string) Name of the YIN file generated by 'pyang'.  The name of the code-generated
                                  python file is extracted from the YIN file (module name).
        :param: model_dir (string) Directory name of where the model is.
                                   Used in constructing the import statement.
        :param: verbose (integer) Flag indicating if verbose output is to be presented
        """
        self._yin = YINFile(os.path.join(yin_path, yin_file), verbose)
        self._verbose = verbose

        # Import the model
        self._import_models(model_dir)
Ejemplo n.º 2
0
    def __init__(self, yin_path, yin_file, model_dir, verbose=False):
        """
        YANG model initializer

        :param: yin_path (string) Directory path to the location of the YIN file (and python file)
        :param: yin_file (string) Name of the YIN file generated by 'pyang'.  The name of the code-generated
                                  python file is extracted from the YIN file (module name).
        :param: model_dir (string) Directory name of where the model is.
                                   Used in constructing the import statement.
        :param: verbose (integer) Flag indicating if verbose output is to be presented
        """
        self._yin = YINFile(os.path.join(yin_path, yin_file), verbose)
        self._verbose = verbose

        # Import the model
        self._import_models(model_dir)
Ejemplo n.º 3
0
class YangModel:
    """
    This class wraps the yang model and helps to hide some of the ugly details needed to
    get this code-generated RESTCONF server working.
    """

    _extmethods = None
    _yang_class = None
    _yin = None

    def __init__(self, yin_path, yin_file, model_dir, verbose=False):
        """
        YANG model initializer

        :param: yin_path (string) Directory path to the location of the YIN file (and python file)
        :param: yin_file (string) Name of the YIN file generated by 'pyang'.  The name of the code-generated
                                  python file is extracted from the YIN file (module name).
        :param: model_dir (string) Directory name of where the model is.
                                   Used in constructing the import statement.
        :param: verbose (integer) Flag indicating if verbose output is to be presented
        """
        self._yin = YINFile(os.path.join(yin_path, yin_file), verbose)
        self._verbose = verbose

        # Import the model
        self._import_models(model_dir)

    def __str__(self):
        return "YangModel: %s" % self.name

    @property
    def name(self):
        """
        Get the module name.

        @:returns: (string) YANG Model name
        """
        return self._yin.module_name

    @property
    def package_name(self):
        """
        Get the code-generated package name.  The pyangbind package will replace hypens and
        spaces with underscores.

        @:returns: (string) Python code-generated module name
        """
        return self.name.replace("-", "_").replace(" ", "_")

    def _import_models(self, model_dir):
        """
        This method is responsible for accessing the code-generated class and building up
        a model that can be used to provide a simple RESTCONF server implementation of the
        model.

        :param: model_dir (string) Base directory name of where the model is.
        """
        package = model_dir
        module = self.package_name
        _class = self.package_name

        try:
            if self._verbose > 0:
                print "Dynamic import -> from %s.%s import %s" % (package, module, _class)

            yang_module = __import__("%s.%s" % (package, module), fromlist=[_class])
            yang_class = getattr(yang_module, _class)

            if self._verbose > 0:
                print "YANG class initially imported: %s" % yang_class

            # Construct the extmethods for all appropriate nodes in the class and then
            # reconstruct the class if needed with these method

            self._extmethods = self._yin.get_extmethods(yang_class().get())

            # Now reconstruct the class and pass in these methods

            if self._extmethods is not None and len(self._extmethods) > 0:
                self._yang_class = getattr(yang_module, _class)(extmethods=self._extmethods)
            else:
                self._yang_class = yang_class

        except ImportError:
            print "Import Error while attempting to import class %s from %s.%s" % (_class, package, module)

            # Instantiate the models the first time so we can generate all the paths within
            # them so we can create extension methods that provide for RESTCONF required
            # methods
            ###########################################################################

    def _get_extmethods(self, element, path_base=""):
        """
        A recursive function to convert a yang model into a extmethods dictionary

        :param element: (list of YANGDynClass) Child elements of a the model instance
        :param path_base: (dict) Existing dictionary of elements

        :return: (dict) A Pyangbind compatible extmethods dictionary
        """
        extmethods = {}

        if element is None:
            return extmethods

        if isinstance(element, dict):
            # print '%s is a dictionary of length %d' % (element, len(element))

            # yang_name = getattr(element, "yang_name") if hasattr(element, "yang_name") else None
            # is_container = hasattr(element, "get")

            for key, value in element.items():
                path = path_base + "/" + key
                config = True

                yang_name = getattr(value, "yang_name") if hasattr(element, "yang_name") else None
                is_container = hasattr(value, "get")

                try:
                    if value._is_leaf:  # Protected, but I really need to know
                        config = value.flags.writeable

                except AttributeError:
                    pass  # Was another dictionary item or did not have a writeable flag

                # Add this to our path
                extmethods[path] = config
                extmethods.update(self._get_extmethods(value, path_base=path))

        return extmethods

    def _fix_extmethods(self, extmethods):
        """
        Walk through the methods and fix up any parents that have no children that
        are writeable.
        """
        # TODO: Need to implement
        return extmethods
Ejemplo n.º 4
0
class YangModel:
    """
    This class wraps the yang model and helps to hide some of the ugly details needed to
    get this code-generated RESTCONF server working.
    """
    _extmethods = None
    _yang_class = None
    _yin = None

    def __init__(self, yin_path, yin_file, model_dir, verbose=False):
        """
        YANG model initializer

        :param: yin_path (string) Directory path to the location of the YIN file (and python file)
        :param: yin_file (string) Name of the YIN file generated by 'pyang'.  The name of the code-generated
                                  python file is extracted from the YIN file (module name).
        :param: model_dir (string) Directory name of where the model is.
                                   Used in constructing the import statement.
        :param: verbose (integer) Flag indicating if verbose output is to be presented
        """
        self._yin = YINFile(os.path.join(yin_path, yin_file), verbose)
        self._verbose = verbose

        # Import the model
        self._import_models(model_dir)

    def __str__(self):
        return 'YangModel: %s' % self.name

    @property
    def name(self):
        """
        Get the module name.

        @:returns: (string) YANG Model name
        """
        return self._yin.module_name

    @property
    def package_name(self):
        """
        Get the code-generated package name.  The pyangbind package will replace hypens and
        spaces with underscores.

        @:returns: (string) Python code-generated module name
        """
        return self.name.replace('-', '_').replace(' ', '_')

    def _import_models(self, model_dir):
        """
        This method is responsible for accessing the code-generated class and building up
        a model that can be used to provide a simple RESTCONF server implementation of the
        model.

        :param: model_dir (string) Base directory name of where the model is.
        """
        package = model_dir
        module = self.package_name
        _class = self.package_name

        try:
            if self._verbose > 0:
                print 'Dynamic import -> from %s.%s import %s' % (
                    package, module, _class)

            yang_module = __import__('%s.%s' % (package, module),
                                     fromlist=[_class])
            yang_class = getattr(yang_module, _class)

            if self._verbose > 0:
                print 'YANG class initially imported: %s' % yang_class

            # Construct the extmethods for all appropriate nodes in the class and then
            # reconstruct the class if needed with these method

            self._extmethods = self._yin.get_extmethods(yang_class().get())

            # Now reconstruct the class and pass in these methods

            if self._extmethods is not None and len(self._extmethods) > 0:
                self._yang_class = getattr(yang_module,
                                           _class)(extmethods=self._extmethods)
            else:
                self._yang_class = yang_class

        except ImportError:
            print 'Import Error while attempting to import class %s from %s.%s' % (
                _class, package, module)

            # Instantiate the models the first time so we can generate all the paths within
            # them so we can create extension methods that provide for RESTCONF required
            # methods
            ###########################################################################

    def _get_extmethods(self, element, path_base=''):
        """
        A recursive function to convert a yang model into a extmethods dictionary

        :param element: (list of YANGDynClass) Child elements of a the model instance
        :param path_base: (dict) Existing dictionary of elements

        :return: (dict) A Pyangbind compatible extmethods dictionary
        """
        extmethods = {}

        if element is None:
            return extmethods

        if isinstance(element, dict):
            # print '%s is a dictionary of length %d' % (element, len(element))

            # yang_name = getattr(element, "yang_name") if hasattr(element, "yang_name") else None
            # is_container = hasattr(element, "get")

            for key, value in element.items():
                path = path_base + '/' + key
                config = True

                yang_name = getattr(value, "yang_name") if hasattr(
                    element, "yang_name") else None
                is_container = hasattr(value, "get")

                try:
                    if value._is_leaf:  # Protected, but I really need to know
                        config = value.flags.writeable

                except AttributeError:
                    pass  # Was another dictionary item or did not have a writeable flag

                # Add this to our path
                extmethods[path] = config
                extmethods.update(self._get_extmethods(value, path_base=path))

        return extmethods

    def _fix_extmethods(self, extmethods):
        """
        Walk through the methods and fix up any parents that have no children that
        are writeable.
        """
        # TODO: Need to implement
        return extmethods