Where can I get enough info on must statement?

Confd Team,
Where can I get enough info on must statement.
statement syntax and examples etc.

Thanks in advance,
Kamal

Here is the main requirement,
Actually I have a container which has ipv4 and ipv6 list with ipv4 and ipv6 leafs as keys respectively.
here I should be able to configure either ipv4 or ipv6 leaf but not both.

container address{
    tailf:info "define shared key with IP address";
    list ipv4{
        key ipv4;
        leaf ipv4{
            must "(current() not(../ipv6))"
            {
                    error-message "Either ipv4/ipv6 only not both";
            }
            type inet:ipv4-address{
                tailf:info "IPV4 Address for peer";
            }
        }
            leaf netmask{
                type inet:ipv4-address{
                    tailf:info "Peer IP subnet mask";
                }
            }
    }
    list ipv6{
        key ipv6;
        tailf:info "define shared key with IP address";
        leaf ipv6{
            must "(current() not(../ipv4))"
            {
                    error-message "Either ipv4/ipv6 only not both";
            }
            type inet:ipv6-address{
                tailf:info "IPV6 Address for peer";
            }
        }
        leaf netmask{
                type uint8{
                    tailf:info "Peer IP subnet mask";
                    range "1 .. 128";
                }
            }
    }
}

“Lots of places”… The YANG spec, RFC 7950 - The YANG 1.1 Data Modeling Language, as well as the “Integrity Constraints” section of the YANG chapter in the ConfD User Guide, says that the argument to the must statement is an XPath expression that must evaluate to “true”. (The User Guide also says “… or a non-empty node-set”, but that is actually redundant, as it is implicit in the XPath conversion of a node-set to a boolean).

XPath is of course neither a ConfD nor a YANG invention, but a W3C standard - the version used in YANG is formally defined in XML Path Language (XPath) per the YANG spec. If you search the net, you can probably find XPath tutorials and even answers to how to express specific conditions - and there are even books written on the subject.

So, this is not a valid XPath expression. It has two elements, current() and not(../ipv6), but no operator to combine them. It’s like saying 17 42 in an arithmetic expression - it has no meaning. For your purpose, it’s actually enough to use must "not(../ipv6)". This says that a constraint on the leaf that has this must expression (i.e. the ipv4 leaf) is that the node-set ../ipv6 is empty - i.e. there are no entries in the ipv6 list. (You also need the corresponding statement for the ipv6 leaf - and it may actually be more logical to have the must statements on the lists than on the leafs).

However, the very common “mutual exclusion” scenario has its own YANG statement - choice. Thus it would probably make more sense for your model to use this statement instead of ‘must’, i.e.

choice address-family {
   list ipv4 {
      ...
   }
   list ipv6 {
     ...
   }
}

Both methods ensure that it is impossible to create a configuration that has both ipv4 and ipv6 lists, but the detailed semantics are a bit different. E.g. in the ConfD CLI, the must method will allow the user to configure both, but the commit will fail in that case, while the choice method will have the effect that when you configure ipv4, the ipv6 list (if any) will be silently deleted.

Correction: with the must expression on the leaf, it should of course be not(../../ipv6), since the ipv6 list is not a sibling of the ipv4 leaf. (If the must expression is on the ipv4 list, not(../ipv6) is correct.) The .. in an XPath expression is analogous to the same in a *nix file system path - means “go up one level”.