Edit
WYSIWYG
Attach
P
rintable
r10 - 2011-02-16 - 09:44:37 -
LadaLhotka
You are here:
TWiki
>
Main Web
>
YangTools
>
DSDLMappingTutorial
<!-- Author: Ladislav Lhotka <lhotka@cesnet.cz> URL: http://www.yang-central.org/twiki/bin/view/Main/DSDLMappingTutorial Note to pyang committers: please edit the TWiki source in the pyang repository at Google Code, file doc/DSDLMappingTutorial.twiki. --> ---+ DSDL Mapping Tutorial ---++ Introduction One of the functions implemented in [[http://code.google.com/p/pyang][pyang]] is the mapping of [[http://tools.ietf.org/html/draft-ietf-netmod-yang-12][YANG]] data models to [[http://www.dsdl.org][DSDL]] schemas – [[http://relaxng.org][RELAX NG]], [[http://www.schematron.com/][Schematron]] and DSRL. The resulting schemas may be used with off-the-shelf XML tools for validating NETCONF datastores and messages and other related purposes. The mapping procedure is described in [[http://tools.ietf.org/html/draft-ietf-netmod-dsdl-map-05][draft-ietf-netmod-dsdl-map]]. This tutorial works with a very simple data model consisting of two YANG modules. We first show how to perform the DSDL mapping procedure with the _yang2dsdl_ script that is a part of _pyang_ distribution, and then experiment with validating configuration datastore contents. %ICON{"help"}% The software tools presented in this tutorial produce compact XML data with no intervening whitespace. The corresponding files that are attached to this wiki page and referred to in the text are their pretty-printed versions obtained by using [[http://xmlsoft.org/xmllint.html][xmllint]]. ---++ The Data Model As an example, we use the YANG module _acme-system_ shown at the bottom of WebHome (see also [[%ATTACHURL%/acme-system.yang][acme-system.yang]]). To make things slightly more interesting, we _augment_ this module by adding three new nodes to the entries of the "interface" list. This is accomplished by the following module (see also [[%ATTACHURL%/extra-interface-data.yang][extra-interface-data.yang]]): <pre class="yang"><span class='kw'>module</span> extra-interface-data { <span class='kw'>namespace</span> <span class='str'>"http://foo.example.com/extra-if-data"</span>; <span class='kw'>prefix</span> eid; <span class='kw'>import</span> acme-system { <span class='kw'>prefix</span> acme; } <span class='kw'>import</span> ietf-inet-types { <span class='kw'>prefix</span> inet; } <span class='kw'>augment</span> <span class='str'>"/acme:system/acme:interface"</span> { <span class='kw'>leaf</span> enabled { <span class='kw'>type</span> boolean; <span class='kw'>default</span> <span class='str'>"false"</span>; <span class='kw'>must</span> <span class='str'>".='false' or ../ipv4-address and ../subnet-mask-length"</span> { <span class='kw'>error-message</span> <span class='str'>"IP address and mask must be configured "</span> + <span class='str'>"for enabled interfaces."</span>; } } <span class='kw'>leaf</span> ipv4-address { <span class='kw'>type</span> inet:ipv4-address; } <span class='kw'>leaf</span> subnet-mask-length { <span class='kw'>type</span> uint8 { <span class='kw'>range</span> <span class='str'>"0..32"</span>; } } } } </pre> Our data model now defines a _compound document_ containing nodes in the namespaces of both the contributing modules, _acme-system_ and _extra-interface-data_. ---++ Generating the Schemas The DSDL schemas can be generated quite easily (at least on Linux and Unix systems) from the two YANG modules by using the _yang2dsdl_ shell script which is provided with the _pyang_ distribution. The details about its usage can be found in the [[%ATTACHURL%/yang2dsdl.1.html][manual page]] or by running =yang2dsdl -h=. But before we start, we need to decide which target document type the generated schemas are to address. Currently, _yang2dsdl_ supports the following targets that are selected via the =-t= command line option: $ *dstore*: raw datastore content; $ *get-reply*: a complete NETCONF message containing a reply to =<get>= operation; $ *getconf-reply*: a complete NETCONF message containing a reply to =<get-config>= operation; $ *rpc*: An RPC request defined in the input YANG module(s); $ *rpc-reply*: An RPC reply defined in the input YANG module(s); $ *notif*: An event notification defined in the input YANG module(s). Only the first three targets make sense in our case as the YANG modules define neither RPC operations nor event notifications. Moreover, there are no operational state data or statistics in our modules, so the replies to =<get>= and =<get-config>= are bound to be identical. Another detail to consider are the file names in which the output schemas will be stored. The names have the following general form: <verbatim> BASE-TARGET.EXT </verbatim> The first part, BASE, can be chosen by the user while the other two cannot. TARGET is always set to the selected target (see above) and EXT is a file extension specific for each DSDL schema language – =rng= is used for RELAX NG, =sch= for Schematron and =dsrl= for DSRL. If the BASE part isn't provided by the user, the script constructs a default one, which is a concatenation of the names of all input YANG modules connected with the underscore character =_=. The result in our example – =acme-system_extra-interface-data= – would lead to rather long file names. We therefore decide to specify a shorter BASE part explicitly, say =aug-acme-system=. All right, let's generate the DSDL schemas for the "dstore" target. We needn't use the =-t= option here as "dstore" is the default: <verbatim> $ yang2dsdl -b aug-acme-system acme-system.yang extra-interface-data.yang == Generating RELAX NG schema './aug-acme-system-dstore.rng' Done. == Generating Schematron schema './aug-acme-system-dstore.sch' Done. == Generating DSRL schema './aug-acme-system-dstore.dsrl' Done. </verbatim> As indicated by the program output, the resulting DSDL schemas were written to three files: * RELAX NG schema in [[%ATTACHURL%/aug-acme-system-dstore.rng][aug-acme-system-dstore.rng]] * Schematron schema in [[%ATTACHURL%/aug-acme-system-dstore.sch][aug-acme-system-dstore.sch]] * DSRL schema in [[%ATTACHURL%/aug-acme-system-dstore.dsrl][aug-acme-system-dstore.dsrl]] But wait, the script also created a fourth file, namely [[%ATTACHURL%/aug-acme-system-gdefs.rng][aug-acme-system-gdefs.rng]]. This is actually a part of the RELAX NG schema containing all global definitions (mapped from YANG top-level groupings and typedefs). For technical reasons, these definitions have to be included from an external file. ---++ An Instance Configuration Datastore In order to be able to see the generated DSDL schemas in action, we need to create an XML document containing, in our case, a "raw" configuration datastore. If we have an appropriate schema-aware editor, we can provide it with the RELAX NG schema (or Schematron as well). An excellent choice is [[http://www.gnu.org/software/emacs/][GNU Emacs]] with James Clark's [[http://www.thaiopensource.com/nxml-mode/][nXML mode]]. The following is a valid datastore content (see also [[%ATTACHURL%/aug-acme-system-dstore.xml][aug-acme-system-dstore.xml]]): <verbatim> <?xml version="1.0" encoding="utf-8"?> <system xmlns="http://acme.example.com/system" xmlns:eid="http://foo.example.com/extra-if-data"> <host-name>katz</host-name> <domain-search>acme.example.com foo.example.com</domain-search> <interface> <name>eth0</name> <type>Ethernet</type> <mtu>1500</mtu> <eid:enabled>true</eid:enabled> <eid:ipv4-address>192.0.2.1</eid:ipv4-address> <eid:subnet-mask-length>24</eid:subnet-mask-length> </interface> <interface> <name>eth1</name> <mtu>1500</mtu> <type>Ethernet</type> </interface> </system> </verbatim> _Emacs_ with _nXML mode_ is also a user-friendly RELAX NG validator. For example, we can try to change the value of the =<eid:subnet-mask-length>= element to =42=, which violates a datatype constraint – this value must be in the range between 0 and 32. As a result, the wrong value is underlined in _Emacs_ and the status line indicates that the edited XML document is invalid. ---++ Validation We can use the _yang2dsdl_ script for validating the above datastore content (the =-s= flag instructs the script to use the existing DSDL schemas, without it the schemas would be regenerated): <verbatim> $ yang2dsdl -s -b aug-acme-system -v aug-acme-system-dstore.xml == Using pre-generated schemas == Validating grammar and datatypes ... aug-acme-system-dstore.xml validates == Adding default values... done. == Validating semantic constraints ... No errors found. </verbatim> Sure enough, no errors were detected in the instance document. Now, let's change the value of the =<eid:subnet-mask-length>= element to =42= again and re-run the same command: <verbatim> $ yang2dsdl -s -b aug-acme-system -v aug-acme-system-dstore.xml == Using pre-generated schemas == Validating grammar and datatypes ... Relax-NG validity error : Extra element subnet-mask-length in interleave aug-acme-system-dstore.xml:12: element subnet-mask-length: Relax-NG validity error : Element interface failed to validate content Relax-NG validity error : Extra element interface in interleave aug-acme-system-dstore.xml:6: element interface: Relax-NG validity error : Element system failed to validate content aug-acme-system-dstore.xml fails to validate </verbatim> The error message is not particularly informative – it is a direct output of the RELAX NG validator built in the _xmllint_ tool – but at least the conclusion in the last line is correct. Next, change the value of =<eid:subnet-mask-length>= back to =24= but also introduce two new errors in the second =<interface>= entry: 1. Change the value of =<name>= from =eth1= to =eth0=. Both list entries now have the same key. 1. Add a new element: <verbatim><eid:enabled>true</eid:enabled></verbatim> This violates the constraint stated by the 'must' statement in the _extra-interface-data_ module. In this case, RELAX NG validators won't complain since the instance document remains grammatically valid and all datatype constraints are satisfied as well. The errors we deal with here are _semantic_. So let's try the validation with _yang2dsdl_ again: <verbatim> $ yang2dsdl -s -b aug-acme-system -v aug-acme-system-dstore.xml == Using pre-generated schemas == Validating grammar and datatypes ... aug-acme-system-dstore.xml validates == Adding default values... done. == Validating semantic constraints ... --- Validity error at "/acme:system/acme:interface": Duplicate key "acme:name" --- Failed assert at "/acme:system/acme:interface/eid:enabled": IP address and mask must be configured for enabled interfaces. </verbatim> The error messages are now very clear, Schematron rocks! Feel free to make any other modifications in the instance document and re-run the validation to see what happens. Developers and technically inclined readers may find further technical details about the DSDL mapping and instance validation in DSDLTechDetails.
Edit
|
WYSIWYG
|
Attach
|
P
rintable
|
V
iew topic
|
Backlinks:
We
b
,
A
l
l Webs
|
H
istory
:
r12
<
r11
<
r10
<
r9
<
r8
|
More topic actions...
Main
Main
FAQ
Tools
Documents
Tutorials
Examples
Copyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki?
Send feedback