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

Generated class SubinterfaceListEntry() index property annotated as optional but should be required #6

Closed
dgethings opened this issue Feb 1, 2025 · 3 comments · Fixed by #7

Comments

@dgethings
Copy link

The following model attempts to create an untagged IPv4 interface. The index property is commented out to demonstrate the problem:

e_1_1 = ifd.InterfaceListEntry(
    name="ethernet-1/1",
    admin_state=ifd.EnumerationEnum.enable,
    description="test description",
    subinterface=[
        ifd.SubinterfaceListEntry(
            # index=0,
            admin_state=ifd.EnumerationEnum.enable,
            ipv4=ifd.Ipv4Container(
                admin_state=ifd.EnumerationEnum.enable,
                address=[ifd.AddressListEntry(ip_prefix="192.168.0.1/30")]
            )
        )
    ]
)

When applying the config (using the JSONRPC API used in the example dir) using the following context manager:

with SRLClient(host="clab-srlinux-leaf1") as client:
    client.add_command(
        action=Action.UPDATE,
        path="/interface[name=ethernet-1/1]",
        value=e_1_1,
    )
    resp = client.send_request()
    print(resp.text)

The following output is produced - with logging set to debug level:

[02/01/25 23:12:54] DEBUG    connect_tcp.started host='clab-srlinux-leaf1' port=80 local_address=None timeout=5.0  _trace.py:47
                             socket_options=None                                                                               
                    DEBUG    connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at       _trace.py:47
                             0xffffab28aba0>                                                                                   
                    DEBUG    send_request_headers.started request=<Request >                                       _trace.py:47
                    DEBUG    send_request_headers.complete                                                         _trace.py:47
                    DEBUG    send_request_body.started request=<Request >                                          _trace.py:47
                    DEBUG    send_request_body.complete                                                            _trace.py:47
                    DEBUG    receive_response_headers.started request=<Request >                                   _trace.py:47
                    DEBUG    receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Server', _trace.py:47
                             b'gunicorn'), (b'Date', b'Sat, 01 Feb 2025 23:12:54 GMT'), (b'Connection', b'close'),             
                             (b'Content-Type', b'application/json'), (b'Content-Length', b'289'),                              
                             (b'Access-Control-Allow-Origin', b'*'), (b'Content-Encoding', b'gzip')])                          
                    INFO     HTTP Request: POST http://clab-srlinux-leaf1/jsonrpc "HTTP/1.1 200 OK"             _client.py:1025
                    DEBUG    receive_response_body.started request=<Request >                                      _trace.py:47
                    DEBUG    receive_response_body.complete                                                        _trace.py:47
                    DEBUG    response_closed.started                                                               _trace.py:47
                    DEBUG    response_closed.complete                                                              _trace.py:47
{"error": {"code": -1, "message": "Keys are missing for schema node '/interface/subinterface'. Requires '[index]': Parse error on line 1: {\"srl_nokia-interfaces:name\": \"ethernet-1/1\", \"srl_nokia-inte...\nInput:\n'{\"srl_nokia-interfaces:name\": \"ethernet-1/1\", \"srl_nokia-interfaces:description\": \"test description\", \"srl_nokia-interfaces:admin-state\": \"enable\", \"srl_nokia-interfaces:subinterface\": [{\"srl_nokia-interfaces:admin-state\": \"enable\", \"srl_nokia-interfaces:ipv4\": {\"srl_nokia-interfaces:admin-state\": \"enable\", \"srl_nokia-interfaces:address\": [{\"srl_nokia-interfaces:ip-prefix\": \"192.168.0.1/30\"}]}}]}'"}, "id": 1, "jsonrpc": "2.0"}

If I uncomment the index=0 line and run the script again I get the following output:

[02/01/25 23:21:35] DEBUG    connect_tcp.started host='clab-srlinux-leaf1' port=80 local_address=None timeout=5.0  _trace.py:47
                             socket_options=None                                                                               
                    DEBUG    connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at       _trace.py:47
                             0xffff834546e0>                                                                                   
                    DEBUG    send_request_headers.started request=<Request >                                       _trace.py:47
                    DEBUG    send_request_headers.complete                                                         _trace.py:47
                    DEBUG    send_request_body.started request=<Request >                                          _trace.py:47
                    DEBUG    send_request_body.complete                                                            _trace.py:47
                    DEBUG    receive_response_headers.started request=<Request >                                   _trace.py:47
                    DEBUG    receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Server', _trace.py:47
                             b'gunicorn'), (b'Date', b'Sat, 01 Feb 2025 23:21:35 GMT'), (b'Connection', b'close'),             
                             (b'Content-Type', b'application/json'), (b'Content-Length', b'59'),                               
                             (b'Access-Control-Allow-Origin', b'*'), (b'Content-Encoding', b'gzip')])                          
                    INFO     HTTP Request: POST http://clab-srlinux-leaf1/jsonrpc "HTTP/1.1 200 OK"             _client.py:1025
                    DEBUG    receive_response_body.started request=<Request >                                      _trace.py:47
                    DEBUG    receive_response_body.complete                                                        _trace.py:47
                    DEBUG    response_closed.started                                                               _trace.py:47
                    DEBUG    response_closed.complete                                                              _trace.py:47
{"result": [{}], "id": 1, "jsonrpc": "2.0"}

I believe the cause is that the index property is defined as optional when it should be required. From `interfaces.py:

class SubinterfaceListEntry(BaseModel):
...
    index: Annotated[
        Optional[int], Field(alias='srl_nokia-interfaces:index', ge=0, le=9999)
    ] = None
    """
    The index of the subinterface, or logical interface number
    """
...
@hellt
Copy link
Member

hellt commented Feb 1, 2025

Thanks @dgethings
this is indeed a known issue; currently pydantify does not set list keys as required fields, and this is something we track as feature for later releases.

Right now, it is up to a users' discretion to set list keys, as omitting them will render the payload incomplete.

adding @ubaumann and @dpeachey for awareness

@dgethings
Copy link
Author

Thanks @hellt

It's easy enough to work around. Will continue with my YANG adventures 😄

@hellt hellt mentioned this issue Feb 8, 2025
@hellt
Copy link
Member

hellt commented Feb 8, 2025

will be addressed in #7

@hellt hellt closed this as completed in #7 Feb 8, 2025
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 a pull request may close this issue.

2 participants