{"id":21636120,"url":"https://github.com/bigevilbeard/grpc_xr_example","last_synced_at":"2026-04-07T14:31:10.509Z","repository":{"id":128721690,"uuid":"338042172","full_name":"bigevilbeard/grpc_xr_example","owner":"bigevilbeard","description":null,"archived":false,"fork":false,"pushed_at":"2023-02-20T10:36:58.000Z","size":68,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T15:59:16.317Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bigevilbeard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-11T13:50:26.000Z","updated_at":"2023-02-20T10:37:03.000Z","dependencies_parsed_at":"2023-03-11T08:30:45.646Z","dependency_job_id":null,"html_url":"https://github.com/bigevilbeard/grpc_xr_example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bigevilbeard/grpc_xr_example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigevilbeard%2Fgrpc_xr_example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigevilbeard%2Fgrpc_xr_example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigevilbeard%2Fgrpc_xr_example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigevilbeard%2Fgrpc_xr_example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bigevilbeard","download_url":"https://codeload.github.com/bigevilbeard/grpc_xr_example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigevilbeard%2Fgrpc_xr_example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31515382,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T03:30:01.828Z","updated_at":"2026-04-07T14:31:10.490Z","avatar_url":"https://github.com/bigevilbeard.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# IOS-XR over GRPC\n\n\nThis public repo contains python code that can be used to interact with the Cisco IOS XR devices.The environment is pre-configured to access the [Cisco DevNet Always-On Sandbox](https://devnetsandbox.cisco.com/RM/Diagram/Index/e83cfd31-ade3-4e15-91d6-3118b867a0dd?diagramType=Topology). You can edit the variables in the environment to point to your own IOS-XR device.\n\n\nThis package contains a library with the methods that are available to use over gRPC with IOS-XR boxes after 6.0.0. The API has several methods which allows a user to send simple RPC commands such as get and push using YANG and JSON.\n\nThe repo consists of two main components:\n\nThe compiled pb2 file from the proto definition.\nA Python module accessing the pb2 file with the library bindings.\n\n## Information\n\nXR devices ship with the YANG files that define the data models they support. Using a management protocol such as NETCONF or gRPC, you can programmatically query a device for the list of models it supports and retrieve the model files.\n\ngRPC is an open-source RPC framework. It is based on Protocol Buffers (Protobuf), which is an open source binary serialization protocol. gRPC provides a flexible, efficient, automated mechanism for serializing structured data, like XML, but is smaller and simpler to use. You define the structure using protocol buffer message types in .proto files. Each protocol buffer message is a small logical record of information, containing a series of name-value pairs.\n\n## Getting Started\n\n### Enable gRPC\n\nSSH in to the Always-On Sandbox IOS XR router and turn on gRPC and disable tls, below is an example configuration\n\n```\ngrpc\n port 57777\n no-tls \n```\n\n\n### Python Environment Setup\nIt is recommended that this code be used with Python 3.6. It is highly recommended to leverage Python Virtual Environments (venv).\n\nFollow these steps to create and activate a venv.\n\n### OS X or Linux\n```\nvirtualenv venv --python=python3.6\nsource venv/bin/activate\n```\nInstall the code requirements\n\n```\npip install -r requirements.txt\n```\n\n\n## Code Example \"Get Interfaces\"\n\nTo get all the interfaces from the Always-On Sandbox IOS-XR device, we can run this small piece of code derived from OpenConfig YANG models and serialise this as `JSON`. Change into the `examples` directory and run the following code, this uses the yang model https://github.com/YangModels/yang/blob/master/vendor/cisco/xr/653/openconfig-interfaces.yang and will print all the interface from the Always-On Sandbox IOS-XR device in the `json` format.\n\n```\n(venv)python grpc_example.py \n{\n    \"openconfig-interfaces:interfaces\": {\n        \"interface\": [\n            {\n                \"name\": \"Loopback100\",\n                \"config\": {\n                    \"name\": \"Loopback100\",\n                    \"type\": \"iana-if-type:softwareLoopback\",\n                    \"enabled\": true,\n                    \"description\": \"***MERGE LOOPBACK 100****\"\n                },\n                \"subinterfaces\": {\n                    \"subinterface\": [\n                        {\n                            \"index\": 0,\n                            \"openconfig-if-ip:ipv4\": {\n                                \"addresses\": {\n                                    \"address\": [\n                                        {\n                                            \"ip\": \"1.1.1.100\",\n                                            \"config\": {\n                                                \"ip\": \"1.1.1.100\",\n                                                \"prefix-length\": 32\n                                            }\n                                        }\n                                    ]\n                                }\n                            }\n                        }\n                    ]\n                }\n            },\n[/snip]\n```\n\n## Code Example \"Configure, update and detele BGP\"\n\nThis code uses the JSON below is based off the YANG model provided by Cisco: https://github.com/YangModels/yang/blob/master/vendor/cisco/xr/653/Cisco-IOS-XR-ipv4-bgp-cfg.yang You can walk through the hierachy using pyang, and create a JSON model similar to the example below. https://github.com/mbj4668/pyang/wiki/TreeOutput\n\nThis JSON model is for a BGP configuration. We can see that it is defining a BGP instance and a single neighbor.\n\n```\n{\n \"Cisco-IOS-XR-ipv4-bgp-cfg:bgp\": {\n  \"instance\": [\n   {\n    \"instance-name\": \"default\",\n    \"instance-as\": [\n     {\n      \"as\": 0,\n      \"four-byte-as\": [\n       {\n        \"as\": 65400,\n        \"bgp-running\": [\n         null\n        ],\n        \"default-vrf\": {\n         \"global\": {\n          \"router-id\": \"11.1.1.10\",\n          \"global-afs\": {\n           \"global-af\": [\n            {\n             \"af-name\": \"ipv4-unicast\",\n             \"enable\": [\n              null\n             ],\n             \"sourced-networks\": {\n              \"sourced-network\": [\n               {\n                \"network-addr\": \"11.1.1.0\",\n                \"network-prefix\": 24\n               }\n              ]\n             }\n            }\n           ]\n          }\n         },\n         \"bgp-entity\": {\n          \"neighbors\": {\n           \"neighbor\": [\n            {\n             \"neighbor-address\": \"11.1.1.20\",\n             \"remote-as\": {\n              \"as-xx\": 0,\n              \"as-yy\": 65450\n             },\n             \"neighbor-afs\": {\n              \"neighbor-af\": [\n               {\n                \"af-name\": \"ipv4-unicast\",\n                \"activate\": [\n                 null\n                ],\n                \"next-hop-self\": true\n               }\n              ]\n             }\n            }\n           ]\n          }\n         }\n        }\n       }\n      ]\n     }\n    ]\n   }\n  ]\n }\n}\n```\n\nThis code uses Object-Oriented Programming (OOP). This is a programming paradigm where different components of a computer program are modeled after real-world objects. An object is anything that has some characteristics and can perform a function. All args used in the running of the code are handled using Click. Click is a Python package for creating beautiful command line interfaces in a composable way with as little code as necessary. From the examples directory run the following\n\n```\n(venv) grpc_xr_example$ python grpc_cfg.py --help\nUsage: grpc_cfg.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --help  Show this message and exit.\n\nCommands:\n  delete\n  get\n  merge\n  replace\n\n```\n\n Start with a `get` this will look at the Always-On Sandbox IOS-XR device configuration and return that BGP is not configured (note that this is an Always-On Sandbox and that other users might be using this or there could be stale conifgurations on the device), \n \n ```\n(venv)examples$ python grpc_cfg.py get\nBGP instance 'default' not active\n ```\n\n Next, add a base BGP config using the `JSON` file we looked at earlier\n\n ```\n(venv)examples$python grpc_cfg.py replace\nReplace Completed\n\n ```\n\n If we loggged into the Always-On Sandbox IOS-XR device, we would now see one Neighbor conifgured.\n\n ```\nRP/0/RP0/CPU0:iosxr1#sh run router bgp\nSat Feb 13 06:01:47.321 UTC\nrouter bgp 65400\n bgp router-id 11.1.1.10\n address-family ipv4 unicast\n  network 11.1.1.0/24\n !\n neighbor 11.1.1.20\n  remote-as 65450\n  address-family ipv4 unicast\n   next-hop-self\n  !\n !\n!\n```\n\nHowever, we can use the `get` function once again to see this.\n\n\n```\n(venv)examples$ python grpc_cfg.py get\n{\n    \"Cisco-IOS-XR-ipv4-bgp-cfg:bgp\": {\n        \"instance\": [\n            {\n                \"instance-name\": \"default\",\n                \"instance-as\": [\n                    {\n                        \"as\": 0,\n                        \"four-byte-as\": [\n                            {\n                                \"as\": 65400,\n                                \"bgp-running\": [\n                                    null\n                                ],\n                                \"default-vrf\": {\n                                    \"global\": {\n                                        \"router-id\": \"11.1.1.10\",\n                                        \"global-afs\": {\n                                            \"global-af\": [\n                                                {\n                                                    \"af-name\": \"ipv4-unicast\",\n                                                    \"enable\": [\n                                                        null\n                                                    ],\n                                                    \"sourced-networks\": {\n                                                        \"sourced-network\": [\n                                                            {\n                                                                \"network-addr\": \"11.1.1.0\",\n                                                                \"network-prefix\": 24\n                                                            }\n                                                        ]\n                                                    }\n                                                }\n                                            ]\n                                        }\n                                    },\n                                    \"bgp-entity\": {\n                                        \"neighbors\": {\n                                            \"neighbor\": [\n                                                {\n                                                    \"neighbor-address\": \"11.1.1.20\",\n                                                    \"remote-as\": {\n                                                        \"as-xx\": 0,\n                                                        \"as-yy\": 65450\n                                                    },\n                                                    \"neighbor-afs\": {\n                                                        \"neighbor-af\": [\n                                                            {\n                                                                \"af-name\": \"ipv4-unicast\",\n                                                                \"activate\": [\n                                                                    null\n                                                                ],\n                                                                \"next-hop-self\": true\n                                                            }\n                                                        ]\n                                                    }\n                                                }\n                                            ]\n                                        }\n                                    }\n                                }\n                            }\n                        ]\n                    }\n                ]\n            }\n        ]\n    }\n}\n\n```\n\nIf this worked correctly you should see the `JSON` file we looked at, and the response from the `get` should be identical Now, use a merge request to add another neighbor with the second `JSON` file\n\n```\n(venv)examples$python grpc_cfg.py merge\nMerge Completed\n```\n\n```\nRP/0/RP0/CPU0:iosxr1#sh run router bgp\nSat Feb 13 06:05:33.336 UTC\nrouter bgp 65400\n bgp router-id 11.1.1.10\n address-family ipv4 unicast\n  network 11.1.1.0/24\n !\n neighbor 11.1.1.20\n  remote-as 65450\n  address-family ipv4 unicast\n   next-hop-self\n  !\n !\n neighbor 11.1.1.60\n  remote-as 65460\n  address-family ipv4 unicast\n   next-hop-self\n  !\n !\n!\n```\n\nThe resulting config should be the first config plus the second, or in other words there are two neighbors defined.\nThis can also been seen by running the `python grpc_cfg.py get` file once more.\n\nTo delete the configuration we can send an empty `JSON` file, followed by the `get` file to confirm that BGP is no longer configured/active.\n\n```\n(venv)examples$ cat snips/bgp_delete.json \n{\n    \"Cisco-IOS-XR-ipv4-bgp-cfg:bgp\": [null]\n}\n\n```\n\n```\n(venv)examples$ python grpc_cfg.py delete\nDelete Completed\n(venv)examples$ python grpc_cfg.py get\nBGP instance 'default' not active\n```\n\n\n## About me\n\nNetwork Automation Developer Advocate for Cisco DevNet.\nFind me here: [LinkedIn](https://www.linkedin.com/in/stuarteclark/) / [Twitter](https://twitter.com/bigevilbeard)\n\nThanks to Karthik Kumaravel and Patrick \"Bench Press 500\" Rockholz for their code samples and debugging skills.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigevilbeard%2Fgrpc_xr_example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbigevilbeard%2Fgrpc_xr_example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigevilbeard%2Fgrpc_xr_example/lists"}