Update ncclient examples 31/13331/8
authorMichal Cmarada <[email protected]>
Wed, 23 Jan 2019 10:41:26 +0000 (11:41 +0100)
committerMichal Cmarada <[email protected]>
Wed, 23 Jan 2019 10:43:40 +0000 (11:43 +0100)
- added optional parameter host for copy_config, get_config
  and edit-config.
- added basic tests for interfaces:
  - loopback interface
  - af-packet interface
  - tap interface
- added diff_xml.py to find differences between two sets of config.
  It supports both full xml comparison and comparison based on xPath
- added example diff between running and candidate config (interfaces)
- fixed formatting and namespaces

Change-Id: If6dd7a76fab538735ab92c67f9457326fbcba7ec
Signed-off-by: Michal Cmarada <[email protected]>
36 files changed:
examples/ncclient/acl/config_acl.xml
examples/ncclient/acl/config_acl_update.xml
examples/ncclient/acl/config_invalid_acl.xml
examples/ncclient/acl/expected_config_acl.xml
examples/ncclient/acl/expected_config_acl_update.xml
examples/ncclient/acl/test_acl.sh
examples/ncclient/acl/test_acl_update.sh
examples/ncclient/bd/config_bd.xml
examples/ncclient/bd/expected_config_bd.xml
examples/ncclient/bd/test_bd.sh
examples/ncclient/copy_config.py
examples/ncclient/diff_xml.py [new file with mode: 0755]
examples/ncclient/edit_config.py
examples/ncclient/get_config.py
examples/ncclient/interfaces/af-packet/candidate_config_af_packet_interface.xml [new file with mode: 0644]
examples/ncclient/interfaces/af-packet/edit_config_af_packet_interface.xml [new file with mode: 0644]
examples/ncclient/interfaces/af-packet/test_diff_af_packet.sh [new file with mode: 0755]
examples/ncclient/interfaces/af-packet/test_edit_af_packet.sh [new file with mode: 0755]
examples/ncclient/interfaces/loop/candidate_config_loop_interface.xml [new file with mode: 0644]
examples/ncclient/interfaces/loop/edit_config_loop_interface.xml [new file with mode: 0644]
examples/ncclient/interfaces/loop/test_diff_loopback.sh [new file with mode: 0755]
examples/ncclient/interfaces/loop/test_edit_loopback.sh [new file with mode: 0755]
examples/ncclient/interfaces/tap/candidate_config_tap_interface.xml [new file with mode: 0644]
examples/ncclient/interfaces/tap/edit_config_tap_interface.xml [new file with mode: 0644]
examples/ncclient/interfaces/tap/test_diff_tap.sh [new file with mode: 0755]
examples/ncclient/interfaces/tap/test_edit_tap.sh [new file with mode: 0755]
examples/ncclient/nat/config_nat.xml
examples/ncclient/nat/config_nat_update.xml
examples/ncclient/nat/expected_config_nat.xml
examples/ncclient/nat/expected_config_nat_update.xml
examples/ncclient/nat/test_nat.sh
examples/ncclient/nat/test_nat_update.sh
examples/ncclient/test_copy_config.sh
examples/ncclient/test_diff_config.sh [new file with mode: 0755]
examples/ncclient/test_edit_config.sh [new file with mode: 0755]
examples/ncclient/xmldiffs.py

index ed4d9b4..826a83e 100644 (file)
         <interface>
             <name>loop1</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>00:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
-                <ingress>
-                    <vpp-acls>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
-                        <name>tcp-acl</name>
-                    </vpp-acls>
-                    <vpp-acls>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
-                        <name>udp-acl</name>
-                    </vpp-acls>
-                    <vpp-macip-acl>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</type>
-                        <name>macip-acl</name>
-                    </vpp-macip-acl>
-                </ingress>
-            </acl>
         </interface>
     </interfaces>
-    <access-lists xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
+    <acls xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
         <acl>
-            <acl-name>macip-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</acl-type>
-            <access-list-entries>
+            <name>tcp-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>macip-rule</rule-name>
+                    <name>tcp-rule</name>
                     <matches>
-                        <vpp-macip-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                        <tcp>
+                            <vpp-tcp-ace xmlns="http://fd.io/hc2vpp/yang/vpp/acl">
+                                <flags-mask>cwr</flags-mask>
+                            </vpp-tcp-ace>
+                            <source-port>
+                                <lower-port>1</lower-port>
+                                <upper-port>5487</upper-port>
+                            </source-port>
+                            <destination-port>
+                                <lower-port>87</lower-port>
+                                <upper-port>6745</upper-port>
+                            </destination-port>
+                            <flags>cwr ece urg</flags>
+                        </tcp>
+                        <ipv4>
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
                             <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <source-mac-address>aa:aa:aa:aa:aa:aa</source-mac-address>
-                            <source-mac-address-mask>ff:00:00:00:00:00</source-mac-address-mask>
-                        </vpp-macip-ace-nodes>
+                        </ipv4>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-acl</type>
         </acl>
         <acl>
-            <acl-name>icmp-v6-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
+            <name>icmp-v6-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>imcp-v6-rule</rule-name>
+                    <name>imcp-v6-rule</name>
                     <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0001/64</destination-ipv6-network>
-                            <source-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0002/48</source-ipv6-network>
-                            <icmp-v6-nodes>
+                        <icmp>
+                            <vpp-icmp-ace xmlns="http://fd.io/hc2vpp/yang/vpp/acl">
                                 <icmp-type-range>
                                     <last>8</last>
                                     <first>5</first>
                                     <last>3</last>
                                     <first>1</first>
                                 </icmp-code-range>
-                            </icmp-v6-nodes>
-                        </vpp-ace-nodes>
+                            </vpp-icmp-ace>
+                        </icmp>
+                        <ipv6>
+                            <destination-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0001/64</destination-ipv6-network>
+                            <source-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0002/48</source-ipv6-network>
+                        </ipv6>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-acl</type>
         </acl>
         <acl>
-            <acl-name>udp-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
+            <name>macip-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>udp-rule</rule-name>
+                    <name>macip-rule</name>
                     <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                        <eth>
+                            <source-mac-address-mask>ff:00:00:00:00:00</source-mac-address-mask>
+                            <source-mac-address>aa:aa:aa:aa:aa:aa</source-mac-address>
+                        </eth>
+                        <ipv4>
                             <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <udp-nodes>
-                                <source-port-range>
-                                    <upper-port>5487</upper-port>
-                                    <lower-port>1</lower-port>
-                                </source-port-range>
-                                <destination-port-range>
-                                    <upper-port>6745</upper-port>
-                                    <lower-port>87</lower-port>
-                                </destination-port-range>
-                            </udp-nodes>
-                        </vpp-ace-nodes>
+                        </ipv4>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-macip-acl</type>
         </acl>
         <acl>
-            <acl-name>tcp-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
+            <name>udp-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>tcp-rule</rule-name>
+                    <name>udp-rule</name>
                     <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                        <udp>
+                            <source-port>
+                                <lower-port>1</lower-port>
+                                <upper-port>5487</upper-port>
+                            </source-port>
+                            <destination-port>
+                                <lower-port>87</lower-port>
+                                <upper-port>6745</upper-port>
+                            </destination-port>
+                        </udp>
+                        <ipv4>
                             <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
                             <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <tcp-nodes>
-                                <source-port-range>
-                                    <upper-port>5487</upper-port>
-                                    <lower-port>1</lower-port>
-                                </source-port-range>
-                                <destination-port-range>
-                                    <upper-port>6745</upper-port>
-                                    <lower-port>87</lower-port>
-                                </destination-port-range>
-                                <tcp-flags-mask>1</tcp-flags-mask>
-                                <tcp-flags-value>7</tcp-flags-value>
-                            </tcp-nodes>
-                        </vpp-ace-nodes>
+                        </ipv4>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-acl</type>
         </acl>
         <acl>
-            <acl-name>icmp-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
+            <name>icmp-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>imcp-rule</rule-name>
+                    <name>imcp-rule</name>
                     <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
-                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <icmp-nodes>
+                        <icmp>
+                            <vpp-icmp-ace xmlns="http://fd.io/hc2vpp/yang/vpp/acl">
                                 <icmp-type-range>
                                     <last>8</last>
                                     <first>5</first>
                                     <last>3</last>
                                     <first>1</first>
                                 </icmp-code-range>
-                            </icmp-nodes>
-                        </vpp-ace-nodes>
+                            </vpp-icmp-ace>
+                        </icmp>
+                        <ipv4>
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                        </ipv4>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-acl</type>
         </acl>
-    </access-lists>
+        <attachment-points>
+            <interface>
+                <interface-id>local0</interface-id>
+                <ingress>
+                    <acl-sets>
+                        <acl-set>
+                            <name>tcp-acl</name>
+                        </acl-set>
+                        <acl-set>
+                            <name>udp-acl</name>
+                        </acl-set>
+                        <acl-set>
+                            <name>macip-acl</name>
+                        </acl-set>
+                    </acl-sets>
+                </ingress>
+            </interface>
+        </attachment-points>
+    </acls>
 </config>
index 379e4f4..5541e1c 100644 (file)
         <interface>
             <name>loop1</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>00:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
-                <ingress>
-                    <vpp-macip-acl>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</type>
-                        <name>macip-acl</name>
-                    </vpp-macip-acl>
-                </ingress>
-            </acl>
         </interface>
         <interface>
             <name>loop2</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>aa:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
-                <ingress>
-                    <vpp-acls>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
-                        <name>tcp-acl2</name>
-                    </vpp-acls>
-                    <vpp-acls>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
-                        <name>udp-acl</name>
-                    </vpp-acls>
-                </ingress>
-            </acl>
         </interface>
     </interfaces>
-    <access-lists xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
-        <acl>
-            <acl-name>macip-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</acl-type>
-            <access-list-entries>
-                <ace>
-                    <rule-name>macip-rule</rule-name>
-                    <matches>
-                        <vpp-macip-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <source-mac-address>aa:aa:aa:aa:aa:aa</source-mac-address>
-                            <source-mac-address-mask>ff:00:00:00:00:00</source-mac-address-mask>
-                        </vpp-macip-ace-nodes>
-                    </matches>
-                    <actions>
-                        <permit/>
-                    </actions>
-                </ace>
-            </access-list-entries>
-        </acl>
+    <acls xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
         <acl>
-            <acl-name>icmp-v6-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
+            <name>tcp-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>imcp-v6-rule</rule-name>
+                    <name>tcp-rule</name>
                     <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0001/64
-                            </destination-ipv6-network>
-                            <source-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0002/48</source-ipv6-network>
-                            <icmp-v6-nodes>
-                                <icmp-type-range>
-                                    <last>8</last>
-                                    <first>5</first>
-                                </icmp-type-range>
-                                <icmp-code-range>
-                                    <last>3</last>
-                                    <first>1</first>
-                                </icmp-code-range>
-                            </icmp-v6-nodes>
-                        </vpp-ace-nodes>
-                    </matches>
-                    <actions>
-                        <permit/>
-                    </actions>
-                </ace>
-            </access-list-entries>
-        </acl>
-        <acl>
-            <acl-name>udp-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
-                <ace>
-                    <rule-name>udp-rule</rule-name>
-                    <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                        <tcp>
+                            <vpp-tcp-ace xmlns="http://fd.io/hc2vpp/yang/vpp/acl">
+                                <flags-mask>cwr</flags-mask>
+                            </vpp-tcp-ace>
+                            <source-port>
+                                <lower-port>1</lower-port>
+                                <upper-port>5487</upper-port>
+                            </source-port>
+                            <destination-port>
+                                <lower-port>87</lower-port>
+                                <upper-port>6745</upper-port>
+                            </destination-port>
+                            <flags>cwr ece urg</flags>
+                        </tcp>
+                        <ipv4>
                             <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
                             <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <udp-nodes>
-                                <source-port-range>
-                                    <upper-port>5486</upper-port>
-                                    <lower-port>11</lower-port>
-                                </source-port-range>
-                            </udp-nodes>
-                        </vpp-ace-nodes>
+                        </ipv4>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-acl</type>
         </acl>
-        <acl>
-            <acl-name>tcp-acl2</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
-                <ace>
-                    <rule-name>tcp-rule</rule-name>
-                    <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
-                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <tcp-nodes>
-                                <source-port-range>
-                                    <upper-port>5487</upper-port>
-                                    <lower-port>1</lower-port>
-                                </source-port-range>
-                                <destination-port-range>
-                                    <upper-port>6745</upper-port>
-                                    <lower-port>87</lower-port>
-                                </destination-port-range>
-                                <tcp-flags-mask>1</tcp-flags-mask>
-                                <tcp-flags-value>7</tcp-flags-value>
-                            </tcp-nodes>
-                        </vpp-ace-nodes>
-                    </matches>
-                    <actions>
-                        <permit/>
-                    </actions>
-                </ace>
-            </access-list-entries>
-        </acl>
-        <acl>
-            <acl-name>icmp-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
-                <ace>
-                    <rule-name>renamed-imcp-rule</rule-name>
-                    <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
-                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <icmp-nodes>
-                                <icmp-type-range>
-                                    <last>8</last>
-                                    <first>5</first>
-                                </icmp-type-range>
-                                <icmp-code-range>
-                                    <last>3</last>
-                                    <first>1</first>
-                                </icmp-code-range>
-                            </icmp-nodes>
-                        </vpp-ace-nodes>
-                    </matches>
-                    <actions>
-                        <permit/>
-                    </actions>
-                </ace>
-                <ace>
-                    <rule-name>new-icmp-rule</rule-name>
-                    <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv4-network>10.1.1.1/24</destination-ipv4-network>
-                            <source-ipv4-network>10.2.2.2/32</source-ipv4-network>
-                            <icmp-nodes>
-                                <icmp-type-range>
-                                    <first>4</first>
-                                    <last>9</last>
-                                </icmp-type-range>
-                            </icmp-nodes>
-                        </vpp-ace-nodes>
-                    </matches>
-                    <actions>
-                        <permit/>
-                    </actions>
-                </ace>
-            </access-list-entries>
-        </acl>
-    </access-lists>
+        <attachment-points>
+            <interface>
+                <interface-id>loop2</interface-id>
+                <ingress>
+                    <acl-sets>
+                        <acl-set>
+                            <name>tcp-acl</name>
+                        </acl-set>
+                    </acl-sets>
+                </ingress>
+            </interface>
+        </attachment-points>
+    </acls>
 </config>
index f1ea803..215d9a1 100644 (file)
@@ -1,8 +1,8 @@
 <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <access-lists xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list" xc:operation="create">
+    <acls xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list" xc:operation="create">
         <acl>
             <acl-name>acl0</acl-name>
-            <acl-type>ipv4-acl</acl-type>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:ipv4-acl</type>
         </acl>
-    </access-lists>
+    </acls>
 </config>
index 54e3d91..a6f40e6 100644 (file)
         <interface>
             <name>loop1</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>00:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
-                <ingress>
-                    <vpp-acls>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
-                        <name>tcp-acl</name>
-                    </vpp-acls>
-                    <vpp-acls>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
-                        <name>udp-acl</name>
-                    </vpp-acls>
-                    <vpp-macip-acl>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</type>
-                        <name>macip-acl</name>
-                    </vpp-macip-acl>
-                </ingress>
-            </acl>
         </interface>
     </interfaces>
-    <access-lists xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
+    <acls xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
         <acl>
-            <acl-name>macip-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</acl-type>
-            <access-list-entries>
+            <name>tcp-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>macip-rule</rule-name>
+                    <name>tcp-rule</name>
                     <matches>
-                        <vpp-macip-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                        <tcp>
+                            <vpp-tcp-ace xmlns="http://fd.io/hc2vpp/yang/vpp/acl">
+                                <flags-mask>cwr</flags-mask>
+                            </vpp-tcp-ace>
+                            <source-port>
+                                <lower-port>1</lower-port>
+                                <upper-port>5487</upper-port>
+                            </source-port>
+                            <destination-port>
+                                <lower-port>87</lower-port>
+                                <upper-port>6745</upper-port>
+                            </destination-port>
+                            <flags>cwr ece urg</flags>
+                        </tcp>
+                        <ipv4>
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
                             <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <source-mac-address>aa:aa:aa:aa:aa:aa</source-mac-address>
-                            <source-mac-address-mask>ff:00:00:00:00:00</source-mac-address-mask>
-                        </vpp-macip-ace-nodes>
+                        </ipv4>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-acl</type>
         </acl>
         <acl>
-            <acl-name>icmp-v6-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
+            <name>icmp-v6-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>imcp-v6-rule</rule-name>
+                    <name>imcp-v6-rule</name>
                     <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0001/64</destination-ipv6-network>
-                            <source-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0002/48</source-ipv6-network>
-                            <icmp-v6-nodes>
+                        <icmp>
+                            <vpp-icmp-ace xmlns="http://fd.io/hc2vpp/yang/vpp/acl">
                                 <icmp-type-range>
                                     <last>8</last>
                                     <first>5</first>
                                     <last>3</last>
                                     <first>1</first>
                                 </icmp-code-range>
-                            </icmp-v6-nodes>
-                        </vpp-ace-nodes>
+                            </vpp-icmp-ace>
+                        </icmp>
+                        <ipv6>
+                            <destination-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0001/64</destination-ipv6-network>
+                            <source-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0002/48</source-ipv6-network>
+                        </ipv6>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-acl</type>
         </acl>
         <acl>
-            <acl-name>udp-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
+            <name>macip-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>udp-rule</rule-name>
+                    <name>macip-rule</name>
                     <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                        <eth>
+                            <source-mac-address-mask>ff:00:00:00:00:00</source-mac-address-mask>
+                            <source-mac-address>aa:aa:aa:aa:aa:aa</source-mac-address>
+                        </eth>
+                        <ipv4>
                             <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <udp-nodes>
-                                <source-port-range>
-                                    <upper-port>5487</upper-port>
-                                    <lower-port>1</lower-port>
-                                </source-port-range>
-                                <destination-port-range>
-                                    <upper-port>6745</upper-port>
-                                    <lower-port>87</lower-port>
-                                </destination-port-range>
-                            </udp-nodes>
-                        </vpp-ace-nodes>
+                        </ipv4>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-macip-acl</type>
         </acl>
         <acl>
-            <acl-name>tcp-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
+            <name>udp-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>tcp-rule</rule-name>
+                    <name>udp-rule</name>
                     <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                        <udp>
+                            <source-port>
+                                <lower-port>1</lower-port>
+                                <upper-port>5487</upper-port>
+                            </source-port>
+                            <destination-port>
+                                <lower-port>87</lower-port>
+                                <upper-port>6745</upper-port>
+                            </destination-port>
+                        </udp>
+                        <ipv4>
                             <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
                             <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <tcp-nodes>
-                                <source-port-range>
-                                    <upper-port>5487</upper-port>
-                                    <lower-port>1</lower-port>
-                                </source-port-range>
-                                <destination-port-range>
-                                    <upper-port>6745</upper-port>
-                                    <lower-port>87</lower-port>
-                                </destination-port-range>
-                                <tcp-flags-mask>1</tcp-flags-mask>
-                                <tcp-flags-value>7</tcp-flags-value>
-                            </tcp-nodes>
-                        </vpp-ace-nodes>
+                        </ipv4>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-acl</type>
         </acl>
         <acl>
-            <acl-name>icmp-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
+            <name>icmp-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>imcp-rule</rule-name>
+                    <name>imcp-rule</name>
                     <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
-                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <icmp-nodes>
+                        <icmp>
+                            <vpp-icmp-ace xmlns="http://fd.io/hc2vpp/yang/vpp/acl">
                                 <icmp-type-range>
                                     <last>8</last>
                                     <first>5</first>
                                     <last>3</last>
                                     <first>1</first>
                                 </icmp-code-range>
-                            </icmp-nodes>
-                        </vpp-ace-nodes>
+                            </vpp-icmp-ace>
+                        </icmp>
+                        <ipv4>
+                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
+                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
+                        </ipv4>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-acl</type>
         </acl>
-    </access-lists>
+        <attachment-points>
+            <interface>
+                <interface-id>local0</interface-id>
+                <ingress>
+                    <acl-sets>
+                        <acl-set>
+                            <name>tcp-acl</name>
+                        </acl-set>
+                        <acl-set>
+                            <name>udp-acl</name>
+                        </acl-set>
+                        <acl-set>
+                            <name>macip-acl</name>
+                        </acl-set>
+                    </acl-sets>
+                </ingress>
+            </interface>
+        </attachment-points>
+    </acls>
 </data>
index eefef19..71013b5 100644 (file)
         <interface>
             <name>loop1</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>00:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
-                <ingress>
-                    <vpp-macip-acl>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</type>
-                        <name>macip-acl</name>
-                    </vpp-macip-acl>
-                </ingress>
-            </acl>
         </interface>
         <interface>
             <name>loop2</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>aa:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <acl xmlns="urn:opendaylight:params:xml:ns:yang:interface:acl">
-                <ingress>
-                    <vpp-acls>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
-                        <name>tcp-acl2</name>
-                    </vpp-acls>
-                    <vpp-acls>
-                        <type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</type>
-                        <name>udp-acl</name>
-                    </vpp-acls>
-                </ingress>
-            </acl>
         </interface>
     </interfaces>
-    <access-lists xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
-        <acl>
-            <acl-name>macip-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-macip-acl</acl-type>
-            <access-list-entries>
-                <ace>
-                    <rule-name>macip-rule</rule-name>
-                    <matches>
-                        <vpp-macip-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <source-mac-address>aa:aa:aa:aa:aa:aa</source-mac-address>
-                            <source-mac-address-mask>ff:00:00:00:00:00</source-mac-address-mask>
-                        </vpp-macip-ace-nodes>
-                    </matches>
-                    <actions>
-                        <permit/>
-                    </actions>
-                </ace>
-            </access-list-entries>
-        </acl>
+    <acls xmlns="urn:ietf:params:xml:ns:yang:ietf-access-control-list">
         <acl>
-            <acl-name>icmp-v6-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
+            <name>tcp-acl</name>
+            <aces>
                 <ace>
-                    <rule-name>imcp-v6-rule</rule-name>
+                    <name>tcp-rule</name>
                     <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0001/64
-                            </destination-ipv6-network>
-                            <source-ipv6-network>2001:0db8:0a0b:12f0:0000:0000:0000:0002/48</source-ipv6-network>
-                            <icmp-v6-nodes>
-                                <icmp-type-range>
-                                    <last>8</last>
-                                    <first>5</first>
-                                </icmp-type-range>
-                                <icmp-code-range>
-                                    <last>3</last>
-                                    <first>1</first>
-                                </icmp-code-range>
-                            </icmp-v6-nodes>
-                        </vpp-ace-nodes>
-                    </matches>
-                    <actions>
-                        <permit/>
-                    </actions>
-                </ace>
-            </access-list-entries>
-        </acl>
-        <acl>
-            <acl-name>udp-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
-                <ace>
-                    <rule-name>udp-rule</rule-name>
-                    <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
+                        <tcp>
+                            <vpp-tcp-ace xmlns="http://fd.io/hc2vpp/yang/vpp/acl">
+                                <flags-mask>cwr</flags-mask>
+                            </vpp-tcp-ace>
+                            <source-port>
+                                <lower-port>1</lower-port>
+                                <upper-port>5487</upper-port>
+                            </source-port>
+                            <destination-port>
+                                <lower-port>87</lower-port>
+                                <upper-port>6745</upper-port>
+                            </destination-port>
+                            <flags>cwr ece urg</flags>
+                        </tcp>
+                        <ipv4>
                             <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
                             <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <udp-nodes>
-                                <source-port-range>
-                                    <upper-port>5486</upper-port>
-                                    <lower-port>11</lower-port>
-                                </source-port-range>
-                            </udp-nodes>
-                        </vpp-ace-nodes>
+                        </ipv4>
                     </matches>
                     <actions>
-                        <permit/>
+                        <forwarding>accept</forwarding>
                     </actions>
                 </ace>
-            </access-list-entries>
+            </aces>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/vpp/acl">x:vpp-acl</type>
         </acl>
-        <acl>
-            <acl-name>tcp-acl2</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
-                <ace>
-                    <rule-name>tcp-rule</rule-name>
-                    <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
-                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <tcp-nodes>
-                                <source-port-range>
-                                    <upper-port>5487</upper-port>
-                                    <lower-port>1</lower-port>
-                                </source-port-range>
-                                <destination-port-range>
-                                    <upper-port>6745</upper-port>
-                                    <lower-port>87</lower-port>
-                                </destination-port-range>
-                                <tcp-flags-mask>1</tcp-flags-mask>
-                                <tcp-flags-value>7</tcp-flags-value>
-                            </tcp-nodes>
-                        </vpp-ace-nodes>
-                    </matches>
-                    <actions>
-                        <permit/>
-                    </actions>
-                </ace>
-            </access-list-entries>
-        </acl>
-        <acl>
-            <acl-name>icmp-acl</acl-name>
-            <acl-type xmlns:x="urn:opendaylight:params:xml:ns:yang:vpp:acl">x:vpp-acl</acl-type>
-            <access-list-entries>
-                <ace>
-                    <rule-name>renamed-imcp-rule</rule-name>
-                    <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv4-network>192.168.2.1/24</destination-ipv4-network>
-                            <source-ipv4-network>192.168.2.2/32</source-ipv4-network>
-                            <icmp-nodes>
-                                <icmp-type-range>
-                                    <last>8</last>
-                                    <first>5</first>
-                                </icmp-type-range>
-                                <icmp-code-range>
-                                    <last>3</last>
-                                    <first>1</first>
-                                </icmp-code-range>
-                            </icmp-nodes>
-                        </vpp-ace-nodes>
-                    </matches>
-                    <actions>
-                        <permit/>
-                    </actions>
-                </ace>
-                <ace>
-                    <rule-name>new-icmp-rule</rule-name>
-                    <matches>
-                        <vpp-ace-nodes xmlns="urn:opendaylight:params:xml:ns:yang:vpp:acl">
-                            <destination-ipv4-network>10.1.1.1/24</destination-ipv4-network>
-                            <source-ipv4-network>10.2.2.2/32</source-ipv4-network>
-                            <icmp-nodes>
-                                <icmp-type-range>
-                                    <first>4</first>
-                                    <last>9</last>
-                                </icmp-type-range>
-                            </icmp-nodes>
-                        </vpp-ace-nodes>
-                    </matches>
-                    <actions>
-                        <permit/>
-                    </actions>
-                </ace>
-            </access-list-entries>
-        </acl>
-    </access-lists>
+        <attachment-points>
+            <interface>
+                <interface-id>loop2</interface-id>
+                <ingress>
+                    <acl-sets>
+                        <acl-set>
+                            <name>tcp-acl</name>
+                        </acl-set>
+                    </acl-sets>
+                </ingress>
+            </interface>
+        </attachment-points>
+    </acls>
 </data>
index e55296e..f961069 100755 (executable)
@@ -15,4 +15,4 @@
 
 DIR_NAME=$(dirname $0)
 
-${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_acl.xml ${DIR_NAME}/expected_config_acl.xml
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_acl.xml ${DIR_NAME}/expected_config_acl.xml *
index cb62c18..2a266db 100755 (executable)
@@ -15,6 +15,6 @@
 
 DIR_NAME=$(dirname $0)
 
-${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_acl.xml ${DIR_NAME}/expected_config_acl.xml
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_acl.xml ${DIR_NAME}/expected_config_acl.xml *
 
-${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_acl_update.xml ${DIR_NAME}/expected_config_acl_update.xml
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_acl_update.xml ${DIR_NAME}/expected_config_acl_update.xml *
index 17f221b..b4e7955 100644 (file)
         </interface>
         <interface>
             <name>loop1</name>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>00:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <l2 xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <l2 xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <bridge-domain>test_bd</bridge-domain>
             </l2>
         </interface>
     </interfaces>
-    <bridge-domains xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+    <bridge-domains xmlns="http://fd.io/hc2vpp/yang/v3po">
         <bridge-domain>
             <name>test_bd</name>
         </bridge-domain>
index 3ad69d8..f5aa765 100644 (file)
         </interface>
         <interface>
             <name>loop1</name>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>00:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <l2 xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <l2 xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <bridge-domain>test_bd</bridge-domain>
             </l2>
         </interface>
     </interfaces>
-    <bridge-domains xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+    <bridge-domains xmlns="http://fd.io/hc2vpp/yang/v3po">
         <bridge-domain>
             <name>test_bd</name>
         </bridge-domain>
index 6b3ac8f..180d85e 100755 (executable)
@@ -15,4 +15,4 @@
 
 DIR_NAME=$(dirname $0)
 
-${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_bd.xml ${DIR_NAME}/expected_config_bd.xml
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_bd.xml ${DIR_NAME}/expected_config_bd.xml *
index f397aaa..84b7a4a 100755 (executable)
@@ -15,6 +15,7 @@
 
 import argparse
 import logging
+
 from ncclient import manager
 
 _SOURCE_TEMPLATE = """<source xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">%s</source>"""
@@ -34,6 +35,7 @@ if __name__ == '__main__':
     argparser = argparse.ArgumentParser(description="Configures VPP using <copy-config> RPC")
     argparser.add_argument('config_filename', help="name of XML file with <config> element")
     argparser.add_argument('--verbose', help="increase output verbosity", action="store_true")
+    argparser.add_argument('--host', default="localhost", help="host/node for which to write <config> element")
     args = argparser.parse_args()
 
     logger = logging.getLogger("hc2vpp.examples.copy_config")
@@ -42,4 +44,4 @@ if __name__ == '__main__':
     else:
         logging.basicConfig(level=logging.INFO)
 
-    _copy_config(args.config_filename)
+    _copy_config(args.config_filename, host=args.host)
diff --git a/examples/ncclient/diff_xml.py b/examples/ncclient/diff_xml.py
new file mode 100755 (executable)
index 0000000..e217734
--- /dev/null
@@ -0,0 +1,139 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Usage: {prog} [OPTION] FILE1 FILE2 xPath
+
+Compare two XML files, while sorting elements.
+
+xPath optional parameter
+example:
+    ./{{urn:ietf:params:xml:ns:yang:ietf-interfaces}}interfaces/
+    {{urn:ietf:params:xml:ns:yang:ietf-interfaces}}interface[
+    {{urn:ietf:params:xml:ns:yang:ietf-interfaces}}name='loop0']
+"""
+import os
+import re
+import subprocess
+import sys
+from tempfile import NamedTemporaryFile
+from xml.etree import ElementTree
+from xml.etree.ElementTree import Element
+
+TAG_PATTERN = re.compile(r"""({(?P<namespace>[a-zA-Z0-9.:@\-/]+)}(?P<tag>[0-9a-zA-Z\-]+))|(?P<name>[0-9a-zA-Z\-]+)""",
+                         re.VERBOSE)
+PREFIX_PATTERN = re.compile(r"""(((urn)|(.+://))[a-zA-Z0-9.:@\-/]+[:/](?P<prefix>[0-9a-zA-Z\-]+))""", re.VERBOSE)
+
+if sys.version_info < (3, 0):
+    # Python 2
+    import codecs
+
+    def unicode_writer(fp):
+        return codecs.getwriter('utf-8')(fp)
+else:
+    # Python 3
+    def unicode_writer(fp):
+        return fp
+
+
+def print_usage(program):
+    print(__doc__.format(prog=program).strip())
+
+
+def parse_namespace(namespace):
+    """
+    Extracts module name fom namespace.
+    example:
+        urn:ietf:params:xml:ns:yang:ietf-nat -> ietf-nat
+        http://fd.io/hc2vpp/yang/vpp-fib-table-management -> vpp-fib-table-management
+        https://fd.io/hc2vpp/yang/vpp-fib-table-management -> vpp-fib-table-management
+    :param namespace: namespace in urn or http format
+    :return: module name from namespace
+    """
+    matcher = PREFIX_PATTERN.match(namespace)
+    if matcher.group("prefix"):
+        return matcher.group("prefix").lower()
+
+
+def sort(xml_element):
+    """
+    Sorts elements in xml in alphabetical order.
+    :param xml_element: root element of xml
+    """
+    if not isinstance(xml_element, Element):
+        exit(-1)
+    xml_element[:] = sorted(xml_element, key=lambda child: child.tag)
+
+    mo = TAG_PATTERN.match(xml_element.tag)
+    if mo.group("namespace") and mo.group("tag") and not mo.group("namespace").__contains__(
+            "urn:ietf:params:xml:ns:netconf:base:1.0"):
+        ElementTree.register_namespace(parse_namespace(mo.group("namespace")), mo.group("namespace"))
+
+    for element in xml_element:
+        sort(element)
+
+
+def diff_xml(xml1, xml2, xpath):
+    """
+    Resolves differences between two xml files.
+    :param xml1: input file left side (original)
+    :param xml2: input file right side (to compare with)
+    :param xpath: xpath of element to read. example:
+                  ./{urn:ietf:params:xml:ns:yang:ietf-interfaces}interfaces/{ \
+                  urn:ietf:params:xml:ns:yang:ietf-interfaces}interface[{ \
+                  urn:ietf:params:xml:ns:yang:ietf-interfaces}name='loop0']
+    :return: diff of input files
+    """
+    ElementTree.register_namespace("nc", "urn:ietf:params:xml:ns:netconf:base:1.0")
+    tmp1 = unicode_writer(NamedTemporaryFile('w'))
+    normalize_xml(tmp1, ElementTree.parse(xml1), xpath)
+
+    tmp2 = unicode_writer(NamedTemporaryFile('w'))
+    normalize_xml(tmp2, ElementTree.parse(xml2), xpath)
+
+    return subprocess.call(["diff", "-u", "-s", "-d", "--label", xml1, "--label", xml2, tmp1.name, tmp2.name])
+
+
+def normalize_xml(tmp, tree, xpath):
+    root = tree.getroot() if (xpath == "*") else tree.getroot().find(xPath)
+    sort(root)
+    xml_str = ElementTree.tostring(root, encoding="utf-8", method="xml")
+    tmp.write(xml_str.decode("utf-8"))
+    tmp.flush()
+    #   format and normalize output using xmllint
+    #   cmd: xmllint --exc-c14n [file_name] -o [file_name]
+    subprocess.call(["xmllint", "--format", tmp.name, "-o", tmp.name])
+
+
+if __name__ == '__main__':
+    args = sys.argv
+    prog = os.path.basename(args.pop(0))
+
+    if '-h' in args or '--help' in args:
+        print_usage(prog)
+        exit(0)
+
+    if len(args) < 2:
+        print_usage(prog)
+        exit(1)
+    args.reverse()
+    file1 = args.pop(-1)
+    file2 = args.pop(-1)
+    if len(args) > 2:
+        xPath = args.pop(-1)
+    else:
+        xPath = "*"
+
+    exit(diff_xml(file1, file2, xPath))
index 5987707..a1b148f 100755 (executable)
@@ -40,6 +40,7 @@ if __name__ == '__main__':
     argparser.add_argument('-c', '--commit', help="commits candidate configuration",
                            action="store_true")
     argparser.add_argument('--verbose', help="increase output verbosity", action="store_true")
+    argparser.add_argument('--host', default="localhost", help="host/node for which to write <config> element")
     args = argparser.parse_args()
 
     logger = logging.getLogger("hc2vpp.examples.edit_config")
@@ -48,4 +49,4 @@ if __name__ == '__main__':
     else:
         logging.basicConfig(level=logging.INFO)
 
-    _edit_config(args.config_filename, validate=args.validate, commit=args.commit)
+    _edit_config(args.config_filename, validate=args.validate, commit=args.commit, host=args.host)
index 631926e..3eb4fec 100755 (executable)
@@ -34,12 +34,20 @@ if __name__ == '__main__':
     argparser = argparse.ArgumentParser(description="Obtains VPP configuration using <get-config> RPC")
     argparser.add_argument('--reply_filename', help="name of XML file to store received configuration")
     argparser.add_argument('--verbose', help="increase output verbosity", action="store_true")
+    argparser.add_argument('--host', default="localhost", help="host/node for which to write <config> element")
+    argparser.add_argument('--simple', help="decrease output verbosity", action="store_true")
     args = argparser.parse_args()
 
     logger = logging.getLogger("hc2vpp.examples.get_config")
-    if args.verbose:
-        logging.basicConfig(level=logging.DEBUG)
+
+    if args.simple:
+        logging.basicConfig(level=logging.ERROR)
     else:
-        logging.basicConfig(level=logging.INFO)
+        if args.verbose:
+            logging.basicConfig(level=logging.DEBUG)
+        else:
+            logging.basicConfig(level=logging.INFO)
+
+
 
-    _get_config(args.reply_filename)
+    _get_config(args.reply_filename, host=args.host)
diff --git a/examples/ncclient/interfaces/af-packet/candidate_config_af_packet_interface.xml b/examples/ncclient/interfaces/af-packet/candidate_config_af_packet_interface.xml
new file mode 100644 (file)
index 0000000..dd2a458
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2019 Cisco and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at:
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <nat xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <instances>
+            <instance>
+                <id>0</id>
+                <policy>
+                    <id>0</id>
+                </policy>
+            </instance>
+        </instances>
+    </nat>
+    <fib-table-management xmlns="http://fd.io/hc2vpp/yang/vpp-fib-table-management">
+        <fib-tables>
+            <table>
+                <table-id>0</table-id>
+                <address-family>ipv4</address-family>
+                <name>ipv4-VRF:0</name>
+            </table>
+            <table>
+                <table-id>0</table-id>
+                <address-family>ipv6</address-family>
+                <name>ipv6-VRF:0</name>
+            </table>
+        </fib-tables>
+    </fib-table-management>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>GigabitEthernet0/9/0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+            <ethernet xmlns="http://fd.io/hc2vpp/yang/v3po">
+                <mtu>9206</mtu>
+            </ethernet>
+        </interface>
+        <interface>
+            <name>host-vethAF</name>
+            <description>VethAF host interface</description>
+            <af-packet xmlns="http://fd.io/hc2vpp/yang/v3po">
+                <host-interface-name>vethAF</host-interface-name>
+            </af-packet>
+            <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
+                <address>
+                    <ip>10.2.0.2</ip>
+                    <prefix-length>24</prefix-length>
+                </address>
+            </ipv4>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:af-packet</type>
+        </interface>
+    </interfaces>
+    <gpe xmlns="http://fd.io/hc2vpp/yang/gpe">
+        <gpe-feature-data>
+            <enable>false</enable>
+        </gpe-feature-data>
+    </gpe>
+    <native-forward-paths-tables xmlns="http://fd.io/hc2vpp/yang/gpe">
+        <native-forward-paths-table>
+            <table-id>0</table-id>
+        </native-forward-paths-table>
+    </native-forward-paths-tables>
+    <lisp xmlns="http://fd.io/hc2vpp/yang/lisp">
+        <enable>false</enable>
+    </lisp>
+</data>
+
diff --git a/examples/ncclient/interfaces/af-packet/edit_config_af_packet_interface.xml b/examples/ncclient/interfaces/af-packet/edit_config_af_packet_interface.xml
new file mode 100644 (file)
index 0000000..f8c4367
--- /dev/null
@@ -0,0 +1,34 @@
+<!--
+  ~ Copyright (c) 2019 Cisco and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at:
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>host-vethAF</name>
+            <description>VethAF host interface</description>
+            <af-packet xmlns="http://fd.io/hc2vpp/yang/v3po">
+                <host-interface-name>vethAF</host-interface-name>
+            </af-packet>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:af-packet</type>
+            <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
+                <address>
+                    <ip>10.2.0.2</ip>
+                    <prefix-length>24</prefix-length>
+                </address>
+            </ipv4>
+        </interface>
+    </interfaces>
+</config>
diff --git a/examples/ncclient/interfaces/af-packet/test_diff_af_packet.sh b/examples/ncclient/interfaces/af-packet/test_diff_af_packet.sh
new file mode 100755 (executable)
index 0000000..8bce3b6
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# Copyright (c) 2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR_NAME=$(dirname $0)
+
+${DIR_NAME}/../../test_diff_config.sh ${DIR_NAME}/candidate_config_af_packet_interface.xml
diff --git a/examples/ncclient/interfaces/af-packet/test_edit_af_packet.sh b/examples/ncclient/interfaces/af-packet/test_edit_af_packet.sh
new file mode 100755 (executable)
index 0000000..058d478
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/bash
+#
+# Copyright (c) 2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR_NAME=$(dirname $0)
+
+# create linux side of AF-packet interface
+sudo ip link add vethAF type veth peer name vethFA
+xPath="./{urn:ietf:params:xml:ns:yang:ietf-interfaces}interfaces/\
+{urn:ietf:params:xml:ns:yang:ietf-interfaces}interface[{urn:ietf:params:xml:ns:yang:ietf-interfaces}name='host-vethAF']"
+
+${DIR_NAME}/../../test_edit_config.sh ${DIR_NAME}/edit_config_af_packet_interface.xml ${DIR_NAME}/edit_config_af_packet_interface.xml ${xPath}
diff --git a/examples/ncclient/interfaces/loop/candidate_config_loop_interface.xml b/examples/ncclient/interfaces/loop/candidate_config_loop_interface.xml
new file mode 100644 (file)
index 0000000..c477ad2
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <fib-table-management xmlns="http://fd.io/hc2vpp/yang/vpp-fib-table-management">
+        <fib-tables>
+            <table>
+                <table-id>0</table-id>
+                <address-family>ipv4</address-family>
+                <name>ipv4-VRF:0</name>
+            </table>
+            <table>
+                <table-id>0</table-id>
+                <address-family>ipv6</address-family>
+                <name>ipv6-VRF:0</name>
+            </table>
+        </fib-tables>
+    </fib-table-management>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>loop0</name>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <enabled>true</enabled>
+            <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
+                <address>
+                    <ip>10.0.0.1</ip>
+                    <prefix-length>24</prefix-length>
+                </address>
+            </ipv4>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
+            </loopback>
+        </interface>
+    </interfaces>
+    <nat xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <instances>
+            <instance>
+                <id>0</id>
+                <policy>
+                    <id>0</id>
+                </policy>
+            </instance>
+        </instances>
+    </nat>
+    <gpe xmlns="http://fd.io/hc2vpp/yang/gpe">
+        <gpe-feature-data>
+            <enable>false</enable>
+        </gpe-feature-data>
+    </gpe>
+    <native-forward-paths-tables xmlns="http://fd.io/hc2vpp/yang/gpe">
+        <native-forward-paths-table>
+            <table-id>0</table-id>
+        </native-forward-paths-table>
+    </native-forward-paths-tables>
+    <lisp xmlns="http://fd.io/hc2vpp/yang/lisp">
+        <enable>false</enable>
+    </lisp>
+</data>
+
diff --git a/examples/ncclient/interfaces/loop/edit_config_loop_interface.xml b/examples/ncclient/interfaces/loop/edit_config_loop_interface.xml
new file mode 100644 (file)
index 0000000..9dfeead
--- /dev/null
@@ -0,0 +1,33 @@
+<!--
+  ~ Copyright (c) 2019 Cisco and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at:
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>loop0</name>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <enabled>true</enabled>
+            <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
+                <address>
+                    <ip>10.0.0.1</ip>
+                    <prefix-length>24</prefix-length>
+                </address>
+            </ipv4>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
+            </loopback>
+        </interface>
+    </interfaces>
+</config>
diff --git a/examples/ncclient/interfaces/loop/test_diff_loopback.sh b/examples/ncclient/interfaces/loop/test_diff_loopback.sh
new file mode 100755 (executable)
index 0000000..fdc07ec
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# Copyright (c) 2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR_NAME=$(dirname $0)
+
+${DIR_NAME}/../../test_diff_config.sh ${DIR_NAME}/candidate_config_loop_interface.xml
diff --git a/examples/ncclient/interfaces/loop/test_edit_loopback.sh b/examples/ncclient/interfaces/loop/test_edit_loopback.sh
new file mode 100755 (executable)
index 0000000..757d656
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+#
+# Copyright (c) 2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR_NAME=$(dirname $0)
+xPath="./{urn:ietf:params:xml:ns:yang:ietf-interfaces}interfaces/\
+{urn:ietf:params:xml:ns:yang:ietf-interfaces}interface[{urn:ietf:params:xml:ns:yang:ietf-interfaces}name='loop0']"
+
+${DIR_NAME}/../../test_edit_config.sh ${DIR_NAME}/edit_config_loop_interface.xml ${DIR_NAME}/edit_config_loop_interface.xml ${xPath}
diff --git a/examples/ncclient/interfaces/tap/candidate_config_tap_interface.xml b/examples/ncclient/interfaces/tap/candidate_config_tap_interface.xml
new file mode 100644 (file)
index 0000000..7d0a5d6
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2019 Cisco and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at:
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <fib-table-management xmlns="http://fd.io/hc2vpp/yang/vpp-fib-table-management">
+        <fib-tables>
+            <table>
+                <table-id>0</table-id>
+                <address-family>ipv4</address-family>
+                <name>ipv4-VRF:0</name>
+            </table>
+            <table>
+                <table-id>0</table-id>
+                <address-family>ipv6</address-family>
+                <name>ipv6-VRF:0</name>
+            </table>
+        </fib-tables>
+    </fib-table-management>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>local0</name>
+            <type xmlns:x="urn:ietf:params:xml:ns:yang:iana-if-type">x:ethernetCsmacd</type>
+            <enabled>false</enabled>
+        </interface>
+        <interface>
+            <name>tap1</name>
+            <description>TAP 1 test interface</description>
+            <tap xmlns="http://fd.io/hc2vpp/yang/v3po">
+                <tap-name>tap1</tap-name>
+            </tap>
+            <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
+                <address>
+                    <ip>10.1.0.3</ip>
+                    <prefix-length>24</prefix-length>
+                </address>
+            </ipv4>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:tap</type>
+        </interface>
+    </interfaces>
+    <nat xmlns="urn:ietf:params:xml:ns:yang:ietf-nat">
+        <instances>
+            <instance>
+                <id>0</id>
+                <policy>
+                    <id>0</id>
+                </policy>
+            </instance>
+        </instances>
+    </nat>
+    <gpe xmlns="http://fd.io/hc2vpp/yang/gpe">
+        <gpe-feature-data>
+            <enable>false</enable>
+        </gpe-feature-data>
+    </gpe>
+    <native-forward-paths-tables xmlns="http://fd.io/hc2vpp/yang/gpe">
+        <native-forward-paths-table>
+            <table-id>0</table-id>
+        </native-forward-paths-table>
+    </native-forward-paths-tables>
+    <lisp xmlns="http://fd.io/hc2vpp/yang/lisp">
+        <enable>false</enable>
+    </lisp>
+</data>
diff --git a/examples/ncclient/interfaces/tap/edit_config_tap_interface.xml b/examples/ncclient/interfaces/tap/edit_config_tap_interface.xml
new file mode 100644 (file)
index 0000000..4f03ef2
--- /dev/null
@@ -0,0 +1,34 @@
+<!--
+  ~ Copyright (c) 2019 Cisco and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at:
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<config>
+    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+            <name>tap1</name>
+            <description>TAP 1 test interface</description>
+            <tap xmlns="http://fd.io/hc2vpp/yang/v3po">
+                <tap-name>tap1</tap-name>
+            </tap>
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:tap</type>
+            <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
+                <address>
+                    <ip>10.1.0.3</ip>
+                    <prefix-length>24</prefix-length>
+                </address>
+            </ipv4>
+        </interface>
+    </interfaces>
+</config>
diff --git a/examples/ncclient/interfaces/tap/test_diff_tap.sh b/examples/ncclient/interfaces/tap/test_diff_tap.sh
new file mode 100755 (executable)
index 0000000..6da56f6
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# Copyright (c) 2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR_NAME=$(dirname $0)
+
+${DIR_NAME}/../../test_diff_config.sh ${DIR_NAME}/candidate_config_tap_interface.xml
diff --git a/examples/ncclient/interfaces/tap/test_edit_tap.sh b/examples/ncclient/interfaces/tap/test_edit_tap.sh
new file mode 100755 (executable)
index 0000000..1a752cb
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+#
+# Copyright (c) 2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR_NAME=$(dirname $0)
+xPath="./{urn:ietf:params:xml:ns:yang:ietf-interfaces}interfaces/\
+{urn:ietf:params:xml:ns:yang:ietf-interfaces}interface[{urn:ietf:params:xml:ns:yang:ietf-interfaces}name='tap1']"
+
+${DIR_NAME}/../../test_edit_config.sh ${DIR_NAME}/edit_config_tap_interface.xml ${DIR_NAME}/edit_config_tap_interface.xml ${xPath}
index 74f4020..690eb58 100644 (file)
@@ -8,11 +8,11 @@
         <interface>
             <name>loop1</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>01:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+            <nat xmlns="http://fd.io/hc2vpp/yang/interface-nat">
                 <outbound>
                     <post-routing>true</post-routing>
                 </outbound>
         <interface>
             <name>loop0</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>00:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+            <nat xmlns="http://fd.io/hc2vpp/yang/interface-nat">
                 <inbound>
                     <nat64-support>true</nat64-support>
                     <nat44-support>false</nat44-support>
@@ -45,7 +45,7 @@
                     <external-ip-address-pool>
                         <pool-id>3</pool-id>
                         <external-ip-pool>10.10.10.1/30</external-ip-pool>
-                        <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                        <pool-type xmlns="http://fd.io/hc2vpp/yang/vpp-nat">nat64</pool-type>
                     </external-ip-address-pool>
                     <external-ip-address-pool>
                         <pool-id>2</pool-id>
index 96a6e9d..ca3c366 100644 (file)
@@ -8,19 +8,19 @@
         <interface>
             <name>loop1</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>01:ff:ff:ff:ff:ff</mac>
             </loopback>
         </interface>
         <interface>
             <name>loop2</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>02:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+            <nat xmlns="http://fd.io/hc2vpp/yang/interface-nat">
                 <inbound>
                     <nat64-support>true</nat64-support>
                     <nat44-support>false</nat44-support>
         <interface>
             <name>loop3</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>03:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+            <nat xmlns="http://fd.io/hc2vpp/yang/interface-nat">
                 <outbound>
                     <post-routing>true</post-routing>
                 </outbound>
@@ -43,8 +43,8 @@
         <interface>
             <name>loop0</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>00:ff:ff:ff:ff:ff</mac>
             </loopback>
         </interface>
@@ -61,7 +61,7 @@
                     <external-ip-address-pool>
                         <pool-id>6</pool-id>
                         <external-ip-pool>1.2.3.4/32</external-ip-pool>
-                        <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                        <pool-type xmlns="http://fd.io/hc2vpp/yang/vpp-nat">nat64</pool-type>
                     </external-ip-address-pool>
                     <external-ip-address-pool>
                         <pool-id>5</pool-id>
@@ -70,7 +70,7 @@
                     <external-ip-address-pool>
                         <pool-id>3</pool-id>
                         <external-ip-pool>10.10.10.1/30</external-ip-pool>
-                        <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                        <pool-type xmlns="http://fd.io/hc2vpp/yang/vpp-nat">nat64</pool-type>
                     </external-ip-address-pool>
                     <external-ip-address-pool>
                         <pool-id>2</pool-id>
index f42eddb..55d15a2 100644 (file)
         <interface>
             <name>loop1</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>01:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+            <nat xmlns="http://fd.io/hc2vpp/yang/interface-nat">
                 <outbound>
                     <post-routing>true</post-routing>
                 </outbound>
         <interface>
             <name>loop0</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>00:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+            <nat xmlns="http://fd.io/hc2vpp/yang/interface-nat">
                 <inbound>
                     <nat64-support>true</nat64-support>
                     <nat44-support>false</nat44-support>
@@ -60,7 +60,7 @@
                     <external-ip-address-pool>
                         <pool-id>3</pool-id>
                         <external-ip-pool>10.10.10.1/30</external-ip-pool>
-                        <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                        <pool-type xmlns="http://fd.io/hc2vpp/yang/vpp-nat">nat64</pool-type>
                     </external-ip-address-pool>
                     <external-ip-address-pool>
                         <pool-id>2</pool-id>
index cf21408..426e6bc 100644 (file)
         <interface>
             <name>loop1</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>01:ff:ff:ff:ff:ff</mac>
             </loopback>
         </interface>
         <interface>
             <name>loop2</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>02:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+            <nat xmlns="http://fd.io/hc2vpp/yang/interface-nat">
                 <inbound>
                     <nat64-support>true</nat64-support>
                     <nat44-support>false</nat44-support>
         <interface>
             <name>loop3</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>03:ff:ff:ff:ff:ff</mac>
             </loopback>
-            <nat xmlns="urn:opendaylight:params:xml:ns:yang:interface:nat">
+            <nat xmlns="http://fd.io/hc2vpp/yang/interface-nat">
                 <outbound>
                     <post-routing>true</post-routing>
                 </outbound>
@@ -58,8 +58,8 @@
         <interface>
             <name>loop0</name>
             <description>for testing purposes</description>
-            <type xmlns:x="urn:opendaylight:params:xml:ns:yang:v3po">x:loopback</type>
-            <loopback xmlns="urn:opendaylight:params:xml:ns:yang:v3po">
+            <type xmlns:x="http://fd.io/hc2vpp/yang/v3po">x:loopback</type>
+            <loopback xmlns="http://fd.io/hc2vpp/yang/v3po">
                 <mac>00:ff:ff:ff:ff:ff</mac>
             </loopback>
         </interface>
@@ -76,7 +76,7 @@
                     <external-ip-address-pool>
                         <pool-id>6</pool-id>
                         <external-ip-pool>1.2.3.4/32</external-ip-pool>
-                        <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                        <pool-type xmlns="http://fd.io/hc2vpp/yang/vpp-nat">nat64</pool-type>
                     </external-ip-address-pool>
                     <external-ip-address-pool>
                         <pool-id>5</pool-id>
@@ -85,7 +85,7 @@
                     <external-ip-address-pool>
                         <pool-id>3</pool-id>
                         <external-ip-pool>10.10.10.1/30</external-ip-pool>
-                        <pool-type xmlns="urn:opendaylight:params:xml:ns:yang:vpp:nat">nat64</pool-type>
+                        <pool-type xmlns="http://fd.io/hc2vpp/yang/vpp-nat">nat64</pool-type>
                     </external-ip-address-pool>
                     <external-ip-address-pool>
                         <pool-id>2</pool-id>
index b9ec896..37f8047 100755 (executable)
@@ -15,4 +15,4 @@
 
 DIR_NAME=$(dirname $0)
 
-${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_nat.xml ${DIR_NAME}/expected_config_nat.xml
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_nat.xml ${DIR_NAME}/expected_config_nat.xml *
index c5ae446..5c6b527 100755 (executable)
@@ -15,6 +15,6 @@
 
 DIR_NAME=$(dirname $0)
 
-${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_nat.xml ${DIR_NAME}/expected_config_nat.xml
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_nat.xml ${DIR_NAME}/expected_config_nat.xml *
 
-${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_nat_update.xml ${DIR_NAME}/expected_config_nat_update.xml
+${DIR_NAME}/../test_copy_config.sh ${DIR_NAME}/config_nat_update.xml ${DIR_NAME}/expected_config_nat_update.xml *
index 2b751d5..bf70c82 100755 (executable)
@@ -15,6 +15,7 @@
 #
 # $1 config element for <copy-config> RPC
 # $2 expected running config
+# $3 xPath to verify config against
 
 DIR_NAME=$(dirname $0)
 
@@ -23,10 +24,10 @@ ${DIR_NAME}/get_config.py --reply_filename _actual_config.xml
 
 # fixme: find better xml comparison tool
 # xmldiffs does not work well when difference occurs on deep level
-${DIR_NAME}/xmldiffs.py $2 _actual_config.xml
+${DIR_NAME}/xmldiffs.py $2 _actual_config.xml $3
 ret_code=$?
 
-if [ $ret_code == 0 ]; then
+if [[ ${ret_code} == 0 ]]; then
     echo "<copy-config> successful"
     rm _actual_config.xml
     exit 0
diff --git a/examples/ncclient/test_diff_config.sh b/examples/ncclient/test_diff_config.sh
new file mode 100755 (executable)
index 0000000..9180064
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# Copyright (c) 2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# $1 candidate config element to diff against actual config
+# $2 xPath to verify config against
+
+DIR_NAME=$(dirname $0)
+
+${DIR_NAME}/get_config.py --reply_filename _actual_config.xml --simple
+
+echo "Differences in running and candidate config:"
+
+${DIR_NAME}/diff_xml.py $1 _actual_config.xml $2
+ret_code=$?
+
+if [[ ${ret_code} == 0 ]]; then
+    exit 0
+fi
+rm _actual_config.xml
+echo "finished."
+exit 0
diff --git a/examples/ncclient/test_edit_config.sh b/examples/ncclient/test_edit_config.sh
new file mode 100755 (executable)
index 0000000..a135709
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# Copyright (c) 2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# $1 config element for <copy-config> RPC
+# $2 expected running config
+# $3 xPath to verify config against
+
+DIR_NAME=$(dirname $0)
+
+${DIR_NAME}/edit_config.py $1 -c
+${DIR_NAME}/get_config.py --reply_filename _actual_config.xml
+
+# fixme: find better xml comparison tool
+# xmldiffs does not work well when difference occurs on deep level
+${DIR_NAME}/xmldiffs.py $2 _actual_config.xml $3
+ret_code=$?
+
+if [[ ${ret_code} == 0 ]]; then
+    echo "<edit-config> successful"
+    rm _actual_config.xml
+    exit 0
+fi
+
+echo "<edit-config> failed"
+exit 1
index b78fa8f..6e43b3f 100755 (executable)
@@ -1,40 +1,53 @@
 #!/usr/bin/env python
 """
-Usage: {prog} [OPTION] FILE1 FILE2
+Usage: {prog} [OPTION] FILE1 FILE2 xPath
 
 Compare two XML files, ignoring element and attribute order.
 
+xPath a valid path should be defined or wildcard "*" should be used.
+example:
+    ./{{urn:ietf:params:xml:ns:yang:ietf-interfaces}}interfaces/
+    {{urn:ietf:params:xml:ns:yang:ietf-interfaces}}interface[
+    {{urn:ietf:params:xml:ns:yang:ietf-interfaces}}name='loop0']
+
 Any extra options are passed to the `diff' command.
 
 Copyright (c) 2017, Johannes H. Jensen.
 License: BSD, see LICENSE for more details.
 """
 from __future__ import print_function, unicode_literals
-import sys
+
 import os
-import io
+import subprocess
+import sys
 import xml.etree.ElementTree as ET
 from tempfile import NamedTemporaryFile
-import subprocess
+
 
 def attr_str(k, v):
-    return "{}=\"{}\"".format(k,v)
+    return "{}=\"{}\"".format(k, v)
+
 
 def node_str(n):
     attrs = sorted(n.attrib.items())
-    astr = " ".join(attr_str(k,v) for k,v in attrs)
+    astr = " ".join(attr_str(k, v) for k, v in attrs)
     s = n.tag
     if astr:
         s += " " + astr
     return s
 
+
 def node_key(n):
     return node_str(n)
 
+
 def indent(s, level):
     return "  " * level + s
 
+
 def write_sorted(stream, node, level=0):
+    if node is None:
+        return
     children = node.getchildren()
     text = (node.text or "").strip()
     tail = (node.tail or "").strip()
@@ -57,9 +70,11 @@ def write_sorted(stream, node, level=0):
     if tail:
         stream.write(indent(tail + "\n", level))
 
+
 if sys.version_info < (3, 0):
     # Python 2
     import codecs
+
     def unicode_writer(fp):
         return codecs.getwriter('utf-8')(fp)
 else:
@@ -67,27 +82,37 @@ else:
     def unicode_writer(fp):
         return fp
 
-def xmldiffs(file1, file2, diffargs=["-u"]):
+
+def xmldiffs(file1, file2, xpath="*", diffargs=["-u"]):
     tree = ET.parse(file1)
     tmp1 = unicode_writer(NamedTemporaryFile('w'))
-    write_sorted(tmp1, tree.getroot())
+    if xpath == "*":
+        write_sorted(tmp1, tree.getroot())
+    else:
+        write_sorted(tmp1, tree.getroot().find(xpath))
+
     tmp1.flush()
 
     tree = ET.parse(file2)
     tmp2 = unicode_writer(NamedTemporaryFile('w'))
-    write_sorted(tmp2, tree.getroot())
+    if xpath == "*":
+        write_sorted(tmp2, tree.getroot())
+    else:
+        write_sorted(tmp2, tree.getroot().find(xpath))
     tmp2.flush()
 
-    args = [ "diff" ]
+    args = ["diff"]
     args += diffargs
-    args += [ "--label", file1, "--label", file2 ]
-    args += [ tmp1.name, tmp2.name ]
+    args += ["--label", file1, "--label", file2]
+    args += [tmp1.name, tmp2.name]
 
     return subprocess.call(args)
 
+
 def print_usage(prog):
     print(__doc__.format(prog=prog).strip())
 
+
 if __name__ == '__main__':
     args = sys.argv
     prog = os.path.basename(args.pop(0))
@@ -96,12 +121,16 @@ if __name__ == '__main__':
         print_usage(prog)
         exit(0)
 
-    if len(args) < 2:
+    if len(args) < 3:
         print_usage(prog)
         exit(1)
 
+    xPath = args.pop(-1)
     file2 = args.pop(-1)
     file1 = args.pop(-1)
-    diffargs = args if args else ["-u"]
 
-    exit(xmldiffs(file1, file2, diffargs))
+    xPath = xPath if xPath else "*"
+
+    diffargs = args if args else ["-u", "-s"]
+
+    exit(xmldiffs(file1, file2, xPath, diffargs))