Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[generic_config_updater] VRF modification failed when loopback interface is assigned with two or more IP addresses #2000

Closed
wen587 opened this issue Jan 7, 2022 · 2 comments

Comments

@wen587
Copy link
Contributor

wen587 commented Jan 7, 2022

Description

If the Loopback is assigned with two or more IP address(either v4 or v6), VRF config by config apply-patch on that interface will fail.

Steps to reproduce the issue

  1. Take T0 topo for example, we will make change on Loopback0.
  2. Create VRF by config
  3. apply-patch to add Loopback0 to Vrf_01
admin@vlab-01:~$ sudo config vrf add Vrf_01
admin@vlab-01:~$ sudo config vrf add Vrf_02
Case 1: vrf change on loopback intf with only one ipv4 address by remove ipv6 address.

admin@vlab-01:~$ sudo config interface ip remove Loopback0 FC00:1::32/128
admin@vlab-01:~$ sudo config apply-patch  -i /FEATURE -i /QUEUE -i /SCHEDULER lo/temp.json
Patch Applier: Patch application starting.
Patch Applier: Patch: [{"op": "add", "path": "/LOOPBACK_INTERFACE/Loopback0/vrf_name", "value": "Vrf_01"}]
Patch Applier: Getting current config db.
Patch Applier: Simulating the target full config after applying the patch.
Patch Applier: Validating target config does not have empty tables, since they do not show up in ConfigDb.
Patch Applier: Sorting patch updates.
Note: Below table(s) have no YANG models:
BGP_PEER_RANGE, CONSOLE_SWITCH, DEVICE_NEIGHBOR_METADATA, DHCP_SERVER, KDUMP, RESTAPI, SNMP, SNMP_COMMUNITY, TELEMETRY,
Note: Below table(s) have no YANG models:
BGP_PEER_RANGE, CONSOLE_SWITCH, DEVICE_NEIGHBOR_METADATA, DHCP_SERVER, KDUMP, RESTAPI, SNMP, SNMP_COMMUNITY, TELEMETRY,
Note: Below table(s) have no YANG models:
BGP_PEER_RANGE, CONSOLE_SWITCH, DEVICE_NEIGHBOR_METADATA, DHCP_SERVER, KDUMP, RESTAPI, SNMP, SNMP_COMMUNITY, TELEMETRY,
libyang[0]: Leafref "../../LOOPBACK_INTERFACE_LIST/name" of value "Loopback0" points to a non-existing leaf. (path: /sonic-loopback-interface:sonic-loopback-interface/LOOPBACK_INTERFACE/LOOPBACK_INTERFACE_IPPREFIX_LIST[name='Loopback0'][ip-prefix='10.1.0.32/32']/name)
sonic_yang(3):Data Loading Failed:Leafref "../../LOOPBACK_INTERFACE_LIST/name" of value "Loopback0" points to a non-existing leaf.
Patch Applier: The patch was sorted into 4 changes:
Patch Applier:   * [{"op": "remove", "path": "/LOOPBACK_INTERFACE/Loopback0|10.1.0.32~132"}]
Patch Applier:   * [{"op": "remove", "path": "/LOOPBACK_INTERFACE"}]
Patch Applier:   * [{"op": "add", "path": "/LOOPBACK_INTERFACE", "value": {"Loopback0": {"vrf_name": "Vrf_01"}}}]
Patch Applier:   * [{"op": "add", "path": "/LOOPBACK_INTERFACE/Loopback0|10.1.0.32~132", "value": {}}]
Patch Applier: Applying 4 changes in order:
Patch Applier:   * [{"op": "remove", "path": "/LOOPBACK_INTERFACE/Loopback0|10.1.0.32~132"}]
Patch Applier:   * [{"op": "remove", "path": "/LOOPBACK_INTERFACE"}]
Patch Applier:   * [{"op": "add", "path": "/LOOPBACK_INTERFACE", "value": {"Loopback0": {"vrf_name": "Vrf_01"}}}]
Patch Applier:   * [{"op": "add", "path": "/LOOPBACK_INTERFACE/Loopback0|10.1.0.32~132", "value": {}}]
Patch Applier: Verifying patch updates are reflected on ConfigDB.
Patch Applier: Patch application completed.
Patch applied successfully.

Case 2: We just keep Loopback intf with two address which is predefined with one ipv4 and one ipv6 address.
                Other tests show similar output.
admin@vlab-01:~$ sudo config apply-patch  -i /FEATURE -i /QUEUE -i /SCHEDULER lo/temp.json
Patch Applier: Patch application starting.
Patch Applier: Patch: [{"op": "add", "path": "/LOOPBACK_INTERFACE/Loopback0/vrf_name", "value": "Vrf_01"}]
Patch Applier: Getting current config db.
Patch Applier: Simulating the target full config after applying the patch.
Patch Applier: Validating target config does not have empty tables, since they do not show up in ConfigDb.
Patch Applier: Sorting patch updates.
Note: Below table(s) have no YANG models:
BGP_PEER_RANGE, CONSOLE_SWITCH, DEVICE_NEIGHBOR_METADATA, DHCP_SERVER, KDUMP, RESTAPI, SNMP, SNMP_COMMUNITY, TELEMETRY,
Note: Below table(s) have no YANG models:
BGP_PEER_RANGE, CONSOLE_SWITCH, DEVICE_NEIGHBOR_METADATA, DHCP_SERVER, KDUMP, RESTAPI, SNMP, SNMP_COMMUNITY, TELEMETRY,
Note: Below table(s) have no YANG models:
BGP_PEER_RANGE, CONSOLE_SWITCH, DEVICE_NEIGHBOR_METADATA, DHCP_SERVER, KDUMP, RESTAPI, SNMP, SNMP_COMMUNITY, TELEMETRY,
libyang[0]: Leafref "../../LOOPBACK_INTERFACE_LIST/name" of value "Loopback0" points to a non-existing leaf. (path: /sonic-loopback-interface:sonic-loopback-interface/LOOPBACK_INTERFACE/LOOPBACK_INTERFACE_IPPREFIX_LIST[name='Loopback0'][ip-prefix='10.1.0.32/32']/name)
libyang[0]: Leafref "../../LOOPBACK_INTERFACE_LIST/name" of value "Loopback0" points to a non-existing leaf. (path: /sonic-loopback-interface:sonic-loopback-interface/LOOPBACK_INTERFACE/LOOPBACK_INTERFACE_IPPREFIX_LIST[name='Loopback0'][ip-prefix='fc00:1::32/128']/name)
sonic_yang(3):Data Loading Failed:Leafref "../../LOOPBACK_INTERFACE_LIST/name" of value "Loopback0" points to a non-existing leaf.
libyang[0]: Leafref "../../LOOPBACK_INTERFACE_LIST/name" of value "Loopback0" points to a non-existing leaf. (path: /sonic-loopback-interface:sonic-loopback-interface/LOOPBACK_INTERFACE/LOOPBACK_INTERFACE_IPPREFIX_LIST[name='Loopback0'][ip-prefix='fc00:1::32/128']/name)
sonic_yang(3):Data Loading Failed:Leafref "../../LOOPBACK_INTERFACE_LIST/name" of value "Loopback0" points to a non-existing leaf.
libyang[0]: Leafref "../../LOOPBACK_INTERFACE_LIST/name" of value "Loopback0" points to a non-existing leaf. (path: /sonic-loopback-interface:sonic-loopback-interface/LOOPBACK_INTERFACE/LOOPBACK_INTERFACE_IPPREFIX_LIST[name='Loopback0'][ip-prefix='10.1.0.32/32']/name)
sonic_yang(3):Data Loading Failed:Leafref "../../LOOPBACK_INTERFACE_LIST/name" of value "Loopback0" points to a non-existing leaf.
Failed to apply patch
Usage: config apply-patch [OPTIONS] PATCH_FILE_PATH
Try "config apply-patch -h" for help.
Error: no leaf

Describe the results you received

apply-patch fail

Describe the results you expected

apply-patch success

Additional information you deem important (e.g. issue happens only occasionally)

Output of show version

admin@vlab-01:~$ show ver

SONiC Software Version: SONiC.master.58770-6402a0226
Distribution: Debian 11.1
Kernel: 5.10.0-8-2-amd64
Build commit: 6402a0226
Build date: Mon Dec 13 09:02:14 UTC 2021
Built by: AzDevOps@sonic-build-workers-000Z9S

Platform: x86_64-kvm_x86_64-r0
HwSKU: Force10-S6000
ASIC: vs
ASIC Count: 1
Serial Number: N/A
Model Number: N/A
Hardware Revision: N/A
Uptime: 00:28:53 up 2 days, 20:57,  2 users,  load average: 0.96, 0.41, 0.25

@ghooo
Copy link
Contributor

ghooo commented Jan 11, 2022

I think this error is also related:

admin@vlab-03:~$ sudo config apply-patch -n  -i /FEATURE -i /SCHEDULER -i /QUEUE -v ~/data/11_01_2022_04_05/logs/configlet/AddRack/patch_add/patch.json 
Patch Applier: Patch application starting.
Patch Applier: Patch: [{"op": "add", "path": "/ACL_TABLE/EVERFLOW/ports/8", "value": "Ethernet64"}, {"op": "add", "path": "/ACL_TABLE/EVERFLOWV6/ports/8", "value": "Ethernet64"}, {"op": "add", "path": "/PORT/Ethernet64/admin_status", "value": "up"}, {"op": "replace", "path": "/PORT/Ethernet64/description", "value": "ARISTA01T0:Ethernet1"}, {"op": "add", "path": "/BUFFER_PG/Ethernet64|3-4", "value": {"profile": "pg_lossless_40000_40m_profile"}}, {"op": "add", "path": "/BUFFER_PG/Ethernet64|0", "value": {"profile": "ingress_lossy_profile"}}, {"op": "add", "path": "/DEVICE_NEIGHBOR_METADATA/ARISTA01T0", "value": {"hwsku": "Arista-VM", "lo_addr": "None", "mgmt_addr": "10.250.0.63", "type": "ToRRouter"}}, {"op": "add", "path": "/DEVICE_NEIGHBOR/Ethernet64", "value": {"name": "ARISTA01T0", "port": "Ethernet1"}}, {"op": "add", "path": "/QUEUE/Ethernet64|4", "value": {"scheduler": "scheduler.1", "wred_profile": "AZURE_LOSSLESS"}}, {"op": "add", "path": "/QUEUE/Ethernet64|5", "value": {"scheduler": "scheduler.0"}}, {"op": "add", "path": "/QUEUE/Ethernet64|0", "value": {"scheduler": "scheduler.0"}}, {"op": "add", "path": "/QUEUE/Ethernet64|1", "value": {"scheduler": "scheduler.0"}}, {"op": "add", "path": "/QUEUE/Ethernet64|3", "value": {"scheduler": "scheduler.1", "wred_profile": "AZURE_LOSSLESS"}}, {"op": "add", "path": "/QUEUE/Ethernet64|6", "value": {"scheduler": "scheduler.0"}}, {"op": "add", "path": "/QUEUE/Ethernet64|2", "value": {"scheduler": "scheduler.0"}}, {"op": "add", "path": "/INTERFACE/Ethernet64|10.0.0.32~131", "value": {}}, {"op": "add", "path": "/INTERFACE/Ethernet64", "value": {}}, {"op": "add", "path": "/INTERFACE/Ethernet64|FC00::41~1126", "value": {}}, {"op": "add", "path": "/BUFFER_QUEUE/Ethernet64|3-4", "value": {"profile": "egress_lossless_profile"}}, {"op": "add", "path": "/BUFFER_QUEUE/Ethernet64|0-2", "value": {"profile": "egress_lossy_profile"}}, {"op": "add", "path": "/BUFFER_QUEUE/Ethernet64|5-6", "value": {"profile": "egress_lossy_profile"}}, {"op": "add", "path": "/PORT_QOS_MAP/Ethernet64", "value": {"dscp_to_tc_map": "AZURE", "pfc_enable": "3,4", "pfc_to_queue_map": "AZURE", "tc_to_pg_map": "AZURE", "tc_to_queue_map": "AZURE"}}, {"op": "replace", "path": "/CABLE_LENGTH/AZURE/Ethernet64", "value": "40m"}, {"op": "add", "path": "/BGP_NEIGHBOR/10.0.0.33", "value": {"admin_status": "up", "asn": "64001", "holdtime": "10", "keepalive": "3", "local_addr": "10.0.0.32", "name": "ARISTA01T0", "nhopself": "0", "rrclient": "0"}}, {"op": "add", "path": "/BGP_NEIGHBOR/fc00::42", "value": {"admin_status": "up", "asn": "64001", "holdtime": "10", "keepalive": "3", "local_addr": "fc00::41", "name": "ARISTA01T0", "nhopself": "0", "rrclient": "0"}}]
Patch Applier: Getting current config db.
Patch Applier: Simulating the target full config after applying the patch.
Patch Applier: Validating target config does not have empty tables, since they do not show up in ConfigDb.
Patch Applier: Sorting patch updates.
Patch Sorter - Non-Strict: Splitting current/target config based on YANG covered vs non-YANG covered configs.
Note: Below table(s) have no YANG models:
CONSOLE_SWITCH, DEVICE_NEIGHBOR_METADATA, DHCP_SERVER, KDUMP, RESTAPI, SNMP, SNMP_COMMUNITY, TELEMETRY, 
Note: Below table(s) have no YANG models:
CONSOLE_SWITCH, DEVICE_NEIGHBOR_METADATA, DHCP_SERVER, KDUMP, RESTAPI, SNMP, SNMP_COMMUNITY, TELEMETRY, 
Patch Sorter - Non-Strict: Validating YANG covered target config according to YANG models.
Patch Sorter - Non-Strict: Sorting non-YANG covered configs patch updates.
Patch Sorter - Non-Strict: The Non-YANG covered config update was sorted into 1 change:
Patch Sorter - Non-Strict:   * [{"op": "add", "path": "/DEVICE_NEIGHBOR_METADATA/ARISTA01T0", "value": {"hwsku": "Arista-VM", "lo_addr": "None", "mgmt_addr": "10.250.0.63", "type": "ToRRouter"}}, {"op": "add", "path": "/QUEUE/Ethernet64|1", "value": {"scheduler": "scheduler.0"}}, {"op": "add", "path": "/QUEUE/Ethernet64|4", "value": {"scheduler": "scheduler.1", "wred_profile": "AZURE_LOSSLESS"}}, {"op": "add", "path": "/QUEUE/Ethernet64|2", "value": {"scheduler": "scheduler.0"}}, {"op": "add", "path": "/QUEUE/Ethernet64|5", "value": {"scheduler": "scheduler.0"}}, {"op": "add", "path": "/QUEUE/Ethernet64|0", "value": {"scheduler": "scheduler.0"}}, {"op": "add", "path": "/QUEUE/Ethernet64|3", "value": {"scheduler": "scheduler.1", "wred_profile": "AZURE_LOSSLESS"}}, {"op": "add", "path": "/QUEUE/Ethernet64|6", "value": {"scheduler": "scheduler.0"}}]
Patch Sorter - Non-Strict: Regenerating patch for YANG covered configs only.
Patch Sorter - Non-Strict: Generated patch [{"op": "add", "path": "/BUFFER_PG/Ethernet64|0", "value": {"profile": "ingress_lossy_profile"}}, {"op": "add", "path": "/BUFFER_PG/Ethernet64|3-4", "value": {"profile": "pg_lossless_40000_40m_profile"}}, {"op": "add", "path": "/PORT_QOS_MAP/Ethernet64", "value": {"dscp_to_tc_map": "AZURE", "pfc_enable": "3,4", "pfc_to_queue_map": "AZURE", "tc_to_pg_map": "AZURE", "tc_to_queue_map": "AZURE"}}, {"op": "add", "path": "/INTERFACE/Ethernet64|FC00::41~1126", "value": {}}, {"op": "add", "path": "/INTERFACE/Ethernet64", "value": {}}, {"op": "add", "path": "/INTERFACE/Ethernet64|10.0.0.32~131", "value": {}}, {"op": "replace", "path": "/CABLE_LENGTH/AZURE/Ethernet64", "value": "40m"}, {"op": "add", "path": "/PORT/Ethernet64/admin_status", "value": "up"}, {"op": "replace", "path": "/PORT/Ethernet64/description", "value": "ARISTA01T0:Ethernet1"}, {"op": "add", "path": "/BUFFER_QUEUE/Ethernet64|5-6", "value": {"profile": "egress_lossy_profile"}}, {"op": "add", "path": "/BUFFER_QUEUE/Ethernet64|0-2", "value": {"profile": "egress_lossy_profile"}}, {"op": "add", "path": "/BUFFER_QUEUE/Ethernet64|3-4", "value": {"profile": "egress_lossless_profile"}}, {"op": "add", "path": "/DEVICE_NEIGHBOR/Ethernet64", "value": {"name": "ARISTA01T0", "port": "Ethernet1"}}, {"op": "add", "path": "/BGP_NEIGHBOR/10.0.0.33", "value": {"admin_status": "up", "asn": "64001", "holdtime": "10", "keepalive": "3", "local_addr": "10.0.0.32", "name": "ARISTA01T0", "nhopself": "0", "rrclient": "0"}}, {"op": "add", "path": "/BGP_NEIGHBOR/fc00::42", "value": {"admin_status": "up", "asn": "64001", "holdtime": "10", "keepalive": "3", "local_addr": "fc00::41", "name": "ARISTA01T0", "nhopself": "0", "rrclient": "0"}}, {"op": "add", "path": "/ACL_TABLE/EVERFLOW/ports/8", "value": "Ethernet64"}, {"op": "add", "path": "/ACL_TABLE/EVERFLOWV6/ports/8", "value": "Ethernet64"}]
Patch Sorter - Non-Strict: Validating YANG covered config patch is not making changes to tables without YANG models.
Patch Sorter - Non-Strict: Sorting YANG-covered configs patch updates.
Failed to apply patch
Usage: config apply-patch [OPTIONS] PATCH_FILE_PATH
Try "config apply-patch -h" for help.

Error: Token not found
admin@vlab-03:~$

Improving the error we get:

Error: Token not found.
  Model: 'OrderedDict([('@name', 'CABLE_LENGTH_LIST'), ('key', OrderedDict([('@value', 'name')])), ('leaf', OrderedDict([('@name', 'name'), ('type', OrderedDict([('@name', 'string'), ('length', OrderedDict([('@value', '1..32'), ('error-message', OrderedDict([('value', 'Invalid length for the cable length list name.')])), ('error-app-tag', OrderedDict([('@value', 'cable-length-invalid-list-name-length')]))])), ('pattern', OrderedDict([('@value', '[a-zA-Z0-9]{1}([-a-zA-Z0-9_]{0,31})'), ('error-message', OrderedDict([('value', 'Invalid cable length list name.')])), ('error-app-tag', OrderedDict([('@value', 'cable-length-invalid-list-name')]))]))]))])), ('list', OrderedDict([('@name', 'CABLE_LENGTH'), ('key', OrderedDict([('@value', 'port')])), ('leaf', [OrderedDict([('@name', 'port'), ('type', OrderedDict([('@name', 'leafref'), ('path', OrderedDict([('@value', '/port:sonic-port/port:PORT/port:PORT_LIST/port:name')]))])), ('__isleafList', False)]), OrderedDict([('@name', 'length'), ('type', OrderedDict([('@name', 'string'), ('pattern', OrderedDict([('@value', '[0-9]+m'), ('error-message', OrderedDict([('value', 'Invalid cable length.')])), ('error-app-tag', OrderedDict([('@value', 'cable-length-invalid-length')]))]))])), ('__isleafList', False)])])]))])'
  Token Index: '2'
  Path Tokens: '['CABLE_LENGTH', 'AZURE', 'Ethernet100']'
  Config: '{'Ethernet0': '0m', 'Ethernet100': '0m', 'Ethernet104': '0m', 'Ethernet108': '0m', 'Ethernet112': '40m', 'Ethernet116': '40m', 'Ethernet12': '5m', 'Ethernet120': '40m', 'Ethernet124': '40m', 'Ethernet16': '5m', 'Ethernet20': '5m', 'Ethernet24': '5m', 'Ethernet28': '5m', 'Ethernet32': '5m', 'Ethernet36': '5m', 'Ethernet4': '5m', 'Ethernet40': '5m', 'Ethernet44': '5m', 'Ethernet48': '5m', 'Ethernet52': '5m', 'Ethernet56': '5m', 'Ethernet60': '5m', 'Ethernet64': '5m', 'Ethernet68': '5m', 'Ethernet72': '5m', 'Ethernet76': '5m', 'Ethernet8': '5m', 'Ethernet80': '5m', 'Ethernet84': '5m', 'Ethernet88': '5m', 'Ethernet92': '5m', 'Ethernet96': '5m'}'

@ghooo
Copy link
Contributor

ghooo commented Jan 12, 2022

The error in the original problem with more data:

The exception is at gu_common::PathAddressing::find_ref_paths which is calling gu_common::PathAddressing::_get_path_tokens_from_leaf

Error: not leaf
  Model: 'OrderedDict([('@name', 'CABLE_LENGTH_LIST'), ('key', OrderedDict([('@value', 'name')])), ('leaf', OrderedDict([('@name', 'name'), ('type', OrderedDict([('@name', 'string'), ('length', OrderedDict([('@value', '1..32'), ('error-message', OrderedDict([('value', 'Invalid length for the cable length list name.')])), ('error-app-tag', OrderedDict([('@value', 'cable-length-invalid-list-name-length')]))])), ('pattern', OrderedDict([('@value', '[a-zA-Z0-9]{1}([-a-zA-Z0-9_]{0,31})'), ('error-message', OrderedDict([('value', 'Invalid cable length list name.')])), ('error-app-tag', OrderedDict([('@value', 'cable-length-invalid-list-name')]))]))]))])), ('list', OrderedDict([('@name', 'CABLE_LENGTH'), ('key', OrderedDict([('@value', 'port')])), ('leaf', [OrderedDict([('@name', 'port'), ('type', OrderedDict([('@name', 'leafref'), ('path', OrderedDict([('@value', '/port:sonic-port/port:PORT/port:PORT_LIST/port:name')]))])), ('__isleafList', False)]), OrderedDict([('@name', 'length'), ('type', OrderedDict([('@name', 'string'), ('pattern', OrderedDict([('@value', '[0-9]+m'), ('error-message', OrderedDict([('value', 'Invalid cable length.')])), ('error-app-tag', OrderedDict([('@value', 'cable-length-invalid-length')]))]))])), ('__isleafList', False)])])]))])'
  Token Index: '3'
  Xpath Tokens: '['sonic-cable-length:sonic-cable-length', 'CABLE_LENGTH', "CABLE_LENGTH_LIST[name='AZURE']", "CABLE_LENGTH[port='Ethernet0']", 'port']'
  Config: '{'Ethernet0': '0m', 'Ethernet100': '0m', 'Ethernet104': '0m', 'Ethernet108': '0m', 'Ethernet112': '40m', 'Ethernet116': '40m', 'Ethernet12': '5m', 'Ethernet120': '40m', 'Ethernet124': '40m', 'Ethernet16': '5m', 'Ethernet20': '5m', 'Ethernet24': '5m', 'Ethernet28': '5m', 'Ethernet32': '5m', 'Ethernet36': '5m', 'Ethernet4': '5m', 'Ethernet40': '5m', 'Ethernet44': '5m', 'Ethernet48': '5m', 'Ethernet52': '5m', 'Ethernet56': '5m', 'Ethernet60': '5m', 'Ethernet64': '5m', 'Ethernet68': '5m', 'Ethernet72': '5m', 'Ethernet76': '5m', 'Ethernet8': '5m', 'Ethernet80': '5m', 'Ethernet84': '5m', 'Ethernet88': '5m', 'Ethernet92': '5m', 'Ethernet96': '5m'}

The exception shows that we are trying to get the referrers for PORT table inside CABLE_LENGTH. There is 2 problems here:

1. Why do need to get PORT table referrers?

Answer:

  1. The following happens when trying to generate the move
    1. trying: [{"op": "add", "path": "/LOOPBACK_INTERFACE/Loopback0/vrf_name", "value": "Vrf_01"}] .. fails because vrf_name is create-only
    2. trying: [{"op": "replace", "path": "/LOOPBACK_INTERFACE/Loopback0", "value": {"vrf_name": "Vrf_01"}}] .. fails because vrf_name is create-only (from the point of view of the ChangeApplier this is the same as the first one)
    3. trying: [{"op": "replace", "path": "/LOOPBACK_INTERFACE", "value": {"Loopback0": {"vrf_name": "Vrf_01"}, "Loopback0|10.1.0.32/32": {}, "Loopback0|FC00:1::32/128": {}}}] .. fails because vrf_name is create-only (from the point of view of the ChangeApplier this is the same as the first one)
    4. trying [{"op": "remove", "path": "/LOOPBACK_INTERFACE/Loopback0"}].. fails because we cannot delete loopback0 and its referrers loopback0|10.1.0.32/32 and loopback0|FC00... at the same time because some items depend on the rest, and the ChangeApplier should not do ordering. PatchSorter takes care of that
    5. trying [{"op": "replace", "path": "", "value":{"ACL_TABLE": {"DATAACL": {"policy_desc": "...} .. fails because vrf_name is create-only (from the point of view of the ChangeApplier this is the same as the first one)
    6. ... some other moves failing
    7. trying [{"op": "remove", "path": ""}] .. fails because we cannot delete loopback0 and its referrers loopback0|10.1.0.32/32 and loopback0|FC00... at the same time because some items depend on the rest, and the ChangeApplier should not do ordering. PatchSorter takes care of that
    8. ... some other moves later
    9. trying to extend [{"op": "remove", "path": ""}] using DeleteRefsMoveExtender will try to delete all referrers to all configs. This will try the CABLE_LENGTH table which is referring PORT.

We should not try to delete the whole configs for 2 reasons:

  1. It is not supported by JsonPatch lib and ConfigDb cannot be equal to NULL
  2. We are deleting lots of tables that are not related

These are the whole list of moves generated, if there is an indentation, it means the moved passed the validation and we are going to use, and we will try the next possible valid move:

2. Why getting PORT table referrers failed?

sonic_yang_mgmt follows these guidelines in order to convert from config_db to config_yang and vice versa.
in GCU we rely on the same guidelines to convert from config_db path to config_yang xpath and vice versa.

There were modifications to how sonic_yang_mgmt converts data recently, and this was supported by gcu, the changes are the following:

I think only the first change is related to the current issue, we need to fix both though.

[update] Will follow up on the 2nd issue separately #2034

ghooo added a commit that referenced this issue Jan 13, 2022
…delete whole config move (#2006)

#### What I did
Not generating delete whole config move because it is not allowed by JsonPatch library and it is not possible for ConfigDb to be equal to NULL.

This solves the first problem in issue #2000 (comment)

#### How I did it
- Verified UpperLevelMoveExtender does not generate delete whole config move
- Modified DeleteInsteadOfReplaceMoveExtender to not generate delete whole config move
- DeleteRefsMoveExtender cannot generate delete whole config move, because it deletes the referrer leafs

#### How to verify it
unit-test

#### Previous command output (if the output of a command-line utility has changed)

#### New command output (if the output of a command-line utility has changed)
judyjoseph pushed a commit that referenced this issue Jan 17, 2022
…delete whole config move (#2006)

#### What I did
Not generating delete whole config move because it is not allowed by JsonPatch library and it is not possible for ConfigDb to be equal to NULL.

This solves the first problem in issue #2000 (comment)

#### How I did it
- Verified UpperLevelMoveExtender does not generate delete whole config move
- Modified DeleteInsteadOfReplaceMoveExtender to not generate delete whole config move
- DeleteRefsMoveExtender cannot generate delete whole config move, because it deletes the referrer leafs

#### How to verify it
unit-test

#### Previous command output (if the output of a command-line utility has changed)

#### New command output (if the output of a command-line utility has changed)
@ghooo ghooo closed this as completed Jan 24, 2022
malletvapid23 added a commit to malletvapid23/Sonic-Utility that referenced this issue Aug 3, 2023
…delete whole config move (#2006)

#### What I did
Not generating delete whole config move because it is not allowed by JsonPatch library and it is not possible for ConfigDb to be equal to NULL.

This solves the first problem in issue sonic-net/sonic-utilities#2000 (comment)

#### How I did it
- Verified UpperLevelMoveExtender does not generate delete whole config move
- Modified DeleteInsteadOfReplaceMoveExtender to not generate delete whole config move
- DeleteRefsMoveExtender cannot generate delete whole config move, because it deletes the referrer leafs

#### How to verify it
unit-test

#### Previous command output (if the output of a command-line utility has changed)

#### New command output (if the output of a command-line utility has changed)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants