cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
326
Views
5
Helpful
7
Replies

NSO Basic DNS Service failing ''Container' object has no attribute"

richbotham
Level 1
Level 1

Hi all,

I hope someone can show me the obvious mistake i'm making.

I am following this https://developer.cisco.com/docs/nso-guides-5.7/creating-a-service/#creating-a-service to create a basic DNS service.

Whenever i issue a "commit dry-run" i get this error

admin@ncs(config)# dns-config test dns-server 1.1.1.1
admin@ncs(config-dns-config-test)# commit dry-run 
Aborted: Python cb_create error. 'Container' object has no attribute 'sys'

my python code is very similar to the example

@Service.create
    def cb_create(self, tctx, root, service, proplist):
        self.log.info('Service create(service=', service._path, ')')
        dns_ip = service.dns_server
        router0_device = root.devices.device['router0']
        router0_config = router0_device.config
        dns_server_list = router0_config.sys.dns.server
        if dns_ip not in dns_server_list:
            dns_server_list.create(dns_ip)

my yang file is as follows - the same as the example

module dns-config {

  namespace "http://example.com/dns-config";
  prefix dns-config;

  import ietf-inet-types {
    prefix inet;
  }
  import tailf-common {
    prefix tailf;
  }
  import tailf-ncs {
    prefix ncs;
  }

  description
    "Bla bla...";

  revision 2016-01-01 {
    description
      "Initial revision.";
  }

  list dns-config {
    description "This is an RFS skeleton service";

    key name;
    leaf name {
      tailf:info "Unique service id";
      tailf:cli-allow-range;
      type string;
    }

    uses ncs:service-data;
    ncs:servicepoint dns-config-servicepoint;

    // may replace this with other ways of refering to the devices.
    leaf-list device {
      type leafref {
        path "/ncs:devices/ncs:device/ncs:name";
      }
    }

    // replace with your own stuff here
    leaf dns-server {
      type inet:ipv4-address;
    }
  }
}

my router package is as follows

 ~/ncs-6.2/nso-instance/packages/ ls -la
total 0
drwxr-xr-x@  4 rich  staff  128 10 Nov 15:59 .
drwxr-xr-x@ 13 rich  staff  416 10 Nov 16:16 ..
lrwxr-xr-x@  1 rich  staff   51  7 Nov 16:03 cisco-ios-cli-3.8 -> /Users/rich/ncs-6.2/packages/neds/cisco-ios-cli-3.8
drwxr-xr-x@  9 rich  staff  288 10 Nov 16:17 dns-config

Thanks

Rich

2 Accepted Solutions

Accepted Solutions

Jesus Illescas
Cisco Employee
Cisco Employee

Hi, I haven't had the chance to look closely at your issue. But if I'm not mistaken, this line refers to the config on the Device from the NED, where you most probably don't have a sys container. You can try to configure manually a device from the cli using the NED (not from your service)

router0_config.sys.dns.server

 

if you want to refer to the structure of your service, you should use the `service` parameter from the `cb_create` function. Then you commit that config. On your yang file I also don't see a sys container, unless you are using the top yang model from the example.

def cb_create(self, tctx, root, service, proplist)

 

here you can see an example I created for a workshop I delivered on the Python API of NSO https://github.com/jillesca/DEVWKS-3551/blob/main/answers/package_router/router.py#L18 you can run this workshop if you want. Read main the README to find the instructions since the workshop is broken and is up to you to fix it (that was the goal of the workshop. The answers are there, in fact the link I sent you is one of them).

Here are some general recommendations that I think can be useful for your use case.

 

View solution in original post

@richbotham sure i am mostly guessing here, the python part i know, my nso is little shaky, but we have @Jesus Illescas here who is on of the best in the world with nso... so we are in good hands and he will tell you if i can talking pony here.

This new errors, is happening due to where you are accessing the configuration path as python interprets the hyphens as subtraction operators. So to fix this i 'think' yuo need to use the square brackets (like a dictionary), when using name which have special chars, such as hyphens... this is a little bit of a guess, but see if this fixed the error

 

@Service.create
def cb_create(self, tctx, root, service, proplist):
    self.log.info('Service create(service=', service._path, ')')
    dns_ip = service.dns_server
    router0_device = root.devices.device['router0']
    dns_list = router0_device.config.ip['name-server']['name-server-list']
    if dns_ip not in dns_list:
        dns_list.create(dns_ip)

 Fingers crossed here!

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

View solution in original post

7 Replies 7

Check if the NED has the sys.dns.server path, i think it doesn’t and this is the issue.

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

Jesus Illescas
Cisco Employee
Cisco Employee

Hi, I haven't had the chance to look closely at your issue. But if I'm not mistaken, this line refers to the config on the Device from the NED, where you most probably don't have a sys container. You can try to configure manually a device from the cli using the NED (not from your service)

router0_config.sys.dns.server

 

if you want to refer to the structure of your service, you should use the `service` parameter from the `cb_create` function. Then you commit that config. On your yang file I also don't see a sys container, unless you are using the top yang model from the example.

def cb_create(self, tctx, root, service, proplist)

 

here you can see an example I created for a workshop I delivered on the Python API of NSO https://github.com/jillesca/DEVWKS-3551/blob/main/answers/package_router/router.py#L18 you can run this workshop if you want. Read main the README to find the instructions since the workshop is broken and is up to you to fix it (that was the goal of the workshop. The answers are there, in fact the link I sent you is one of them).

Here are some general recommendations that I think can be useful for your use case.

 

Hi @jesusillescas Many many thanks for the link - more learning to do

richbotham
Level 1
Level 1

Hi @bigevilbeard 

Many thanks for taking the time to reply - appreciate it.

So i looked at ~/ncs6.2/nso-instance/packages/neds/cisco-ios-cli-3.8/src/yang/tailf-ned-cisco-ios.yang

admin@ncs# show devices ned-ids 
ID                 NAME                       REVISION    NAMESPACE      
-------------------------------------------------------------------------
lsa-netconf                                                              
netconf                                                                  
snmp                                                                     
cisco-ios-cli-3.8  tailf-ned-cisco-ios        2015-03-16  urn:ios        
                   tailf-ned-cisco-ios-stats  -           urn:ios-stats  


I found that by looking at the URL in NSO under 'edit config' i see this

ncs:devices/device{router0}/config/ios:ip/name-server/name-server-list

Which corresponds with this in the NED yang file

// ip-name-server-grouping
grouping ip-name-server-grouping {
list name-server-list {
tailf:cli-drop-node-name;
tailf:cli-suppress-mode;
tailf:cli-delete-when-empty;
max-elements 6;
key address;
leaf address {
type union {
type inet:ipv4-address {
tailf:info "A.B.C.D;;Domain server IP address (maximum of 6)";
}
type inet:ipv6-address {
tailf:info "X:X:X:X::X;;Domain server IPv6 address (maximum of 6)";
}
}
}
}
}


So I amended the code as follows

 

@Service.create
def cb_create(self, tctx, root, service, proplist):
self.log.info('Service create(service=', service._path, ')')
dns_ip = service.dns_server
router0_device = root.devices.device['router0']
router0_config = router0_device.config
dns_server_list = router0_config.ip.name-server.name-server-list.address
if dns_ip not in dns_server_list:
  dns_server_list.create(dns_ip)


Then i reload the package which is successful
Then i apply the config, however when I commit dry-run i get this

admin@ncs(config)# dns-config router0 dns-server 1.1.1.1
admin@ncs(config-dns-config-router0)# commit dry-run
Aborted: Python cb_create error. 'Container' object has no attribute 'name'
admin@ncs(config-dns-config-router0)#

 

@richbotham sure i am mostly guessing here, the python part i know, my nso is little shaky, but we have @Jesus Illescas here who is on of the best in the world with nso... so we are in good hands and he will tell you if i can talking pony here.

This new errors, is happening due to where you are accessing the configuration path as python interprets the hyphens as subtraction operators. So to fix this i 'think' yuo need to use the square brackets (like a dictionary), when using name which have special chars, such as hyphens... this is a little bit of a guess, but see if this fixed the error

 

@Service.create
def cb_create(self, tctx, root, service, proplist):
    self.log.info('Service create(service=', service._path, ')')
    dns_ip = service.dns_server
    router0_device = root.devices.device['router0']
    dns_list = router0_device.config.ip['name-server']['name-server-list']
    if dns_ip not in dns_list:
        dns_list.create(dns_ip)

 Fingers crossed here!

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

richbotham
Level 1
Level 1

Hey @bigevilbeard 

Thanks buddy - that did it - i should have seen that coming in the python code ( DOH) - makes sense now

admin@ncs(config-dns-config-router0)# commit dry-run 
cli {
    local-node {
        data  devices {
                  device router0 {
                      config {
                          ip {
                              name-server {
             +                    name-server-list 1.1.1.1 {
             +                    }
                              }
                          }
                      }
                  }
              }
             +dns-config router0 {
             +    dns-server 1.1.1.1;
             +}
    }
}
admin@ncs(config-dns-config-router0)#  
router0# show running-config
<snip>
!
ip name-server 1.1.1.1

@richbotham amazing! Lucky guess, you did all the hard work!

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io