Automation

 View Only
last person joined: 8 days ago 

Ask questions and share experiences about Apstra, Paragon, and all things network automation.
  • 1.  pyez and export-format state-data json compact

    Posted 04-08-2024 13:20

    hi expert 

    I  have a question  when i using pyez 

    here is my code 

    from jnpr.junos import Device
    from pprint import pprint
    
    def get_ospf_neighbor_information(username, pwd, host ):
        dev = Device(host=host, user=username, password=pwd)
        dev.open()
        rpc = dev.rpc.get_ospf_neighbor_information({'format':'json'})
        dev.close()
        return rpc
    
    
    if __name__ == "__main__": 
        
        ospf_r1 = get_ospf_neighbor_information('lab', 'lab123', '172.27.0.22' )
        pprint(ospf_r1)

    the code is work but if i change json format by this cli 

    export-format state-data json compact    

    system will report this error 

    ---------------------------------------------------------------------------
    JSONDecodeError                           Traceback (most recent call last)
    File ~/anaconda3/lib/python3.11/site-packages/jnpr/junos/device.py:878, in _Connection.execute(self, rpc_cmd, ignore_warning, **kvargs)
        877 try:
    --> 878     return json.loads(rpc_rsp_e.text, strict=False)
        879 except ValueError as ex:
        880     # when data is {}{.*} types
    
    File ~/anaconda3/lib/python3.11/json/__init__.py:359, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
        358     kw['parse_constant'] = parse_constant
    --> 359 return cls(**kw).decode(s)
    
    File ~/anaconda3/lib/python3.11/json/decoder.py:337, in JSONDecoder.decode(self, s, _w)
        333 """Return the Python representation of ``s`` (a ``str`` instance
        334 containing a JSON document).
        335 
        336 """
    --> 337 obj, end = self.raw_decode(s, idx=_w(s, 0).end())
        338 end = _w(s, end).end()
    
    File ~/anaconda3/lib/python3.11/json/decoder.py:353, in JSONDecoder.raw_decode(self, s, idx)
        352 try:
    --> 353     obj, end = self.scan_once(s, idx)
        354 except StopIteration as err:
    
    JSONDecodeError: Expecting property name enclosed in double quotes: line 14 column 9 (char 355)
    
    During handling of the above exception, another exception occurred:
    
    JSONLoadError                             Traceback (most recent call last)
    Cell In[1], line 14
          9     return rpc
         12 if __name__ == "__main__": 
    ---> 14     ospf_r1 = get_ospf_neighbor_information('lab', 'lab123', '172.27.100.93' )
         15     pprint(ospf_r1)
    
    Cell In[1], line 7, in get_ospf_neighbor_information(username, pwd, host)
          5 dev = Device(host=host, user=username, password=pwd)
          6 dev.open()
    ----> 7 rpc = dev.rpc.get_ospf_neighbor_information({'format':'json'})
          8 dev.close()
          9 return rpc
    
    File ~/anaconda3/lib/python3.11/site-packages/jnpr/junos/rpcmeta.py:363, in _RpcMetaExec.__getattr__.<locals>._exec_rpc(*vargs, **kvargs)
        358             rpc.attrib[k] = v
        360 # now invoke the command against the
        361 # associated :junos: device and return
        362 # the results per :junos:execute()
    --> 363 return self._junos.execute(rpc, **dec_args)
    
    File ~/anaconda3/lib/python3.11/site-packages/jnpr/junos/decorators.py:76, in normalizeDecorator.<locals>.wrapper(*args, **kwargs)
         74 else:
         75     try:
    ---> 76         return function(*args, **kwargs)
         77     except Exception:
         78         raise
    
    File ~/anaconda3/lib/python3.11/site-packages/jnpr/junos/decorators.py:31, in timeoutDecorator.<locals>.wrapper(*args, **kwargs)
         29 else:
         30     try:
    ---> 31         return function(*args, **kwargs)
         32     except Exception:
         33         raise
    
    File ~/anaconda3/lib/python3.11/site-packages/jnpr/junos/device.py:884, in _Connection.execute(self, rpc_cmd, ignore_warning, **kvargs)
        882             return json.loads(re.sub(r"\s?{\s?}\s?", "", rpc_rsp_e.text))
        883         else:
    --> 884             raise JSONLoadError(ex, rpc_rsp_e.text)
        885 else:
        886     warnings.warn(
        887         "Native JSON support is only from 14.2 onwards", RuntimeWarning
        888     )
    
    JSONLoadError: JSONLoadError(reason: Expecting property name enclosed in double quotes: line 14 column 9 (char 355), 
    The offending config appears to be: 
    12:             "activity-timer" : "36"
    13:         }, 
    14:         {
    15:             "neighbor-address" : "12.0.0.2", 
    16:             "interface-name" : "ge-0/0/2.0", 
    )

    I am not sure how to change that ,but old json format is so difficult to read 



  • 2.  RE: pyez and export-format state-data json compact

     
    Posted 04-15-2024 15:21

    From the error message displayed, it looks as though the data structure is not correct, since JSONLoad isn't accepting it.  However, from the code snippet shown I can't see where the error is in the returned data, when using export-format state-data json compact.

    Maybe the following commands will help get the full JSON response back and then take a look to see if the JSON response is actually valid JSON or not, I suspect that there is issue in how the data is being returned by Junos.

    This is just performing a NETCONF RPC via SSH with the -s netconf argument.

    e.g.

    ssh user@device -s netconf

    <rpc><get-ospf-neighbor-information format="json"/></rpc>

    <rpc><close-session/></rpc>

    Then look at the response and see if you can see if anything is incorrect in the reply.   If it is a Junos issue with the output then either you will have to use the standard JSON output, or perhaps XML instead... Else discuss with JTAC.

    ssh user@device -s netconf
    <!-- No zombies were killed during the creation of this user interface -->
    <!-- user root, class super-user -->
    <nc:hello xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <nc:capabilities>
    ...
      </nc:capabilities>
      <nc:session-id>64605</nc:session-id>
    </nc:hello>
    ]]>]]>
    <rpc><get-ospf-neighbor-information format="json"/></rpc>
    <nc:rpc-reply xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/22.1R0/junos">
    ...
    </nc:rpc-reply>
    ]]>]]>
    <rpc><close-session/></rpc>
    <nc:rpc-reply xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/22.1R0/junos">
    <nc:ok/>
    </nc:rpc-reply>
    ]]>]]>
    <!-- session end at 2024-04-15 12:14:38 PDT -->


    ------------------------------
    Andy Sharp
    ------------------------------



  • 3.  RE: pyez and export-format state-data json compact

    Posted 07-28-2024 22:18

    Compact JSON output is broken in that it does not make an array or list of the ospf-interfaces. Since junos-pyez tries to use json.loadsto parse that output when using  the {"format"="json"} argument, the function errors out instead of just giving the command's output as a string that can be manipulated.

    This is what I get off of a router running 21.4 when doing show ospf neighbors | display json; I've tested on more recent versions as well, with the same results.

    {
        "ospf-neighbor-information" :
        {
            "ospf-neighbor" :
            {
                "neighbor-address" : "10.10.47.81",
                "interface-name" : "xe-0/2/3.1503",
                "ospf-neighbor-state" : "Full",
                "neighbor-id" : "10.10.112.14",
                "neighbor-priority" : "128",
                "activity-timer" : "38"
            },
            {
                "neighbor-address" : "10.10.130.145",
                "interface-name" : "xe-0/2/3.503",
                "ospf-neighbor-state" : "Full",
                "neighbor-id" : "10.10.112.92",
                "neighbor-priority" : "128",
                "activity-timer" : "39"
            }
        }
    }

    Putting an open and close bracket around the all the entries of the "ospf-neighbor" : array will make the output valid JSON: 

    {
        "ospf-neighbor-information":
        {
            "ospf-neighbor":
            [
                {
                    "neighbor-address": "10.10.47.81",
                    "interface-name": "xe-0/2/3.1503",
                    "ospf-neighbor-state": "Full",
                    "neighbor-id": "10.10.112.14",
                    "neighbor-priority": "128",
                    "activity-timer": "38"
                },
                {
                    "neighbor-address": "10.10.130.145",
                    "interface-name": "xe-0/2/3.503",
                    "ospf-neighbor-state": "Full",
                    "neighbor-id": "10.10.112.92",
                    "neighbor-priority": "128",
                    "activity-timer": "39"
                }
            ]
        }
    }

    I worked around it by using oxs with our oxidzied setup to go through my list of routers, run 'show ospf neighbors | display json' on each of them then dumping the output to a file that I then used python's re module to regex search and replace as needed. Eventually I got it to a usable dictionary from the nearly json output.