Skip to content

Missing new line and space when push device config via service #48

@bhumong

Description

@bhumong

Missing new line and space when push device config via service

1. Overview

A formatting issue in Clixon causes malformed rpl-prefix-set values when a prefix-set contains multiple prefixes. The generated configuration omits required separators before end-set, resulting in invalid routing-policy syntax being sent to Cisco XR devices.

nobody@dc1528a56793[/]# commit Dec 18 06:26:31.071044: transaction_notification_handler: pid: 1222 Transaction 21 failed in xr: Device xr in state PUSH-EDIT2:application operation-failed 'YANG framework' detected the 'fatal' condition 'Operation failed' : ns1:routing-policy/ns1:sets/ns1:prefix-sets/ns1:prefix-set[set-name = 'prefixset']/ns1:rpl-prefix-set Failed

2. Step To Reproduce

Environment Setup

  1. Set up a Cisco XR device (recommended over a VM).

  2. Configure a prefix-set on the XR device that contains more than one prefix (at least two IP prefixes).

  3. Set up the Clixon controller and ensure it is successfully connected to the XR device (NETCONF session established and device in sync).

Reproduction Steps

  1. In the Clixon controller, create a service (for example, a service that updates an interface description).

  2. Commit the service changes through the controller.

  3. Observe the NETCONF edit-config payload sent to the XR device.

3. Possible Root Cause

the rpl-prefix-set string in your controller’s device config is malformed (at minimum missing a separator before end-set; XR typically expects proper spacing/newlines like the CLI form).le 24end-set (missing whitespace/newline before end-set).

Dec 18 06:26:29.265005: xml_cmp:412: vm vm eq:0 nr: 0 0 yi: 0 0
Dec 18 06:26:29.265010: xml_cmp:412: config config eq:0 nr: 0 0 yi: 0 0
Dec 18 06:26:29.265013: xml_cmp:412: memory memory eq:0 nr: 0 0 yi: 0 0
Dec 18 06:26:29.265015: xml_cmp:412: admin admin eq:0 nr: 0 0 yi: 0 0
Dec 18 06:26:29.265016: xml_cmp:412: rp rp eq:0 nr: 0 0 yi: 0 0
Dec 18 06:26:29.265018: xml_cmp:412: lc lc eq:0 nr: 0 0 yi: 0 0
Dec 18 06:26:29.265020: xml_cmp:412: cpu cpu eq:0 nr: 0 0 yi: 0 0
Dec 18 06:26:29.265021: xml_cmp:412: assign assign eq:0 nr: 0 0 yi: 0 0
Dec 18 06:26:29.265242: clixon_msg_send:374: Send [xr] 
#1124
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="13"><edit-config><target><candidate/></target><default-operation>merge</default-operation><config><interfaces xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-interface-cfg"><interface><interface-name>MgmtEth0/RP0/CPU0/0</interface-name><description nc:operation="replace">update from service 14</description></interface></interfaces><routing-policy xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-policy-repository-cfg"><sets><prefix-sets><prefix-set><set-name>prefixset</set-name><rpl-prefix-set nc:operation="replace">prefix-set prefixset  192.168.0.0/24 le 24,  192.168.1.0/24 le 24end-set</rpl-prefix-set></prefix-set></prefix-sets></sets></routing-policy><routing-policy xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-route-policy-cfg"><sets><prefix-sets><prefix-set><set-name>prefixset</set-name><rpl-prefix-set nc:operation="replace">prefix-set prefixset  192.168.0.0/24 le 24,  192.168.1.0/24 le 24end-set</rpl-prefix-set></prefix-set></prefix-sets></sets></routing-policy></config></edit-config></rpc>
##

4. Propose Solution / Fix

--- a/clixon/parser.py
+++ b/clixon/parser.py
@@ -81,14 +81,9 @@ class Handler(handler.ContentHandler):
-        if cdata.startswith("\n"):
-            cdata = cdata[1:]
-
-        if cdata.endswith("\n"):
-            cdata = cdata[:-1]
-
-        if cdata.isspace() and self.last_cdata == "":
-            return
+        if cdata.isspace():
+            if self.elements and self.elements[-1].cdata == "":
+                return`
--- a/tests/test_parse.py
+++ b/tests/test_parse.py
@@ -222,3 +222,21 @@ def test_delete_create():
     root.foo.bar.delete()
 
     assert root.dumps() == """<foo/>"""
+
+
+def test_preserve_newline_in_split_characters_chunks():
+    """
+    Expat/SAX may split element character data into multiple chunks.
+    Ensure we do not strip a leading newline from a non-whitespace chunk.
+    """
+
+    from clixon.parser import Handler
+
+    h = Handler()
+    h.startElement("rpl-prefix-set", {})
+    h.characters("prefix-set prefixset 192.168.1.0/24 le 24")
+    h.characters("\nend-set")
+    h.endElement("rpl-prefix-set")
+
+    elem = h.root.get_elements()[0]
+    assert elem.cdata == "prefix-set prefixset 192.168.1.0/24 le 24\nend-set"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions