Possible Completions

Hello Team,

I have a yang model with 3 input leaf nodes under a container.

input {
  leaf ipv4 {
    type inet:ipv4-address;
  }
  leaf interface {
    type uint16;
  }
 leaf vpn {
   type uint16;
  }
}

There is another model that has the config of all the configured interfaces and VPNs on the device. I want that while configuring interfaces and vpn in my new model, the possible completions to show the configured values of interfaces/VPNs in the other model. How can I achieve that?

One way is to use YANG leafref statement (see RFC section) to configure leaf value as sort of “pointer” to other model you mention -> this will automatically do the completion for you without any extra coding/work.

Other way, without directly binding data on YANG level, is to implement completion callback as described in ConfD user guide section “Customizing CLI completion”.

Say, I have a master model that has the config of multiple interfaces configured under a specific VPN. There can be multiple such VPNs configured each containing multiple interfaces.
In my new model, I want the possible completions to show only those interfaces that are part of the vpn that I have configured in this new model.

Example: master config has

vpn 0 {
  interface ge0/0
  interface ge0/1
}
vpn 1 {
  interface ge0/2
  eth0
}

In my new model(as mentioned in the original description) when I configure vpn 0 I want the possible completions for interface to show only ge0/0 and ge0/1.

I tried using something like this but didn’t help:

leaf interface {
  type leafref {
    path "/vpn/vpn-instance[$(vpn-id)]/interface/if-name";
  }
}

where, “/vpn/vpn-instance/vpn-id” is the path in the master model containing the VPN config.

container vpn {
  list vpn-instance {
    key "vpn-id";
    leaf vpn-id {
      type uint16;
    }
    list interface {
      key "if-name";
      leaf if-name {
        type string;
      }
    }
  }
}

I think you need to do specific projection (key-name = value)…
Let’s assume that value of VPN you want to limit to is in leaf my-vpn that is sibling of interface.
Then, you need something like this:

leaf my-vpn {
  type uint16;
}
leaf interface {
  type leafref {
     path "/vpn/vpn-instance[vpn-id = current()/../my-vpn]/interface/if-name";
  }
}

Tried this construct, but no luck!
I don’t see any possible completions for interface, except the description (tailf:info)

I try with 7.3 basic, and it seems to work with small edit to intro example of ConfD:

--- a/examples.confd/intro/1-2-3-start-query-model/dhcpd.yang
+++ b/examples.confd/intro/1-2-3-start-query-model/dhcpd.yang
@@ -80,6 +80,34 @@ module dhcpd {
     }
   }

+container vpn {
+  list vpn-instance {
+    key "vpn-id";
+    leaf vpn-id { type uint16; }
+    list interface {
+      key "if-name";
+      leaf if-name { type string; }
+    }
+  }
+}
+
+container ref {
+  leaf myvpn { type uint16; }
+  leaf interface {
+    type leafref {
+      path "/vpn/vpn-instance[vpn-id = current()/../myvpn]/interface/if-name";
+    }
+  }
+}
+
   container dhcp {
     leaf default-lease-time {
       type xs:duration;

then after build/startup and playing in C style CLI:

dev# config
Entering configuration mode terminal
dev(config)# vpn vpn-instance 100 interface eth100
dev(config-interface-eth100)# vpn vpn-instance 100 interface eth105
dev(config-interface-eth105)# vpn vpn-instance 100 interface eth107
dev(config-interface-eth107)# vpn vpn-instance 200 interface eth201
dev(config-interface-eth201)# vpn vpn-instance 200 interface eth203
dev(config-interface-eth203)# commit
Commit complete.
dev(config-interface-eth203)# top
dev(config)# ref myvpn 100
dev(config)# ref interface ?
Possible completions:
  eth100  eth105  eth107
dev(config)#
dev(config)# ref myvpn 200
dev(config)# ref interface ?
Possible completions:
  eth201  eth203
dev(config)#
dev(config)# ref interface 100
dev(config)# commit
Aborted: illegal reference 'ref interface'
dev(config)#

Try double checking the path, or reproducing same scenario i have above with your confd version…

Thanks for the example code!

For a myvpn, if I enter an if-name that is not part of the vpn-instance[myvpn]/interface/ then the CLI throws “illegal reference” error, which is expected. This confirms that the leafref path is correct.
But I still don’t see the possible completions of interface on ?

Although, if I set the type of myvpn as leafref to the path: “/vpn/vpn-instance/vpn-id” then I do see the possible completions of vpn-id.
I wonder why I don’t see the same behaviour with interface/if-name.