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

Fix slash in path. #3573

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

xincunli-sonic
Copy link
Contributor

What I did

Addressing issue #3444. The issue caused by unescape in JsonPointer implementation which followed RFC 6901

pointer = jsonpointer.JsonPointer(path)

...

class JsonPointer(object):
    """A JSON Pointer that can reference parts of a JSON document"""

    # Array indices must not contain:
    # leading zeros, signs, spaces, decimals, etc
    _RE_ARRAY_INDEX = re.compile('0|[1-9][0-9]*$')
    _RE_INVALID_ESCAPE = re.compile('(~[^01]|~$)')

    def __init__(self, pointer):

        # validate escapes
        invalid_escape = self._RE_INVALID_ESCAPE.search(pointer)
        if invalid_escape:
            raise JsonPointerException('Found invalid escape {}'.format(
                invalid_escape.group()))

        parts = pointer.split('/')
        if parts.pop(0) != '':
            raise JsonPointerException('Location must start with /')

        parts = [unescape(part) for part in parts]
        self.parts = parts

How I did it

Re-escape / to ~1 to match the real key in json, and JsonPatch will handle it correctly.

How to verify it

admin@str2-7250-lc1-2:~$ cat link.json 
[
    {
        "op": "add",
        "path": "/asic1/PORTCHANNEL_INTERFACE/PortChannel106|10.0.0.6~131",
        "value": {}
    }
]
admin@str2-7250-lc1-2:~$ sudo config apply-patch link.json 
sonic_yang(6):Note: Below table(s) have no YANG models: DHCP_SERVER
sonic_yang(6):Note: Below table(s) have no YANG models: LOGGER
sonic_yang(6):Note: Below table(s) have no YANG models: LOGGER
Patch Applier: asic1: Patch application starting.
Patch Applier: asic1: Patch: [{"op": "add", "path": "/PORTCHANNEL_INTERFACE/PortChannel106|10.0.0.6~131", "value": {}}]
Patch Applier: asic1 getting current config db.
Patch Applier: asic1: simulating the target full config after applying the patch.
Patch Applier: asic1: validating all JsonPatch operations are permitted on the specified fields
Patch Applier: asic1: validating target config does not have empty tables,
                            since they do not show up in ConfigDb.
Patch Applier: asic1: sorting patch updates.
Patch Applier: The asic1 patch was converted into 0 changes.
Patch Applier: asic1: applying 0 changes in order.
Patch Applier: asic1: verifying patch updates are reflected on ConfigDB.
Patch Applier: asic1 patch application completed.
Patch applied successfully.

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)

parts = pointer.parts

# Re-escapes `/` in path parts by converting `/` back to `~1`.
parts = [part.replace("/", "~1") for part in pointer.parts]
Copy link
Contributor

@wen587 wen587 Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it an issue for multi-asic only?
I remember in single asic, the jsonpointer has built in feature to parse / to ~1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was introduced by multi asic change, we have to extract the namespace from the patch, then JsonPointer will do escape ~1 back to /

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. I don't get it.
By the code here, the extract_scope doesn't differentiate single or multi. How do we guarantee single asic is not broken?

sonic-utilities/config/main.py

Lines 1599 to 1600 in 319f58d

for change in patch:
scope, modified_path = extract_scope(change["path"])

Copy link
Contributor Author

@xincunli-sonic xincunli-sonic Oct 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For single asic, the portchannel interface does not have slash in port, but multi asic does have, hence, we could do escape slash to ~1 in jsonpatch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants