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

OpenConfig implementation in IOS-XRv is order-specific when sending JSON over gRPC #4

Closed
jwbensley opened this Issue Nov 9, 2016 · 4 comments

Comments

Projects
None yet
3 participants
@jwbensley

jwbensley commented Nov 9, 2016

NB: This is the gRPC client "grpc_cfg.py" I am using based off of the public Cisco example: https://gist.github.com/jwbensley/cd2f5bfacee321328ca638b5b5523bd9

NB: This is using the IOS-XRv 6.2.1 stable vagrant image from https://devhub.cisco.com/artifactory/appdevci-release/XRv64/6.2.1/ dated 17th Oct 2016

OpenConfig with Pyangbind (v0.5.8) is producing configuration when serialized to JSON in the below order; the key point here is that in the IPv4 config "afi-safi-name": "openconfig-bgp-types:IPV4_UNICAST" comes at the end but for the IPv6 config it's roughly in the middle. The IOS-XRv device will not accept either of these orderings, unless the afi-safi-name is first:

{
    "1.1.1.1": {
        "neighbor-address": "1.1.1.1", 
        "config": {
            ...
        }, 
        "afi-safis": {
            "afi-safi": {
                "openconfig-bgp-types:IPV4_UNICAST": {
                        ...
                    }, 
                    "config": {
                        ...
                    }, 
                    "afi-safi-name": "openconfig-bgp-types:IPV4_UNICAST" ## AT THE END
                }
            }
        }
},
{
    "1::1": {
        "neighbor-address": "1::1", 
        "config": {
            ...
        }, 
        "afi-safis": {
            "afi-safi": {
                "openconfig-bgp-types:IPV6_UNICAST": {
                    "config": {
                        ...
                    }, 
                    "afi-safi-name": "openconfig-bgp-types:IPV6_UNICAST", ## IN THE MIDDLE
                    "ipv6-unicast": {
                        "prefix-limit": {
                            "config": {
                                ...
                            }
                        }
                    }
                }
            }
        }
    }
}

The below works (but I have to manually re-order the statements (also note the case sensitive issue must be corrected):

{
    "1.1.1.1": {
        "neighbor-address": "1.1.1.1", 
        "config": {
            ...
        }, 
        "afi-safis": {
            "afi-safi": {
                "afi-safi-name": "openconfig-bgp-types:ipv4-unicast", ## AT THE START
                "openconfig-bgp-types:ipv4-unicast": {
                        ...
                    }, 
                    "config": {
                        ...
                    }
                }
            }
        }
},
{
    "1::1": {
        "neighbor-address": "1::1", 
        "config": {
            ...
        }, 
        "afi-safis": {
            "afi-safi": {
                "afi-safi-name": "openconfig-bgp-types:ipv6-unicast", ## AT THE START
                "openconfig-bgp-types:ipv6-unicast": {
                    "config": {
                        ...
                    },
                    "ipv6-unicast": {
                        "prefix-limit": {
                            "config": {
                                ...
                            }
                        }
                    }
                }
            }
        }
    }
}

I am filling the OpenConfig object "in order" however this might just come down to the PyangBind serialization into an unordered dict; so I have to manually reorder the items so the the JSON is in the correct order:

from openconfig_bgp import openconfig_bgp
...
oc_bgp = openconfig_bgp()

oc_bgp.bgp.neighbors.neighbor[network["ipaddr4"]].afi_safis.afi_safi.add("openconfig-bgp-types:IPV4_UNICAST")
oc_bgp.bgp.neighbors.neighbor[network["ipaddr4"]].afi_safis.afi_safi["openconfig-bgp-types:IPV4_UNICAST"].config.afi_safi_name = "IPV4_UNICAST"
oc_bgp.bgp.neighbors.neighbor[network["ipaddr4"]].afi_safis.afi_safi["openconfig-bgp-types:IPV4_UNICAST"].config.enabled = "true"

unsorted_afi_safis = copy.deepcopy(neighbor["afi-safis"]["afi-safi"][0])
sorted_afi_safis = OrderedDict(sorted(unsorted_afi_safis.items(), key=lambda t: t[0]))
neighbor["afi-safis"]["afi-safi"][0].clear()
neighbor["afi-safis"]["afi-safi"][0] = copy.deepcopy(sorted_afi_safis)

This is the error message I get because the "config" section is before the "afi-safi-name" section:

bensley@ubuntu-laptop:~/Python/pyb_oc/ios-xr-grpc-python-master/examples$ python grpc_cfg.py 
Config before merge:

{
    "Cisco-IOS-XR-ipv4-bgp-cfg:bgp": {
        "instance": [
            {
                "instance-as": [
                    {
                        "four-byte-as": [
                            {
                                "as": 65001, 
                                "bgp-running": [
                                    null
                                ], 
                                "default-vrf": {
                                    "global": {
                                        "global-afs": {
                                            "global-af": [
                                                {
                                                    "af-name": "ipv4-unicast", 
                                                    "enable": [
                                                        null
                                                    ]
                                                }, 
                                                {
                                                    "af-name": "ipv6-unicast", 
                                                    "enable": [
                                                        null
                                                    ]
                                                }
                                            ]
                                        }, 
                                        "router-id": "1.1.0.10"
                                    }, 
                                    "bgp-entity": {
                                        "neighbor-groups": {
                                            "neighbor-group": [
                                                {
                                                    "neighbor-group-afs": {
                                                        "neighbor-group-af": [
                                                            {
                                                                "af-name": "ipv4-unicast", 
                                                                "activate": [
                                                                    null
                                                                ], 
                                                                "route-policy-in": "public_v4_peering_ingress", 
                                                                "route-policy-out": "public_v4_peering_egress"
                                                            }
                                                        ]
                                                    }, 
                                                    "create": [
                                                        null
                                                    ], 
                                                    "neighbor-group-name": "public_v4_peers"
                                                }, 
                                                {
                                                    "neighbor-group-afs": {
                                                        "neighbor-group-af": [
                                                            {
                                                                "af-name": "ipv6-unicast", 
                                                                "activate": [
                                                                    null
                                                                ], 
                                                                "route-policy-in": "public_v6_peering_ingress", 
                                                                "route-policy-out": "public_v6_peering_egress"
                                                            }
                                                        ]
                                                    }, 
                                                    "create": [
                                                        null
                                                    ], 
                                                    "neighbor-group-name": "public_v6_peers"
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        ], 
                        "as": 0
                    }
                ], 
                "instance-name": "default"
            }
        ]
    }
}
{u'cisco-grpc:errors': {u'error': {u'error-type': u'protocol', u'error-severity': u'error', u'error-tag': u'missing-element', u'error-message': u'An expected element is missing.', u'error-info': {u'bad-element': u'config'}}}}

bensley@ubuntu-laptop:~/Python/pyb_oc/ios-xr-grpc-python-master/examples$ cat snips/broken_ordering.json 
{
    "openconfig-bgp:bgp": {
        "neighbors": {
            "neighbor": [
                {
                    "neighbor-address": "2001:7f8:2d:e:2:0:2686:1", 
                    "config": {
                        "neighbor-address": "2001:7f8:2d:e:2:0:2686:1", 
                        "peer-as": 2686, 
                        "peer-group": "public_v6_peers", 
                        "description": "AT&T EMEA - AS2686"
                    }, 
                    "afi-safis": {
                        "afi-safi": [
                            {
                                "config": {
                                    "enabled": true, 
                                    "afi-safi-name": "openconfig-bgp-types:ipv6-unicast"
                                },
                                "afi-safi-name": "openconfig-bgp-types:ipv6-unicast",
                                "ipv6-unicast": {
                                    "prefix-limit": {
                                        "config": {
                                            "shutdown-threshold-pct": 90, 
                                            "restart-timer": 1, 
                                            "max-prefixes": 500
                                        }
                                    }
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}
RP/0/RP0/CPU0:ios#show  run router bgp         
Wed Nov  9 16:31:03.446 UTC
router bgp 65001
 bgp router-id 1.1.0.10
 address-family ipv4 unicast
 !
 address-family ipv6 unicast
 !
 neighbor-group public_v4_peers
  address-family ipv4 unicast
   route-policy public_v4_peering_ingress in
   route-policy public_v4_peering_egress out
  !
 !
 neighbor-group public_v6_peers
  address-family ipv6 unicast
   route-policy public_v6_peering_ingress in
   route-policy public_v6_peering_egress out
  !
 !
!

RP/0/RP0/CPU0:ios#show ver
Wed Nov  9 16:33:45.682 UTC

Cisco IOS XR Software, Version 6.2.1.17I
Copyright (c) 2013-2016 by Cisco Systems, Inc.

Build Information:
 Built By     : nkhai
 Built On     : Thu Oct 13 12:53:41 PDT 2016
 Build Host   : iox-ucs-002
 Workspace    : /auto/iox-ucs-002-san1/production/6.2.1.17I.DT_IMAGE/iosxrv-x64/workspace
 Version      : 6.2.1.17I
 Location     : /opt/cisco/XR/packages/

cisco IOS XRv x64 () processor
System uptime is 45 minutes

Are the OpenConfig YANG modules defining a strict order that the data should be sent in via JSON? I would expect all data to be sent to the gRPC server and for it evaluate it once it has received it all. It seems like it is receiving the "config" section and then generating the error, even though the "afi-safi-name" section is coming.

@jwbensley jwbensley changed the title from OpenConfig is order-specific in IOS-XRv to OpenConfig implementation in IOS-Xrv is order-specific when sending JSON over gRPC Nov 9, 2016

@jwbensley jwbensley changed the title from OpenConfig implementation in IOS-Xrv is order-specific when sending JSON over gRPC to OpenConfig implementation in IOS-XRv is order-specific when sending JSON over gRPC Nov 9, 2016

@einarnn

This comment has been minimized.

Show comment
Hide comment
@einarnn

einarnn Nov 10, 2016

Contributor

James,

The JSON parsing logic in current releases of XR is following NETCONF XML parsing rules, which specifies that the keys must come first and in the correct order. This behavior will need to change to reflect the non-ordered nature of attributes in JSON objects. I don't have a target release date for that as yet.

Cheers,

Einar

Contributor

einarnn commented Nov 10, 2016

James,

The JSON parsing logic in current releases of XR is following NETCONF XML parsing rules, which specifies that the keys must come first and in the correct order. This behavior will need to change to reflect the non-ordered nature of attributes in JSON objects. I don't have a target release date for that as yet.

Cheers,

Einar

@111pontes

This comment has been minimized.

Show comment
Hide comment
@111pontes

111pontes Nov 12, 2016

Collaborator

@jwbensley, thanks for bringing it up. I've filed a defect (CSCvc09320) and will follow up with the engineer.

Collaborator

111pontes commented Nov 12, 2016

@jwbensley, thanks for bringing it up. I've filed a defect (CSCvc09320) and will follow up with the engineer.

@jwbensley

This comment has been minimized.

Show comment
Hide comment
@jwbensley

jwbensley Nov 12, 2016

Thank you both for your feedback and for clarifying the current behavior @einarnn and opening the bug case @111pontes, this is greatly appreciated!

Thank you both for your feedback and for clarifying the current behavior @einarnn and opening the bug case @111pontes, this is greatly appreciated!

@111pontes

This comment has been minimized.

Show comment
Hide comment
@111pontes

111pontes Feb 21, 2017

Collaborator

Fixed. Expected to be released in XR 6.2.1.

Collaborator

111pontes commented Feb 21, 2017

Fixed. Expected to be released in XR 6.2.1.

@111pontes 111pontes closed this Feb 21, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment