1
0
Fork 0

Adding upstream version 3.1.0+dfsg.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-05 08:00:08 +01:00
parent 64dbec996d
commit cfcebb1a7d
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
569 changed files with 205393 additions and 0 deletions

View file

@ -0,0 +1,36 @@
if(WIN32)
set(YANGLINT_INTERACTIVE OFF)
else()
set(YANGLINT_INTERACTIVE ON)
endif()
function(add_yanglint_test)
cmake_parse_arguments(ADDTEST "" "NAME;VIA;SCRIPT" "" ${ARGN})
set(TEST_NAME yanglint_${ADDTEST_NAME})
if(${ADDTEST_VIA} STREQUAL "tclsh")
set(WRAPPER ${PATH_TCLSH})
else()
message(FATAL_ERROR "build: unexpected wrapper '${ADDTEST_VIA}'")
endif()
add_test(NAME ${TEST_NAME} COMMAND ${WRAPPER} ${CMAKE_CURRENT_SOURCE_DIR}/${ADDTEST_SCRIPT})
set_property(TEST ${TEST_NAME} APPEND PROPERTY ENVIRONMENT "TESTS_DIR=${CMAKE_CURRENT_SOURCE_DIR}")
set_property(TEST ${TEST_NAME} APPEND PROPERTY ENVIRONMENT "YANG_MODULES_DIR=${CMAKE_CURRENT_SOURCE_DIR}/modules")
set_property(TEST ${TEST_NAME} APPEND PROPERTY ENVIRONMENT "YANGLINT=${PROJECT_BINARY_DIR}")
endfunction(add_yanglint_test)
if(ENABLE_TESTS)
# tests of interactive mode using tclsh
find_program(PATH_TCLSH NAMES tclsh)
if(NOT PATH_TCLSH)
message(WARNING "'tclsh' not found! The yanglint(1) interactive tests will not be available.")
else()
if(YANGLINT_INTERACTIVE)
add_yanglint_test(NAME interactive VIA tclsh SCRIPT interactive/all.tcl)
add_yanglint_test(NAME non-interactive VIA tclsh SCRIPT non-interactive/all.tcl)
else()
add_yanglint_test(NAME non-interactive VIA tclsh SCRIPT non-interactive/all.tcl)
endif()
endif()
endif()

107
tests/yanglint/README.md Normal file
View file

@ -0,0 +1,107 @@
# yanglint testing
Testing yanglint is divided into two ways.
It is either tested in interactive mode using the tcl command 'expect' or non-interactively, classically from the command line.
For both modes, unit testing was used using the tcl package tcltest.
## How to
The sample commands in this chapter using `tclsh` are called in the `interactive` or `non-interactive` directories.
### How to run all yanglint tests?
In the build directory designated for cmake, enter:
```
ctest -R yanglint
```
### How to run all yanglint tests that are in interactive mode?
In the interactive directory, run:
```
tclsh all.tcl
```
### How to run all yanglint tests that are in non-interactive mode?
In the non-interactive directory, run:
```
tclsh all.tcl
```
### How to run all unit-tests from .test file?
```
tclsh clear.test
```
or alternatively:
```
tclsh all.tcl -file clear.test
```
### How to run one unit-test?
```
tclsh clear.test -match clear_ietf_yang_library
```
or alternatively:
```
tclsh all.tcl -file clear.test -match clear_ietf_yang_library
```
### How to run unit-tests for a certain yanglint command?
Test names are assumed to consist of the command name:
```
tclsh all.tcl -match clear*
```
### How do I get more detailed information about 'expect' for a certain test?
In the interactive directory, run:
```
tclsh clear.test -match clear_ietf_yang_library -load "exp_internal 1"
```
### How do I get more detailed dialog between 'expect' and yanglint for a certain test?
In the interactive directory, run:
```
tclsh clear.test -match clear_ietf_yang_library -load "log_user 1"
```
### How do I suppress error message from tcltest?
Probably only possible to do via `-verbose ""`
### How can I also debug?
You can write commands `interact` and `interpreter` from 'Expect' package into some test.
However, the most useful are the `exp_internal` and `log_user`, which can also be written directly into the test.
See also the rlwrap tool.
You can also use other debugging methods used in tcl programming.
### Are the tests between interactive mode and non-interactive mode similar?
Sort of...
- regex \n must be changed to \r\n in the tests for interactive yanglint
### I would like to add a new "ly_" function.
Add it to the ly.tcl file.
If you need to call other subfunctions in it, add them to namespace ly::private.
### I would like to use function other than those prefixed with "ly_".
Look in the common.tcl file in the "uti" namespace,
which contains general tcl functions that can be used in both interactive and non-interactive tests.

114
tests/yanglint/common.tcl Normal file
View file

@ -0,0 +1,114 @@
# @brief Common functions and variables for yanglint-interactive and yanglint-non-interactive.
#
# The script requires variables:
# ::env(TESTS_DIR) - Main test directory. Must be set if the script is run via ctest.
#
# The script sets the variables:
# ::env(TESTS_DIR) - Main test directory. It is set by default if not defined.
# ::env(YANG_MODULES_DIR) - Directory of YANG modules.
# TUT_PATH - Assumed absolute path to the directory in which the TUT is located.
# TUT_NAME - TUT name (without path).
# ::tcltest::testConstraint ctest - A tcltest variable that is set to true if the script is run via ctest. Causes tests
# to be a skipped.
package require tcltest
namespace import ::tcltest::test ::tcltest::cleanupTests
# Set directory paths for testing yanglint.
if { ![info exists ::env(TESTS_DIR)] } {
# the script is not run via 'ctest' so paths must be set
set ::env(TESTS_DIR) "../"
set ::env(YANG_MODULES_DIR) "../modules"
set TUT_PATH "../../../build"
::tcltest::testConstraint ctest false
} else {
# cmake (ctest) already sets ::env variables
set TUT_PATH $::env(YANGLINT)
::tcltest::testConstraint ctest true
}
set TUT_NAME "yanglint"
# The script continues by defining functions specific to the yanglint tool.
namespace eval uti {
namespace export *
}
# Iterate through the items in the list 'lst' and return a new list where
# the items will have the form: <prefix><item><suffix>.
# Parameter 'index' determines at which index it will start wrapping.
# Parameter 'step' specifies how far the iterator must move to wrap the next item.
proc uti::wrap_list_items {lst {prefix ""} {suffix ""} {index 0} {step 1}} {
# counter to track when to insert wrapper
set cnt $step
set len [llength $lst]
if {$index > 0} {
# copy list from interval <0;$index)
set ret [lrange $lst 0 [expr {$index - 1}]]
} else {
set ret {}
}
for {set i $index} {$i < $len} {incr i} {
incr cnt
set item [lindex $lst $i]
if {$cnt >= $step} {
# insert wrapper for item
set cnt 0
lappend ret [string cat $prefix $item $suffix]
} else {
# just copy item
lappend ret $item
}
}
return $ret
}
# Wrap list items with xml tags.
# The element format is: <tag>value</tag>
# Parameter 'values' is list of values.
# Parameter 'tag' is the name of the searched tag.
proc uti::wrap_to_xml {values tag {index 0} {step 1}} {
return [wrap_list_items $values "<$tag>" "</$tag>" $index $step]
}
# Wrap list items with json attributes.
# The pair format is: "attribute": "value"
# Parameter 'values' is list of values.
# Parameter 'attribute' is the name of the searched attribute.
proc uti::wrap_to_json {values attribute {index 0} {step 1}} {
return [wrap_list_items $values "\"$attribute\": \"" "\"" $index $step]
}
# Convert list to a regex (which is just a string) so that 'delim' is between items,
# 'begin' is at the beginning of the expression and 'end' is at the end.
proc uti::list_to_regex {lst {delim ".*"} {begin ".*"} {end ".*"}} {
return [string cat $begin [join $lst $delim] $end]
}
# Merge two lists into one such that the nth items are merged into one separated by a delimiter.
# Returns a list that is the same length as 'lst1' and 'lst2'
proc uti::blend_lists {lst1 lst2 {delim ".*"}} {
return [lmap a $lst1 b $lst2 {string cat $a $delim $b}]
}
# Create regex to find xml elements.
# The element format is: <tag>value</tag>
# Parameter 'values' is list of values.
# Parameter 'tag' is the name of the searched tag.
# The resulting expression looks like: ".*<tag>value1</tag>.*<tag>value2</tag>.*..."
proc uti::regex_xml_elements {values tag} {
return [list_to_regex [wrap_to_xml $values $tag]]
}
# Create regex to find json pairs.
# The pair format is: "attribute": "value"
# Parameter 'values' is list of values.
# Parameter 'attribute' is the name of the searched attribute.
# The resulting expression looks like: ".*\"attribute\": \"value1\".*\"attribute\": \"value2\".*..."
proc uti::regex_json_pairs {values attribute} {
return [list_to_regex [wrap_to_json $values $attribute]]
}

View file

@ -0,0 +1,8 @@
<con xmlns="urn:yanglint:modaction">
<ls>
<lfkey>kv</lfkey>
<act>
<lfi>some_input</lfi>
</act>
</ls>
</con>

View file

@ -0,0 +1,5 @@
<con xmlns="urn:yanglint:modaction">
<ls>
<lfkey>kv</lfkey>
</ls>
</con>

View file

@ -0,0 +1,13 @@
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<action xmlns="urn:ietf:params:xml:ns:yang:1">
<con xmlns="urn:yanglint:modaction">
<ls>
<lfkey>kv</lfkey>
<act>
<lfi>some_input</lfi>
</act>
</ls>
</con>
</action>
</rpc>

View file

@ -0,0 +1,8 @@
<con xmlns="urn:yanglint:modaction">
<ls>
<lfkey>kv</lfkey>
<act>
<lfo>-56</lfo>
</act>
</ls>
</con>

View file

@ -0,0 +1,4 @@
<rpc-reply message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<lfo xmlns="urn:yanglint:modaction">-56</lfo>
</rpc-reply>

View file

@ -0,0 +1,4 @@
<mcc xmlns="urn:yanglint:modconfig">
<lft>rw</lft>
<lff>ro</lff>
</mcc>

View file

@ -0,0 +1,3 @@
<mcc xmlns="urn:yanglint:modconfig">
<lft>rw</lft>
</mcc>

View file

@ -0,0 +1,13 @@
<yang-library xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
<module-set>
<name>main-set</name>
<module>
<name>modconfig</name>
<namespace>urn:yanglint:modconfig</namespace>
</module>
</module-set>
<content-id>1</content-id>
</yang-library>
<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
<module-set-id>1</module-set-id>
</modules-state>

View file

@ -0,0 +1,17 @@
<dnc xmlns="urn:yanglint:moddatanodes">
<lf>x</lf>
<lfl>1</lfl>
<lfl>2</lfl>
<con>
<lt>
<kalf>ka1</kalf>
<kblf>kb1</kblf>
<vlf>v1</vlf>
</lt>
<lt>
<kalf>ka2</kalf>
<kblf>kb2</kblf>
<vlf>v2</vlf>
</lt>
</con>
</dnc>

View file

@ -0,0 +1,4 @@
<mdc xmlns="urn:yanglint:moddefault">
<lf>0</lf>
<di>5</di>
</mdc>

View file

@ -0,0 +1,13 @@
<yang-library xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
<module-set>
<name>main-set</name>
<module>
<name>modimp-type</name>
<namespace>urn:yanglint:modimp-type</namespace>
</module>
</module-set>
<content-id>1</content-id>
</yang-library>
<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
<module-set-id>1</module-set-id>
</modules-state>

View file

@ -0,0 +1,3 @@
{
"modleaf:lfl": 7
}

View file

@ -0,0 +1 @@
<lfl xmlns="urn:yanglint:modleaf">7</lfl>

View file

@ -0,0 +1 @@
<lfl xmlns="urn:yanglint:modleaf">7</lfl>

View file

@ -0,0 +1,2 @@
<lfl xmlns="urn:yanglint:modleaf">7</lfl>
<lfr xmlns="urn:yanglint:modleafref">7</lfr>

View file

@ -0,0 +1,2 @@
<lfl xmlns="urn:yanglint:modleaf">7</lfl>
<lfr xmlns="urn:yanglint:modleafref">10</lfr>

View file

@ -0,0 +1,3 @@
<mmc xmlns="urn:yanglint:modmandatory">
<lft>9</lft>
</mmc>

View file

@ -0,0 +1,3 @@
<mmc xmlns="urn:yanglint:modmandatory">
<lff>9</lff>
</mmc>

View file

@ -0,0 +1,4 @@
<mmc xmlns="urn:yanglint:modmerge">
<en>one</en>
<lm>4</lm>
</mmc>

View file

@ -0,0 +1,3 @@
<mmc xmlns="urn:yanglint:modmerge">
<en>zero</en>
</mmc>

View file

@ -0,0 +1,3 @@
<mmc xmlns="urn:yanglint:modmerge">
<lf>str</lf>
</mmc>

View file

@ -0,0 +1,5 @@
<con xmlns="urn:yanglint:modnotif">
<nfn>
<lf>nested</lf>
</nfn>
</con>

View file

@ -0,0 +1,3 @@
<nfg xmlns="urn:yanglint:modnotif">
<lf>top</lf>
</nfg>

View file

@ -0,0 +1,6 @@
<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
<eventTime>2010-12-06T08:00:01Z</eventTime>
<nfg xmlns="urn:yanglint:modnotif">
<lf>top</lf>
</nfg>
</notification>

View file

@ -0,0 +1 @@
<con xmlns="urn:yanglint:modnotif"></con>

View file

@ -0,0 +1,8 @@
<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
<eventTime>2010-12-06T08:00:01Z</eventTime>
<con xmlns="urn:yanglint:modnotif">
<nfn>
<lf>nested</lf>
</nfn>
</con>
</notification>

View file

@ -0,0 +1,8 @@
<cond xmlns="urn:yanglint:modoper-leafref">
<list>
<klf>key_val</klf>
<act>
<lfi>rw</lfi>
</act>
</list>
</cond>

View file

@ -0,0 +1,8 @@
<cond xmlns="urn:yanglint:modoper-leafref">
<list>
<klf>key_val</klf>
<act>
<lfo>rw</lfo>
</act>
</list>
</cond>

View file

@ -0,0 +1,9 @@
<mcc xmlns="urn:yanglint:modconfig">
<lft>rw</lft>
<lff>ro</lff>
</mcc>
<cond xmlns="urn:yanglint:modoper-leafref">
<list>
<klf>key_val</klf>
</list>
</cond>

View file

@ -0,0 +1,3 @@
<notifg xmlns="urn:yanglint:modoper-leafref">
<lfr>rw</lfr>
</notifg>

View file

@ -0,0 +1,8 @@
<cond xmlns="urn:yanglint:modoper-leafref">
<list>
<klf>key_val</klf>
<notif>
<lfn>rw</lfn>
</notif>
</list>
</cond>

View file

@ -0,0 +1,7 @@
<mcc xmlns="urn:yanglint:modconfig">
<lft>rw</lft>
<lff>ro</lff>
</mcc>
<notifg xmlns="urn:yanglint:modoper-leafref">
<lf>rw</lf>
</notifg>

View file

@ -0,0 +1,3 @@
<rpcg xmlns="urn:yanglint:modoper-leafref">
<lfi>rw</lfi>
</rpcg>

View file

@ -0,0 +1,5 @@
<rpcg xmlns="urn:yanglint:modoper-leafref">
<cono>
<lfo>rw</lfo>
</cono>
</rpcg>

View file

@ -0,0 +1,3 @@
<rpc xmlns="urn:yanglint:modrpc">
<lfi>some_input</lfi>
</rpc>

View file

@ -0,0 +1,6 @@
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<rpc xmlns="urn:yanglint:modrpc">
<lfi>some_input</lfi>
</rpc>
</rpc>

View file

@ -0,0 +1,5 @@
<rpc xmlns="urn:yanglint:modrpc">
<con>
<lfo>-56</lfo>
</con>
</rpc>

View file

@ -0,0 +1,6 @@
<rpc-reply message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<con xmlns="urn:yanglint:modrpc">
<lfo>-56</lfo>
</con>
</rpc-reply>

View file

@ -0,0 +1,3 @@
<root xmlns="urn:yanglint:modsm">
<lfl xmlns="urn:yanglint:modleaf">7</lfl>
</root>

View file

@ -0,0 +1,4 @@
<root xmlns="urn:yanglint:modsm">
<lfl xmlns="urn:yanglint:modleaf">7</lfl>
<alf xmlns="urn:yanglint:modsm-augment">str</alf>
</root>

View file

@ -0,0 +1,20 @@
<yang-library xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
<module-set>
<name>test-set</name>
<module>
<name>modleaf</name>
<namespace>urn:yanglint:modleaf</namespace>
</module>
</module-set>
<content-id>1</content-id>
</yang-library>
<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
<module-set-id>1</module-set-id>
</modules-state>
<schema-mounts xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount">
<mount-point>
<module>modsm</module>
<label>root</label>
<inline></inline>
</mount-point>
</schema-mounts>

View file

@ -0,0 +1,17 @@
<yang-library xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
<module-set>
<name>main-set</name>
<module>
<name>modsm</name>
<namespace>urn:yanglint:modsm</namespace>
</module>
<module>
<name>modsm-augment</name>
<namespace>urn:yanglint:modsm-augment</namespace>
</module>
</module-set>
<content-id>1</content-id>
</yang-library>
<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
<module-set-id>1</module-set-id>
</modules-state>

View file

@ -0,0 +1,59 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set mdir $::env(YANG_MODULES_DIR)
test add_basic {} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "add $mdir/modleafref.yang"
ly_cmd "list" "I modleafref\r.*I modleaf"
}}
test add_disable_searchdir_once {add --disable-searchdir} {
-setup $ly_setup -cleanup $ly_cleanup -constraints {!ctest} -body {
ly_cmd "add $mdir/modimp-cwd.yang"
ly_cmd "clear"
ly_cmd_err "add -D $mdir/modimp-cwd.yang" "not found in local searchdirs"
}}
test add_disable_searchdir_twice {add -D -D} {
-setup $ly_setup -cleanup $ly_cleanup -constraints {!ctest} -body {
ly_cmd "add $mdir/ietf-ip.yang"
ly_cmd "clear"
ly_cmd_err "add -D -D $mdir/ietf-ip.yang" "Loading \"ietf-interfaces\" module failed."
}}
test add_with_feature {Add module with feature} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "add --feature modfeature:ftr2 $mdir/modfeature.yang"
ly_cmd "feature -a" "modfeature:\r\n\tftr1 \\(off\\)\r\n\tftr2 \\(on\\)"
}}
test add_make_implemented_once {add --make-implemented} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_ignore "add $mdir/modmust.yang"
ly_cmd "list" "I modmust\r.*i modleaf"
ly_cmd "clear"
ly_ignore "add -i $mdir/modmust.yang"
ly_cmd "list" "I modmust\r.*I modleaf"
}}
test add_make_implemented_twice {add -i -i} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "add $mdir/modimp-type.yang"
ly_cmd "list" "I modimp-type\r.*i modtypedef"
ly_cmd "clear"
ly_cmd "add -i -i $mdir/modimp-type.yang"
ly_cmd "list" "I modimp-type\r.*I modtypedef"
}}
test add_extended_leafref_enabled {Valid module with --extended-leafref option} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "add -X $mdir/modextleafref.yang"
}}
test add_extended_leafref_disabled {Expected error if --extended-leafref is not set} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd_err "add $mdir/modextleafref.yang" "Unexpected XPath token \"FunctionName\""
}}
cleanupTests

View file

@ -0,0 +1,15 @@
package require tcltest
# Hook to determine if any of the tests failed.
# Sets a global variable exitCode to 1 if any test fails otherwise it is set to 0.
proc tcltest::cleanupTestsHook {} {
variable numTests
set ::exitCode [expr {$numTests(Failed) > 0}]
}
if {[info exists ::env(TESTS_DIR)]} {
tcltest::configure -testdir "$env(TESTS_DIR)/interactive"
}
tcltest::runAllTests
exit $exitCode

View file

@ -0,0 +1,53 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set mdir $::env(YANG_MODULES_DIR)
set ddir $::env(TESTS_DIR)/data
test clear_searchpath {searchpath is also deleted} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "searchpath ./"
ly_cmd "clear"
ly_cmd "searchpath" "List of the searchpaths:" -ex
}}
test clear_make_implemented_once {clear --make-implemented} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -i"
ly_cmd "add $mdir/modmust.yang"
ly_cmd "list" "I modmust\r.*I modleaf"
}}
test clear_make_implemented_twice {clear -i -i} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -i -i"
ly_cmd "add $mdir/modmust.yang"
ly_cmd "list" "I modmust\r.*I modleaf"
}}
test clear_ietf_yang_library {clear --yang-library} {
-setup $ly_setup -cleanup $ly_cleanup -body {
# add models
ly_cmd "clear -y"
ly_cmd "list" "I ietf-yang-library"
}}
test clear_ylf_list {apply --yang-library-file and check result by --list} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -Y $ddir/modimp_type_ctx.xml"
ly_cmd "list" "I modimp-type.*i modtypedef"
}}
test clear_ylf_make_implemented {apply --yang-library-file and --make-implemented} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -Y $ddir/modimp_type_ctx.xml -i -i"
ly_cmd "list" "I modimp-type.*I modtypedef"
}}
test clear_ylf_augment_ctx {Setup context by yang-library-file and augment module} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -Y $ddir/modconfig_ctx.xml"
ly_cmd "add $mdir/modconfig-augment.yang"
ly_cmd "print -f tree modconfig" "mca:alf"
}}
cleanupTests

View file

@ -0,0 +1,69 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set mdir "$::env(YANG_MODULES_DIR)"
variable ly_cleanup {
ly_ignore
ly_exit
}
test completion_hints_ietf_ip {Completion and hints for ietf-ip.yang} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "add $mdir/ietf-ip.yang"
# completion and hint
ly_completion "print -f info -P " "print -f info -P /ietf-"
set hints {"/ietf-yang-schema-mount:schema-mounts" "/ietf-interfaces:interfaces" "/ietf-interfaces:interfaces-state"}
ly_hint "" "print -f info -P /ietf-" $hints
# double completion
ly_completion "i" "print -f info -P /ietf-interfaces:interfaces"
ly_completion "/" "print -f info -P /ietf-interfaces:interfaces/interface"
# a lot of hints
set hints {"/ietf-interfaces:interfaces/interface"
"/ietf-interfaces:interfaces/interface/name" "/ietf-interfaces:interfaces/interface/description"
"/ietf-interfaces:interfaces/interface/type" "/ietf-interfaces:interfaces/interface/enabled"
"/ietf-interfaces:interfaces/interface/link-up-down-trap-enable"
"/ietf-interfaces:interfaces/interface/ietf-ip:ipv4" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6"
}
ly_hint "" "print -f info -P /ietf-interfaces:interfaces/interface" $hints
# double tab
ly_completion "/i" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv"
ly_completion "4" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv4"
set hints { "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/enabled"
"/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/forwarding" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/mtu"
"/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/neighbor"
}
ly_hint "\t" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv" $hints
# no more completion
ly_completion "/e" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv4/enabled "
}}
# Note that somehow a command is automatically sent again (\t\t replaced by \r) after the hints.
# But that doesn't affect the test because the tests only focus on the word in the hint.
test hint_data_file {Show file hints for command data} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_hint "data $mdir\t\t" "data $mdir" "modleaf.yang.*"
}}
test hint_data_format {Show print hints for command data --format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_hint "data -f \t\t" "data -f " "xml.*"
}}
test hint_data_file_after_opt {Show file hints after option with argument} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_hint "data -f xml $mdir\t\t" "data -f xml $mdir" "modleaf.yang.*"
}}
test hint_data_file_after_opt2 {Show file hints after option without argument} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_hint "data -m $mdir\t\t" "data -m $mdir" "modleaf.yang.*"
}}
cleanupTests

View file

@ -0,0 +1,41 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set mods "ietf-netconf-with-defaults moddefault"
set data "$::env(TESTS_DIR)/data/moddefault.xml"
test data_default_not_set {Print data without --default parameter} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load $mods"
ly_cmd "data -f xml $data" "</lf>.*</di>\r\n</mdc>"
ly_cmd "data -f json $data" "lf\".*di\"\[^\"]*"
}}
test data_default_all {data --default all} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load $mods"
ly_cmd "data -d all -f xml $data" "</lf>.*</di>.*</ds>\r\n</mdc>"
ly_cmd "data -d all -f json $data" "lf\".*di\".*ds\"\[^\"]*"
}}
test data_default_all_tagged {data --default all-tagged} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load $mods"
ly_cmd "data -d all-tagged -f xml $data" "</lf>.*<di.*default.*</di>.*<ds.*default.*</ds>\r\n</mdc>"
ly_cmd "data -d all-tagged -f json $data" "lf\".*di\".*ds\".*@ds\".*default\"\[^\"]*"
}}
test data_default_trim {data --default trim} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load $mods"
ly_cmd "data -d trim -f xml $data" "</lf>\r\n</mdc>"
ly_cmd "data -d trim -f json $data" "lf\"\[^\"]*"
}}
test data_default_implicit_tagged {data --default implicit-tagged} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load $mods"
ly_cmd "data -d implicit-tagged -f xml $data" "</lf>.*<di>5</di>.*<ds.*default.*</ds>\r\n</mdc>"
ly_cmd "data -d implicit-tagged -f json $data" "lf\".*di\"\[^@]*ds\".*default\"\[^\"]*"
}}
cleanupTests

View file

@ -0,0 +1,23 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set ddir "$::env(TESTS_DIR)/data"
test data_format_xml {Print data in xml format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd "data -f xml $ddir/modleaf.xml" "<lfl xmlns=\"urn:yanglint:modleaf\">7</lfl>"
}}
test data_format_json {Print data in json format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd "data -f json $ddir/modleaf.xml" "{\r\n \"modleaf:lfl\": 7\r\n}"
}}
test data_format_lyb_err {Print data in lyb format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd_err "data -f lyb $ddir/modleaf.xml" "The LYB format requires the -o"
}}
cleanupTests

View file

@ -0,0 +1,21 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set ddir "$::env(TESTS_DIR)/data"
test data_in_format_xml {--in-format xml} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd "data -F xml $ddir/modleaf.dxml"
ly_cmd_err "data -F json $ddir/modleaf.dxml" "Failed to parse"
ly_cmd_err "data -F lyb $ddir/modleaf.dxml" "Failed to parse"
}}
test data_in_format_json {--in-format json} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd "data -F json $ddir/modleaf.djson"
ly_cmd_err "data -F xml $ddir/modleaf.djson" "Failed to parse"
ly_cmd_err "data -F lyb $ddir/modleaf.djson" "Failed to parse"
}}
cleanupTests

View file

@ -0,0 +1,33 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set ddir "$::env(TESTS_DIR)/data"
test data_merge_basic {Data is merged and the node is added} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modmerge"
ly_cmd "data -m -f xml $ddir/modmerge.xml $ddir/modmerge3.xml" "<en>.*<lm>.*<lf>"
}}
test data_merge_validation_failed {Data is merged but validation failed.} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modmerge"
ly_cmd "data $ddir/modmerge.xml"
ly_cmd "data $ddir/modmerge2.xml"
ly_cmd "data -m $ddir/modmerge2.xml $ddir/modmerge.xml"
ly_cmd_err "data -m $ddir/modmerge.xml $ddir/modmerge2.xml" "Merged data are not valid"
}}
test data_merge_dataconfig {The merge option has effect only for 'data' and 'config' TYPEs} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modrpc modnotif modconfig modleaf"
set wrn1 "option has effect only for"
ly_cmd_wrn "data -m -t rpc $ddir/modrpc.xml $ddir/modrpc.xml" $wrn1
ly_cmd_wrn "data -m -t notif $ddir/modnotif2.xml $ddir/modnotif2.xml" $wrn1
ly_cmd_wrn "data -m -t get $ddir/modleaf.xml $ddir/modconfig.xml" $wrn1
ly_cmd_wrn "data -m -t getconfig $ddir/modleaf.xml $ddir/modconfig2.xml" $wrn1
ly_cmd_wrn "data -m -t edit $ddir/modleaf.xml $ddir/modconfig2.xml" $wrn1
ly_cmd "data -m -t config $ddir/modleaf.xml $ddir/modconfig2.xml"
ly_cmd "data -m -t data $ddir/modleaf.xml $ddir/modconfig.xml"
}}
cleanupTests

View file

@ -0,0 +1,25 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set ddir $::env(TESTS_DIR)/data
test data_no_strict_basic {} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd_err "data $ddir/modmandatory.xml" "No module with namespace \"urn:yanglint:modmandatory\" in the context."
ly_cmd "data -n $ddir/modmandatory.xml"
}}
test data_no_strict_invalid_data {validation with --no-strict but data are invalid} {
-setup $ly_setup -cleanup $ly_cleanup -body {
set errmsg "Mandatory node \"lft\" instance does not exist."
ly_cmd "load modmandatory"
ly_cmd_err "data -n $ddir/modmandatory_invalid.xml" $errmsg
}}
test data_no_strict_ignore_invalid_data {--no-strict ignore invalid data if no schema is provided} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd "data -f xml -n $ddir/modmandatory_invalid.xml $ddir/modleaf.xml" "modleaf.*</lfl>$"
}}
cleanupTests

View file

@ -0,0 +1,86 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set ddir "$::env(TESTS_DIR)/data"
set err1 "Operational datastore takes effect only with RPCs/Actions/Replies/Notification input data types"
test data_operational_twice {it is not allowed to specify more than one --operational parameter} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modoper-leafref"
ly_cmd "data -t notif -O $ddir/modconfig.xml -O $ddir/modleaf.xml" "cannot be set multiple times"
}}
test data_operational_no_type {--operational should be with parameter --type} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modoper-leafref"
ly_cmd_wrn "data -O $ddir/modconfig.xml $ddir/modoper_leafref_notif.xml" $err1
}}
test data_operational_missing {--operational is omitted and the datastore contents is in the data file} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modoper-leafref"
ly_cmd_err "data $ddir/modoper_leafref_notif_err.xml" "Failed to parse input data file"
}}
test data_operational_wrong_type {data are not defined as an operation} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd_wrn "data -t data -O $ddir/modconfig.xml $ddir/modleaf.xml" $err1
}}
test data_operational_datastore_with_unknown_data {unknown data are ignored} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modrpc"
ly_cmd "data -t rpc -O $ddir/modmandatory_invalid.xml $ddir/modrpc.xml"
}}
test data_operational_empty_datastore {datastore is considered empty because it contains unknown data} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modrpc modnotif"
ly_cmd "data -t rpc -O $ddir/modmandatory_invalid.xml $ddir/modrpc.xml"
set msg "parent \"/modnotif:con\" not found in the operational data"
ly_cmd_err "data -t notif -O $ddir/modmandatory_invalid.xml $ddir/modnotif.xml" $msg
}}
test data_operational_notif_leafref {--operational data is referenced from notification-leafref} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modoper-leafref"
ly_cmd "data -t notif -O $ddir/modconfig.xml $ddir/modoper_leafref_notif.xml"
}}
test data_operational_nested_notif_leafref {--operational data is referenced from nested-notification-leafref} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modoper-leafref"
ly_cmd "data -t notif -O $ddir/modoper_leafref_ds.xml $ddir/modoper_leafref_notif2.xml"
}}
test data_operational_nested_notif_parent_missing {--operational data are invalid due to missing parent node} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modoper-leafref"
set msg "klf='key_val']\" not found in the operational data"
ly_cmd_err "data -t notif -O $ddir/modconfig.xml $ddir/modoper_leafref_notif2.xml" $msg
}}
test data_operational_action_leafref {--operational data is referenced from action-leafref} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modoper-leafref"
ly_cmd "data -t rpc -O $ddir/modoper_leafref_ds.xml $ddir/modoper_leafref_action.xml"
}}
test data_operational_action_reply_leafref {--operational data is referenced from action-leafref output} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modoper-leafref"
ly_cmd "data -t reply -O $ddir/modoper_leafref_ds.xml $ddir/modoper_leafref_action_reply.xml"
}}
test data_operational_rpc_leafref {--operational data is referenced from rpc-leafref} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modoper-leafref"
ly_cmd "data -t rpc -O $ddir/modconfig.xml $ddir/modoper_leafref_rpc.xml"
}}
test data_operational_rpc_reply_leafref {--operational data is referenced from rpc-leafref output} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modoper-leafref"
ly_cmd "data -t reply -O $ddir/modconfig.xml $ddir/modoper_leafref_rpc_reply.xml"
}}
cleanupTests

View file

@ -0,0 +1,25 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set ddir "$::env(TESTS_DIR)/data"
test data_present_via_mandatory {validation of mandatory-stmt will pass only with the --present} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf modmandatory"
ly_cmd_err "data $ddir/modleaf.xml" "Mandatory node \"lft\" instance does not exist."
ly_cmd "data -e $ddir/modleaf.xml"
}}
test data_present_merge {validation with --present and --merge} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf modmandatory moddefault"
ly_cmd_err "data -m $ddir/modleaf.xml $ddir/moddefault.xml" "Mandatory node \"lft\" instance does not exist."
ly_cmd "data -e -m $ddir/modleaf.xml $ddir/moddefault.xml"
}}
test data_present_merge_invalid {using --present and --merge but data are invalid} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf modmandatory"
ly_cmd_err "data -e -m $ddir/modleaf.xml $ddir/modmandatory_invalid.xml" "Mandatory node \"lft\" instance does not exist."
}}
cleanupTests

View file

@ -0,0 +1,140 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set ddir "$::env(TESTS_DIR)/data"
test data_type_data {data --type data} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modconfig"
ly_cmd "data -t data $ddir/modconfig.xml"
}}
test data_type_config {data --type config} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modconfig"
ly_cmd_err "data -t config $ddir/modconfig.xml" "Unexpected data state node \"lff\""
ly_cmd "data -t config $ddir/modconfig2.xml"
}}
test data_type_get {data --type get} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleafref"
ly_cmd_err "data -t data $ddir/modleafref2.xml" "Invalid leafref value"
ly_cmd "data -t get $ddir/modleafref2.xml"
}}
test data_type_getconfig_no_state {No state node for data --type getconfig} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modconfig"
ly_cmd_err "data -t getconfig $ddir/modconfig.xml" "Unexpected data state node \"lff\""
ly_cmd "data -t getconfig $ddir/modconfig2.xml"
}}
test data_type_getconfig_parse_only {No validation performed for data --type getconfig} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleafref"
ly_cmd_err "data -t data $ddir/modleafref2.xml" "Invalid leafref value"
ly_cmd "data -t getconfig $ddir/modleafref2.xml"
}}
test data_type_edit_no_state {No state node for data --type edit} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modconfig"
ly_cmd_err "data -t edit $ddir/modconfig.xml" "Unexpected data state node \"lff\""
ly_cmd "data -t edit $ddir/modconfig2.xml"
}}
test data_type_edit_parse_only {No validation performed for data --type edit} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleafref"
ly_cmd_err "data -t data $ddir/modleafref2.xml" "Invalid leafref value"
ly_cmd "data -t edit $ddir/modleafref2.xml"
}}
test data_type_rpc {Validation of rpc-statement by data --type rpc} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modrpc modleaf"
ly_cmd_err "data -t rpc $ddir/modleaf.xml" "Missing the operation node."
ly_cmd "data -t rpc $ddir/modrpc.xml"
}}
test data_type_rpc_nc {Validation of rpc-statement by data --type nc-rpc} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modrpc modleaf ietf-netconf"
ly_cmd_err "data -t nc-rpc $ddir/modleaf.xml" "Missing NETCONF <rpc> envelope"
ly_cmd "data -t nc-rpc $ddir/modrpc_nc.xml"
}}
test data_type_rpc_reply {Validation of rpc-reply by data --type reply} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modrpc modleaf"
ly_cmd_err "data -t rpc $ddir/modleaf.xml" "Missing the operation node."
ly_cmd_wrn "data -t reply -R $ddir/modrpc.xml $ddir/modrpc_reply.xml" "needed only for NETCONF"
ly_cmd "data -t reply $ddir/modrpc_reply.xml"
}}
test data_type_rpc_reply_nc {Validation of rpc-reply by data --type nc-reply} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modrpc modleaf"
ly_cmd_err "data -t nc-reply -R $ddir/modrpc_nc.xml $ddir/modleaf.xml" "Missing NETCONF <rpc-reply> envelope"
ly_cmd_err "data -t nc-reply $ddir/modrpc_reply_nc.xml" "Missing source RPC"
ly_cmd "data -t nc-reply -R $ddir/modrpc_nc.xml $ddir/modrpc_reply_nc.xml"
}}
test data_type_rpc_action {Validation of action-statement by data --type rpc} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modaction modleaf"
ly_cmd_err "data -t rpc $ddir/modleaf.xml" "Missing the operation node."
ly_cmd "data -t rpc -O $ddir/modaction_ds.xml $ddir/modaction.xml"
}}
test data_type_rpc_action_nc {Validation of action-statement by data --type nc-rpc} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modaction modleaf"
ly_cmd_err "data -t nc-rpc $ddir/modleaf.xml" "Missing NETCONF <rpc> envelope"
ly_cmd "data -t nc-rpc -O $ddir/modaction_ds.xml $ddir/modaction_nc.xml"
}}
test data_type_rpc_action_reply {Validation of action-reply by data --type reply} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modaction modleaf"
ly_cmd_err "data -t rpc $ddir/modleaf.xml" "Missing the operation node."
ly_cmd "data -t reply -O $ddir/modaction_ds.xml $ddir/modaction_reply.xml"
}}
test data_type_rpc_action_reply_nc {Validation of action-reply by data --type nc-reply} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modaction modleaf"
ly_cmd_err "data -t nc-reply -R $ddir/modaction_nc.xml $ddir/modleaf.xml" "Missing NETCONF <rpc-reply> envelope"
ly_cmd_err "data -t nc-reply $ddir/modaction_reply_nc.xml" "Missing source RPC"
ly_cmd_err "data -t nc-reply -R $ddir/modaction_nc.xml $ddir/modaction_reply_nc.xml" "operational parameter needed"
ly_cmd "data -t nc-reply -O $ddir/modaction_ds.xml -R $ddir/modaction_nc.xml $ddir/modaction_reply_nc.xml"
}}
test data_type_notif {Validation of notification-statement by data --type notif} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modnotif modleaf"
ly_cmd_err "data -t notif $ddir/modleaf.xml" "Missing the operation node."
ly_cmd "data -t notif $ddir/modnotif2.xml"
}}
test data_type_notif_nc {Validation of notification-statement by data --type nc-notif} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modnotif modleaf ietf-netconf"
ly_cmd_err "data -t nc-notif $ddir/modleaf.xml" "Missing NETCONF <notification> envelope"
ly_cmd "data -t nc-notif $ddir/modnotif2_nc.xml"
}}
test data_type_notif_nested {Validation of nested-notification-statement by data --type notif} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modnotif modleaf"
ly_cmd "data -t notif -O $ddir/modnotif_ds.xml $ddir/modnotif.xml"
}}
test data_type_notif_nested_nc {Validation of nested-notification-statement by data --type nc-notif} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modnotif modleaf ietf-netconf"
ly_cmd_err "data -t nc-notif $ddir/modleaf.xml" "Missing NETCONF <notification> envelope"
ly_cmd "data -t nc-notif -O $ddir/modnotif_ds.xml $ddir/modnotif_nc.xml"
}}
cleanupTests

View file

@ -0,0 +1,57 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set data "$::env(TESTS_DIR)/data/moddatanodes.xml"
test data_xpath_empty {--xpath to missing node} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load moddatanodes"
ly_cmd "data -x /moddatanodes:dnc/mis $data" "Empty"
}}
test data_xpath_leaf {--xpath to leaf node} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load moddatanodes"
ly_cmd "data -x /moddatanodes:dnc/lf $data" "leaf \"lf\" \\(value: \"x\"\\)"
}}
test data_xpath_leaflist {--xpath to leaf-list node} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load moddatanodes"
set r1 "leaf-list \"lfl\" \\(value: \"1\"\\)"
set r2 "leaf-list \"lfl\" \\(value: \"2\"\\)"
ly_cmd "data -x /moddatanodes:dnc/lfl $data" "$r1\r\n $r2"
}}
test data_xpath_list {--xpath to list} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load moddatanodes"
set r1 "list \"lt\" \\(\"kalf\": \"ka1\"; \"kblf\": \"kb1\";\\)"
set r2 "list \"lt\" \\(\"kalf\": \"ka2\"; \"kblf\": \"kb2\";\\)"
ly_cmd "data -x /moddatanodes:dnc/con/lt $data" "$r1\r\n $r2"
}}
test data_xpath_container {--xpath to container} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load moddatanodes"
ly_cmd "data -x /moddatanodes:dnc/con $data" "container \"con\""
}}
test data_xpath_wrong_path {--xpath to a non-existent node} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load moddatanodes"
ly_cmd_err "data -x /moddatanodes:dnc/wrng $data" "xpath failed"
}}
test data_xpath_err_format {--xpath cannot be combined with --format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load moddatanodes"
ly_cmd_err "data -f xml -x /moddatanodes:dnc/lf $data" "option cannot be combined"
}}
test data_xpath_err_default {--xpath cannot be combined with --default} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load moddatanodes ietf-netconf-with-defaults"
ly_cmd_err "data -d all -x /moddatanodes:dnc/lf $data" "option cannot be combined"
}}
cleanupTests

View file

@ -0,0 +1,33 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set mdir $::env(YANG_MODULES_DIR)
test debug_dict {Check debug message DICT} {
-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body {
ly_cmd "verb debug"
ly_cmd "debug dict"
ly_cmd "load modleaf" "DICT"
}}
test debug_xpath {Check debug message XPATH} {
-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body {
ly_cmd "verb debug"
ly_cmd "debug xpath"
ly_cmd "load modmust" "XPATH"
}}
test debug_dep_sets {Check debug message DEPSETS} {
-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body {
ly_cmd "verb debug"
ly_cmd "debug dep-sets"
ly_cmd "load modleaf" "DEPSETS"
}}
test debug_depsets_xpath {Check debug message DEPSETS and XPATH} {
-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body {
ly_cmd "verb debug"
ly_cmd "debug dep-sets xpath"
ly_cmd "load modmust" "DEPSETS.*XPATH"
}}
cleanupTests

View file

@ -0,0 +1,63 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set mdir "$::env(YANG_MODULES_DIR)"
set ddir "$::env(TESTS_DIR)/data"
test extdata_set_clear {Set and clear extdata file} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "extdata" "No file set"
ly_cmd "extdata $ddir/modsm_ctx_ext.xml"
ly_cmd "extdata" "$ddir/modsm_ctx_ext.xml"
ly_cmd "extdata -c"
ly_cmd "extdata" "No file set"
}}
test extdata_clear_cmd {Clear extdata file by 'clear' command} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "extdata $ddir/modsm_ctx_ext.xml"
ly_cmd "clear"
ly_cmd "extdata" "No file set"
}}
test extdata_one_only {Only one file for extdata} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd_err "extdata $ddir/modsm_ctx_ext.xml $ddir/modsm_ctx_ext.xml" "Only one file must be entered"
}}
test extdata_schema_mount_tree {Print tree output of a model with Schema Mount} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -y"
ly_cmd "searchpath $mdir"
ly_cmd "load modsm"
ly_cmd "extdata $ddir/modsm_ctx_ext.xml"
ly_cmd "print -f tree modsm" "--mp root.*--rw lfl/"
}}
test ext_data_schema_mount_tree_yanglibfile {Print tree output of a model with Schema Mount and --yang-library-file} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -Y $ddir/modsm_ctx_main.xml"
ly_cmd "searchpath $mdir"
ly_cmd "load modsm"
ly_cmd "extdata $ddir/modsm_ctx_ext.xml"
ly_cmd "print -f tree modsm" "--mp root.*--rw lfl/.*--rw msa:alf?"
}}
test ext_data_schema_mount_xml {Validating and printing mounted data} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -y"
ly_cmd "searchpath $mdir"
ly_cmd "load modsm"
ly_cmd "extdata $ddir/modsm_ctx_ext.xml"
ly_cmd "data -f xml -t config $ddir/modsm.xml" "</lfl>"
}}
test ext_data_schema_mount_xml_yanglibfile {Validating and printing mounted data with --yang-library-file} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -Y $ddir/modsm_ctx_main.xml"
ly_cmd "searchpath $mdir"
ly_cmd "load modsm"
ly_cmd "extdata $ddir/modsm_ctx_ext.xml"
ly_cmd "data -f xml -t config $ddir/modsm2.xml" "</lfl>.*</alf>"
}}
cleanupTests

View file

@ -0,0 +1,37 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
test feature_all_default {Default output of feature --all} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "feature -a" "yang:\r\n\t(none)\r\n\r\nietf-yang-schema-mount:\r\n\t(none)\r\n" -ex
}}
test feature_all_add_module {Add module with only one feature and call feature --all} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load --feature modfeature:ftr1 modfeature"
ly_cmd "feature -a" "modfeature:\r\n\tftr1 \\(on\\)\r\n\tftr2 \\(off\\)"
}}
test feature_all_on {Add module with all enabled features and call feature --all} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load --feature modfeature:* modfeature"
ly_cmd "feature -a" "modfeature:\r\n\tftr1 \\(on\\)\r\n\tftr2 \\(on\\)"
}}
test feature_one_module {Show features for one module} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load ietf-ip"
ly_cmd "feature -f ietf-ip" " -F ietf-ip:ipv4-non-contiguous-netmasks,ipv6-privacy-autoconf" -ex
}}
test feature_more_modules {Show a mix of modules with and without features} {
-setup $ly_setup -cleanup $ly_cleanup -body {
set features " -F modfeature:ftr1,ftr2\
-F modleaf:\
-F ietf-ip:ipv4-non-contiguous-netmasks,ipv6-privacy-autoconf"
ly_cmd "load ietf-ip modleaf modfeature"
ly_cmd "feature -f modfeature modleaf ietf-ip" $features -ex
}}
cleanupTests

View file

@ -0,0 +1,34 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
namespace import uti::regex_xml_elements uti::regex_json_pairs
set modules {ietf-yang-library ietf-inet-types}
test list_basic {basic test} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "list" "ietf-yang-types"
}}
test list_format_xml {list --format xml} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -y"
ly_cmd "list -f xml" [regex_xml_elements $modules "name"]
}}
test list_format_json {list --format json} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -y"
ly_cmd "list -f json" [regex_json_pairs $modules "name"]
}}
test list_ietf_yang_library {Error due to missing ietf-yang-library} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd_err "list -f xml" "Module \"ietf-yang-library\" is not implemented."
}}
test list_bad_format {Error due to bad format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "clear -y"
ly_cmd_err "list -f csv" "Unknown output format csv"
}}
cleanupTests

View file

@ -0,0 +1,45 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
test load_basic {} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleafref"
ly_cmd "list" "I modleafref\r.*I modleaf"
}}
test load_with_feature {Load module with feature} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load --feature modfeature:ftr2 modfeature"
ly_cmd "feature -a" "modfeature:\r\n\tftr1 \\(off\\)\r\n\tftr2 \\(on\\)"
}}
test load_make_implemented_once {load --make-implemented} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_ignore "load modmust"
ly_cmd "list" "I modmust\r.*i modleaf"
ly_cmd "clear"
ly_cmd "searchpath $::env(YANG_MODULES_DIR)"
ly_cmd "load -i modmust"
ly_cmd "list" "I modmust\r.*I modleaf"
}}
test load_make_implemented_twice {load -i -i} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modimp-type"
ly_cmd "list" "I modimp-type\r.*i modtypedef"
ly_cmd "clear"
ly_cmd "searchpath $::env(YANG_MODULES_DIR)"
ly_cmd "load -i -i modimp-type"
ly_cmd "list" "I modimp-type\r.*I modtypedef"
}}
test load_extended_leafref_enabled {Valid module with --extended-leafref option} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load -X modextleafref"
}}
test load_extended_leafref_disabled {Expected error if --extended-leafref is not set} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd_err "load modextleafref" "Unexpected XPath token \"FunctionName\""
}}
cleanupTests

View file

@ -0,0 +1,81 @@
# @brief The main source of functions and variables for testing yanglint in the interactive mode.
# For testing yanglint.
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/common.tcl" : "../common.tcl"}]
# For testing any interactive tool.
source "$::env(TESTS_DIR)/../tool_i.tcl"
# The script continues by defining variables and functions specific to the interactive yanglint tool.
# set the timeout to 5 seconds
set timeout 5
# prompt of yanglint
set prompt "> "
# turn off dialog between expect and yanglint
log_user 0
# setting some large terminal width
stty columns 720
# default setup for every unit test
variable ly_setup {
spawn $TUT
ly_skip_warnings
# Searchpath is set, so modules can be loaded via the 'load' command.
ly_cmd "searchpath $::env(YANG_MODULES_DIR)"
}
# default cleanup for every unit test
variable ly_cleanup {
ly_exit
}
# Skip no dir and/or no history warnings and prompt.
proc ly_skip_warnings {} {
global prompt
expect -re "(YANGLINT.*)*$prompt" {}
}
# Send command 'cmd' to the process, expect error header and then check output string by 'pattern'.
# Parameter cmd is a string of arguments.
# Parameter pattern is a regex. It must not contain a prompt.
proc ly_cmd_err {cmd pattern} {
global prompt
send -- "${cmd}\r"
expect -- "${cmd}\r\n"
expect {
-re "YANGLINT\\\[E\\\]: .*${pattern}.*\r\n${prompt}$" {}
-re "libyang\\\[\[0-9]+\\\]: .*${pattern}.*\r\n${prompt}$" {}
-re "\r\n${prompt}$" {
error "unexpected output:\n$expect_out(buffer)"
}
}
}
# Send command 'cmd' to the process, expect warning header and then check output string by 'pattern'.
# Parameter cmd is a string of arguments.
# Parameter pattern is a regex. It must not contain a prompt.
proc ly_cmd_wrn {cmd pattern} {
ly_cmd_header $cmd "YANGLINT\\\[W\\\]:" $pattern
}
# Send 'exit' and wait for eof.
proc ly_exit {} {
send "exit\r"
expect eof
}
# Check if yanglint is configured as DEBUG.
# Return 1 on success.
proc yanglint_debug {} {
global TUT
# Call non-interactive yanglint with --help.
set output [exec -- $TUT "-h"]
# Find option --debug.
if { [regexp -- "--debug=GROUPS" $output] } {
return 1
} else {
return 0
}
}

View file

@ -0,0 +1,4 @@
module modcwd {
namespace "urn:yanglint:modcwd";
prefix mc;
}

View file

@ -0,0 +1,77 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set ipv6_path "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address"
test print_yang {} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd "print -f yang modleaf" "leaf lfl"
}}
test print_yang_submodule {Print submodule in yang format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modinclude"
ly_cmd "print -f yang modsub" "submodule modsub"
}}
test print_yin {} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd "print -f yin modleaf" "<leaf name=\"lfl\">"
}}
test print_yin_submodule {Print submodule in yin format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modinclude"
ly_cmd "print -f yin modsub" "<submodule name=\"modsub\""
}}
test print_info {} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd "print -f info modleaf" "status current"
}}
test print_info_path {Print subtree in info format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load ietf-ip"
ly_cmd "print -f info -P $ipv6_path" "^list address .* leaf prefix-length"
}}
test print_info_path_single_node {Print node in info format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load ietf-ip"
ly_cmd "print -f info -q -P $ipv6_path" "^list address .* IPv6 addresses on the interface.\";\r\n\}$"
}}
test print_tree {} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modleaf"
ly_cmd "print -f tree modleaf" "\\+--rw lfl"
}}
test print_tree_submodule {Print submodule in tree format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load modinclude"
ly_cmd "print -f tree modsub" "submodule: modsub"
}}
test print_tree_path {Print subtree in tree format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load ietf-ip"
ly_cmd "print -f tree -P $ipv6_path" "\\+--rw address.*\\+--rw prefix-length"
}}
test print_tree_path_single_node {Print node in tree format} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load ietf-ip"
ly_cmd "print -f tree -q -P $ipv6_path" "\\+--rw address\\* \\\[ip\\\]$"
}}
test print_tree_path_single_node_line_length {Print node in the tree format and limit row size} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "load ietf-ip"
ly_cmd "print -f tree -L 20 -q -P $ipv6_path" "\\+--rw address\\*\r\n *\\\[ip\\\]$"
}}
cleanupTests

View file

@ -0,0 +1,24 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}]
set mdir $::env(YANG_MODULES_DIR)
variable ly_setup {
spawn $TUT
ly_skip_warnings
}
test searchpath_basic {} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "searchpath $mdir"
ly_cmd "searchpath" "$mdir"
ly_cmd "load modleaf"
}}
test searchpath_clear {searchpath --clear} {
-setup $ly_setup -cleanup $ly_cleanup -body {
ly_cmd "searchpath $mdir"
ly_cmd "searchpath --clear"
ly_cmd_err "load modleaf" "Data model \"modleaf\" not found in local searchdirs"
}}
cleanupTests

View file

@ -0,0 +1,725 @@
module ietf-interfaces {
namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
prefix if;
import ietf-yang-types {
prefix yang;
}
organization
"IETF NETMOD (NETCONF Data Modeling Language) Working Group";
contact
"WG Web: <http://tools.ietf.org/wg/netmod/>
WG List: <mailto:netmod@ietf.org>
WG Chair: Thomas Nadeau
<mailto:tnadeau@lucidvision.com>
WG Chair: Juergen Schoenwaelder
<mailto:j.schoenwaelder@jacobs-university.de>
Editor: Martin Bjorklund
<mailto:mbj@tail-f.com>";
description
"This module contains a collection of YANG definitions for
managing network interfaces.
Copyright (c) 2014 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 7223; see
the RFC itself for full legal notices.";
revision 2014-05-08 {
description
"Initial revision.";
reference
"RFC 7223: A YANG Data Model for Interface Management";
}
/*
* Typedefs
*/
typedef interface-ref {
type leafref {
path "/if:interfaces/if:interface/if:name";
}
description
"This type is used by data models that need to reference
configured interfaces.";
}
typedef interface-state-ref {
type leafref {
path "/if:interfaces-state/if:interface/if:name";
}
description
"This type is used by data models that need to reference
the operationally present interfaces.";
}
/*
* Identities
*/
identity interface-type {
description
"Base identity from which specific interface types are
derived.";
}
/*
* Features
*/
feature arbitrary-names {
description
"This feature indicates that the device allows user-controlled
interfaces to be named arbitrarily.";
}
feature pre-provisioning {
description
"This feature indicates that the device supports
pre-provisioning of interface configuration, i.e., it is
possible to configure an interface whose physical interface
hardware is not present on the device.";
}
feature if-mib {
description
"This feature indicates that the device implements
the IF-MIB.";
reference
"RFC 2863: The Interfaces Group MIB";
}
/*
* Configuration data nodes
*/
container interfaces {
description
"Interface configuration parameters.";
list interface {
key "name";
description
"The list of configured interfaces on the device.
The operational state of an interface is available in the
/interfaces-state/interface list. If the configuration of a
system-controlled interface cannot be used by the system
(e.g., the interface hardware present does not match the
interface type), then the configuration is not applied to
the system-controlled interface shown in the
/interfaces-state/interface list. If the configuration
of a user-controlled interface cannot be used by the system,
the configured interface is not instantiated in the
/interfaces-state/interface list.";
leaf name {
type string;
description
"The name of the interface.
A device MAY restrict the allowed values for this leaf,
possibly depending on the type of the interface.
For system-controlled interfaces, this leaf is the
device-specific name of the interface. The 'config false'
list /interfaces-state/interface contains the currently
existing interfaces on the device.
If a client tries to create configuration for a
system-controlled interface that is not present in the
/interfaces-state/interface list, the server MAY reject
the request if the implementation does not support
pre-provisioning of interfaces or if the name refers to
an interface that can never exist in the system. A
NETCONF server MUST reply with an rpc-error with the
error-tag 'invalid-value' in this case.
If the device supports pre-provisioning of interface
configuration, the 'pre-provisioning' feature is
advertised.
If the device allows arbitrarily named user-controlled
interfaces, the 'arbitrary-names' feature is advertised.
When a configured user-controlled interface is created by
the system, it is instantiated with the same name in the
/interface-state/interface list.";
}
leaf description {
type string;
description
"A textual description of the interface.
A server implementation MAY map this leaf to the ifAlias
MIB object. Such an implementation needs to use some
mechanism to handle the differences in size and characters
allowed between this leaf and ifAlias. The definition of
such a mechanism is outside the scope of this document.
Since ifAlias is defined to be stored in non-volatile
storage, the MIB implementation MUST map ifAlias to the
value of 'description' in the persistently stored
datastore.
Specifically, if the device supports ':startup', when
ifAlias is read the device MUST return the value of
'description' in the 'startup' datastore, and when it is
written, it MUST be written to the 'running' and 'startup'
datastores. Note that it is up to the implementation to
decide whether to modify this single leaf in 'startup' or
perform an implicit copy-config from 'running' to
'startup'.
If the device does not support ':startup', ifAlias MUST
be mapped to the 'description' leaf in the 'running'
datastore.";
reference
"RFC 2863: The Interfaces Group MIB - ifAlias";
}
leaf type {
type identityref {
base interface-type;
}
mandatory true;
description
"The type of the interface.
When an interface entry is created, a server MAY
initialize the type leaf with a valid value, e.g., if it
is possible to derive the type from the name of the
interface.
If a client tries to set the type of an interface to a
value that can never be used by the system, e.g., if the
type is not supported or if the type does not match the
name of the interface, the server MUST reject the request.
A NETCONF server MUST reply with an rpc-error with the
error-tag 'invalid-value' in this case.";
reference
"RFC 2863: The Interfaces Group MIB - ifType";
}
leaf enabled {
type boolean;
default "true";
description
"This leaf contains the configured, desired state of the
interface.
Systems that implement the IF-MIB use the value of this
leaf in the 'running' datastore to set
IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry
has been initialized, as described in RFC 2863.
Changes in this leaf in the 'running' datastore are
reflected in ifAdminStatus, but if ifAdminStatus is
changed over SNMP, this leaf is not affected.";
reference
"RFC 2863: The Interfaces Group MIB - ifAdminStatus";
}
leaf link-up-down-trap-enable {
if-feature if-mib;
type enumeration {
enum enabled {
value 1;
}
enum disabled {
value 2;
}
}
description
"Controls whether linkUp/linkDown SNMP notifications
should be generated for this interface.
If this node is not configured, the value 'enabled' is
operationally used by the server for interfaces that do
not operate on top of any other interface (i.e., there are
no 'lower-layer-if' entries), and 'disabled' otherwise.";
reference
"RFC 2863: The Interfaces Group MIB -
ifLinkUpDownTrapEnable";
}
}
}
/*
* Operational state data nodes
*/
container interfaces-state {
config false;
description
"Data nodes for the operational state of interfaces.";
list interface {
key "name";
description
"The list of interfaces on the device.
System-controlled interfaces created by the system are
always present in this list, whether they are configured or
not.";
leaf name {
type string;
description
"The name of the interface.
A server implementation MAY map this leaf to the ifName
MIB object. Such an implementation needs to use some
mechanism to handle the differences in size and characters
allowed between this leaf and ifName. The definition of
such a mechanism is outside the scope of this document.";
reference
"RFC 2863: The Interfaces Group MIB - ifName";
}
leaf type {
type identityref {
base interface-type;
}
mandatory true;
description
"The type of the interface.";
reference
"RFC 2863: The Interfaces Group MIB - ifType";
}
leaf admin-status {
if-feature if-mib;
type enumeration {
enum up {
value 1;
description
"Ready to pass packets.";
}
enum down {
value 2;
description
"Not ready to pass packets and not in some test mode.";
}
enum testing {
value 3;
description
"In some test mode.";
}
}
mandatory true;
description
"The desired state of the interface.
This leaf has the same read semantics as ifAdminStatus.";
reference
"RFC 2863: The Interfaces Group MIB - ifAdminStatus";
}
leaf oper-status {
type enumeration {
enum up {
value 1;
description
"Ready to pass packets.";
}
enum down {
value 2;
description
"The interface does not pass any packets.";
}
enum testing {
value 3;
description
"In some test mode. No operational packets can
be passed.";
}
enum unknown {
value 4;
description
"Status cannot be determined for some reason.";
}
enum dormant {
value 5;
description
"Waiting for some external event.";
}
enum not-present {
value 6;
description
"Some component (typically hardware) is missing.";
}
enum lower-layer-down {
value 7;
description
"Down due to state of lower-layer interface(s).";
}
}
mandatory true;
description
"The current operational state of the interface.
This leaf has the same semantics as ifOperStatus.";
reference
"RFC 2863: The Interfaces Group MIB - ifOperStatus";
}
leaf last-change {
type yang:date-and-time;
description
"The time the interface entered its current operational
state. If the current state was entered prior to the
last re-initialization of the local network management
subsystem, then this node is not present.";
reference
"RFC 2863: The Interfaces Group MIB - ifLastChange";
}
leaf if-index {
if-feature if-mib;
type int32 {
range "1..2147483647";
}
mandatory true;
description
"The ifIndex value for the ifEntry represented by this
interface.";
reference
"RFC 2863: The Interfaces Group MIB - ifIndex";
}
leaf phys-address {
type yang:phys-address;
description
"The interface's address at its protocol sub-layer. For
example, for an 802.x interface, this object normally
contains a Media Access Control (MAC) address. The
interface's media-specific modules must define the bit
and byte ordering and the format of the value of this
object. For interfaces that do not have such an address
(e.g., a serial line), this node is not present.";
reference
"RFC 2863: The Interfaces Group MIB - ifPhysAddress";
}
leaf-list higher-layer-if {
type interface-state-ref;
description
"A list of references to interfaces layered on top of this
interface.";
reference
"RFC 2863: The Interfaces Group MIB - ifStackTable";
}
leaf-list lower-layer-if {
type interface-state-ref;
description
"A list of references to interfaces layered underneath this
interface.";
reference
"RFC 2863: The Interfaces Group MIB - ifStackTable";
}
leaf speed {
type yang:gauge64;
units "bits/second";
description
"An estimate of the interface's current bandwidth in bits
per second. For interfaces that do not vary in
bandwidth or for those where no accurate estimation can
be made, this node should contain the nominal bandwidth.
For interfaces that have no concept of bandwidth, this
node is not present.";
reference
"RFC 2863: The Interfaces Group MIB -
ifSpeed, ifHighSpeed";
}
container statistics {
description
"A collection of interface-related statistics objects.";
leaf discontinuity-time {
type yang:date-and-time;
mandatory true;
description
"The time on the most recent occasion at which any one or
more of this interface's counters suffered a
discontinuity. If no such discontinuities have occurred
since the last re-initialization of the local management
subsystem, then this node contains the time the local
management subsystem re-initialized itself.";
}
leaf in-octets {
type yang:counter64;
description
"The total number of octets received on the interface,
including framing characters.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB - ifHCInOctets";
}
leaf in-unicast-pkts {
type yang:counter64;
description
"The number of packets, delivered by this sub-layer to a
higher (sub-)layer, that were not addressed to a
multicast or broadcast address at this sub-layer.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
}
leaf in-broadcast-pkts {
type yang:counter64;
description
"The number of packets, delivered by this sub-layer to a
higher (sub-)layer, that were addressed to a broadcast
address at this sub-layer.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB -
ifHCInBroadcastPkts";
}
leaf in-multicast-pkts {
type yang:counter64;
description
"The number of packets, delivered by this sub-layer to a
higher (sub-)layer, that were addressed to a multicast
address at this sub-layer. For a MAC-layer protocol,
this includes both Group and Functional addresses.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB -
ifHCInMulticastPkts";
}
leaf in-discards {
type yang:counter32;
description
"The number of inbound packets that were chosen to be
discarded even though no errors had been detected to
prevent their being deliverable to a higher-layer
protocol. One possible reason for discarding such a
packet could be to free up buffer space.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB - ifInDiscards";
}
leaf in-errors {
type yang:counter32;
description
"For packet-oriented interfaces, the number of inbound
packets that contained errors preventing them from being
deliverable to a higher-layer protocol. For character-
oriented or fixed-length interfaces, the number of
inbound transmission units that contained errors
preventing them from being deliverable to a higher-layer
protocol.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB - ifInErrors";
}
leaf in-unknown-protos {
type yang:counter32;
description
"For packet-oriented interfaces, the number of packets
received via the interface that were discarded because
of an unknown or unsupported protocol. For
character-oriented or fixed-length interfaces that
support protocol multiplexing, the number of
transmission units received via the interface that were
discarded because of an unknown or unsupported protocol.
For any interface that does not support protocol
multiplexing, this counter is not present.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
}
leaf out-octets {
type yang:counter64;
description
"The total number of octets transmitted out of the
interface, including framing characters.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
}
leaf out-unicast-pkts {
type yang:counter64;
description
"The total number of packets that higher-level protocols
requested be transmitted, and that were not addressed
to a multicast or broadcast address at this sub-layer,
including those that were discarded or not sent.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
}
leaf out-broadcast-pkts {
type yang:counter64;
description
"The total number of packets that higher-level protocols
requested be transmitted, and that were addressed to a
broadcast address at this sub-layer, including those
that were discarded or not sent.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB -
ifHCOutBroadcastPkts";
}
leaf out-multicast-pkts {
type yang:counter64;
description
"The total number of packets that higher-level protocols
requested be transmitted, and that were addressed to a
multicast address at this sub-layer, including those
that were discarded or not sent. For a MAC-layer
protocol, this includes both Group and Functional
addresses.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB -
ifHCOutMulticastPkts";
}
leaf out-discards {
type yang:counter32;
description
"The number of outbound packets that were chosen to be
discarded even though no errors had been detected to
prevent their being transmitted. One possible reason
for discarding such a packet could be to free up buffer
space.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB - ifOutDiscards";
}
leaf out-errors {
type yang:counter32;
description
"For packet-oriented interfaces, the number of outbound
packets that could not be transmitted because of errors.
For character-oriented or fixed-length interfaces, the
number of outbound transmission units that could not be
transmitted because of errors.
Discontinuities in the value of this counter can occur
at re-initialization of the management system, and at
other times as indicated by the value of
'discontinuity-time'.";
reference
"RFC 2863: The Interfaces Group MIB - ifOutErrors";
}
}
}
}
}

View file

@ -0,0 +1,758 @@
module ietf-ip {
namespace "urn:ietf:params:xml:ns:yang:ietf-ip";
prefix ip;
import ietf-interfaces {
prefix if;
}
import ietf-inet-types {
prefix inet;
}
import ietf-yang-types {
prefix yang;
}
organization
"IETF NETMOD (NETCONF Data Modeling Language) Working Group";
contact
"WG Web: <http://tools.ietf.org/wg/netmod/>
WG List: <mailto:netmod@ietf.org>
WG Chair: Thomas Nadeau
<mailto:tnadeau@lucidvision.com>
WG Chair: Juergen Schoenwaelder
<mailto:j.schoenwaelder@jacobs-university.de>
Editor: Martin Bjorklund
<mailto:mbj@tail-f.com>";
description
"This module contains a collection of YANG definitions for
configuring IP implementations.
Copyright (c) 2014 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 7277; see
the RFC itself for full legal notices.";
revision 2014-06-16 {
description
"Initial revision.";
reference
"RFC 7277: A YANG Data Model for IP Management";
}
/*
* Features
*/
feature ipv4-non-contiguous-netmasks {
description
"Indicates support for configuring non-contiguous
subnet masks.";
}
feature ipv6-privacy-autoconf {
description
"Indicates support for Privacy Extensions for Stateless Address
Autoconfiguration in IPv6.";
reference
"RFC 4941: Privacy Extensions for Stateless Address
Autoconfiguration in IPv6";
}
/*
* Typedefs
*/
typedef ip-address-origin {
type enumeration {
enum other {
description
"None of the following.";
}
enum static {
description
"Indicates that the address has been statically
configured - for example, using NETCONF or a Command Line
Interface.";
}
enum dhcp {
description
"Indicates an address that has been assigned to this
system by a DHCP server.";
}
enum link-layer {
description
"Indicates an address created by IPv6 stateless
autoconfiguration that embeds a link-layer address in its
interface identifier.";
}
enum random {
description
"Indicates an address chosen by the system at
random, e.g., an IPv4 address within 169.254/16, an
RFC 4941 temporary address, or an RFC 7217 semantically
opaque address.";
reference
"RFC 4941: Privacy Extensions for Stateless Address
Autoconfiguration in IPv6
RFC 7217: A Method for Generating Semantically Opaque
Interface Identifiers with IPv6 Stateless
Address Autoconfiguration (SLAAC)";
}
}
description
"The origin of an address.";
}
typedef neighbor-origin {
type enumeration {
enum other {
description
"None of the following.";
}
enum static {
description
"Indicates that the mapping has been statically
configured - for example, using NETCONF or a Command Line
Interface.";
}
enum dynamic {
description
"Indicates that the mapping has been dynamically resolved
using, e.g., IPv4 ARP or the IPv6 Neighbor Discovery
protocol.";
}
}
description
"The origin of a neighbor entry.";
}
/*
* Configuration data nodes
*/
augment "/if:interfaces/if:interface" {
description
"Parameters for configuring IP on interfaces.
If an interface is not capable of running IP, the server
must not allow the client to configure these parameters.";
container ipv4 {
presence
"Enables IPv4 unless the 'enabled' leaf
(which defaults to 'true') is set to 'false'";
description
"Parameters for the IPv4 address family.";
leaf enabled {
type boolean;
default true;
description
"Controls whether IPv4 is enabled or disabled on this
interface. When IPv4 is enabled, this interface is
connected to an IPv4 stack, and the interface can send
and receive IPv4 packets.";
}
leaf forwarding {
type boolean;
default false;
description
"Controls IPv4 packet forwarding of datagrams received by,
but not addressed to, this interface. IPv4 routers
forward datagrams. IPv4 hosts do not (except those
source-routed via the host).";
}
leaf mtu {
type uint16 {
range "68..max";
}
units octets;
description
"The size, in octets, of the largest IPv4 packet that the
interface will send and receive.
The server may restrict the allowed values for this leaf,
depending on the interface's type.
If this leaf is not configured, the operationally used MTU
depends on the interface's type.";
reference
"RFC 791: Internet Protocol";
}
list address {
key "ip";
description
"The list of configured IPv4 addresses on the interface.";
leaf ip {
type inet:ipv4-address-no-zone;
description
"The IPv4 address on the interface.";
}
choice subnet {
mandatory true;
description
"The subnet can be specified as a prefix-length, or,
if the server supports non-contiguous netmasks, as
a netmask.";
leaf prefix-length {
type uint8 {
range "0..32";
}
description
"The length of the subnet prefix.";
}
leaf netmask {
if-feature ipv4-non-contiguous-netmasks;
type yang:dotted-quad;
description
"The subnet specified as a netmask.";
}
}
}
list neighbor {
key "ip";
description
"A list of mappings from IPv4 addresses to
link-layer addresses.
Entries in this list are used as static entries in the
ARP Cache.";
reference
"RFC 826: An Ethernet Address Resolution Protocol";
leaf ip {
type inet:ipv4-address-no-zone;
description
"The IPv4 address of the neighbor node.";
}
leaf link-layer-address {
type yang:phys-address;
mandatory true;
description
"The link-layer address of the neighbor node.";
}
}
}
container ipv6 {
presence
"Enables IPv6 unless the 'enabled' leaf
(which defaults to 'true') is set to 'false'";
description
"Parameters for the IPv6 address family.";
leaf enabled {
type boolean;
default true;
description
"Controls whether IPv6 is enabled or disabled on this
interface. When IPv6 is enabled, this interface is
connected to an IPv6 stack, and the interface can send
and receive IPv6 packets.";
}
leaf forwarding {
type boolean;
default false;
description
"Controls IPv6 packet forwarding of datagrams received by,
but not addressed to, this interface. IPv6 routers
forward datagrams. IPv6 hosts do not (except those
source-routed via the host).";
reference
"RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
Section 6.2.1, IsRouter";
}
leaf mtu {
type uint32 {
range "1280..max";
}
units octets;
description
"The size, in octets, of the largest IPv6 packet that the
interface will send and receive.
The server may restrict the allowed values for this leaf,
depending on the interface's type.
If this leaf is not configured, the operationally used MTU
depends on the interface's type.";
reference
"RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
Section 5";
}
list address {
key "ip";
description
"The list of configured IPv6 addresses on the interface.";
leaf ip {
type inet:ipv6-address-no-zone;
description
"The IPv6 address on the interface.";
}
leaf prefix-length {
type uint8 {
range "0..128";
}
mandatory true;
description
"The length of the subnet prefix.";
}
}
list neighbor {
key "ip";
description
"A list of mappings from IPv6 addresses to
link-layer addresses.
Entries in this list are used as static entries in the
Neighbor Cache.";
reference
"RFC 4861: Neighbor Discovery for IP version 6 (IPv6)";
leaf ip {
type inet:ipv6-address-no-zone;
description
"The IPv6 address of the neighbor node.";
}
leaf link-layer-address {
type yang:phys-address;
mandatory true;
description
"The link-layer address of the neighbor node.";
}
}
leaf dup-addr-detect-transmits {
type uint32;
default 1;
description
"The number of consecutive Neighbor Solicitation messages
sent while performing Duplicate Address Detection on a
tentative address. A value of zero indicates that
Duplicate Address Detection is not performed on
tentative addresses. A value of one indicates a single
transmission with no follow-up retransmissions.";
reference
"RFC 4862: IPv6 Stateless Address Autoconfiguration";
}
container autoconf {
description
"Parameters to control the autoconfiguration of IPv6
addresses, as described in RFC 4862.";
reference
"RFC 4862: IPv6 Stateless Address Autoconfiguration";
leaf create-global-addresses {
type boolean;
default true;
description
"If enabled, the host creates global addresses as
described in RFC 4862.";
reference
"RFC 4862: IPv6 Stateless Address Autoconfiguration
Section 5.5";
}
leaf create-temporary-addresses {
if-feature ipv6-privacy-autoconf;
type boolean;
default false;
description
"If enabled, the host creates temporary addresses as
described in RFC 4941.";
reference
"RFC 4941: Privacy Extensions for Stateless Address
Autoconfiguration in IPv6";
}
leaf temporary-valid-lifetime {
if-feature ipv6-privacy-autoconf;
type uint32;
units "seconds";
default 604800;
description
"The time period during which the temporary address
is valid.";
reference
"RFC 4941: Privacy Extensions for Stateless Address
Autoconfiguration in IPv6
- TEMP_VALID_LIFETIME";
}
leaf temporary-preferred-lifetime {
if-feature ipv6-privacy-autoconf;
type uint32;
units "seconds";
default 86400;
description
"The time period during which the temporary address is
preferred.";
reference
"RFC 4941: Privacy Extensions for Stateless Address
Autoconfiguration in IPv6
- TEMP_PREFERRED_LIFETIME";
}
}
}
}
/*
* Operational state data nodes
*/
augment "/if:interfaces-state/if:interface" {
description
"Data nodes for the operational state of IP on interfaces.";
container ipv4 {
presence "Present if IPv4 is enabled on this interface";
config false;
description
"Interface-specific parameters for the IPv4 address family.";
leaf forwarding {
type boolean;
description
"Indicates whether IPv4 packet forwarding is enabled or
disabled on this interface.";
}
leaf mtu {
type uint16 {
range "68..max";
}
units octets;
description
"The size, in octets, of the largest IPv4 packet that the
interface will send and receive.";
reference
"RFC 791: Internet Protocol";
}
list address {
key "ip";
description
"The list of IPv4 addresses on the interface.";
leaf ip {
type inet:ipv4-address-no-zone;
description
"The IPv4 address on the interface.";
}
choice subnet {
description
"The subnet can be specified as a prefix-length, or,
if the server supports non-contiguous netmasks, as
a netmask.";
leaf prefix-length {
type uint8 {
range "0..32";
}
description
"The length of the subnet prefix.";
}
leaf netmask {
if-feature ipv4-non-contiguous-netmasks;
type yang:dotted-quad;
description
"The subnet specified as a netmask.";
}
}
leaf origin {
type ip-address-origin;
description
"The origin of this address.";
}
}
list neighbor {
key "ip";
description
"A list of mappings from IPv4 addresses to
link-layer addresses.
This list represents the ARP Cache.";
reference
"RFC 826: An Ethernet Address Resolution Protocol";
leaf ip {
type inet:ipv4-address-no-zone;
description
"The IPv4 address of the neighbor node.";
}
leaf link-layer-address {
type yang:phys-address;
description
"The link-layer address of the neighbor node.";
}
leaf origin {
type neighbor-origin;
description
"The origin of this neighbor entry.";
}
}
}
container ipv6 {
presence "Present if IPv6 is enabled on this interface";
config false;
description
"Parameters for the IPv6 address family.";
leaf forwarding {
type boolean;
default false;
description
"Indicates whether IPv6 packet forwarding is enabled or
disabled on this interface.";
reference
"RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
Section 6.2.1, IsRouter";
}
leaf mtu {
type uint32 {
range "1280..max";
}
units octets;
description
"The size, in octets, of the largest IPv6 packet that the
interface will send and receive.";
reference
"RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
Section 5";
}
list address {
key "ip";
description
"The list of IPv6 addresses on the interface.";
leaf ip {
type inet:ipv6-address-no-zone;
description
"The IPv6 address on the interface.";
}
leaf prefix-length {
type uint8 {
range "0..128";
}
mandatory true;
description
"The length of the subnet prefix.";
}
leaf origin {
type ip-address-origin;
description
"The origin of this address.";
}
leaf status {
type enumeration {
enum preferred {
description
"This is a valid address that can appear as the
destination or source address of a packet.";
}
enum deprecated {
description
"This is a valid but deprecated address that should
no longer be used as a source address in new
communications, but packets addressed to such an
address are processed as expected.";
}
enum invalid {
description
"This isn't a valid address, and it shouldn't appear
as the destination or source address of a packet.";
}
enum inaccessible {
description
"The address is not accessible because the interface
to which this address is assigned is not
operational.";
}
enum unknown {
description
"The status cannot be determined for some reason.";
}
enum tentative {
description
"The uniqueness of the address on the link is being
verified. Addresses in this state should not be
used for general communication and should only be
used to determine the uniqueness of the address.";
}
enum duplicate {
description
"The address has been determined to be non-unique on
the link and so must not be used.";
}
enum optimistic {
description
"The address is available for use, subject to
restrictions, while its uniqueness on a link is
being verified.";
}
}
description
"The status of an address. Most of the states correspond
to states from the IPv6 Stateless Address
Autoconfiguration protocol.";
reference
"RFC 4293: Management Information Base for the
Internet Protocol (IP)
- IpAddressStatusTC
RFC 4862: IPv6 Stateless Address Autoconfiguration";
}
}
list neighbor {
key "ip";
description
"A list of mappings from IPv6 addresses to
link-layer addresses.
This list represents the Neighbor Cache.";
reference
"RFC 4861: Neighbor Discovery for IP version 6 (IPv6)";
leaf ip {
type inet:ipv6-address-no-zone;
description
"The IPv6 address of the neighbor node.";
}
leaf link-layer-address {
type yang:phys-address;
description
"The link-layer address of the neighbor node.";
}
leaf origin {
type neighbor-origin;
description
"The origin of this neighbor entry.";
}
leaf is-router {
type empty;
description
"Indicates that the neighbor node acts as a router.";
}
leaf state {
type enumeration {
enum incomplete {
description
"Address resolution is in progress, and the link-layer
address of the neighbor has not yet been
determined.";
}
enum reachable {
description
"Roughly speaking, the neighbor is known to have been
reachable recently (within tens of seconds ago).";
}
enum stale {
description
"The neighbor is no longer known to be reachable, but
until traffic is sent to the neighbor no attempt
should be made to verify its reachability.";
}
enum delay {
description
"The neighbor is no longer known to be reachable, and
traffic has recently been sent to the neighbor.
Rather than probe the neighbor immediately, however,
delay sending probes for a short while in order to
give upper-layer protocols a chance to provide
reachability confirmation.";
}
enum probe {
description
"The neighbor is no longer known to be reachable, and
unicast Neighbor Solicitation probes are being sent
to verify reachability.";
}
}
description
"The Neighbor Unreachability Detection state of this
entry.";
reference
"RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
Section 7.3.2";
}
}
}
}
}

View file

@ -0,0 +1,411 @@
module ietf-netconf-acm {
namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-acm";
prefix nacm;
import ietf-yang-types {
prefix yang;
}
organization
"IETF NETCONF (Network Configuration) Working Group";
contact
"WG Web: <http://tools.ietf.org/wg/netconf/>
WG List: <mailto:netconf@ietf.org>
WG Chair: Mehmet Ersue
<mailto:mehmet.ersue@nsn.com>
WG Chair: Bert Wijnen
<mailto:bertietf@bwijnen.net>
Editor: Andy Bierman
<mailto:andy@yumaworks.com>
Editor: Martin Bjorklund
<mailto:mbj@tail-f.com>";
description
"NETCONF Access Control Model.
Copyright (c) 2012 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD
License set forth in Section 4.c of the IETF Trust's
Legal Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 6536; see
the RFC itself for full legal notices.";
revision 2012-02-22 {
description
"Initial version";
reference
"RFC 6536: Network Configuration Protocol (NETCONF)
Access Control Model";
}
extension default-deny-write {
description
"Used to indicate that the data model node
represents a sensitive security system parameter.
If present, and the NACM module is enabled (i.e.,
/nacm/enable-nacm object equals 'true'), the NETCONF server
will only allow the designated 'recovery session' to have
write access to the node. An explicit access control rule is
required for all other users.
The 'default-deny-write' extension MAY appear within a data
definition statement. It is ignored otherwise.";
}
extension default-deny-all {
description
"Used to indicate that the data model node
controls a very sensitive security system parameter.
If present, and the NACM module is enabled (i.e.,
/nacm/enable-nacm object equals 'true'), the NETCONF server
will only allow the designated 'recovery session' to have
read, write, or execute access to the node. An explicit
access control rule is required for all other users.
The 'default-deny-all' extension MAY appear within a data
definition statement, 'rpc' statement, or 'notification'
statement. It is ignored otherwise.";
}
typedef user-name-type {
type string {
length "1..max";
}
description
"General Purpose Username string.";
}
typedef matchall-string-type {
type string {
pattern "\\*";
}
description
"The string containing a single asterisk '*' is used
to conceptually represent all possible values
for the particular leaf using this data type.";
}
typedef access-operations-type {
type bits {
bit create {
description
"Any protocol operation that creates a
new data node.";
}
bit read {
description
"Any protocol operation or notification that
returns the value of a data node.";
}
bit update {
description
"Any protocol operation that alters an existing
data node.";
}
bit delete {
description
"Any protocol operation that removes a data node.";
}
bit exec {
description
"Execution access to the specified protocol operation.";
}
}
description
"NETCONF Access Operation.";
}
typedef group-name-type {
type string {
length "1..max";
pattern "[^\\*].*";
}
description
"Name of administrative group to which
users can be assigned.";
}
typedef action-type {
type enumeration {
enum "permit" {
description
"Requested action is permitted.";
}
enum "deny" {
description
"Requested action is denied.";
}
}
description
"Action taken by the server when a particular
rule matches.";
}
typedef node-instance-identifier {
type yang:xpath1.0;
description
"Path expression used to represent a special
data node instance identifier string.
A node-instance-identifier value is an
unrestricted YANG instance-identifier expression.
All the same rules as an instance-identifier apply
except predicates for keys are optional. If a key
predicate is missing, then the node-instance-identifier
represents all possible server instances for that key.
This XPath expression is evaluated in the following context:
o The set of namespace declarations are those in scope on
the leaf element where this type is used.
o The set of variable bindings contains one variable,
'USER', which contains the name of the user of the current
session.
o The function library is the core function library, but
note that due to the syntax restrictions of an
instance-identifier, no functions are allowed.
o The context node is the root node in the data tree.";
}
container nacm {
nacm:default-deny-all;
description
"Parameters for NETCONF Access Control Model.";
leaf enable-nacm {
type boolean;
default "true";
description
"Enables or disables all NETCONF access control
enforcement. If 'true', then enforcement
is enabled. If 'false', then enforcement
is disabled.";
}
leaf read-default {
type action-type;
default "permit";
description
"Controls whether read access is granted if
no appropriate rule is found for a
particular read request.";
}
leaf write-default {
type action-type;
default "deny";
description
"Controls whether create, update, or delete access
is granted if no appropriate rule is found for a
particular write request.";
}
leaf exec-default {
type action-type;
default "permit";
description
"Controls whether exec access is granted if no appropriate
rule is found for a particular protocol operation request.";
}
leaf enable-external-groups {
type boolean;
default "true";
description
"Controls whether the server uses the groups reported by the
NETCONF transport layer when it assigns the user to a set of
NACM groups. If this leaf has the value 'false', any group
names reported by the transport layer are ignored by the
server.";
}
leaf denied-operations {
type yang:zero-based-counter32;
config false;
mandatory true;
description
"Number of times since the server last restarted that a
protocol operation request was denied.";
}
leaf denied-data-writes {
type yang:zero-based-counter32;
config false;
mandatory true;
description
"Number of times since the server last restarted that a
protocol operation request to alter
a configuration datastore was denied.";
}
leaf denied-notifications {
type yang:zero-based-counter32;
config false;
mandatory true;
description
"Number of times since the server last restarted that
a notification was dropped for a subscription because
access to the event type was denied.";
}
container groups {
description
"NETCONF Access Control Groups.";
list group {
key "name";
description
"One NACM Group Entry. This list will only contain
configured entries, not any entries learned from
any transport protocols.";
leaf name {
type group-name-type;
description
"Group name associated with this entry.";
}
leaf-list user-name {
type user-name-type;
description
"Each entry identifies the username of
a member of the group associated with
this entry.";
}
}
}
list rule-list {
key "name";
ordered-by user;
description
"An ordered collection of access control rules.";
leaf name {
type string {
length "1..max";
}
description
"Arbitrary name assigned to the rule-list.";
}
leaf-list group {
type union {
type matchall-string-type;
type group-name-type;
}
description
"List of administrative groups that will be
assigned the associated access rights
defined by the 'rule' list.
The string '*' indicates that all groups apply to the
entry.";
}
list rule {
key "name";
ordered-by user;
description
"One access control rule.
Rules are processed in user-defined order until a match is
found. A rule matches if 'module-name', 'rule-type', and
'access-operations' match the request. If a rule
matches, the 'action' leaf determines if access is granted
or not.";
leaf name {
type string {
length "1..max";
}
description
"Arbitrary name assigned to the rule.";
}
leaf module-name {
type union {
type matchall-string-type;
type string;
}
default "*";
description
"Name of the module associated with this rule.
This leaf matches if it has the value '*' or if the
object being accessed is defined in the module with the
specified module name.";
}
choice rule-type {
description
"This choice matches if all leafs present in the rule
match the request. If no leafs are present, the
choice matches all requests.";
case protocol-operation {
leaf rpc-name {
type union {
type matchall-string-type;
type string;
}
description
"This leaf matches if it has the value '*' or if
its value equals the requested protocol operation
name.";
}
}
case notification {
leaf notification-name {
type union {
type matchall-string-type;
type string;
}
description
"This leaf matches if it has the value '*' or if its
value equals the requested notification name.";
}
}
case data-node {
leaf path {
type node-instance-identifier;
mandatory true;
description
"Data Node Instance Identifier associated with the
data node controlled by this rule.
Configuration data or state data instance
identifiers start with a top-level data node. A
complete instance identifier is required for this
type of path value.
The special value '/' refers to all possible
datastore contents.";
}
}
}
leaf access-operations {
type union {
type matchall-string-type;
type access-operations-type;
}
default "*";
description
"Access operations associated with this rule.
This leaf matches if it has the value '*' or if the
bit corresponding to the requested operation is set.";
}
leaf action {
type action-type;
mandatory true;
description
"The access control action associated with the
rule. If a rule is determined to match a
particular request, then this object is used
to determine whether to permit or deny the
request.";
}
leaf comment {
type string;
description
"A textual description of the access rule.";
}
}
}
}
}

View file

@ -0,0 +1,140 @@
module ietf-netconf-with-defaults {
namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults";
prefix ncwd;
import ietf-netconf { prefix nc; }
organization
"IETF NETCONF (Network Configuration Protocol) Working Group";
contact
"WG Web: <http://tools.ietf.org/wg/netconf/>
WG List: <netconf@ietf.org>
WG Chair: Bert Wijnen
<bertietf@bwijnen.net>
WG Chair: Mehmet Ersue
<mehmet.ersue@nsn.com>
Editor: Andy Bierman
<andy.bierman@brocade.com>
Editor: Balazs Lengyel
<balazs.lengyel@ericsson.com>";
description
"This module defines an extension to the NETCONF protocol
that allows the NETCONF client to control how default
values are handled by the server in particular NETCONF
operations.
Copyright (c) 2011 IETF Trust and the persons identified as
the document authors. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 6243; see
the RFC itself for full legal notices.";
revision 2011-06-01 {
description
"Initial version.";
reference
"RFC 6243: With-defaults Capability for NETCONF";
}
typedef with-defaults-mode {
description
"Possible modes to report default data.";
reference
"RFC 6243; Section 3.";
type enumeration {
enum report-all {
description
"All default data is reported.";
reference
"RFC 6243; Section 3.1";
}
enum report-all-tagged {
description
"All default data is reported.
Any nodes considered to be default data
will contain a 'default' XML attribute,
set to 'true' or '1'.";
reference
"RFC 6243; Section 3.4";
}
enum trim {
description
"Values are not reported if they contain the default.";
reference
"RFC 6243; Section 3.2";
}
enum explicit {
description
"Report values that contain the definition of
explicitly set data.";
reference
"RFC 6243; Section 3.3";
}
}
}
grouping with-defaults-parameters {
description
"Contains the <with-defaults> parameter for control
of defaults in NETCONF retrieval operations.";
leaf with-defaults {
description
"The explicit defaults processing mode requested.";
reference
"RFC 6243; Section 4.5.1";
type with-defaults-mode;
}
}
// extending the get-config operation
augment /nc:get-config/nc:input {
description
"Adds the <with-defaults> parameter to the
input of the NETCONF <get-config> operation.";
reference
"RFC 6243; Section 4.5.1";
uses with-defaults-parameters;
}
// extending the get operation
augment /nc:get/nc:input {
description
"Adds the <with-defaults> parameter to
the input of the NETCONF <get> operation.";
reference
"RFC 6243; Section 4.5.1";
uses with-defaults-parameters;
}
// extending the copy-config operation
augment /nc:copy-config/nc:input {
description
"Adds the <with-defaults> parameter to
the input of the NETCONF <copy-config> operation.";
reference
"RFC 6243; Section 4.5.1";
uses with-defaults-parameters;
}
}

View file

@ -0,0 +1,934 @@
module ietf-netconf {
// the namespace for NETCONF XML definitions is unchanged
// from RFC 4741, which this document replaces
namespace "urn:ietf:params:xml:ns:netconf:base:1.0";
prefix nc;
import ietf-inet-types {
prefix inet;
}
import ietf-netconf-acm { prefix nacm; }
organization
"IETF NETCONF (Network Configuration) Working Group";
contact
"WG Web: <http://tools.ietf.org/wg/netconf/>
WG List: <netconf@ietf.org>
WG Chair: Bert Wijnen
<bertietf@bwijnen.net>
WG Chair: Mehmet Ersue
<mehmet.ersue@nsn.com>
Editor: Martin Bjorklund
<mbj@tail-f.com>
Editor: Juergen Schoenwaelder
<j.schoenwaelder@jacobs-university.de>
Editor: Andy Bierman
<andy.bierman@brocade.com>";
description
"NETCONF Protocol Data Types and Protocol Operations.
Copyright (c) 2011 IETF Trust and the persons identified as
the document authors. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 6241; see
the RFC itself for full legal notices.";
revision 2011-06-01 {
description
"Initial revision;
2013-09-29: Updated to include NACM attributes,
as specified in RFC 6536: sec 3.2.5 and 3.2.8";
reference
"RFC 6241: Network Configuration Protocol";
}
extension get-filter-element-attributes {
description
"If this extension is present within an 'anyxml'
statement named 'filter', which must be conceptually
defined within the RPC input section for the <get>
and <get-config> protocol operations, then the
following unqualified XML attribute is supported
within the <filter> element, within a <get> or
<get-config> protocol operation:
type : optional attribute with allowed
value strings 'subtree' and 'xpath'.
If missing, the default value is 'subtree'.
If the 'xpath' feature is supported, then the
following unqualified XML attribute is
also supported:
select: optional attribute containing a
string representing an XPath expression.
The 'type' attribute must be equal to 'xpath'
if this attribute is present.";
}
// NETCONF capabilities defined as features
feature writable-running {
description
"NETCONF :writable-running capability;
If the server advertises the :writable-running
capability for a session, then this feature must
also be enabled for that session. Otherwise,
this feature must not be enabled.";
reference "RFC 6241, Section 8.2";
}
feature candidate {
description
"NETCONF :candidate capability;
If the server advertises the :candidate
capability for a session, then this feature must
also be enabled for that session. Otherwise,
this feature must not be enabled.";
reference "RFC 6241, Section 8.3";
}
feature confirmed-commit {
if-feature candidate;
description
"NETCONF :confirmed-commit:1.1 capability;
If the server advertises the :confirmed-commit:1.1
capability for a session, then this feature must
also be enabled for that session. Otherwise,
this feature must not be enabled.";
reference "RFC 6241, Section 8.4";
}
feature rollback-on-error {
description
"NETCONF :rollback-on-error capability;
If the server advertises the :rollback-on-error
capability for a session, then this feature must
also be enabled for that session. Otherwise,
this feature must not be enabled.";
reference "RFC 6241, Section 8.5";
}
feature validate {
description
"NETCONF :validate:1.1 capability;
If the server advertises the :validate:1.1
capability for a session, then this feature must
also be enabled for that session. Otherwise,
this feature must not be enabled.";
reference "RFC 6241, Section 8.6";
}
feature startup {
description
"NETCONF :startup capability;
If the server advertises the :startup
capability for a session, then this feature must
also be enabled for that session. Otherwise,
this feature must not be enabled.";
reference "RFC 6241, Section 8.7";
}
feature url {
description
"NETCONF :url capability;
If the server advertises the :url
capability for a session, then this feature must
also be enabled for that session. Otherwise,
this feature must not be enabled.";
reference "RFC 6241, Section 8.8";
}
feature xpath {
description
"NETCONF :xpath capability;
If the server advertises the :xpath
capability for a session, then this feature must
also be enabled for that session. Otherwise,
this feature must not be enabled.";
reference "RFC 6241, Section 8.9";
}
// NETCONF Simple Types
typedef session-id-type {
type uint32 {
range "1..max";
}
description
"NETCONF Session Id";
}
typedef session-id-or-zero-type {
type uint32;
description
"NETCONF Session Id or Zero to indicate none";
}
typedef error-tag-type {
type enumeration {
enum in-use {
description
"The request requires a resource that
already is in use.";
}
enum invalid-value {
description
"The request specifies an unacceptable value for one
or more parameters.";
}
enum too-big {
description
"The request or response (that would be generated) is
too large for the implementation to handle.";
}
enum missing-attribute {
description
"An expected attribute is missing.";
}
enum bad-attribute {
description
"An attribute value is not correct; e.g., wrong type,
out of range, pattern mismatch.";
}
enum unknown-attribute {
description
"An unexpected attribute is present.";
}
enum missing-element {
description
"An expected element is missing.";
}
enum bad-element {
description
"An element value is not correct; e.g., wrong type,
out of range, pattern mismatch.";
}
enum unknown-element {
description
"An unexpected element is present.";
}
enum unknown-namespace {
description
"An unexpected namespace is present.";
}
enum access-denied {
description
"Access to the requested protocol operation or
data model is denied because authorization failed.";
}
enum lock-denied {
description
"Access to the requested lock is denied because the
lock is currently held by another entity.";
}
enum resource-denied {
description
"Request could not be completed because of
insufficient resources.";
}
enum rollback-failed {
description
"Request to roll back some configuration change (via
rollback-on-error or <discard-changes> operations)
was not completed for some reason.";
}
enum data-exists {
description
"Request could not be completed because the relevant
data model content already exists. For example,
a 'create' operation was attempted on data that
already exists.";
}
enum data-missing {
description
"Request could not be completed because the relevant
data model content does not exist. For example,
a 'delete' operation was attempted on
data that does not exist.";
}
enum operation-not-supported {
description
"Request could not be completed because the requested
operation is not supported by this implementation.";
}
enum operation-failed {
description
"Request could not be completed because the requested
operation failed for some reason not covered by
any other error condition.";
}
enum partial-operation {
description
"This error-tag is obsolete, and SHOULD NOT be sent
by servers conforming to this document.";
}
enum malformed-message {
description
"A message could not be handled because it failed to
be parsed correctly. For example, the message is not
well-formed XML or it uses an invalid character set.";
}
}
description "NETCONF Error Tag";
reference "RFC 6241, Appendix A";
}
typedef error-severity-type {
type enumeration {
enum error {
description "Error severity";
}
enum warning {
description "Warning severity";
}
}
description "NETCONF Error Severity";
reference "RFC 6241, Section 4.3";
}
typedef edit-operation-type {
type enumeration {
enum merge {
description
"The configuration data identified by the
element containing this attribute is merged
with the configuration at the corresponding
level in the configuration datastore identified
by the target parameter.";
}
enum replace {
description
"The configuration data identified by the element
containing this attribute replaces any related
configuration in the configuration datastore
identified by the target parameter. If no such
configuration data exists in the configuration
datastore, it is created. Unlike a
<copy-config> operation, which replaces the
entire target configuration, only the configuration
actually present in the config parameter is affected.";
}
enum create {
description
"The configuration data identified by the element
containing this attribute is added to the
configuration if and only if the configuration
data does not already exist in the configuration
datastore. If the configuration data exists, an
<rpc-error> element is returned with an
<error-tag> value of 'data-exists'.";
}
enum delete {
description
"The configuration data identified by the element
containing this attribute is deleted from the
configuration if and only if the configuration
data currently exists in the configuration
datastore. If the configuration data does not
exist, an <rpc-error> element is returned with
an <error-tag> value of 'data-missing'.";
}
enum remove {
description
"The configuration data identified by the element
containing this attribute is deleted from the
configuration if the configuration
data currently exists in the configuration
datastore. If the configuration data does not
exist, the 'remove' operation is silently ignored
by the server.";
}
}
default "merge";
description "NETCONF 'operation' attribute values";
reference "RFC 6241, Section 7.2";
}
// NETCONF Standard Protocol Operations
rpc get-config {
description
"Retrieve all or part of a specified configuration.";
reference "RFC 6241, Section 7.1";
input {
container source {
description
"Particular configuration to retrieve.";
choice config-source {
mandatory true;
description
"The configuration to retrieve.";
leaf candidate {
if-feature candidate;
type empty;
description
"The candidate configuration is the config source.";
}
leaf running {
type empty;
description
"The running configuration is the config source.";
}
leaf startup {
if-feature startup;
type empty;
description
"The startup configuration is the config source.
This is optional-to-implement on the server because
not all servers will support filtering for this
datastore.";
}
}
}
anyxml filter {
description
"Subtree or XPath filter to use.";
nc:get-filter-element-attributes;
}
}
output {
anyxml data {
description
"Copy of the source datastore subset that matched
the filter criteria (if any). An empty data container
indicates that the request did not produce any results.";
}
}
}
rpc edit-config {
description
"The <edit-config> operation loads all or part of a specified
configuration to the specified target configuration.";
reference "RFC 6241, Section 7.2";
input {
container target {
description
"Particular configuration to edit.";
choice config-target {
mandatory true;
description
"The configuration target.";
leaf candidate {
if-feature candidate;
type empty;
description
"The candidate configuration is the config target.";
}
leaf running {
if-feature writable-running;
type empty;
description
"The running configuration is the config source.";
}
}
}
leaf default-operation {
type enumeration {
enum merge {
description
"The default operation is merge.";
}
enum replace {
description
"The default operation is replace.";
}
enum none {
description
"There is no default operation.";
}
}
default "merge";
description
"The default operation to use.";
}
leaf test-option {
if-feature validate;
type enumeration {
enum test-then-set {
description
"The server will test and then set if no errors.";
}
enum set {
description
"The server will set without a test first.";
}
enum test-only {
description
"The server will only test and not set, even
if there are no errors.";
}
}
default "test-then-set";
description
"The test option to use.";
}
leaf error-option {
type enumeration {
enum stop-on-error {
description
"The server will stop on errors.";
}
enum continue-on-error {
description
"The server may continue on errors.";
}
enum rollback-on-error {
description
"The server will roll back on errors.
This value can only be used if the 'rollback-on-error'
feature is supported.";
}
}
default "stop-on-error";
description
"The error option to use.";
}
choice edit-content {
mandatory true;
description
"The content for the edit operation.";
anyxml config {
description
"Inline Config content.";
}
leaf url {
if-feature url;
type inet:uri;
description
"URL-based config content.";
}
}
}
}
rpc copy-config {
description
"Create or replace an entire configuration datastore with the
contents of another complete configuration datastore.";
reference "RFC 6241, Section 7.3";
input {
container target {
description
"Particular configuration to copy to.";
choice config-target {
mandatory true;
description
"The configuration target of the copy operation.";
leaf candidate {
if-feature candidate;
type empty;
description
"The candidate configuration is the config target.";
}
leaf running {
if-feature writable-running;
type empty;
description
"The running configuration is the config target.
This is optional-to-implement on the server.";
}
leaf startup {
if-feature startup;
type empty;
description
"The startup configuration is the config target.";
}
leaf url {
if-feature url;
type inet:uri;
description
"The URL-based configuration is the config target.";
}
}
}
container source {
description
"Particular configuration to copy from.";
choice config-source {
mandatory true;
description
"The configuration source for the copy operation.";
leaf candidate {
if-feature candidate;
type empty;
description
"The candidate configuration is the config source.";
}
leaf running {
type empty;
description
"The running configuration is the config source.";
}
leaf startup {
if-feature startup;
type empty;
description
"The startup configuration is the config source.";
}
leaf url {
if-feature url;
type inet:uri;
description
"The URL-based configuration is the config source.";
}
anyxml config {
description
"Inline Config content: <config> element. Represents
an entire configuration datastore, not
a subset of the running datastore.";
}
}
}
}
}
rpc delete-config {
nacm:default-deny-all;
description
"Delete a configuration datastore.";
reference "RFC 6241, Section 7.4";
input {
container target {
description
"Particular configuration to delete.";
choice config-target {
mandatory true;
description
"The configuration target to delete.";
leaf startup {
if-feature startup;
type empty;
description
"The startup configuration is the config target.";
}
leaf url {
if-feature url;
type inet:uri;
description
"The URL-based configuration is the config target.";
}
}
}
}
}
rpc lock {
description
"The lock operation allows the client to lock the configuration
system of a device.";
reference "RFC 6241, Section 7.5";
input {
container target {
description
"Particular configuration to lock.";
choice config-target {
mandatory true;
description
"The configuration target to lock.";
leaf candidate {
if-feature candidate;
type empty;
description
"The candidate configuration is the config target.";
}
leaf running {
type empty;
description
"The running configuration is the config target.";
}
leaf startup {
if-feature startup;
type empty;
description
"The startup configuration is the config target.";
}
}
}
}
}
rpc unlock {
description
"The unlock operation is used to release a configuration lock,
previously obtained with the 'lock' operation.";
reference "RFC 6241, Section 7.6";
input {
container target {
description
"Particular configuration to unlock.";
choice config-target {
mandatory true;
description
"The configuration target to unlock.";
leaf candidate {
if-feature candidate;
type empty;
description
"The candidate configuration is the config target.";
}
leaf running {
type empty;
description
"The running configuration is the config target.";
}
leaf startup {
if-feature startup;
type empty;
description
"The startup configuration is the config target.";
}
}
}
}
}
rpc get {
description
"Retrieve running configuration and device state information.";
reference "RFC 6241, Section 7.7";
input {
anyxml filter {
description
"This parameter specifies the portion of the system
configuration and state data to retrieve.";
nc:get-filter-element-attributes;
}
}
output {
anyxml data {
description
"Copy of the running datastore subset and/or state
data that matched the filter criteria (if any).
An empty data container indicates that the request did not
produce any results.";
}
}
}
rpc close-session {
description
"Request graceful termination of a NETCONF session.";
reference "RFC 6241, Section 7.8";
}
rpc kill-session {
nacm:default-deny-all;
description
"Force the termination of a NETCONF session.";
reference "RFC 6241, Section 7.9";
input {
leaf session-id {
type session-id-type;
mandatory true;
description
"Particular session to kill.";
}
}
}
rpc commit {
if-feature candidate;
description
"Commit the candidate configuration as the device's new
current configuration.";
reference "RFC 6241, Section 8.3.4.1";
input {
leaf confirmed {
if-feature confirmed-commit;
type empty;
description
"Requests a confirmed commit.";
reference "RFC 6241, Section 8.3.4.1";
}
leaf confirm-timeout {
if-feature confirmed-commit;
type uint32 {
range "1..max";
}
units "seconds";
default "600"; // 10 minutes
description
"The timeout interval for a confirmed commit.";
reference "RFC 6241, Section 8.3.4.1";
}
leaf persist {
if-feature confirmed-commit;
type string;
description
"This parameter is used to make a confirmed commit
persistent. A persistent confirmed commit is not aborted
if the NETCONF session terminates. The only way to abort
a persistent confirmed commit is to let the timer expire,
or to use the <cancel-commit> operation.
The value of this parameter is a token that must be given
in the 'persist-id' parameter of <commit> or
<cancel-commit> operations in order to confirm or cancel
the persistent confirmed commit.
The token should be a random string.";
reference "RFC 6241, Section 8.3.4.1";
}
leaf persist-id {
if-feature confirmed-commit;
type string;
description
"This parameter is given in order to commit a persistent
confirmed commit. The value must be equal to the value
given in the 'persist' parameter to the <commit> operation.
If it does not match, the operation fails with an
'invalid-value' error.";
reference "RFC 6241, Section 8.3.4.1";
}
}
}
rpc discard-changes {
if-feature candidate;
description
"Revert the candidate configuration to the current
running configuration.";
reference "RFC 6241, Section 8.3.4.2";
}
rpc cancel-commit {
if-feature confirmed-commit;
description
"This operation is used to cancel an ongoing confirmed commit.
If the confirmed commit is persistent, the parameter
'persist-id' must be given, and it must match the value of the
'persist' parameter.";
reference "RFC 6241, Section 8.4.4.1";
input {
leaf persist-id {
type string;
description
"This parameter is given in order to cancel a persistent
confirmed commit. The value must be equal to the value
given in the 'persist' parameter to the <commit> operation.
If it does not match, the operation fails with an
'invalid-value' error.";
}
}
}
rpc validate {
if-feature validate;
description
"Validates the contents of the specified configuration.";
reference "RFC 6241, Section 8.6.4.1";
input {
container source {
description
"Particular configuration to validate.";
choice config-source {
mandatory true;
description
"The configuration source to validate.";
leaf candidate {
if-feature candidate;
type empty;
description
"The candidate configuration is the config source.";
}
leaf running {
type empty;
description
"The running configuration is the config source.";
}
leaf startup {
if-feature startup;
type empty;
description
"The startup configuration is the config source.";
}
leaf url {
if-feature url;
type inet:uri;
description
"The URL-based configuration is the config source.";
}
anyxml config {
description
"Inline Config content: <config> element. Represents
an entire configuration datastore, not
a subset of the running datastore.";
}
}
}
}
}
}

View file

@ -0,0 +1,26 @@
module modaction {
yang-version 1.1;
namespace "urn:yanglint:modaction";
prefix ma;
container con {
list ls {
key "lfkey";
leaf lfkey {
type string;
}
action act {
input {
leaf lfi {
type string;
}
}
output {
leaf lfo {
type int16;
}
}
}
}
}
}

View file

@ -0,0 +1,15 @@
module modconfig-augment {
yang-version 1.1;
namespace "urn:yanglint:modconfig-augment";
prefix "mca";
import modconfig {
prefix mc;
}
augment "/mc:mcc" {
leaf alf {
type string;
}
}
}

View file

@ -0,0 +1,17 @@
module modconfig {
namespace "urn:yanglint:modconfig";
prefix mc;
container mcc {
leaf lft {
type string;
config true;
mandatory true;
}
leaf lff {
type string;
config false;
mandatory true;
}
}
}

View file

@ -0,0 +1,31 @@
module moddatanodes {
yang-version 1.1;
namespace "urn:yanglint:moddatanodes";
prefix mdn;
container dnc {
leaf lf {
type string;
}
leaf-list lfl {
type string;
}
leaf mis {
type string;
}
container con {
list lt {
key "kalf kblf";
leaf kalf {
type string;
}
leaf kblf {
type string;
}
leaf vlf {
type string;
}
}
}
}
}

View file

@ -0,0 +1,19 @@
module moddefault {
namespace "urn:yanglint:moddefault";
prefix md;
container mdc {
leaf lf {
type uint16;
}
leaf di {
type int16;
default "5";
}
leaf ds {
type string;
default "str";
}
}
}

View file

@ -0,0 +1,24 @@
module modextleafref {
namespace "urn:yanglint:modextleafref";
prefix mel;
list ls {
key k;
leaf k {
type string;
}
leaf lf {
type uint8;
}
}
leaf lfr {
type leafref {
path "../ls/k";
}
}
leaf lfrderef {
type leafref {
path "deref(../lfr)/../lf";
}
}
}

View file

@ -0,0 +1,7 @@
module modfeature {
namespace "urn:yanglint:modfeature";
prefix l;
feature ftr1;
feature ftr2;
}

View file

@ -0,0 +1,8 @@
module modimp-cwd {
namespace "urn:yanglint:modimp-cwd";
prefix ic;
import modcwd {
prefix mc;
}
}

View file

@ -0,0 +1,8 @@
module modimp-path {
namespace "urn:yanglint:modimp-path";
prefix ip;
import modpath {
prefix mp;
}
}

View file

@ -0,0 +1,12 @@
module modimp-type {
namespace "urn:yanglint:modimp-type";
prefix mit;
import modtypedef {
prefix mtd;
}
leaf lf {
type mtd:mui8;
}
}

View file

@ -0,0 +1,9 @@
module modinclude {
yang-version 1.1;
namespace "urn:yanglint:modinclude";
prefix mi;
include "modsub";
container mic;
}

View file

@ -0,0 +1,8 @@
module modleaf {
namespace "urn:yanglint:modleaf";
prefix l;
leaf lfl {
type uint16;
}
}

View file

@ -0,0 +1,14 @@
module modleafref {
namespace "urn:yanglint:modleafref";
prefix m;
import modleaf {
prefix ml;
}
leaf lfr {
type leafref {
path "/ml:lfl";
}
}
}

View file

@ -0,0 +1,14 @@
module modmandatory {
namespace "urn:yanglint:modmandatory";
prefix mm;
container mmc {
leaf lft {
type int16;
mandatory true;
}
leaf lff {
type int16;
}
}
}

View file

@ -0,0 +1,21 @@
module modmerge {
namespace "urn:yanglint:modmerge";
prefix mm;
container mmc {
leaf en {
type enumeration {
enum zero;
enum one;
}
}
leaf lm {
type int16;
must "../en != 'zero'";
}
leaf lf {
type string;
}
}
}

View file

@ -0,0 +1,13 @@
module modmust {
namespace "urn:yanglint:modmust";
prefix m;
import modleaf {
prefix ml;
}
leaf lfm {
type string;
must "/ml:lfl > 0";
}
}

View file

@ -0,0 +1,19 @@
module modnotif {
yang-version 1.1;
namespace "urn:yanglint:modnotif";
prefix mn;
container con {
notification nfn {
leaf lf {
type string;
}
}
}
notification nfg {
leaf lf {
type string;
}
}
}

View file

@ -0,0 +1,68 @@
module modoper-leafref {
yang-version 1.1;
namespace "urn:yanglint:modoper-leafref";
prefix mol;
import modconfig {
prefix mc;
}
container cond {
list list {
key "klf";
leaf klf {
type string;
}
action act {
input {
leaf lfi {
type leafref {
path "/mc:mcc/mc:lft";
}
}
}
output {
leaf lfo {
type leafref {
path "/mc:mcc/mc:lft";
}
}
}
}
notification notif {
leaf lfn {
type leafref {
path "/mc:mcc/mc:lft";
}
}
}
}
}
rpc rpcg {
input {
leaf lfi {
type leafref {
path "/mc:mcc/mc:lft";
}
}
}
output {
container cono {
leaf lfo {
type leafref {
path "/mc:mcc/mc:lft";
}
}
}
}
}
notification notifg {
leaf lfr {
type leafref {
path "/mc:mcc/mc:lft";
}
}
}
}

View file

@ -0,0 +1,4 @@
module modpath {
namespace "urn:yanglint:modpath";
prefix mp;
}

View file

@ -0,0 +1,19 @@
module modrpc {
namespace "urn:yanglint:modrpc";
prefix mr;
rpc rpc {
input {
leaf lfi {
type string;
}
}
output {
container con {
leaf lfo {
type int16;
}
}
}
}
}

View file

@ -0,0 +1,15 @@
module modsm-augment {
yang-version 1.1;
namespace "urn:yanglint:modsm-augment";
prefix "msa";
import modsm {
prefix msm;
}
augment "/msm:root" {
leaf alf {
type string;
}
}
}

View file

@ -0,0 +1,13 @@
module modsm {
yang-version 1.1;
namespace "urn:yanglint:modsm";
prefix "msm";
import ietf-yang-schema-mount {
prefix sm;
}
container root {
sm:mount-point "root";
}
}

View file

@ -0,0 +1,8 @@
submodule modsub {
yang-version 1.1;
belongs-to modinclude {
prefix mi;
}
container msc;
}

View file

@ -0,0 +1,8 @@
module modtypedef {
namespace "urn:yanglint:typedef";
prefix mt;
typedef mui8 {
type uint8;
}
}

View file

@ -0,0 +1,15 @@
package require tcltest
# Hook to determine if any of the tests failed.
# Sets a global variable exitCode to 1 if any test fails otherwise it is set to 0.
proc tcltest::cleanupTestsHook {} {
variable numTests
set ::exitCode [expr {$numTests(Failed) > 0}]
}
if {[info exists ::env(TESTS_DIR)]} {
tcltest::configure -testdir "$env(TESTS_DIR)/non-interactive"
}
tcltest::runAllTests
exit $exitCode

View file

@ -0,0 +1,31 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
set mods "$::env(YANG_MODULES_DIR)/ietf-netconf-with-defaults@2011-06-01.yang $::env(YANG_MODULES_DIR)/moddefault.yang"
set data "$::env(TESTS_DIR)/data/moddefault.xml"
test data_default_not_set {Print data without --default parameter} {
ly_cmd "-f xml $mods $data" "</lf>.*</di>\n</mdc>"
ly_cmd "-f json $mods $data" "lf\".*di\"\[^\"]*"
} {}
test data_default_all {data --default all} {
ly_cmd "-d all -f xml $mods $data" "</lf>.*</di>.*</ds>\n</mdc>"
ly_cmd "-d all -f json $mods $data" "lf\".*di\".*ds\"\[^\"]*"
} {}
test data_default_all_tagged {data --default all-tagged} {
ly_cmd "-d all-tagged -f xml $mods $data" "</lf>.*<di.*default.*</di>.*<ds.*default.*</ds>\n</mdc>"
ly_cmd "-d all-tagged -f json $mods $data" "lf\".*di\".*ds\".*@ds\".*default\"\[^\"]*"
} {}
test data_default_trim {data --default trim} {
ly_cmd "-d trim -f xml $mods $data" "</lf>\n</mdc>"
ly_cmd "-d trim -f json $mods $data" "lf\"\[^\"]*"
} {}
test data_default_implicit_tagged {data --default implicit-tagged} {
ly_cmd "-d implicit-tagged -f xml $mods $data" "</lf>.*<di>5</di>.*<ds.*default.*</ds>\n</mdc>"
ly_cmd "-d implicit-tagged -f json $mods $data" "lf\".*di\"\[^@]*ds\".*default\"\[^\"]*"
} {}
cleanupTests

View file

@ -0,0 +1,18 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
set mdir $::env(YANG_MODULES_DIR)
set ddir $::env(TESTS_DIR)/data
test data_in_format_xml {--in-format xml} {
ly_cmd "-I xml $mdir/modleaf.yang $ddir/modleaf.dxml"
ly_cmd_err "-I json $mdir/modleaf.yang $ddir/modleaf.dxml" "Failed to parse"
ly_cmd_err "-I lyb $mdir/modleaf.yang $ddir/modleaf.dxml" "Failed to parse"
} {}
test data_in_format_json {--in-format json} {
ly_cmd "-I json $mdir/modleaf.yang $ddir/modleaf.djson"
ly_cmd_err "-I xml $mdir/modleaf.yang $ddir/modleaf.djson" "Failed to parse"
ly_cmd_err "-I lyb $mdir/modleaf.yang $ddir/modleaf.djson" "Failed to parse"
} {}
cleanupTests

View file

@ -0,0 +1,28 @@
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
set mdir $::env(YANG_MODULES_DIR)
set ddir $::env(TESTS_DIR)/data
test data_merge_basic {Data is merged and the node is added} {
ly_cmd "-m -f xml $mdir/modmerge.yang $ddir/modmerge.xml $ddir/modmerge3.xml" "<en>.*<lm>.*<lf>"
} {}
test data_merge_validation_failed {Data is merged but validation failed.} {
ly_cmd "$mdir/modmerge.yang $ddir/modmerge.xml"
ly_cmd "$mdir/modmerge.yang $ddir/modmerge2.xml"
ly_cmd "-m $mdir/modmerge.yang $ddir/modmerge2.xml $ddir/modmerge.xml"
ly_cmd_err "-m $mdir/modmerge.yang $ddir/modmerge.xml $ddir/modmerge2.xml" "Merged data are not valid"
} {}
test data_merge_dataconfig {The merge option has effect only for 'data' and 'config' TYPEs} {
set wrn1 "option has effect only for"
ly_cmd_wrn "-m -t rpc $mdir/modrpc.yang $ddir/modrpc.xml $ddir/modrpc.xml" $wrn1
ly_cmd_wrn "-m -t notif $mdir/modnotif.yang $ddir/modnotif2.xml $ddir/modnotif2.xml" $wrn1
ly_cmd_wrn "-m -t get $mdir/modconfig.yang $mdir/modleaf.yang $ddir/modleaf.xml $ddir/modconfig.xml" $wrn1
ly_cmd_wrn "-m -t getconfig $mdir/modconfig.yang $mdir/modleaf.yang $ddir/modleaf.xml $ddir/modconfig2.xml" $wrn1
ly_cmd_wrn "-m -t edit $mdir/modconfig.yang $mdir/modleaf.yang $ddir/modleaf.xml $ddir/modconfig2.xml" $wrn1
ly_cmd "-m -t config $mdir/modconfig.yang $mdir/modleaf.yang $ddir/modleaf.xml $ddir/modconfig2.xml"
ly_cmd "-m -t data $mdir/modconfig.yang $mdir/modleaf.yang $ddir/modleaf.xml $ddir/modconfig.xml"
} {}
cleanupTests

Some files were not shown because too many files have changed in this diff Show more