cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
3335
Views
0
Helpful
12
Replies

CSR1000v (IOS XE Version 16.09.03) doesn't react on RPC

horseinthesky
Level 1
Level 1

Hello.
I'm trying to set up BGP config via YDK with the following example:

import logging

from ydk.services import CodecService, CRUDService
from ydk.providers import CodecServiceProvider, NetconfServiceProvider
from ydk.models.openconfig import openconfig_bgp as oc_bgp
from ydk.models.openconfig import openconfig_bgp_types as oc_bgp_types
from ydk.filters import YFilter

logger = logging.getLogger('ydk')
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter(("%(asctime)s - %(name)s - "
                               "%(levelname)s - %(message)s"))
handler.setFormatter(formatter)
logger.addHandler(handler)

DEVICES = {
    'junos': {
        'ip': '10.10.30.4',
        'pass': 'Juniper'
    },
    'xr': {
        'ip': '10.10.30.5',
        'pass': 'admin'
    },
    'xe': {
        'ip': '10.10.30.6',
        'pass': 'admin'
    }
}


def config_bgp(bgp):
    """Add config data to bgp object."""
    # global configuration
    bgp.global_.config.as_ = 65001
    afi_safi = bgp.global_.afi_safis.AfiSafi()
    afi_safi.afi_safi_name = oc_bgp_types.IPV6UNICAST()
    afi_safi.config.afi_safi_name = oc_bgp_types.IPV6UNICAST()
    afi_safi.config.enabled = True
    bgp.global_.afi_safis.afi_safi.append(afi_safi)

    # configure IBGP peer group
    peer_group = bgp.peer_groups.PeerGroup()
    peer_group.peer_group_name = "EBGP"
    peer_group.config.peer_group_name = "EBGP"
    peer_group.config.peer_as = 65002
    peer_group.transport.config.local_address = "Loopback0"
    afi_safi = peer_group.afi_safis.AfiSafi()
    afi_safi.afi_safi_name = oc_bgp_types.IPV6UNICAST()
    afi_safi.config.afi_safi_name = oc_bgp_types.IPV6UNICAST()
    afi_safi.config.enabled = True
    # afi_safi.apply_policy.config.import_policy.append("POLICY3")
    # afi_safi.apply_policy.config.export_policy.append("POLICY1")
    peer_group.afi_safis.afi_safi.append(afi_safi)
    bgp.peer_groups.peer_group.append(peer_group)

    # configure IBGP neighbor
    neighbor = bgp.neighbors.Neighbor()
    neighbor.neighbor_address = '2001:db8:e:1::1'
    neighbor.config.neighbor_address = '2001:db8:e:1::1'
    neighbor.config.peer_group = "EBGP"
    bgp.neighbors.neighbor.append(neighbor)


if __name__ == '__main__':
    # provider = CodecServiceProvider(type='xml')
    # codec = CodecService()

    bgp = oc_bgp.Bgp()
    bgp.yfilter = YFilter.replace
    config_bgp(bgp)

    # print(codec.encode(provider, native))

    device = DEVICES['xe']

    provider = NetconfServiceProvider(
        address=device['ip'],
        port=830,
        username='admin',
        password=device['pass'],
        protocol='ssh'
    )
    crud = CRUDService()
    crud.create(provider, bgp)

In the log output I see that everything went well:

2019-12-06 17:48:16,921 - ydk - INFO - Path where models are to be downloaded: /home/horseinthesky/.ydk/10.10.30.6
2019-12-06 17:48:16,933 - ydk - INFO - Connected to 10.10.30.6 on port 830 using ssh with timeout of -1
2019-12-06 17:48:16,934 - ydk - INFO - Executing CRUD create operation on [openconfig-bgp:bgp]
2019-12-06 17:48:16,934 - ydk - INFO - Executing 'edit-config' RPC on [openconfig-bgp:bgp]
2019-12-06 17:48:17,014 - ydk - INFO - ============= Sending RPC to device =============
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <target>
    <running/>
  </target>
  <config><bgp xmlns="http://openconfig.net/yang/bgp" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="replace">
  <global>
    <config>
      <as>65001</as>
    </config>
    <afi-safis>
      <afi-safi>
        <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
        <config>
          <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
          <enabled>true</enabled>
        </config>
      </afi-safi>
    </afi-safis>
  </global>
  <neighbors>
    <neighbor>
      <neighbor-address>2001:db8:e:1::1</neighbor-address>
      <config>
        <peer-group>EBGP</peer-group>
        <neighbor-address>2001:db8:e:1::1</neighbor-address>
      </config>
    </neighbor>
  </neighbors>
  <peer-groups>
    <peer-group>
      <peer-group-name>EBGP</peer-group-name>
      <config>
        <peer-group-name>EBGP</peer-group-name>
        <peer-as>65002</peer-as>
      </config>
      <transport>
        <config>
          <local-address>Loopback0</local-address>
        </config>
      </transport>
      <afi-safis>
        <afi-safi>
          <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
          <config>
            <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
            <enabled>true</enabled>
          </config>
        </afi-safi>
      </afi-safis>
    </peer-group>
  </peer-groups>
</bgp>
</config>
</edit-config>
</rpc>
2019-12-06 17:48:17,418 - ydk - INFO - ============= Received RPC from device =============
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
  <ok/>
</rpc-reply>

2019-12-06 17:48:17,418 - ydk - INFO - Operation succeeded
2019-12-06 17:48:17,424 - ydk - INFO - Disconnected from device

But there is no BGP config on the device afterward

CSR6#show run | se bgp          
CSR6#
2 Accepted Solutions

Accepted Solutions

Could you please rerun this script with logging level DEBUG and attach the log to the post so I could understand why the YDK failed to get XE configuration.

Note. Because the filter for the NetconfService.get_config() is not specified, the YDK attempts to retrieve full configuration of the device. The returned result in this case is class Config instance, which is alias of EntityCollection class.

I do not understand, why later on you try to call codec.decode(), which expects as a parameter string value of payload. I guess you wanted to get result as XML and then print it. In this case the last operator should be:

    xml_list = codec.encode(pr, config.entities(), pretty=True)
print("\nGOT DEVICE CONFIGURATION:\n%s" % '\n'.join(xml_list))

 I executed such script on CiscoDevNet IOS XE sandbox router and got it working just fine (see attached log file)

Yan Gorelik
YDK Solutions

View solution in original post

Kirill

You get all python objects in the line:

config = netconf.get_config(provider, Datastore.running)

But they are placed into Config class, which is EntityCollection instance. Please check its API and use examples here. In order to get list of entities (python objects) simply run:

list_of_entities = config.entities()

 

Yan Gorelik
YDK Solutions

View solution in original post

12 Replies 12

yangorelik
Spotlight
Spotlight

This is similar to XRv9K NETCONF 1.1. The issue that you are observing is not related to YDK. As I can see in the log, the YDK worked perfectly well.

I believe you cannot configure BGP on Cisco routers using standard openconfig models. For this you should use proprietary Cisco models and/or openconfig-network-instance.

It is also possible that your particular device does not include BGP routing as a feature. You can try to do the BGP configuration on your device using CLI just to see if it is supported.

Yan Gorelik
YDK Solutions

It works really strange for me.

I've configured BGP process manually:

CSR6#show run | se bgp
router bgp 6
 bgp router-id 10.10.30.6
 bgp log-neighbor-changes
 neighbor 10.10.30.5 remote-as 5

And then did get-config via ydk. This is what I've got:

<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
  <data>
    <native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
      <version>16.9</version>
      <boot-start-marker/>
      <boot-end-marker/>
      <service>
        <timestamps>
          <debug>
            <datetime>
              <msec/>
            </datetime>
          </debug>
          <log>
            <datetime>
              <msec/>
            </datetime>
          </log>
        </timestamps>
      </service>
      <platform>
        <console xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-platform">
          <output>serial</output>
        </console>
      </platform>
      <hostname>CSR6</hostname>
      <enable>
        <password>
          <secret>admin</secret>
        </password>
      </enable>
      <username>
        <name>admin</name>
        <privilege>15</privilege>
        <password>
          <encryption>0</encryption>
          <password>admin</password>
        </password>
      </username>
      <username>
        <name>horseinthesky</name>
        <privilege>15</privilege>
      </username>
      <ip>
        <domain>
          <name>lab.local</name>
        </domain>
        <forward-protocol>
          <protocol>nd</protocol>
        </forward-protocol>
        <route>
          <ip-route-interface-forwarding-list>
            <prefix>0.0.0.0</prefix>
            <mask>0.0.0.0</mask>
            <fwd-list>
              <fwd>10.10.30.254</fwd>
            </fwd-list>
          </ip-route-interface-forwarding-list>
        </route>
        <ssh>
          <pubkey-chain>
            <username>
              <name>horseinthesky</name>
              <key-hash>
                <key-type>ssh-rsa</key-type>
                <key-hash-value>D13E140448650E64A6778D40057326E8 horseinthesky@Kappa</key-hash-value>
              </key-hash>
            </username>
          </pubkey-chain>
        </ssh>
        <http xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-http">
          <authentication>
            <local/>
          </authentication>
          <server>true</server>
          <secure-server>true</secure-server>
        </http>
      </ip>
      <ipv6>
        <unicast-routing/>
      </ipv6>
      <interface>
        <GigabitEthernet>
          <name>1</name>
          <description>DON'T TOUCH ME</description>
          <ip>
            <address>
              <primary>
                <address>10.10.30.6</address>
                <mask>255.255.255.0</mask>
              </primary>
            </address>
          </ip>
          <mop>
            <enabled>false</enabled>
            <sysid>false</sysid>
          </mop>
          <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
            <auto>true</auto>
          </negotiation>
        </GigabitEthernet>
        <GigabitEthernet>
          <name>2</name>
          <description>Configured via ydk</description>
          <ip>
            <address>
              <primary>
                <address>172.16.1.0</address>
                <mask>255.255.255.254</mask>
              </primary>
            </address>
          </ip>
          <ipv6>
            <address>
              <prefix-list>
                <prefix>2001:DB8::1:0/127</prefix>
              </prefix-list>
            </address>
          </ipv6>
          <load-interval>30</load-interval>
          <mtu>9192</mtu>
          <speed xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
            <value-1000/>
          </speed>
          <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
            <auto>false</auto>
          </negotiation>
        </GigabitEthernet>
        <GigabitEthernet>
          <name>3</name>
          <shutdown/>
          <mop>
            <enabled>false</enabled>
            <sysid>false</sysid>
          </mop>
          <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
            <auto>true</auto>
          </negotiation>
        </GigabitEthernet>
        <GigabitEthernet>
          <name>4</name>
          <shutdown/>
          <mop>
            <enabled>false</enabled>
            <sysid>false</sysid>
          </mop>
          <negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
            <auto>true</auto>
          </negotiation>
        </GigabitEthernet>
        <Loopback>
          <name>0</name>
          <ip>
            <address>
              <primary>
                <address>1.1.1.6</address>
                <mask>255.255.255.255</mask>
              </primary>
            </address>
          </ip>
        </Loopback>
      </interface>
      <control-plane/>
      <login>
        <on-success>
          <log/>
        </on-success>
      </login>
      <multilink>
        <bundle-name xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ppp">authenticated</bundle-name>
      </multilink>
      <redundancy/>
      <spanning-tree>
        <extend xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-spanning-tree">
          <system-id/>
        </extend>
      </spanning-tree>
      <subscriber>
        <templating/>
      </subscriber>
      <crypto>
        <pki xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-crypto">
          <trustpoint>
            <id>TP-self-signed-835353984</id>
            <enrollment>
              <selfsigned/>
            </enrollment>
            <revocation-check>none</revocation-check>
            <rsakeypair>
              <key-label>TP-self-signed-835353984</key-label>
            </rsakeypair>
            <subject-name>cn=IOS-Self-Signed-Certificate-835353984</subject-name>
          </trustpoint>
          <certificate>
            <chain>
              <name>TP-self-signed-835353984</name>
              <certificate>
                <serial>01</serial>
                <certtype>self-signed</certtype>
              </certificate>
            </chain>
          </certificate>
        </pki>
      </crypto>
      <router>
        <bgp xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-bgp">
          <id>6</id>
          <bgp>
            <router-id>
              <ip-id>10.10.30.6</ip-id>
            </router-id>
          </bgp>
          <neighbor>
            <id>10.10.30.5</id>
            <remote-as>5</remote-as>
          </neighbor>
        </bgp>
      </router>
      <license>
        <udi>
          <pid>CSR1000V</pid>
          <sn>9SVCRC7X9CJ</sn>
        </udi>
      </license>
      <line>
        <console>
          <first>0</first>
          <exec-timeout>
            <minutes>0</minutes>
            <seconds>0</seconds>
          </exec-timeout>
          <logging>
            <synchronous/>
          </logging>
          <privilege>
            <level>
              <number>15</number>
            </level>
          </privilege>
          <stopbits>1</stopbits>
          <transport>
            <output>
              <output>none</output>
            </output>
          </transport>
        </console>
        <vty>
          <first>0</first>
          <last>4</last>
          <exec-timeout>
            <minutes>0</minutes>
            <seconds>0</seconds>
          </exec-timeout>
          <logging>
            <synchronous/>
          </logging>
          <login>
            <local/>
          </login>
          <privilege>
            <level>
              <number>15</number>
            </level>
          </privilege>
          <transport>
            <input>
              <input>telnet</input>
              <input>ssh</input>
            </input>
          </transport>
        </vty>
      </line>
      <diagnostic xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-diagnostics">
        <bootup>
          <level>minimal</level>
        </bootup>
      </diagnostic>
    </native>
    <licensing xmlns="http://cisco.com/ns/yang/cisco-smart-license">
      <config>
        <enable>false</enable>
        <privacy>
          <hostname>false</hostname>
          <version>false</version>
        </privacy>
        <utility>
          <utility-enable>false</utility-enable>
        </utility>
      </config>
    </licensing>
    <bgp xmlns="http://openconfig.net/yang/bgp">
      <global>
        <config>
          <as>65001</as>
        </config>
        <afi-safis>
          <afi-safi>
            <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
            <config>
              <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
              <enabled>true</enabled>
            </config>
          </afi-safi>
        </afi-safis>
      </global>
      <neighbors>
        <neighbor>
          <neighbor-address>2001:db8:e:1::1</neighbor-address>
          <config>
            <peer-group>EBGP</peer-group>
            <neighbor-address>2001:db8:e:1::1</neighbor-address>
          </config>
        </neighbor>
      </neighbors>
      <peer-groups>
        <peer-group>
          <peer-group-name>EBGP</peer-group-name>
          <config>
            <peer-group-name>EBGP</peer-group-name>
            <peer-as>65002</peer-as>
          </config>
          <transport>
            <config>
              <local-address>Loopback0</local-address>
            </config>
          </transport>
          <afi-safis>
            <afi-safi>
              <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
              <config>
                <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
                <enabled>true</enabled>
              </config>
            </afi-safi>
          </afi-safis>
        </peer-group>
      </peer-groups>
    </bgp>
    <interfaces xmlns="http://openconfig.net/yang/interfaces">
      <interface>
        <name>GigabitEthernet1</name>
        <config>
          <name>GigabitEthernet1</name>
          <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
          <description>DON'T TOUCH ME</description>
          <enabled>true</enabled>
        </config>
        <subinterfaces>
          <subinterface>
            <index>0</index>
            <config>
              <index>0</index>
              <description>DON'T TOUCH ME</description>
              <enabled>true</enabled>
            </config>
            <ipv4 xmlns="http://openconfig.net/yang/interfaces/ip">
              <addresses>
                <address>
                  <ip>10.10.30.6</ip>
                  <config>
                    <ip>10.10.30.6</ip>
                    <prefix-length>24</prefix-length>
                  </config>
                </address>
              </addresses>
            </ipv4>
            <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip">
              <config>
                <enabled>false</enabled>
              </config>
            </ipv6>
          </subinterface>
        </subinterfaces>
        <ethernet xmlns="http://openconfig.net/yang/interfaces/ethernet">
          <config>
            <mac-address>50:00:00:08:00:00</mac-address>
            <auto-negotiate>true</auto-negotiate>
          </config>
        </ethernet>
      </interface>
      <interface>
        <name>GigabitEthernet2</name>
        <config>
          <name>GigabitEthernet2</name>
          <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
          <mtu>9192</mtu>
          <description>Configured via ydk</description>
          <enabled>true</enabled>
        </config>
        <subinterfaces>
          <subinterface>
            <index>0</index>
            <config>
              <index>0</index>
              <description>Configured via ydk</description>
              <enabled>true</enabled>
            </config>
            <ipv4 xmlns="http://openconfig.net/yang/interfaces/ip">
              <addresses>
                <address>
                  <ip>172.16.1.0</ip>
                  <config>
                    <ip>172.16.1.0</ip>
                    <prefix-length>31</prefix-length>
                  </config>
                </address>
              </addresses>
            </ipv4>
            <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip">
              <addresses>
                <rpc-error xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
                  <error-type>application</error-type>
                  <error-tag>operation-failed</error-tag>
                  <error-severity>error</error-severity>
                  <error-message xml:lang="en">application protocol error</error-message>
                  <error-info>
                    <bad-element>address</bad-element>
                  </error-info>
                </rpc-error>
              </addresses>
              <config>
                <enabled>false</enabled>
              </config>
            </ipv6>
          </subinterface>
        </subinterfaces>
        <ethernet xmlns="http://openconfig.net/yang/interfaces/ethernet">
          <config>
            <mac-address>50:00:00:08:00:01</mac-address>
            <auto-negotiate>false</auto-negotiate>
            <port-speed>SPEED_1GB</port-speed>
          </config>
        </ethernet>
      </interface>
      <interface>
        <name>GigabitEthernet3</name>
        <config>
          <name>GigabitEthernet3</name>
          <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
          <enabled>false</enabled>
        </config>
        <subinterfaces>
          <subinterface>
            <index>0</index>
            <config>
              <index>0</index>
              <enabled>false</enabled>
            </config>
            <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip">
              <config>
                <enabled>false</enabled>
              </config>
            </ipv6>
          </subinterface>
        </subinterfaces>
        <ethernet xmlns="http://openconfig.net/yang/interfaces/ethernet">
          <config>
            <mac-address>50:00:00:08:00:02</mac-address>
            <auto-negotiate>true</auto-negotiate>
          </config>
        </ethernet>
      </interface>
      <interface>
        <name>GigabitEthernet4</name>
        <config>
          <name>GigabitEthernet4</name>
          <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
          <enabled>false</enabled>
        </config>
        <subinterfaces>
          <subinterface>
            <index>0</index>
            <config>
              <index>0</index>
              <enabled>false</enabled>
            </config>
            <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip">
              <config>
                <enabled>false</enabled>
              </config>
            </ipv6>
          </subinterface>
        </subinterfaces>
        <ethernet xmlns="http://openconfig.net/yang/interfaces/ethernet">
          <config>
            <mac-address>50:00:00:08:00:03</mac-address>
            <auto-negotiate>true</auto-negotiate>
          </config>
        </ethernet>
      </interface>
      <interface>
        <name>Loopback0</name>
        <config>
          <name>Loopback0</name>
          <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:softwareLoopback</type>
          <enabled>true</enabled>
        </config>
        <subinterfaces>
          <subinterface>
            <index>0</index>
            <config>
              <index>0</index>
              <enabled>true</enabled>
            </config>
            <ipv4 xmlns="http://openconfig.net/yang/interfaces/ip">
              <addresses>
                <address>
                  <ip>1.1.1.6</ip>
                  <config>
                    <ip>1.1.1.6</ip>
                    <prefix-length>32</prefix-length>
                  </config>
                </address>
              </addresses>
            </ipv4>
            <ipv6 xmlns="http://openconfig.net/yang/interfaces/ip">
              <config>
                <enabled>false</enabled>
              </config>
            </ipv6>
          </subinterface>
        </subinterfaces>
      </interface>
    </interfaces>
    <network-instances xmlns="http://openconfig.net/yang/network-instance">
      <network-instance>
        <name>default</name>
        <config>
          <name>default</name>
          <type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:DEFAULT_INSTANCE</type>
          <description>default-vrf [read-only]</description>
        </config>
        <tables>
          <table>
            <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
            <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
            <config>
              <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
              <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
            </config>
          </table>
          <table>
            <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
            <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family>
            <config>
              <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
              <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family>
            </config>
          </table>
          <table>
            <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
            <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
            <config>
              <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
              <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
            </config>
          </table>
          <table>
            <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
            <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family>
            <config>
              <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
              <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family>
            </config>
          </table>
        </tables>
        <protocols>
          <protocol>
            <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier>
            <name>6</name>
            <config>
              <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier>
              <name>6</name>
            </config>
            <bgp>
              <global>
                <config>
                  <as>6</as>
                  <router-id>10.10.30.6</router-id>
                </config>
                <graceful-restart>
                  <config>
                    <enabled>false</enabled>
                  </config>
                </graceful-restart>
                <route-selection-options>
                  <config>
                    <always-compare-med>false</always-compare-med>
                    <external-compare-router-id>false</external-compare-router-id>
                  </config>
                </route-selection-options>
              </global>
              <neighbors>
                <neighbor>
                  <neighbor-address>10.10.30.5</neighbor-address>
                  <config>
                    <neighbor-address>10.10.30.5</neighbor-address>
                    <peer-as>5</peer-as>
                  </config>
                  <timers>
                    <config>
                      <hold-time>180.0</hold-time>
                      <keepalive-interval>60.0</keepalive-interval>
                    </config>
                  </timers>
                  <ebgp-multihop>
                    <config>
                      <enabled>true</enabled>
                    </config>
                  </ebgp-multihop>
                </neighbor>
              </neighbors>
            </bgp>
          </protocol>
          <protocol>
            <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</identifier>
            <name>DEFAULT</name>
            <config>
              <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</identifier>
              <name>DEFAULT</name>
            </config>
            <static-routes>
              <static>
                <prefix>0.0.0.0/0</prefix>
                <config>
                  <prefix>0.0.0.0/0</prefix>
                </config>
                <next-hops>
                  <next-hop>
                    <index>10.10.30.254</index>
                    <config>
                      <index>10.10.30.254</index>
                      <next-hop>10.10.30.254</next-hop>
                    </config>
                  </next-hop>
                </next-hops>
              </static>
            </static-routes>
          </protocol>
          <protocol>
            <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</identifier>
            <name>DEFAULT</name>
            <config>
              <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</identifier>
              <name>DEFAULT</name>
            </config>
          </protocol>
        </protocols>
      </network-instance>
    </network-instances>
    <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
      <interface>
        <name>GigabitEthernet1</name>
        <description>DON'T TOUCH ME</description>
        <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
        <enabled>true</enabled>
        <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
          <address>
            <ip>10.10.30.6</ip>
            <netmask>255.255.255.0</netmask>
          </address>
        </ipv4>
        <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/>
      </interface>
      <interface>
        <name>GigabitEthernet2</name>
        <description>Configured via ydk</description>
        <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
        <enabled>true</enabled>
        <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
          <address>
            <ip>172.16.1.0</ip>
            <netmask>255.255.255.254</netmask>
          </address>
        </ipv4>
        <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
          <rpc-error xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
            <error-type>application</error-type>
            <error-tag>operation-failed</error-tag>
            <error-severity>error</error-severity>
            <error-message xml:lang="en">application protocol error</error-message>
            <error-info>
              <bad-element>address</bad-element>
            </error-info>
          </rpc-error>
        </ipv6>
      </interface>
      <interface>
        <name>GigabitEthernet3</name>
        <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
        <enabled>false</enabled>
        <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/>
        <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/>
      </interface>
      <interface>
        <name>GigabitEthernet4</name>
        <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
        <enabled>false</enabled>
        <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/>
        <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/>
      </interface>
      <interface>
        <name>Loopback0</name>
        <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:softwareLoopback</type>
        <enabled>true</enabled>
        <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
          <address>
            <ip>1.1.1.6</ip>
            <netmask>255.255.255.255</netmask>
          </address>
        </ipv4>
        <ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"/>
      </interface>
    </interfaces>
    <routing xmlns="urn:ietf:params:xml:ns:yang:ietf-routing">
      <routing-instance>
        <name>default</name>
        <description>default-vrf [read-only]</description>
        <routing-protocols>
          <routing-protocol>
            <type>static</type>
            <name>1</name>
            <static-routes>
              <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ipv4-unicast-routing">
                <route>
                  <destination-prefix>0.0.0.0/0</destination-prefix>
                  <next-hop>
                    <next-hop-address>10.10.30.254</next-hop-address>
                  </next-hop>
                </route>
              </ipv4>
            </static-routes>
          </routing-protocol>
        </routing-protocols>
      </routing-instance>
    </routing>
  </data>
</rpc-reply>

So, you can see my manual BGP config in Native model and Openconfig config in Openconfig BGP model which is not displayed in the config on the device itself.
I understand it is not about YDK but do you know how it is processed on the device?

It all depends on device capabilities to implement certain YANG models. From my personal experience I know that BGP can be configured only by using Cisco native models, but it can be partially read using openconfig models too. The main reason behind that concept is that BGP configuration on Cisco devices is much more complex than openconfig models can describe.

For further investigation on this subject please refer to specific router software documentation and/or Cisco TAC support.

Yan Gorelik
YDK Solutions

I wanted to experiment with CodecService and to transform received config to Python object via decode method:

import logging

from ydk.services import NetconfService, Datastore, CodecService
from ydk.providers import NetconfServiceProvider, CodecServiceProvider

logger = logging.getLogger('ydk')
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter(("%(asctime)s - %(name)s - "
                               "%(levelname)s - %(message)s"))
handler.setFormatter(formatter)
logger.addHandler(handler)

DEVICES = {
    'junos': {
        'ip': '10.10.30.4',
        'pass': 'Juniper'
    },
    'xr': {
        'ip': '10.10.30.5',
        'pass': 'admin'
    },
    'xe': {
        'ip': '10.10.30.6',
        'pass': 'admin'
    }
}

if __name__ == '__main__':
    device = DEVICES['xe']

    provider = NetconfServiceProvider(
        address=device['ip'],
        port=830,
        username='admin',
        password=device['pass'],
        protocol='ssh'
    )

    netconf = NetconfService()
    config = netconf.get_config(provider, Datastore.running)

    codec = CodecService()
    pr = CodecServiceProvider(type='xml')
    cfg = codec.decode(pr, config)


But after it gets RPC-Reply with config it fails:

...
    <routing xmlns="urn:ietf:params:xml:ns:yang:ietf-routing">
      <routing-instance>
        <name>default</name>
        <description>default-vrf [read-only]</description>
        <routing-protocols>
          <routing-protocol>
            <type>static</type>
            <name>1</name>
            <static-routes>
              <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ipv4-unicast-routing">
                <route>
                  <destination-prefix>0.0.0.0/0</destination-prefix>
                  <next-hop>
                    <next-hop-address>10.10.30.254</next-hop-address>
                  </next-hop>
                </route>
              </ipv4>
            </static-routes>
          </routing-protocol>
        </routing-protocols>
      </routing-instance>
    </routing>
  </data>
</rpc-reply>

Traceback (most recent call last):
  File "test.py", line 41, in <module>
    config = netconf.get_config(provider, Datastore.running)
  File "/usr/local/lib/python3.6/dist-packages/ydk/services/netconf_service.py", line 108, in get_config
    return _ns_get(provider, source, read_filter, self._ns.get_config)
  File "/usr/local/lib/python3.6/dist-packages/ydk/services/netconf_service.py", line 153, in _ns_get
    return _read_entities(provider, get_config=is_config)
  File "/usr/lib/python3.6/contextlib.py", line 99, in __exit__
    self.gen.throw(type, value, traceback)
  File "/usr/local/lib/python3.6/dist-packages/ydk/errors/error_handler.py", line 82, in handle_runtime_error
    _raise(_exc)
  File "/usr/local/lib/python3.6/dist-packages/ydk/errors/error_handler.py", line 54, in _raise
    exec("raise exc from None")
  File "<string>", line 1, in <module>
ydk.errors.YServiceProviderError:  application protocol error
2019-12-10 16:00:44,024 - ydk - INFO - Disconnected from device

What is wrong with this one?

Could you please rerun this script with logging level DEBUG and attach the log to the post so I could understand why the YDK failed to get XE configuration.

Note. Because the filter for the NetconfService.get_config() is not specified, the YDK attempts to retrieve full configuration of the device. The returned result in this case is class Config instance, which is alias of EntityCollection class.

I do not understand, why later on you try to call codec.decode(), which expects as a parameter string value of payload. I guess you wanted to get result as XML and then print it. In this case the last operator should be:

    xml_list = codec.encode(pr, config.entities(), pretty=True)
print("\nGOT DEVICE CONFIGURATION:\n%s" % '\n'.join(xml_list))

 I executed such script on CiscoDevNet IOS XE sandbox router and got it working just fine (see attached log file)

Yan Gorelik
YDK Solutions

Yes. This works fine for me too.

In fact, I was trying to do two things:
1) Get XML representation of device config for every model it sends (which you told me how to do)
2) Create Python objects for every XML received, which I still wonder how to do. I thought decode can do this for me

Kirill

You get all python objects in the line:

config = netconf.get_config(provider, Datastore.running)

But they are placed into Config class, which is EntityCollection instance. Please check its API and use examples here. In order to get list of entities (python objects) simply run:

list_of_entities = config.entities()

 

Yan Gorelik
YDK Solutions

Aha, got it. I've just looked into this object and I could discover these objects. This is really convenient.

But with XR it didn't work out.

The script

import logging

from ydk.services import NetconfService, Datastore, CodecService
from ydk.providers import NetconfServiceProvider, CodecServiceProvider

logger = logging.getLogger('ydk')
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
formatter = logging.Formatter(("%(asctime)s - %(name)s - "
                               "%(levelname)s - %(message)s"))
handler.setFormatter(formatter)
logger.addHandler(handler)

DEVICES = {
    'junos': {
        'ip': '10.10.30.4',
        'pass': 'Juniper'
    },
    'xr': {
        'ip': '10.10.30.5',
        'pass': 'admin'
    },
    'xe': {
        'ip': '10.10.30.6',
        'pass': 'admin'
    }
}

if __name__ == '__main__':
    device = DEVICES['xr']

    provider = NetconfServiceProvider(
        address=device['ip'],
        port=830,
        username='admin',
        password=device['pass'],
        protocol='ssh'
    )

    netconf = NetconfService()
    config = netconf.get_config(provider, Datastore.running)

    codec = CodecService()
    pr = CodecServiceProvider(type='xml')

    xml_list = codec.encode(pr, config.entities(), pretty=True)
    print('\nGOT DEVICE CONFIGURATION:\n{}'.format('\n'.join(xml_list)))

DEBUG is attached.

The YDK did receive device configuration, but then failed to convert it to entities due to error in this part of reply:

<vm xmlns="http://www.cisco.com/ns/yang/Cisco-IOS-XR-sysadmin-vm">
<config>
<memory>
<admin>0</admin>
<rp>0</rp>
<lc>0</lc>
</memory>
<cpu>
<assign/>
</cpu>
</config>
</vm>

In particular, it did not like that 'assign' has empty string value. However the model requires it to have some string value, which complies with the pattern:

ydk.errors.YModelError: Value "" does not satisfy the constraint "0(-[0-9]+)?/[0-9]+(-[0-9]+)?" (range, length, or pattern). Path: /Cisco-IOS-XR-sysadmin-vm:vm/config/cpu/assign

Most likely it is an error in the pattern (model error), but it could be a bug in Netconf server on the device, which should not include the 'assign' node into reply.

I am not sure if there is clean workaround for this issue in YDK. One kludgy way - manually change model in device repository in the way that it allows empty string for the 'assign' node.

Yan Gorelik
YDK Solutions

Juniper vMX doesn't work also.

Opened a bug YDK fails to decode RPC received from Juniper device.

Yan Gorelik
YDK Solutions