[action] [PR:28248] [yang-mgmt] Treat empty CONFIG DB leaf-list (['']) as empty so libyang3 accepts empty pattern-constrained leaf-lists#28308
Conversation
…g3 accepts empty pattern-constrained leaf-lists #### Why I did it `config apply-patch`, `config replace` and `config rollback` fail on master for any configuration that contains an empty pattern-constrained leaf-list. `BGP_ALLOWED_PREFIXES` is the common trigger, because a deployment often populates only `prefixes_v4` or only `prefixes_v6`, leaving the other leaf-list empty. An empty leaf-list is stored in CONFIG DB as `field@ = ""`. The Python `ConfigDBConnector` deserialises that empty string into a single empty-string element (`['']`), which is the CONFIG DB representation of "no elements", not a real element. Before the libyang1 to libyang3 port ([sonic-net#26584](sonic-net#26584)) the `''` sentinel was tolerated by the validation library. libyang3 validates the `''` element against the leaf type's pattern (for example the ipv4-prefix pattern of `BGP_ALLOWED_PREFIXES.prefixes_v4`) and rejects the whole config: Unsatisfied pattern - "" does not conform to "(([0-9]| ... )/(([0-9])|([1-2][0-9])|(3[0-2]))( (le|ge) ...)?" Data path: .../BGP_ALLOWED_PREFIXES_LIST[deployment='DEPLOYMENT_ID'][id='0']/prefixes_v4 This is a read-side (config-to-YANG validation) regression. [sonic-net#26584](sonic-net#26584) did add a guard for the sibling case of an empty leaf-list that has a schema `default ""`, but missed the pattern-typed, no-default leaf-list case (`['']`), which is exactly `BGP_ALLOWED_PREFIXES`. This fixes the read-side regression behind sonic-mgmt test `generic_config_updater/test_bgp_prefix.py` (tracked by [sonic-mgmt issue 25549](sonic-net/sonic-mgmt#25549)). It is complementary to, and does not replace, the separate write-side effort that avoids writing `prefixes_v4@ = ""` into CONFIG DB in the first place ([sonic-buildimage issue 27818](sonic-net#27818), [sonic-utilities PR 4478](sonic-net/sonic-utilities#4478)). Even with that write-side fix, existing configs and other tables can still present an empty leaf-list, so the validation layer should accept it. ##### Work item tracking - Microsoft ADO **(number only)**: 38183186 #### How I did it In the CONFIG DB to YANG translation in `src/sonic-yang-mgmt/sonic_yang_ext.py` (the leaf-list branch of `_findYangTypedValue`), drop the empty-string sentinel so an empty leaf-list is represented as an empty list `[]`, which libyang3 accepts. The drop is gated on the leaf-list having no schema default (`not list(leaf.defaults())`), so the existing empty-with-default handling introduced by [sonic-net#26584](sonic-net#26584) is left byte-for-byte unchanged. Added a regression unit test (`test_empty_leaflist_collapses_to_empty`) that loads `BGP_ALLOWED_PREFIXES` with an empty `prefixes_v4` leaf-list and asserts the config validates and the leaf-list collapses to `[]`. #### How to verify it Unit test (sonic-yang-mgmt suite): with the fix the new test passes and the full suite is green; reverting only the two changed lines makes just `test_empty_leaflist_collapses_to_empty` fail with the `Unsatisfied pattern - ""` error above. End-to-end on a KVM t1 testbed (`vms-kvm-t1-lag`), baseline master image built after [sonic-net#26584](sonic-net#26584) (so it carries the regression), matched before/after with only `sonic_yang_ext.py` swapped: | DUT state | `generic_config_updater/test_bgp_prefix.py::test_bgp_prefix_tc1_suite` | |---|---| | before (unpatched baseline) | 2 failed, 2 errors — `config apply-patch` returns non-zero, teardown `config rollback failed` | | after (fix applied) | 2 passed | Also verified the mechanism directly: with `BGP_ALLOWED_PREFIXES|DEPLOYMENT_ID|0` holding `prefixes_v4@ = ""`, a subsequent valid `config apply-patch` fails with the `Unsatisfied pattern - ""` error before the fix and succeeds after it. #### Which release branch to backport (provide reason below if selected) - [ ] 202305 - [ ] 202311 - [ ] 202405 - [ ] 202411 - [ ] 202505 - [ ] 202511 - [ ] 202512 - [ ] 202605 - [ ] 202608 #### Tested branch (Please provide the tested image version) - [x] master — `SONiC.master.1145536-931dbfb70` (build 2026-06-22) #### Description for the changelog [yang-mgmt] Treat an empty CONFIG DB leaf-list (`['']`) as empty so libyang3 does not reject empty pattern-constrained leaf-lists such as BGP_ALLOWED_PREFIXES. #### Link to config_db schema for YANG module changes No YANG model change. `BGP_ALLOWED_PREFIXES` schema: https://github.com/sonic-net/sonic-buildimage/blob/master/src/sonic-yang-models/doc/Configuration.md#bgp_allowed_prefixes #### A picture of a cute animal (not mandatory but encouraged) 🦔 Signed-off-by: Sonic Build Admin <sonicbld@microsoft.com>
|
Original PR: #28248 |
|
/azp run Azure.sonic-buildimage |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
This cherry pick PR has been opened for more than 3 days. The mssonicbld will attempt to retry. ---Powered by SONiC BuildBot
|
|
/azpw retry |
|
Retrying failed(or canceled) jobs... |
|
Retrying failed(or canceled) stages in build 1160048: ✅Stage Build:
✅Stage Test:
|
|
@vaibhavhd The cherry pick PR didn't pass PR checker after retry. Left a comment in original PR #28248 to notify author. ---Powered by SONiC BuildBot
|
CI Failure Analysis — Build 1160048Both failures are not induced by this cherry-pick (which only touches 1.
|
|
/azpw run Azure.sonic-buildimage |
|
Retrying failed(or canceled) jobs... |
|
Retrying failed(or canceled) stages in build 1160048: ✅Stage Build:
✅Stage Test:
|
Why I did it
config apply-patch,config replaceandconfig rollbackfail on master for any configuration that contains an empty pattern-constrained leaf-list.BGP_ALLOWED_PREFIXESis the common trigger, because a deployment often populates onlyprefixes_v4or onlyprefixes_v6, leaving the other leaf-list empty.An empty leaf-list is stored in CONFIG DB as
field@ = "". The PythonConfigDBConnectordeserialises that empty string into a single empty-string element (['']), which is the CONFIG DB representation of "no elements", not a real element. Before the libyang1 to libyang3 port (#26584) the''sentinel was tolerated by the validation library. libyang3 validates the''element against the leaf type's pattern (for example the ipv4-prefix pattern ofBGP_ALLOWED_PREFIXES.prefixes_v4) and rejects the whole config:This is a read-side (config-to-YANG validation) regression. #26584 did add a guard for the sibling case of an empty leaf-list that has a schema
default "", but missed the pattern-typed, no-default leaf-list case (['']), which is exactlyBGP_ALLOWED_PREFIXES.This fixes the read-side regression behind sonic-mgmt test
generic_config_updater/test_bgp_prefix.py(tracked by sonic-mgmt issue 25549). It is complementary to, and does not replace, the separate write-side effort that avoids writingprefixes_v4@ = ""into CONFIG DB in the first place (sonic-buildimage issue 27818, sonic-utilities PR 4478). Even with that write-side fix, existing configs and other tables can still present an empty leaf-list, so the validation layer should accept it.Work item tracking
How I did it
In the CONFIG DB to YANG translation in
src/sonic-yang-mgmt/sonic_yang_ext.py(the leaf-list branch of_findYangTypedValue), drop the empty-string sentinel so an empty leaf-list is represented as an empty list[], which libyang3 accepts. The drop is gated on the leaf-list having no schema default (not list(leaf.defaults())), so the existing empty-with-default handling introduced by #26584 is left byte-for-byte unchanged.Added a regression unit test (
test_empty_leaflist_collapses_to_empty) that loadsBGP_ALLOWED_PREFIXESwith an emptyprefixes_v4leaf-list and asserts the config validates and the leaf-list collapses to[].How to verify it
Unit test (sonic-yang-mgmt suite): with the fix the new test passes and the full suite is green; reverting only the two changed lines makes just
test_empty_leaflist_collapses_to_emptyfail with theUnsatisfied pattern - ""error above.End-to-end on a KVM t1 testbed (
vms-kvm-t1-lag), baseline master image built after #26584 (so it carries the regression), matched before/after with onlysonic_yang_ext.pyswapped:generic_config_updater/test_bgp_prefix.py::test_bgp_prefix_tc1_suiteconfig apply-patchreturns non-zero, teardownconfig rollback failedAlso verified the mechanism directly: with
BGP_ALLOWED_PREFIXES|DEPLOYMENT_ID|0holdingprefixes_v4@ = "", a subsequent validconfig apply-patchfails with theUnsatisfied pattern - ""error before the fix and succeeds after it.Which release branch to backport (provide reason below if selected)
Tested branch (Please provide the tested image version)
SONiC.master.1145536-931dbfb70(build 2026-06-22)Description for the changelog
[yang-mgmt] Treat an empty CONFIG DB leaf-list (
['']) as empty so libyang3 does not reject empty pattern-constrained leaf-lists such as BGP_ALLOWED_PREFIXES.Link to config_db schema for YANG module changes
No YANG model change.
BGP_ALLOWED_PREFIXESschema: https://github.com/sonic-net/sonic-buildimage/blob/master/src/sonic-yang-models/doc/Configuration.md#bgp_allowed_prefixesA picture of a cute animal (not mandatory but encouraged)
🦔
Signed-off-by: Sonic Build Admin sonicbld@microsoft.com