cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1318
Views
0
Helpful
8
Replies

Invalid path-arg

Johan Nemitz
Cisco Employee
Cisco Employee

I am trying to understand why the following is not a proper path-arg statement:

          path "/npb:network/policy-definitions/endpoint/role[name=/npb:network/policy-definitions/endpoint/model[roles=current()/../../model/policy-name]/name]/name";

Reading the documentation (RFC-6020) it says:

path-arg = absolute-path / relative-path

absolute-path = 1*("/" (node-identifier *path-predicate))

path-predicate = "[" *WSP path-equality-expr *WSP "]"

path-equality-expr = node-identifier *WSP "=" *WSP path-key-expr

path-key-expr = current-function-invocation *WSP "/" *WSP rel-path-keyexpr

I think my issue is I don't know how to interpret what the docs are saying, but pressing ahead...

Here is the part of the model that I am trying to reference:

  container network {

    container policy-definitions {

      container endpoint {

        list model {

          key name;

          leaf name {

            type string;

          }

          leaf template {

            type string;

          }

          leaf-list roles {

            type leafref {

              path "../../role/name";

            }

          }

        }

        list role {

          key name;

          leaf name {

            type device-role;

          }

          leaf template {

            type string;

          }

        }

This is my model where this statement exists:

  grouping device-general-policy-grouping {

    list model {

      key "policy-name";

      leaf policy-name {

        type leafref {

          path "/npb:network/policiy-definitions/endpoint/model/name";

        }

      }

    }

    list role {

      key "policy-name";

      leaf policy-name {

        type leafref {

          path "/npb:network/policiy-definitions/endpoint/role[name=/npb:network/policiy-definitions/endpoint/model[roles=current()/../../model/policy-name]/name]/name";

        }

      }

    }

  }

Can you help me understand what is wrong with my statement?

1 Accepted Solution

Accepted Solutions

Actually, this might to what you want:

86     list role {

87       key "policy-name";

88       leaf policy-name {

89         type leafref {

90           path "deref(../../model/policy-name)/../roles";

91         }

92       }

93     }

That will leafref into the roles leaflist (vs. the role list), but you can then use that value in your template/code to get the correct role list entry.

View solution in original post

8 Replies 8

frjansso
Cisco Employee
Cisco Employee

Can you please explain what you're trying to accomplish?

The policy-name in the role list, what should that be and how does it relate to the model list's policy-name?

If you have some example data from the policy-definitions and the policy grouping, that might help me understand what you want.

Thanks in advance.

What I am attempting to do is reference data in the policy-definitions part of the model.  In the policy definitions I have a section where I provide the user the ability to define what template to associate with role and a model.  The idea is to allow the user to specify what templates to associate with either.  The restriction I am placing on the user is that the roles must be one of the roles defined in an ennumeration and the models must only use roles that have been configured by the user as part of the policy-definitions/role that they have configured.  All of this data is meant to be preconfigured before I configure my service.

In the service I want the user to tell me the model and role of the device.  They must first provide the model of the device, which must be one of the models that they previously configured in the policy-definitions part of the model.  Then they can select role(s) for the model, but this must be restricted to the models that they have configured in the policy definitions that support those roles.

In the end I am trying to restrict the roles that can be selected based on the model they have identified - all from the policy-definitions they have configured which dictates the relationship between the roles and models.

Here is the complete model as it stands now:

module network-policy-base {

  namespace "http://example.com/network-policy-base";

  prefix npb;

  import ietf-inet-types {

    prefix inet;

  }

  import tailf-common {

    prefix tailf;

  }

  import tailf-ncs {

    prefix ncs;

  }

  description

    "Base model for network topology based services that use policies.  The intent is to re-use the code that

    is a part of this package without changing it for any given network topology-based service.  Additional

    packages should augment this model only where outlined so that the included code can read the model and

    apply the policies (NSO templates) at the right place";

  revision 2017-11-08 {

    description

      "Initial revision.";

  }

  // Augment this type to add additional roles available for application to devices in the topology.  policy

  // definitions that include any of the enumerated valued here will be applied to devices that are of that role

  typedef device-role {

    type enumeration {

      enum "router";

      enum "switch";

    }

  }

  // Augment this type to add additional physical interface types

  typedef physical-interface-type {

    type enumeration {

      enum "GigabitEthernet";

      enum "TenGigabitEthernet";

    }

  }

  grouping network-actions {

    tailf:action load-topology-template {

      tailf:info "Load Network Topology Template";

      tailf:actionpoint loadservicetemplate-action;

      input {

        leaf network-name {

          tailf:info "Name of the new branch";

          type string;

        }

        leaf topology-template {

          type leafref {

            path "/npb:network/policiy-definitions/network/topology-templates/name";

          }

        }

      }

      output {

      }

    }

  }

  grouping network-general-policy-grouping {

  }

  grouping toplogy-general-policy-grouping {

  }

  grouping device-general-policy-grouping {

    list model {

      key "policy-name";

      leaf policy-name {

        type leafref {

          path "/npb:network/policy-definitions/endpoint/model/name";

        }

      }

    }

    list role {

      key "policy-name";

      leaf policy-name {

        type leafref {

          path "/npb:network/policy-definitions/endpoint/role[name=/npb:network/policy-definitions/endpoint/model[roles=current()/../../model/policy-name]/name]/name";

        }

      }

    }

    list hostname {

      key "policy-name";

      leaf policy-name {

        type leafref {

          path "/npb:network/policy-definitions/endpoint/hostname/name";

        }

      }

    }

  }

  grouping connection-general-policy-grouping {

  }

  grouping physical-device-grouping {

    list device {

      key topology-name;

      leaf topology-name {

        type string;

      }

      leaf uid {

        type string;

      }

      container policies {

        uses device-general-policy-grouping;

      }

    }

  }

  grouping endpoint-grouping {

    uses physical-device-grouping;

  }

  grouping connection-grouping {

  }

  container network {

    list network-service {

      description "Network service based on topology and the policies to apply to the topology";

      key name;

      leaf name {

        description "Name of this network service instance";

        tailf:info "Unique network id";

        tailf:cli-allow-range;

        type string;

      }

      uses ncs:service-data;

      ncs:servicepoint network-policy-base-servicepoint;

      uses npb:network-actions;

      uses npb:network-general-policy-grouping;

      container topology {

        description "The topology (physical, logical, etc.) and its associated policies";

        container policies {

          uses toplogy-general-policy-grouping;

        }

        uses endpoint-grouping;

        uses connection-grouping;

      }

    }

    container policy-definitions {

      // Augment this container with additional list elements that will define new policiy types

      // that can be incorporated in the npb:network-general-policy-grouping element or as data

      // for actions that are added to the topology-actions

      container network {

        list topology-templates {

          key name;

          leaf name {

            type string;

          }

          leaf model-template-file {

            type string;

          }

        }

      }

      container endpoint {

        list model {

          key name;

          leaf name {

            type string;

          }

          leaf template {

            type string;

          }

          leaf-list roles {

            type leafref {

              path "../../role/name";

            }

          }

        }

        list role {

          key name;

          leaf name {

            type device-role;

          }

          leaf template {

            type string;

          }

        }

        list hostname {

          key name;

          leaf name {

            type string;

          }

          leaf template {

            type string;

          }

        }

      }

      container connection {

        list loopback {

          key name;

          leaf name {

            type string;

          }

          container router {

            leaf template {

              type string;

            }

          }

        }

      }

    }

  }

}

What if you model the role list in the model list, then you could do as below.

In that case you could only specify roles that are present in the model/roles leaflist.

list model {

  key "policy-name";

  leaf policy-name {

    type leafref {

      path "/npb:network/policy-definitions/endpoint/model/name";

    }

  }

  list role {

    key "role-name";

    leaf role-name {

      type leafref {

        path "deref(../policy-name)/../roles";

      }

    }

  }

}

Yes that would work.  But further into the rat hole we would go going that route and why I don't want to do that.

I am attempting to create a generic model pattern so that the the service code (if the model is built to the pattern) does not need to change.  Without going into that hole, can what I am trying to do be done given the constraints of the policy-definition part of the model that I have defined?

You probably have to go with a must-expression.

The must expressions are XPATH 1.0, leafrefs don't have full XPATH support.

Thanks Fredrick. I will go that route.

Johan Nemitz | Cisco | Solutions Architect | 917 544 1576

Actually, this might to what you want:

86     list role {

87       key "policy-name";

88       leaf policy-name {

89         type leafref {

90           path "deref(../../model/policy-name)/../roles";

91         }

92       }

93     }

That will leafref into the roles leaflist (vs. the role list), but you can then use that value in your template/code to get the correct role list entry.

Bingo, that was it!  Thanks Fredrick.