From 6e029cd625261b77c94cdf3c38139a7d0fc381c4 Mon Sep 17 00:00:00 2001 From: Ted Trask Date: Mon, 10 Oct 2011 15:24:51 +0000 Subject: Added viewclassparams, getfile, and putfile actions plus determine_class.lua script and provisioning_requests table. viewclassparams shows the parameters and default values for a class getfile is used to get the config file for a known device and a default config file for unconfigured devices putfile is unimplemented, but will be used for parsing files uploaded to the server determine_class.lua determines which device class best matches an unconfigured device (by agent) provisioning_requests table will track the last request (ip, agent, and timestamp) for each device --- provisioning-model.lua | 124 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 4 deletions(-) (limited to 'provisioning-model.lua') diff --git a/provisioning-model.lua b/provisioning-model.lua index c68f513..292082c 100644 --- a/provisioning-model.lua +++ b/provisioning-model.lua @@ -19,6 +19,8 @@ local baseurl = "/etc/provisioning/templates/" local updatedevicescriptfile = "/etc/provisioning/update_device.lua" local updatedeviceparamsscriptfile = "/etc/provisioning/update_device_params.lua" local deletedevicescriptfile = "/etc/provisioning/delete_device.lua" +local determineclassscriptfile = "/etc/provisioning/determine_class.lua" +local scriptfiles = {updatedevicescriptfile, updatedeviceparamsscriptfile, deletedevicescriptfile, determineclassscriptfile} local env local con @@ -261,6 +263,7 @@ validateparamcoded = function(p, top) end local function callscript(script, ...) + local result local env = {} setmetatable (env, {__index = _G}) -- loadfile loads into the global environment @@ -269,13 +272,14 @@ local function callscript(script, ...) local f = loadfile(script) if f then local res, err = pcall(function(...) - f(functions, ...) + result = f(functions, ...) end, ...) if not res and err then assert(res, "Update Successful\nException in post update script\n"..err) end end setfenv (0, _G) + return result end local function validateluacode(code) @@ -1426,6 +1430,62 @@ get_device_params = function(device_id, editable) return output end +get_class_params = function(class_id) + local retval = {} + retval.class_id = cfe({value=class_id or "", label="Class ID", readonly=true, seq=0}) + local errtxt = "Cannot find class" + if class_id and class_id ~= "" then + local res, err = pcall(function() + local connected = databaseconnect() + -- First, just check to see if class_id exists + local sql = "SELECT * FROM provisioning_classes WHERE class_id='"..escape(class_id).."'" + local tmp = getselectresponse(sql) + if tmp and #tmp > 0 then + errtxt = nil + -- Next, get all of the param groups + sql = "SELECT * FROM provisioning_groups" + local tmp = getselectresponse(sql) + -- Loop through the groups and put them into the result + for i,g in ipairs(tmp) do + retval[g.name] = g + retval[g.name].label = g.name + retval[g.name].type="group" + end + -- Then, get all of the parameters for this class + sql = "SELECT g.name AS group, g.label AS grouplabel, p.param_id, p.name, p.type, p.label, p.descr, p.seq, p.regexp, p.validate, CASE WHEN g2p.value IS NOT NULL THEN g2p.value ELSE p.value END AS value ".. + "FROM (provisioning_classes t JOIN classes_to_param_groups t2g USING (class_id) JOIN provisioning_groups g USING(group_id) ".. + "JOIN param_groups_to_params g2p USING(group_id) JOIN provisioning_params p USING(param_id)) ".. + "WHERE t.class_id='"..escape(class_id).."'" + local tmp = getselectresponse(sql) + -- Loop through the params to figure out options and put them into the groups + for i,p in ipairs(tmp) do + p.type = "text" + p.readonly = true + -- Groups + if not retval[p.group].value then + retval[p.group].value = {} + end + retval[p.group].label = p.grouplabel + local value = retval[p.group].value + value[p.name] = p + end + -- Finally, loop through the result and remove empty groups + for name,val in pairs(retval) do + if not val.value then + retval[name] = nil + end + end + end + if connected then databasedisconnect() end + end) + if not res and err then + errtxt = err + end + end + local output = cfe({ type="group", value=retval, label="Provisioning Class Parameters", errtxt=errtxt }) + return output +end + set_editable_device_params = function(params) return set_device_params(params, true) end @@ -1719,16 +1779,16 @@ set_param_options = function(options) end function get_filedetails(filename) - return modelfunctions.getfiledetails(filename, {updatedevicescriptfile, updatedeviceparamsscriptfile, deletedevicescriptfile}) + return modelfunctions.getfiledetails(filename, scriptfiles) end function update_filedetails(filedetails) - return modelfunctions.setfiledetails(filedetails, {updatedevicescriptfile, updatedeviceparamsscriptfile, deletedevicescriptfile}, validatefiledetails) + return modelfunctions.setfiledetails(filedetails, scriptfiles) end function list_files() local retval = {} - for i,file in ipairs({updatedevicescriptfile, updatedeviceparamsscriptfile, deletedevicescriptfile}) do + for i,file in ipairs(scriptfiles) do local details = fs.stat(file) or {} details.filename = file table.insert(retval, details) @@ -1806,3 +1866,59 @@ function dump_database(db) end return db end + +function get_file(mac, ip, agent) + local result = cfe() + + -- Error if there's no mac + if not mac or mac == "" then + result.errtxt = "No MAC Address" + return result + end + + local res, err = pcall(function() + local connected = databaseconnect() + + -- Add the device to the table of requests + local sql = "SELECT * FROM provisioning_requests WHERE mac='"..escape(string.upper(mac)).."'" + local requests = getselectresponse(sql) + if requests and #requests > 0 then + sql = "UPDATE provisioning_requests SET ip='"..escape(ip).."', agent='"..escape(agent).."', date=now() WHERE mac='"..escape(string.upper(mac)).."'" + else + sql = "INSERT INTO provisioning_requests VALUES('"..escape(string.upper(mac)).."', '"..escape(ip).."', '"..escape(agent).."', now())" + end + runsqlcommand(sql) + + -- Now, let's see if this device exists + result = get_search_options() + result.value.id.value = "device.mac" + result.value.value.value = string.upper(mac) + result = fetch_device_values(result) + + -- If can't find the device, return a file with default settings + if #result.value.result.value == 0 then + -- Determine which class to use (need a class that specifies a template) + local c = list_classes() + local class = callscript(determineclassscriptfile, agent, c) + + if class then + result.errtxt = nil + result.value.values = get_class_params(class) + result.value.values.seq = 5 + else + result.errtxt = "Unknown device" + end + end + + if connected then databasedisconnect() end + end) + if not res and err then + result.errtxt = err + end + + return result +end + +function put_file(file, root, data, ip, agent) + return cfe({errtxt="Not implemented"}) +end -- cgit v1.2.3