Parser¶
-
class
yangify.parser.
Parser
(schema: yangson.schemanode.DataNode, model_filter: yangify.model_filter.ModelFilter, native: Any, root_native: Any, keys: Dict[str, str])¶ Parsing classes used to parse groupings need to inherit from this class. In addition to the relevant functions and classes to parse children nodes, they may include a
Yangify
class that inherits fromParserData
to implement some parsing logic. This is mandatory when parsing YANG Lists.-
yy
¶ This attribute will be instantiated using the nested class
Parser.Yangify
. Everything you implement inside yourclass Yangify
will be available through this attribute.Type: ParserData
Example
Interface class to parse
openconfig-interfaces:interfaces/interface
model:class Interface(Parser): class Yangify(ParserData): def extract_elements(self) -> Iterator[Tuple[str, Dict[str, Any]]]: for k, v in interfaces_magic: yield k, v
-
Yangify
¶ alias of
ParserData
-
-
class
yangify.parser.
ParserData
(schema: yangson.schemanode.DataNode, native: Any, root_native: Any, keys: Dict[str, str])¶ This is the base class for the
Parser.Yangify
object.-
schema
¶ Schema of the current grouping being processed
Type: yangson.schemanode.DataNode
-
native
¶ Exact details will depend on the parser implementation. As a rule of thumb points to the native configuration/data relevant for the current element being processed. On start it’s set the same as
ParserData.root_native
, however, it can be changed by the parser implementation. When processing lists, it’s set automatically to the second object returned byParserData.extract_elements
Type: Any
-
root_native
¶ Exact type and details will depend on the parser implementation. However, it points to the original object passed to
RootParser
in thenative
argument.Type: Any
-
keys
¶ This dictionary keeps track of all the keys relevant to the current object being processed. Keys are equal to the path where the key was extracted while the value is the actual value. For instance, if you were parsing the interface
FastEthernet1.1
using theopenconfig:interfaces
model, you’d have the following keys:{ "openconfig-interfaces:interfaces/interface": "FastEthernet1", "openconfig-interfaces:interfaces/interface/subinterfaces/subinterface": 1, }
Type: Dict[str, Any]
-
extract_elements
() → Iterator[Tuple[str, Any]]¶ This function is called when processing a YANG list. It’s mandatory to implement and needs to return an iterator of <key, value> pairs where:
- the key is the identifier of en element of the list
- the value is a relevant block of native data for the current object
The key will be added to
ParserData.keys
(referenced as the path to the node) and the value will be set in theParserData.native
attribute.
-
init
() → None¶ Called only by the
RootParser
in the very beginning of the processing. This function may be used to preprocess the native objects or for anything else that may be needed to do before the actual processing starts.
-
key
¶ Last key extracted in the current object being processed.
-
metadata
= {}¶
-
path
= ''¶
-
post
() → None¶ Called only by the
RootParser
in the very end of the processing.
-
post_process
() → None¶ This is called after processing either a container or a list element.
-
pre_process
() → None¶ This is called before processing either a container or a list element.
-
-
class
yangify.parser.
RootParser
(dm: yangson.datamodel.DataModel, native: Any, config: bool = True, state: bool = False, include: Optional[List[str]] = None, exclude: Optional[List[str]] = None)¶ This object represents the root of the parser and allows the user to choose which parts of the model to parse and with which parsers. To do so assign the parser classes to class attributes named after the nodes you want to parse.
Parameters: - dm – DataModel we are going to be parsing
- native – Native data to parse and map into the model
- config – Parse config leaves
- state – Parse state leaves
Examples
Parsing both
openconfig-interfaces
andopenconfig-vlan
models:from yangify import parser class Interfaces(parser.Parser): ... class Vlans(parser.Parser): ... class Parser(parser.RootParser): interfaces = Interfaces vlans = Vlans
Parsing only
openconfig-interfaces
but using a different parser:from yangify import parser class InterfacesAlt(parser.Parser): ... class Parser(parser.RootParser): interfaces = InterfacesAlt
-
process
(validate: bool = True) → yangson.instance.RootNode¶ Process the native data and map it into the model.
Parameters: validate – Validates the object before returning it
-
yangify.parser.
unneeded
(*args, **kwargs) → None¶ You can use this dummy function to flag that a particular leaf doesn’t need to be processed. Otherwise, the system will flag it as not implemented.
Example
we don’t need to
vlan_id
as it’s the same as the key:class VlanConfig(Parser): def name(self): ... vlan_id = unneeded
-
yangify.parser.text_tree.
parse_indented_config
(config: List[str], current_indent: int = 0, previous_indent: int = 0, nested: bool = False) → Dict[str, Any]¶ This method reads a configuration that conforms to a very poor industry standard CLI (aka IOS-style) and returns a nested structure that behaves like a dict.
Example
The following block of configuration:
interface FastEthernet1 descrption this is a description switchport mode access switchport access vlan 1 shutdown interface FastEthernet2 descrption this is a description switchport mode trunk switchport trunk allowed vlan 10,20
Will yield the following dict:
interface: #text: FastEthernet1 FastEthernet1: #standalone: true descrption: #text: this is a description this: #text: is a description is: #text: a description a: #text: description description: #standalone switchport: #text: access vlan 1 mode: #text: access access: #standalone: true access: #text: vlan 1 vlan: #text: 1 1: #standalone: true shutdown: #standalone: true FastEthernet2: #standalone: true descrption: #text: this is another description this: #text: is another description is: #text: another description a: #text: description description: #standalone switchport: #text: trunk allowed vlan 10,20 mode: #text: trunk trunk: #standalone: true trunk: #text: allowed vlan 10,20 allowed: #text: vlan 10,20 vlan: #text: 10,20 10,20: #standalone: true
Basically, the function does the following:
- It uses the indentation of the configuration to build a hierarchy, that’s for instance how it knows the commands that are nested inside the interfaces.
- For commands with multiple words in the same line it builds a data
structure that follows the following rules:
- each word goes into a nested dictionary inside the previous word.
- if a word is followed by more words, those following words go into
a subkey
#text
. For instance,parsed["interface"]["FastEthernet1"]["description"]["#text"]
will give you the entire description - if a word is not followed by any word, a
#standalone
key equal toTrue
is added. For instance,parsed["interface"]["FastEthernet1"]["shutdown"]["#standalone"]
will indicate the interface is shutdown.