Scripting in presets
User defined scripts can now be used in presets allowing dynamic values and complex provisioning workflow.
This commit is contained in:
1 parent
ba33fc0fe0
commit
48d9adbaff
7 files changed
+441
-117
No files matched your search
@@ -0,0 +1,121 @@
|
||||
###
|
||||
# Copyright 2013-2016 Zaid Abdulla
|
||||
#
|
||||
# GenieACS is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# GenieACS is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with GenieACS. If not, see <http://www.gnu.org/licenses/>.
|
||||
###
|
||||
|
||||
vm = require 'vm'
|
||||
|
||||
common = require './common'
|
||||
device = require './device'
|
||||
|
||||
|
||||
# Used for throwing to exit user script
|
||||
class Declare;
|
||||
|
||||
|
||||
sandbox = {
|
||||
deviceData: null
|
||||
args: null
|
||||
revision: null
|
||||
maxRevision: null
|
||||
declarations: null
|
||||
context: vm.createContext()
|
||||
}
|
||||
|
||||
sandbox.context.declare = (decs) ->
|
||||
if ++ sandbox.revision > sandbox.maxRevision + 1
|
||||
throw new Error('Declare function should not be called from within a try/catch block')
|
||||
|
||||
sandbox.declarations = decs
|
||||
|
||||
if sandbox.revision == sandbox.maxRevision + 1
|
||||
throw new Declare()
|
||||
|
||||
res = {}
|
||||
for k, v of decs
|
||||
path = common.parsePath(k)
|
||||
all = device.getAll(sandbox.deviceData, path, sandbox.revision)
|
||||
res[k] = {}
|
||||
for a in all
|
||||
r = {}
|
||||
r.exist = a[1] if v.exist?
|
||||
r.type = a.slice(3, 5) if v.type?
|
||||
r.writable = a.slice(5, 7) if v.writable?
|
||||
r.value = a.slice(7, 9) if v.value? and a[8]?
|
||||
|
||||
p = a[0].join('.')
|
||||
if p == k
|
||||
res[k] = r
|
||||
else
|
||||
res[k][p] = r
|
||||
|
||||
return res
|
||||
|
||||
Object.freeze(sandbox.context)
|
||||
|
||||
|
||||
# Convert from friendly declaration format
|
||||
toIndexDeclaration = (keyDeclaraiton) ->
|
||||
indexDeclaraiton = []
|
||||
|
||||
if keyDeclaraiton['exist']?
|
||||
if Array.isArray(keyDeclaraiton['exist'])
|
||||
indexDeclaraiton[0] = keyDeclaraiton['exist'][0]
|
||||
else
|
||||
indexDeclaraiton[0] = keyDeclaraiton['exist']
|
||||
|
||||
if keyDeclaraiton['type']?
|
||||
if Array.isArray(keyDeclaraiton['type'])
|
||||
indexDeclaraiton[2] = keyDeclaraiton['type'][0]
|
||||
else
|
||||
indexDeclaraiton[2] = keyDeclaraiton['type']
|
||||
|
||||
if keyDeclaraiton['writable']?
|
||||
if Array.isArray(keyDeclaraiton['writable'])
|
||||
indexDeclaraiton[4] = keyDeclaraiton['writable'][0]
|
||||
else
|
||||
indexDeclaraiton[4] = keyDeclaraiton['writable']
|
||||
|
||||
if keyDeclaraiton['value']?
|
||||
if Array.isArray(keyDeclaraiton['value'])
|
||||
indexDeclaraiton[6] = keyDeclaraiton['value'][0]
|
||||
indexDeclaraiton[7] = keyDeclaraiton['value'][1]
|
||||
else
|
||||
indexDeclaraiton[6] = keyDeclaraiton['value']
|
||||
|
||||
return indexDeclaraiton
|
||||
|
||||
|
||||
run = (script, args, deviceData, revision, declarations) ->
|
||||
sandbox.deviceData = deviceData
|
||||
sandbox.args = args
|
||||
sandbox.maxRevision = revision
|
||||
sandbox.revision = 0
|
||||
sandbox.declarations = []
|
||||
|
||||
try
|
||||
script.runInNewContext(sandbox.context)
|
||||
catch err
|
||||
throw err if err not instanceof Declare
|
||||
for k, v of sandbox.declarations
|
||||
declarations.push([common.parsePath(k)].concat(toIndexDeclaration(v)))
|
||||
return true
|
||||
|
||||
for k, v of sandbox.declarations
|
||||
declarations.push([common.parsePath(k)].concat(toIndexDeclaration(v)))
|
||||
return false
|
||||
|
||||
|
||||
exports.run = run
|
||||
Reference in new issue
Block a user