0.2.1 • Published 9 years ago

asterisk-config v0.2.1

Weekly downloads
3
License
MIT
Repository
-
Last release
9 years ago

asterisk-config GitHub release GitHub tag

NPM

An Asterisk config file parser that processes templates, includes, and section additions. Can be used via AMI or on local files.

Contents

npm install asterisk-config

Dependencies

  • For AMI retrieval * asterisk-manager
  • For local file retrieval async glob * line-by-line
var am = require('asterisk-manager');
var ac = require('asterisk-config');
var util = require('util');

/* Establish an AMI connection */
var ami = new am('5038','localhost','astadmin','yourpassword', false);

/* Define a callback */
var cb = function(err, obj) {
  if (err) {
    console.log(err);
  } else if (obj) {
    console.log(obj);
  }
  ami.disconnect();
  process.exit(0);
};

/* Call remotely via AMI */
ac.getConfigAMI(ami, 'test.conf', cb,
  { varsAsArray:false,
    duphandlers: { 'allow': ',', 'deny': ',', 'match': 'array'}});

/* OR */

/* Call directly on local file */
ac.getConfigLocal('/etc/asterisk/test.conf', cb,
  { varsAsArray:false, 
    duphandlers: { 'allow': ',', 'deny': ',', 'match': 'array' }});
  • NB: eumerable/non-enumerable: Properties marked non-enumerable are considered internal properties and are not normally traversable. You can retrieve them by specific reference however. All other properties are representations of the actual config file contents and are therefore traversable with for..in. This also applies to JSON.stringify() and util.inspect() when called with their defaults.

Category(name [ [ , sourceFile , fileIndex ] , varsAsArray ])

A Category object is created for every [category] entry found in the config file.

Constructor (not normally called externally)

  • name - The name of this category.
  • sourceFile - The file this category was defined in.
  • fileIndex - This category's order in the file.
  • varsAsArray - Determines whether the vars property is an array or object.

Properties

  • name - The category name. (non-enumerable)
  • sourceFile - The file this cntext was defined in. (non-enumerable)
  • fileIndex - This category's order in the file. (non-enumerable)
  • resolvedFileIndex - Since files can include other files, this is the fully resolved order related to the outermost file. (non-enumerable)
  • isTemplate - Set to 1 if this category is a template.
  • templates - An array of category names this category inherits from.
  • vars - If varsAsArray is true, then this is an array of lines for the category in the order they were defined in the config file. Otherwise this is an object containing the variables for the category. See the duphandlers discussion below.

Methods

  • .serialize() - The resulting string will contain a representation of the category that can be used in a config file.
  • .resolve(configFile) - If this category was created with the suppressInheritance flag set, meaning its templates were not applied, calling resolve with a ConfigFile object will fully resolve the category using the templates found in that object.
  • .applyVar({name: value} [ , { duphandlers } , prepend ]) - Applies the name/value pair to the category using the supplied duphandlers. If prepend is set to true, the value will be prepended to the existing values, otherwise it will be appended.

ConfigFile(fileName , params )

Represents the contents of a local config file and its includes.

Constructor

  • fileName - The root file to parse.
  • params - Optional parameter object.
    • varsAsArray: If false (the default), each categories' lines will be parsed into a name/value pair object. This presents problems when parsing files like extensions.conf where all of the variable names are exten or include, etc.. So, if this option is set to true, each categories' contents are returned as an array of lines without further parsing into name/value pairs.
    • duphandlers: When varsAsArray is true, there's no issue with duplicate variable names because they're stored as an array. When the file is parsed into an object however, there can't be duplicate attributes in the resulting object. The default behavior is to overwrite earlier occurrences with the latest but some variables can be legally duplicated like the codec allow and deny variables. For these cases, you can choose how duplicates are concatenated by providing an object with attributes in the form of variable_name: separator where variable_name is the name of the variable to handle and separator is the string to use to delimit the concatenated string. The special separator array will cause the individual values to be placed into an array instead of a concatenated string. In this case, the result will be an array even if there's only 1 element.
    • suppressInheritance: If set to true, properties from templates will not be interited. The templates array will still be populated if you wish to do your own inheritance processing. You can also use Category.resolve().

Properties

  • fileName - The root file this object represents. (non-enumerable)
  • params - The parameters object used in the constructor. (non-enumerable)
  • Category... - The rest of this object's enumerable properties are Category objects keyed by their names.

Methods

  • read(callback(error, configFile)) - Does the actual parsing and calls the callback with an error or this ConfigFile object.

ConfigAMI(ami, fileName , params )

Represents the contents of a remote config file and its includes. The file is retrieved using the AMI GetConfig command.

Constructor

  • ami - An AMI object created with asterisk-manager.
  • fileName - The root file to parse.
  • params - Optional parameter object.
    • varsAsArray: See above.
    • duphandlers: See above.
    • suppressInheritance: Not available with ConfigAMI because Asterisk does the resolution automatically.
    • category: If specified, limits the result to only a single category.
    • filter: Also limits the results. For more information, run manager show command GetConfig in the Asterisk CLI. The default filter is TEMPLATES=include

Properties

  • fileName - The root file this object represents. (non-enumerable)
  • params - The parameters object used in the constructor. (non-enumerable)
  • Category... - The rest of this object's enumerable properties are Category objects keyed by their names.

Methods

  • read(callback(error, configAMI)) - Does the actual parsing and calls the callback with an error or this ConfigAMI object.

asterisk-config

Methods

  • getConfigLocal(fileName, callback , parameters ) - A wrapper around new ConfigFile(...) and read(...).
  • getConfigAMI(ami, fileName, callback , parameters ) - A wrapper around new ConfigAMI(...) and read(...).

Simple scenario

reading:

[template1](!)
variable1 = value1
variable2 = value2
allow = ulaw

[mything](template1)
variable2 = my_value2
allow = gsm

using:

ac.getConfigLocal('test.conf', callback,
  { varsAsArray:false,
    duphandlers: {allow: ',', deny: ',', match: 'array'}});

should pass the following ConfigFile object with 2 Category objects to the callback:

{ template1: 
   { isTemplate: 1,
     templates: [],
     vars: 
      { variable1: 'value1',
        variable2: 'value2',
        allow: 'ulaw' } },
  mything: 
   { isTemplate: 0,
     templates: [ 'template1' ],
     vars: 
      { variable1: 'value1',		// Inherited from template1
        variable2: 'my_value2',		// Overridden from template1
        allow: 'ulaw,gsm' } } }		// Concatenated values

More complex scenario

reading:

[template1](!)
variable1 = value1 from template1
variable2 = value2 from template1
allow = ulaw
match = 192.168.0.1

[template2](!,template1)
variable1 = value1 from template2
variable3 = value3 from template2
allow = gsm
match = 192.168.0.2

#include test2.conf

[mything2](template2)
variable2 = my_value2
allow = gsm
match = 192.168.0.88

and test2.conf:

[mything1](template1)
variable2 = my_value2
allow = g729
match = 192.168.0.99

using:

var params = { 
  varsAsArray:false, 
  duphandlers: { 'allow': ',', 'deny': ',', 'match': 'array' }}; 

var configFile = new ConfigFile('test.conf', params);
configFile.parse(callback);
		

should pass the following ConfigFile object with 4 Category objects to the callback:

{ template1: 
   { istemplate: 1,
     templates: [],
     vars: 
      { variable1: 'value1 from template1',
        variable2: 'value2 from template1',
        allow: 'ulaw',
        match: [ '192.168.0.1' ] } },
  template2: 
   { istemplate: 1,
     templates: [ 'template1' ],
     vars: 
      { variable1: 'value1 from template2',
        variable2: 'value2 from template1',		 // Inherited from template1
        allow: 'ulaw,gsm',						 // Concatenated from local and template1
        match: 
         [ '192.168.0.1',						 // Inherited from template1
           '192.168.0.2' ],						 // Specified locally
        variable3: 'value3 from template2' } },	 // Specified locally
  mything1: 
   { istemplate: 0,
     templates: [ 'template1' ],
     vars: 
      { variable1: 'value1 from template1',		 // Inherited from template1
        variable2: 'my_value2',					 // Overridden from template1
        allow: 'ulaw,g729',						 // Concatenated from local and template1
        match: 
         [ '192.168.0.1',						 // Inherited from template1
           '192.168.0.99' ] } },				 // Specified locally
  mything2: 
   { istemplate: 0,
     templates: [ 'template2' ],
     vars: 
      { variable1: 'value1 from template2',				
        variable2: 'my_value2',					 // Specified locally
        allow: 'ulaw,gsm,g722',					 // Concatenated from local, template1, template2
        match: 
         [ '192.168.0.1',						 // Inherited from template1
           '192.168.0.2',						 // Inherited from template2
           '192.168.0.88' ],					 // Specified locally
        variable3: 'value3 from template2' } } } // Inherited from template2

Extensions.conf scenario

reading:

[default]
exten = _1[01]XX,1,Dial(SIP/${EXTEN})
exten = _1[23]XX,1,Dial(PJSIP/${EXTEN})

[my_context]
include = default
exten = _1[78]XX,1,Dial(Local/${EXTEN})

using:

ac.getConfigLocal('extensions.conf', cb, {varsAsArray:true});

should produce:

{ default: 
   { istemplate: 0,
     templates: [],
     vars: 											//  Note that vars is an array
      [ 'exten=_1[01]XX,1,Dial(SIP/${EXTEN})',
        'exten=_1[23]XX,1,Dial(PJSIP/${EXTEN})' ] },
  my_context: 
   { istemplate: 0,
     templates: [ [length]: 0 ],
     vars: 
      [ 'include=default',
        'exten=_1[78]XX,1,Dial(Local/${EXTEN})' ] } }

Copyright (C) 2015 Fairview 5 Engineering, LLC developers@fairview5.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.