diff options
-rw-r--r-- | provisioning-controller.lua | 12 | ||||
-rw-r--r-- | provisioning-listclasses-html.lsp | 3 | ||||
-rw-r--r-- | provisioning-model.lua | 124 | ||||
-rwxr-xr-x | provisioning-scripts.lua | 5 | ||||
-rw-r--r-- | provisioning-templated.lsp (renamed from provisioning-getdevicevalues-templated.lsp) | 0 | ||||
-rw-r--r-- | provisioning-viewclassparams-html.lsp | 48 | ||||
-rw-r--r-- | provisioning.roles | 2 |
7 files changed, 189 insertions, 5 deletions
diff --git a/provisioning-controller.lua b/provisioning-controller.lua index d9b4cbc..a4a49df 100644 --- a/provisioning-controller.lua +++ b/provisioning-controller.lua @@ -52,6 +52,10 @@ deleteclass = function( self ) return self:redirect_to_referrer(self.model.delete_class(self.clientdata.class_id)) end +viewclassparams = function( self ) + return self.model.get_class_params(self.clientdata.class_id) +end + listgroups = function( self ) return self.model.list_groups() end @@ -140,3 +144,11 @@ end dumpdatabase = function( self ) return controllerfunctions.handle_form(self, self.model.get_database, self.model.dump_database, self.clientdata, "Submit", "Dump Provisioning Database") end + +getfile = function( self ) + return self.model.get_file(self.clientdata.mac, self.clientdata.ip, self.clientdata.agent) +end + +putfile = function( self ) + return self.model.put_file(self.clientdata.file, self.clientdata.root, self.clientdata.data, self.clientdata.ip, self.clientdata.agent) +end diff --git a/provisioning-listclasses-html.lsp b/provisioning-listclasses-html.lsp index d5550c7..4d55604 100644 --- a/provisioning-listclasses-html.lsp +++ b/provisioning-listclasses-html.lsp @@ -33,6 +33,9 @@ require("viewfunctions") <% if viewlibrary.check_permission("editclass") then %> <%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/editclass?class_id="..v.class_id.."&redir="..page_info.orig_action, label="Edit "} %> <% end %> + <% if viewlibrary.check_permission("viewclassparams") then %> + <%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/viewclassparams?class_id="..v.class_id.."&redir="..page_info.orig_action, label="Params "} %> + <% end %> </TD> <TD><%= html.html_escape(v.group) %></TD> <TD><%= html.html_escape(v.label) %></TD> 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 diff --git a/provisioning-scripts.lua b/provisioning-scripts.lua index 3f81d65..958f301 100755 --- a/provisioning-scripts.lua +++ b/provisioning-scripts.lua @@ -588,3 +588,8 @@ provisioning_options = { "INSERT INTO provisioning_options VALUES((SELECT param_id FROM provisioning_params WHERE name='template'), 'Polycom', '/etc/provisioning/templates/polycom-template.lua', '1')", "INSERT INTO provisioning_options VALUES((SELECT param_id FROM provisioning_params WHERE name='template'), 'Linksys ATA', '/etc/provisioning/templates/linksysata-template.lua', '2')", } + +-- List of getfile requests +provisioning_requests = { + "CREATE TABLE provisioning_requests (mac VARCHAR(12) unique, ip VARCHAR(15), agent VARCHAR(255), date timestamp)", +} diff --git a/provisioning-getdevicevalues-templated.lsp b/provisioning-templated.lsp index 0cc624a..0cc624a 100644 --- a/provisioning-getdevicevalues-templated.lsp +++ b/provisioning-templated.lsp diff --git a/provisioning-viewclassparams-html.lsp b/provisioning-viewclassparams-html.lsp new file mode 100644 index 0000000..e07a30f --- /dev/null +++ b/provisioning-viewclassparams-html.lsp @@ -0,0 +1,48 @@ +<% local data, viewlibrary, page_info = ... +require("viewfunctions") +%> + +<% +function displayitemcustom(myitem, header_level) + if not myitem then return end + if myitem.type == "group" then + header_level = header_level or 2 + io.write("<H"..tostring(header_level)..">"..html.html_escape(myitem.label).."</H"..tostring(header_level)..">") + if myitem.descr then io.write('<P CLASS="descr">' .. string.gsub(html.html_escape(myitem.descr), "\n", "<BR>") .. "</P>\n") end + if myitem.errtxt then io.write('<P CLASS="error">' .. string.gsub(html.html_escape(myitem.errtxt), "\n", "<BR>") .. "</P>\n") end + local seqorder = {} + local order = {} + for name,item in pairs(myitem.value) do + if tonumber(item.seq) then + seqorder[#seqorder+1] = {seq=tonumber(item.seq), name=name} + else + order[#order+1] = name + end + end + table.sort(seqorder, function(a,b) if a.seq ~= b.seq then return a.seq > b.seq else return a.name > b.name end end) + table.sort(order) + for i,val in ipairs(seqorder) do + table.insert(order, 1, val.name) + end + for x,name in ipairs(order) do + if myitem.value[name] then + displayitemcustom(myitem.value[name], tonumber(header_level)+1) + end + end + elseif myitem.type ~= "hidden" then + io.write("<DT") + if myitem.errtxt then + myitem.class = "error" + io.write(' class="error"') + end + io.write(">" .. html.html_escape(myitem.label) .. "</DT>\n") + io.write("<DD>") + io.write(string.gsub(html.html_escape(tostring(myitem.value)), "\n", "<BR>") .. "\n") + if myitem.descr then io.write("<P CLASS='descr'>" .. string.gsub(html.html_escape(myitem.descr), "\n", "<BR>") .. "</P>\n") end + if myitem.errtxt then io.write("<P CLASS='error'>" .. string.gsub(html.html_escape(myitem.errtxt), "\n", "<BR>") .. "</P>\n") end + io.write("</DD>\n") + end +end + +displayitemcustom(data, 1) +%> diff --git a/provisioning.roles b/provisioning.roles index 0d95822..e543db3 100644 --- a/provisioning.roles +++ b/provisioning.roles @@ -1,3 +1,3 @@ EDITOR=provisioning:searchdevices,provisioning:listdevices,provisioning:editdevice,provisioning:createdevice,provisioning:duplicatedevice,provisioning:deletedevice,provisioning:searchbyextension,provisioning:searchbymac,provisioning:editdeviceparams EXPERT=provisioning:listtemplates,provisioning:edittemplate,provisioning:createtemplate,provisioning:deletetemplate,provisioning:listclassgroups,provisioning:editclassgroup,provisioning:createclassgroup,provisioning:deleteclassgroup,provisioning:listclasses,provisioning:editclass,provisioning:createclass,provisioning:deleteclass,provisioning:listgroups,provisioning:editgroup,provisioning:creategroup,provisioning:deletegroup,provisioning:listparams,provisioning:editparam,provisioning:createparam,provisioning:deleteparam,provisioning:overridedeviceparams,provisioning:editoptions,provisioning:listfiles,provisioning:editfile,provisioning:getdevicevalues -ADMIN=provisioning:listtemplates,provisioning:edittemplate,provisioning:createtemplate,provisioning:deletetemplate,provisioning:searchdevices,provisioning:listdevices,provisioning:editdevice,provisioning:createdevice,provisioning:duplicatedevice,provisioning:deletedevice,provisioning:listclassgroups,provisioning:editclassgroup,provisioning:createclassgroup,provisioning:deleteclassgroup,provisioning:listclasses,provisioning:editclass,provisioning:createclass,provisioning:deleteclass,provisioning:listgroups,provisioning:editgroup,provisioning:creategroup,provisioning:deletegroup,provisioning:listparams,provisioning:editparam,provisioning:createparam,provisioning:deleteparam,provisioning:editdeviceparams,provisioning:overridedeviceparams,provisioning:editoptions,provisioning:listfiles,provisioning:editfile,provisioning:searchbyextension,provisioning:searchbymac,provisioning:getdevicevalues,provisioning:dumpdatabase +ADMIN=provisioning:listtemplates,provisioning:edittemplate,provisioning:createtemplate,provisioning:deletetemplate,provisioning:searchdevices,provisioning:listdevices,provisioning:editdevice,provisioning:createdevice,provisioning:duplicatedevice,provisioning:deletedevice,provisioning:listclassgroups,provisioning:editclassgroup,provisioning:createclassgroup,provisioning:deleteclassgroup,provisioning:listclasses,provisioning:editclass,provisioning:createclass,provisioning:deleteclass,provisioning:listgroups,provisioning:editgroup,provisioning:creategroup,provisioning:deletegroup,provisioning:listparams,provisioning:editparam,provisioning:createparam,provisioning:deleteparam,provisioning:editdeviceparams,provisioning:overridedeviceparams,provisioning:editoptions,provisioning:listfiles,provisioning:editfile,provisioning:searchbyextension,provisioning:searchbymac,provisioning:getdevicevalues,provisioning:dumpdatabase,provisioning:viewclassparams |