corenova / yang-js

YANG parser and composer
Apache License 2.0
56 stars 18 forks source link

enhance ability to provide custom extensions/typedefs during resolve #11

Closed sekur closed 5 years ago

sekur commented 8 years ago

Current facility expects extensions/typedefs to be internally resolvable while parsing a YANG schema that uses those extensions.

When a YANG schema defines new custom extensions, it requires preparing such extensions at the Registry or Source level which is currently considered private.

Need to come up with a better way of passing in these implementation Extension instance(s) during resolve, so that it becomes easier for developers to create custom extensions.

sekur commented 7 years ago

Enabled extension attachment via .bind() in 731ff72

shlomiassaf commented 7 years ago

@saintkepha I'm unable to import and parse.

I get this error: encountered unknown extension 'tailf:my-extension'

I'v imported the file declaring the extension (with the same prefix)

I believe it's related to this issue, can you provide an example how to use the .bind() method to attach extensions?

Thanks!

sekur commented 7 years ago

Hi @shlomiassaf - I don't think the issue you're encountering is related to the ability to provide custom extension handling capability described in this ticket.

Take a look at the test case for using imported custom extension definition: https://github.com/corenova/yang-js/blob/master/test/extension/extension.coffee#L36

The error of encountered unknown extension usually means that it was unable to resolve the extension my-extension statement within the imported module prefix with tailf. I would check to make sure that the module that contains the extension my-extension statement is being properly imported by the module that is trying to use it.

The .bind() method as enhanced by this ticket enables custom compile logic to be used for implementing the extension and is not affected during parse operation itself.

Also, for more extensive diagnostics, you can always run with DEBUG=yang:* as the environmental variable.

shlomiassaf commented 7 years ago

@saintkepha Thanks for the quick response, the imports are there, here's a simplified exapmle:

FILE: module-ext-demo.yang

submodule module-ext-demo {

  belongs-to module-demo {
    prefix mdemo;
  }

  extension arg-type {
    description
      "Specifies the type of the argument.";
  }
}

FILE: module-demo.yang

module module-demo {
  prefix mdemo;

  include module-ext-demo {
  }

  extension info {
    argument text {
      mdemo:arg-type {
        type string;
      }
    }

    description "info";
  }

}

FILE: model-demo.yang

module model-demo {
 namespace "http://tail-f.com/ned/cisco-nx";
  prefix nx;

  import module-demo {
    prefix mdemo;
  }

  typedef test {
    type union {
      type uint32 {
        mdemo:info "SomeInfo";
      }
      type enumeration {
        enum auto {
          mdemo:info "More Info"";
        }
      }
    }
  }
}

I run this code:

  Yang.import('./module-demo.yang');
  Yang.parse(fs.readFileSync('./model-demo.yang');

It fails on the 1st line:

ExpressionError: [module(module-demo)/extension(info)/argument(text)/mdemo:arg-type] encountered unknown extension 'mdemo:arg-type'
    at Yang.Element.error (/Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/vts-client/node_modules/yang-js/lib/element.js:64:13)
    at Yang.Expression.error (/Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/vts-client/node_modules/yang-js/lib/expression.js:191:40)
    at Yang.error (/Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/vts-client/node_modules/yang-js/lib/yang.js:313:35)
    at Yang.<anonymous> (/Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/vts-client/node_modules/yang-js/lib/yang.js:277:24)
    at EventEmitter.g (events.js:291:16)
    at emitOne (events.js:96:13)
    at EventEmitter.emit (events.js:188:7)
    at Yang.emit (/Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/vts-client/node_modules/yang-js/lib/yang.js:319:33)
    at Yang.Expression.compile (/Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/vts-client/node_modules/yang-js/lib/expression.js:67:12)
    at /Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/vts-client/node_modules/yang-js/lib/expression.js:80:18

DEBUG log:

  yang:schema [match] with extension mdemo:arg-type +0ms
  yang:schema [match] check if current module's prefix +3ms
  yang:schema [match] checking if submodule's parent +1ms
  yang:schema [match] check if one of current module's imports +0ms
  yang:expression [module(module-demo)] compile enter... (undefined) +3ms
  yang:element [module(module-demo)] found 1 new extension(s) +1ms
  yang:expression [module(module-demo)/prefix] compile enter... (undefined) +0ms
  yang:expression [module(module-demo)/prefix] compile: ok +0ms
  yang:expression [module(module-demo)/include(module-ext-demo)] compile enter... (undefined) +0ms
  yang:schema [resolve] module-ext-demo in /Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/vts-client/yang-demo/package.json +1ms
  yang:schema [resolve] module-ext-demo in /Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/vts-client/package.json +0ms
  yang:schema [resolve] module-ext-demo in /Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/package.json +1ms
  yang:schema [resolve] module-ext-demo in /Users/shlomiassaf/Desktop/Cisco/cisco/package.json +0ms
  yang:schema [resolve] module-ext-demo in /Users/shlomiassaf/Desktop/Cisco/package.json +0ms
  yang:schema [resolve] module-ext-demo in /Users/shlomiassaf/Desktop/package.json +0ms
  yang:schema [resolve] module-ext-demo in /Users/shlomiassaf/package.json +0ms
  yang:schema [resolve] module-ext-demo in /Users/package.json +0ms
  yang:schema [resolve] checking if /Users/shlomiassaf/Desktop/Cisco/cisco/github-vts/vts-client/yang-demo/module-ext-demo.yang exists +0ms
  yang:schema retrying import(./module-demo.yang) +3ms
  yang:schema [match] with extension mdemo:arg-type +2ms
  yang:schema [match] check if current module's prefix +0ms
  yang:schema [match] checking if submodule's parent +0ms
  yang:schema [match] check if one of current module's imports +0ms
  yang:expression [module(module-demo)] compile enter... (undefined) +0ms
  yang:element [module(module-demo)] found 1 new extension(s) +1ms
  yang:expression [module(module-demo)/prefix] compile enter... (undefined) +0ms
  yang:expression [module(module-demo)/prefix] compile: ok +0ms
  yang:expression [module(module-demo)/include(module-ext-demo)] compile enter... (undefined) +0ms
  yang:expression [submodule(module-ext-demo)] compile enter... (undefined) +0ms
  yang:expression [submodule(module-ext-demo)/belongs-to(module-demo)] compile enter... (undefined) +0ms
  yang:expression [submodule(module-ext-demo)/belongs-to(module-demo)/prefix] compile enter... (undefined) +1ms
  yang:expression [submodule(module-ext-demo)/belongs-to(module-demo)/prefix] compile: ok +0ms
  yang:expression [submodule(module-ext-demo)/belongs-to(module-demo)] compile: ok +0ms
  yang:expression [submodule(module-ext-demo)/extension(arg-type)] compile enter... (undefined) +0ms
  yang:expression [submodule(module-ext-demo)/extension(arg-type)/description] compile enter... (undefined) +1ms
  yang:expression [submodule(module-ext-demo)/extension(arg-type)/description] compile: ok +0ms
  yang:expression [module(module-demo)/extension(info)/argument(text)] compile enter... (undefined) +0ms
  yang:expression [module(module-demo)/extension(info)/argument(text)/mdemo:arg-type] compile enter... (undefined) +0ms
  yang:schema [match] with extension mdemo:arg-type +0ms
  yang:schema [match] check if current module's prefix +0ms
  yang:schema [match] with extension mdemo:arg-type +1ms
  yang:schema [match] check if current module's prefix +0ms
  yang:schema [match] with extension mdemo:arg-type +0ms
  yang:schema [match] check if current module's prefix +0ms
  yang:schema [match] with extension mdemo:arg-type +0ms
  yang:schema [match] check if current module's prefix +0ms
sekur commented 7 years ago

@shlomiassaf - thanks for the details, it really helps.

I think the issue may be with how yang-js is handling extensions from an included submodule. Looks like a bug. Let me try to reproduce and will let you know what I find.

Thanks!

shlomiassaf commented 7 years ago

Thank you for the hard work!

sekur commented 7 years ago

@shlomiassaf - thanks for flagging this issue!

So after digging into it, I found that it was a rather nasty state bleed-over issue with how I was treating the argument sub-statement. The fix itself was fairly minor but I've committed the change along with something else I was working on so it may be less obvious based on the changeset.

You can try the fix now from the master branch. I'll probably publish a new 'yang-js' package later today so you can try that as well.

shlomiassaf commented 7 years ago

Thanks!