diff options
author | Ted Trask <ttrask01@yahoo.com> | 2017-01-29 03:43:04 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2017-01-29 03:57:29 +0000 |
commit | 07027036bc14ebbb75e54f81b3134ec2b9dc0783 (patch) | |
tree | 9cc0c2844031d4cb27557cd7e2b821fb5c70997b | |
parent | 2f8246dc8b9a0341ca9451f1a20ffe296e76a0be (diff) | |
download | acf-provisioning-07027036bc14ebbb75e54f81b3134ec2b9dc0783.tar.bz2 acf-provisioning-07027036bc14ebbb75e54f81b3134ec2b9dc0783.tar.xz |
Add notifydevices param and add it to all actions that modify devices (not yet implemented)
Modify HTML views to display confirm warning about possible reboot when notifying devices
Split several get_ functions so notifydevices would not appear for new objects
Cleaned up some get_ functions to use handle_clientdata
Do not display filecontent in createtemplate HTML view (or write it in model)
Fix exception if bulkcreatedevices called with empty list
Modify 'device' provisioning_groups seq from 1 to 5 to allow notifydevices to display first
-rw-r--r-- | provisioning-bulkcreatedevices-html.lsp | 17 | ||||
-rw-r--r-- | provisioning-controller.lua | 10 | ||||
-rw-r--r-- | provisioning-editdevice-html.lsp | 10 | ||||
-rw-r--r-- | provisioning-editdeviceparams-html.lsp | 6 | ||||
-rw-r--r-- | provisioning-editparam-html.lsp | 17 | ||||
-rw-r--r-- | provisioning-edittemplate-html.lsp | 21 | ||||
-rw-r--r-- | provisioning-model.lua | 487 | ||||
-rw-r--r-- | provisioning-scripts.lua | 15 | ||||
-rwxr-xr-x | upgradeprovisioning | 2 |
9 files changed, 388 insertions, 197 deletions
diff --git a/provisioning-bulkcreatedevices-html.lsp b/provisioning-bulkcreatedevices-html.lsp index 0f0e45f..71ab322 100644 --- a/provisioning-bulkcreatedevices-html.lsp +++ b/provisioning-bulkcreatedevices-html.lsp @@ -3,6 +3,23 @@ htmlviewfunctions = require("htmlviewfunctions") html = require("acf.html") %> +<script type="text/javascript"> + if (typeof jQuery == 'undefined') { + document.write('<script type="text/javascript" src="<%= html.html_escape(page_info.wwwprefix) %>/js/jquery-latest.js"><\/script>'); + } +</script> + +<script type="text/javascript"> + $(document).ready(function() { + $("[id=<%= page_info.action %>]").submit(function(event){ + if ($(this).find("#notifydevices").is(":checked")) { + return confirm("Are you sure you want to notify affected devices? This might cause a reboot."); + } + return true; + }); + }); +</script> + <% htmlviewfunctions.displayitem(form, page_info) %> <% diff --git a/provisioning-controller.lua b/provisioning-controller.lua index 96ab26f..bcbd52f 100644 --- a/provisioning-controller.lua +++ b/provisioning-controller.lua @@ -11,7 +11,7 @@ mymodule.edittemplate = function( self ) end mymodule.createtemplate = function( self ) - return self.handle_form(self, self.model.get_template, self.model.create_template, self.clientdata, "Create", "Create Template", "Template Created") + return self.handle_form(self, self.model.get_new_template, self.model.create_template, self.clientdata, "Create", "Create Template", "Template Created") end mymodule.deletetemplate = function( self ) @@ -27,7 +27,7 @@ mymodule.editclassgroup = function( self ) end mymodule.createclassgroup = function( self ) - return self.handle_form(self, self.model.get_class_group, self.model.create_class_group, self.clientdata, "Create", "Create Class Group", "Parameter Class Created") + return self.handle_form(self, self.model.get_new_class_group, self.model.create_class_group, self.clientdata, "Create", "Create Class Group", "Parameter Class Created") end mymodule.deleteclassgroup = function( self ) @@ -43,7 +43,7 @@ mymodule.editclass = function( self ) end mymodule.createclass = function( self ) - return self.handle_form(self, self.model.get_class, self.model.create_class, self.clientdata, "Create", "Create Class", "Class Created") + return self.handle_form(self, self.model.get_new_class, self.model.create_class, self.clientdata, "Create", "Create Class", "Class Created") end mymodule.deleteclass = function( self ) @@ -63,7 +63,7 @@ mymodule.editgroup = function( self ) end mymodule.creategroup = function( self ) - return self.handle_form(self, self.model.get_group, self.model.create_group, self.clientdata, "Create", "Create Parameter Group", "Parameter Group Created") + return self.handle_form(self, self.model.get_new_group, self.model.create_group, self.clientdata, "Create", "Create Parameter Group", "Parameter Group Created") end mymodule.deletegroup = function(self ) @@ -79,7 +79,7 @@ mymodule.editparam = function( self ) end mymodule.createparam = function( self ) - return self.handle_form(self, self.model.get_param, self.model.create_param, self.clientdata, "Create", "Create Parameter", "Parameter Created") + return self.handle_form(self, self.model.get_new_param, self.model.create_param, self.clientdata, "Create", "Create Parameter", "Parameter Created") end mymodule.deleteparam = function( self ) diff --git a/provisioning-editdevice-html.lsp b/provisioning-editdevice-html.lsp index fe375aa..85161b7 100644 --- a/provisioning-editdevice-html.lsp +++ b/provisioning-editdevice-html.lsp @@ -29,6 +29,12 @@ html = require("acf.html") $(document).ready(function() { $(".deletedevice").click(function(){ return confirm("Are you sure you want to delete this device?")}); + $("[id=<%= page_info.action %>]").submit(function(event){ + if ($(this).find("#notifydevices").is(":checked")) { + return confirm("Are you sure you want to notify affected devices? This might cause a reboot."); + } + return true; + }); }); </script> @@ -50,7 +56,9 @@ html = require("acf.html") form.value.device_id.readonly = "true" elseif page_info.action == "duplicatedevice" then form.value.classes = nil - else + form.value.notifydevices.value = false + form.value.notifydevices.type = "hidden" + elseif form.value.device_id then form.value.device_id.type = "hidden" end htmlviewfunctions.displayitem(form, page_info) diff --git a/provisioning-editdeviceparams-html.lsp b/provisioning-editdeviceparams-html.lsp index 9229264..2ee0374 100644 --- a/provisioning-editdeviceparams-html.lsp +++ b/provisioning-editdeviceparams-html.lsp @@ -91,6 +91,12 @@ end $(document).ready(function() { $(".deletedevice").click(function(){ return confirm("Are you sure you want to delete this device?")}); + $("[id=<%= page_info.action %>]").submit(function(event){ + if ($(this).find("#notifydevices").is(":checked")) { + return confirm("Are you sure you want to notify affected devices? This might cause a reboot."); + } + return true; + }); $(".groupdefaultoverride").siblings().select("contains('Default:')").addClass("error"); hideunuseddivs(); }); diff --git a/provisioning-editparam-html.lsp b/provisioning-editparam-html.lsp index b154766..96b76f1 100644 --- a/provisioning-editparam-html.lsp +++ b/provisioning-editparam-html.lsp @@ -3,6 +3,23 @@ htmlviewfunctions = require("htmlviewfunctions") html = require("acf.html") %> +<script type="text/javascript"> + if (typeof jQuery == 'undefined') { + document.write('<script type="text/javascript" src="<%= html.html_escape(page_info.wwwprefix) %>/js/jquery-latest.js"><\/script>'); + } +</script> + +<script type="text/javascript"> + $(document).ready(function() { + $("[id=<%= page_info.action %>]").submit(function(event){ + if ($(this).find("#notifydevices").is(":checked")) { + return confirm("Are you sure you want to notify affected devices? This might cause a reboot."); + } + return true; + }); + }); +</script> + <% htmlviewfunctions.displaycommandresults({"editoptions"}, session, true) htmlviewfunctions.displayitem(form, page_info) diff --git a/provisioning-edittemplate-html.lsp b/provisioning-edittemplate-html.lsp index 0ef5bc2..56d3446 100644 --- a/provisioning-edittemplate-html.lsp +++ b/provisioning-edittemplate-html.lsp @@ -2,8 +2,26 @@ <% htmlviewfunctions = require("htmlviewfunctions") %> <% html = require("acf.html") %> +<script type="text/javascript"> + if (typeof jQuery == 'undefined') { + document.write('<script type="text/javascript" src="<%= html.html_escape(page_info.wwwprefix) %>/js/jquery-latest.js"><\/script>'); + } +</script> + +<script type="text/javascript"> + $(document).ready(function() { + $("[id=<%= page_info.action %>]").submit(function(event){ + if ($(this).find("#notifydevices").is(":checked")) { + return confirm("Are you sure you want to notify affected devices? This might cause a reboot."); + } + return true; + }); + }); +</script> + <% local header_level = htmlviewfunctions.displaysectionstart(form, page_info) %> <% htmlviewfunctions.displayformstart(form, page_info) %> +<% htmlviewfunctions.displayformitem(form.value.notifydevices, "notifydevices") %> <% local header_level2 = htmlviewfunctions.displaysectionstart(cfe({label="Template Details"}), page_info, htmlviewfunctions.incrementheader(header_level)) %> <% if page_info.action == "edittemplate" then @@ -15,6 +33,7 @@ htmlviewfunctions.displayformitem(form.value.seq, "seq") %> <% htmlviewfunctions.displaysectionend(header_level2) %> +<% if form.value.filecontent then %> <% htmlviewfunctions.displaysectionstart(cfe({label="File Content"}), page_info, header_level2) %> <textarea name="filecontent"> <%= html.html_escape(form.value.filecontent.value) %> @@ -22,5 +41,7 @@ htmlviewfunctions.displayformitem(form.value.seq, "seq") <% htmlviewfunctions.displayinfo(form.value.filecontent) %> <% htmlviewfunctions.displaysectionend(header_level2) %> +<% end %> + <% htmlviewfunctions.displayformend(form) %> <% htmlviewfunctions.displaysectionend(header_level) %> diff --git a/provisioning-model.lua b/provisioning-model.lua index 5787daa..6d3dc59 100644 --- a/provisioning-model.lua +++ b/provisioning-model.lua @@ -321,11 +321,33 @@ local checkgroupdefaultoverride = function(device_id) return (#tmp ~= 0) end +local add_notify_devices = function(p) + local connected + if not p.errtxt then + local res, err = pcall(function() + connected = databaseconnect(true) + + local sql = "SELECT * FROM provisioning_params WHERE name='notifydevices'" + local tmp = getselectresponse(sql) + if tmp and #tmp ~= 0 then + p.value.notifydevices = tmp[1] + end + + if connected then databasedisconnect() end + end) + if not res and err then + handlesqlexception(connected, err) + p.errtxt = err + end + end + return p +end + -- This function is used by scripts, do not change prototype local get_device = function(device_id, create) local connected local retval = {} - retval.device_id = cfe({value=device_id or "", label="Device ID", seq=1}) + if not create then retval.device_id = cfe({value=device_id or "", label="Device ID", readonly=true, seq=0}) end retval.classes = cfe({type="group", value={}, label="Classes", seq=2}) local errtxt local res, err = pcall(function() @@ -595,45 +617,54 @@ mymodule.list_templates = function() return cfe({ type="structure", value=retval, label="Templates", errtxt=errtxt }) end +mymodule.get_new_template = function(self, clientdata) + local retval = cfe({ type="group", value={}, label="Provisioning Template" }) + retval.value.filename = cfe({label="File Name", descr="Must be in "..baseurl, seq=1}) + retval.value.label = cfe({label="Label", seq=2}) + retval.value.seq = cfe({label="Sequence", seq=3}) + self.handle_clientdata(retval, clientdata) + return retval +end + mymodule.get_template = function(self, clientdata) local connected - clientdata = clientdata or {} - local filename = clientdata.filename - local retval = {} - if filename and not string.match(filename, "/") then + local retval = mymodule.get_new_template(self, clientdata) + + local filename = retval.value.filename.value + if filename~="" and not string.match(filename, "/") then filename = baseurl .. filename + retval.value.filename.value = filename end - retval.filename = cfe({value=filename or "", label="File Name", descr="Must be in "..baseurl, seq=1}) - retval.label = cfe({label="Label", seq=2}) - retval.seq = cfe({label="Sequence", seq=3}) - local errtxt - if filename and filename ~= "" then + if filename ~= "" then local res, err = pcall(function() connected = databaseconnect(true) local sql = "SELECT * FROM provisioning_options WHERE param_id=(SELECT param_id FROM provisioning_params WHERE name = 'template') AND value='"..provdb.escape(filename).."' ORDER BY seq ASC, label ASC, value ASC" local tmp = getselectresponse(sql) if tmp and #tmp > 0 then for n,v in pairs(tmp[1]) do - if n == "value" then - retval.filename.value = v - elseif retval[n] then - retval[n].value = v + if retval.value[n] then + retval.value[n].value = v end end + else + retval.errtxt = "Template does not exist" end if connected then databasedisconnect() end + + local filedetails = modelfunctions.getfiledetails(retval.value.filename.value, function(filename) return validator.is_valid_filename(filename, baseurl) end) + for i,n in ipairs({"filecontent", "size", "mtime"}) do + retval.value[n] = filedetails.value[n] + end end) if not res and err then handlesqlexception(connected, err) - errtxt = err + retval.errtxt = err end - end - local filedetails = modelfunctions.getfiledetails(retval.filename.value, function(filename) return validator.is_valid_filename(filename, baseurl) end) - for i,n in ipairs({"filecontent", "size", "mtime"}) do - retval[n] = filedetails.value[n] + else + retval.errtxt = "Template does not exist" end - return cfe({ type="group", value=retval, label="Provisioning Template", errtxt=errtxt }) + return add_notify_devices(retval) end mymodule.create_template = function(self, template, action) @@ -682,7 +713,9 @@ mymodule.update_template = function(self, template, action, create) end runsqlcommand(sql) - fs.write_file(template.value.filename.value, string.gsub(format.dostounix(template.value.filecontent.value), "\n+$", "")) + if template.value.filecontent then + fs.write_file(template.value.filename.value, string.gsub(format.dostounix(template.value.filecontent.value), "\n+$", "")) + end end if connected then databasedisconnect() end end) @@ -766,39 +799,48 @@ mymodule.list_class_groups = function() return cfe({ type="structure", value=retval, label="Class Groups", errtxt=errtxt }) end +mymodule.get_new_class_group = function(self, clientdata) + local retval = cfe({ type="group", value={}, label="Provisioning Class Group" }) + retval.value.name = cfe({label="Name", seq=2}) + retval.value.label = cfe({label="Label", seq=3}) + retval.value.seq = cfe({label="Sequence", seq=4}) + self.handle_clientdata(retval, clientdata) + return retval +end + mymodule.get_class_group = function(self, clientdata) local connected - clientdata = clientdata or {} - local class_group_id = clientdata.class_group_id - local retval = {} - retval.class_group_id = cfe({value=class_group_id or "", label="Class Group ID", readonly=true, seq=1}) - retval.name = cfe({label="Name", seq=2}) - retval.label = cfe({label="Label", seq=3}) - retval.seq = cfe({label="Sequence", seq=4}) - local errtxt - local res, err = pcall(function() - connected = databaseconnect(true) - if class_group_id and class_group_id ~= "" then + local retval = mymodule.get_new_class_group(self, clientdata) + retval.value.class_group_id = cfe({label="Class Group ID", seq=0}) + self.handle_clientdata(retval, clientdata) + retval.value.class_group_id.readonly=true + + local class_group_id = retval.value.class_group_id.value + if class_group_id ~= "" then + local res, err = pcall(function() + connected = databaseconnect(true) sql = "SELECT * FROM provisioning_class_groups WHERE class_group_id='"..provdb.escape(class_group_id).."'" tmp = getselectresponse(sql) if tmp and #tmp > 0 then for n,v in pairs(tmp[1]) do - if retval[n] then - retval[n].value = v + if retval.value[n] then + retval.value[n].value = v end end + else + retval.errtxt = "Class Group does not exist" end - else - retval.class_group_id = nil + if connected then databasedisconnect() end + end) + if not res and err then + handlesqlexception(connected, err) + retval.errtxt = err end - if connected then databasedisconnect() end - end) - if not res and err then - handlesqlexception(connected, err) - errtxt = err + else + retval.errtxt = "Class Group does not exist" end - return cfe({ type="group", value=retval, label="Provisioning Class Group", errtxt=errtxt }) + return add_notify_devices(retval) end mymodule.create_class_group = function(self, group, action) @@ -925,66 +967,94 @@ mymodule.list_classes = function() return cfe({ type="structure", value=retval, label="Classes", errtxt=errtxt }) end -mymodule.get_class = function(self, clientdata) +mymodule.get_new_class = function(self, clientdata) local connected - clientdata = clientdata or {} - local class_id = clientdata.class_id - local retval = {} - retval.class_id = cfe({value=class_id or "", label="Class ID", readonly=true, seq=1}) - retval.class_group_id = cfe({type="select", label="Class Group", option={}, seq=2}) - retval.label = cfe({label="Label", seq=3}) - retval.seq = cfe({label="Sequence", seq=4}) - retval.groups = cfe({type="group", value={}, label="Parameter Groups", seq=5}) - local errtxt + local retval = cfe({ type="group", value={}, label="Provisioning Class" }) + retval.value.class_group_id = cfe({type="select", label="Class Group", option={}, seq=2}) + retval.value.label = cfe({label="Label", seq=3}) + retval.value.seq = cfe({label="Sequence", seq=4}) + retval.value.groups = cfe({type="group", value={}, label="Parameter Groups", seq=5}) + local res, err = pcall(function() - local groups = {} connected = databaseconnect(true) - if class_id and class_id ~= "" then - local sql = "SELECT * FROM provisioning_classes WHERE class_id='"..provdb.escape(class_id).."'" - local tmp = getselectresponse(sql) - if tmp and #tmp > 0 then - for n,v in pairs(tmp[1]) do - if retval[n] then - retval[n].value = v - end - end - end - -- Now, get the class-to-paramgroup mappings - sql = "SELECT group_id FROM classes_to_param_groups WHERE class_id='"..provdb.escape(class_id).."'" - tmp = getselectresponse(sql) - for i,g in ipairs(tmp) do - groups[g.group_id] = true - end - else - retval.class_id = nil - end -- Get the class_group_id options sql = "SELECT * from provisioning_class_groups ORDER BY seq ASC, label ASC" tmp = getselectresponse(sql) for i,g in ipairs(tmp) do - retval.class_group_id.option[#retval.class_group_id.option + 1] = {value=g.class_group_id, label=g.label} + retval.value.class_group_id.option[#retval.value.class_group_id.option + 1] = {value=g.class_group_id, label=g.label} end -- Finally, get the paramgroup options sql = "SELECT group_id, name, label FROM provisioning_groups ORDER BY seq ASC, name ASC" tmp = getselectresponse(sql) for i,g in ipairs(tmp) do - if not retval.groups.value[g.name] then - retval.groups.value[g.name] = cfe({type="select", label=g.name, option={{value="", label=""}}, seq=i}) + if not retval.value.groups.value[g.name] then + retval.value.groups.value[g.name] = cfe({type="select", label=g.name, option={{value="", label=""}}, seq=i}) end - local group = retval.groups.value[g.name] + local group = retval.value.groups.value[g.name] group.option[#group.option + 1] = {value=g.group_id, label=g.label} - if groups[g.group_id] then - group.value = g.group_id - end end if connected then databasedisconnect() end end) if not res and err then handlesqlexception(connected, err) - errtxt = err + retval.errtxt = err end - return cfe({ type="group", value=retval, label="Provisioning Class", errtxt=errtxt }) + self.handle_clientdata(retval, clientdata) + return retval +end + +mymodule.get_class = function(self, clientdata) + local connected + local retval = mymodule.get_new_class(self, clientdata) + retval.value.class_id = cfe({label="Class ID", seq=0}) + self.handle_clientdata(retval, clientdata) + retval.value.class_id.readonly=true + + local class_id = retval.value.class_id.value + if class_id ~= "" then + local res, err = pcall(function() + local groups = {} + connected = databaseconnect(true) + local sql = "SELECT * FROM provisioning_classes WHERE class_id='"..provdb.escape(class_id).."'" + local tmp = getselectresponse(sql) + if tmp and #tmp > 0 then + for n,v in pairs(tmp[1]) do + if retval.value[n] then + retval.value[n].value = v + end + end + + -- Now, get the class-to-paramgroup mappings + sql = "SELECT group_id FROM classes_to_param_groups WHERE class_id='"..provdb.escape(class_id).."'" + tmp = getselectresponse(sql) + for i,g in ipairs(tmp) do + groups[g.group_id] = true + end + + -- Loop through the groups and options to mark the mappings + for n,g in pairs(retval.value.groups.value) do + for i,o in ipairs(g.option) do + if groups[o.value] then + g.value = o.value + break + end + end + end + else + retval.errtxt = "Class does not exist" + end + if connected then databasedisconnect() end + end) + if not res and err then + handlesqlexception(connected, err) + retval.errtxt = err + end + else + retval.errtxt = "Class does not exist" + end + + return add_notify_devices(retval) end mymodule.create_class = function(self, class, action) @@ -1119,29 +1189,26 @@ mymodule.list_groups = function() return cfe({ type="structure", value=retval, label="Parameter Groups", errtxt=errtxt }) end -mymodule.get_group = function(self, clientdata) +mymodule.get_new_group = function(self, clientdata) local connected - clientdata = clientdata or {} - local group_id = clientdata.group_id - local retval = {} - retval.group_id = cfe({value=group_id or "", label="Group ID", readonly=true, seq=1}) - retval.name = cfe({label="Name", seq=2}) - retval.label = cfe({label="Label", seq=3}) - retval.seq = cfe({label="Sequence", seq=4}) - retval.params = cfe({type="multi", value={}, label="Parameters", option={}, descr="Each selected parameter will be included in the group", seq=5}) - retval.editable = cfe({type="multi", value={}, label="Editable Parameters", option={}, descr="Each selected parameter will be user editable", seq=6}) - retval.override = cfe({type="multi", value={}, label="Overridden Parameters", option={}, descr="Each selected parameter will override the parameter default from the group defaults", seq=7}) - retval.defaults = cfe({type="group", value={}, label="Parameter Defaults", seq=8}) - local errtxt + local retval = cfe({ type="group", value={}, label="Provisioning Parameter Group" }) + retval.value.name = cfe({label="Name", seq=2}) + retval.value.label = cfe({label="Label", seq=3}) + retval.value.seq = cfe({label="Sequence", seq=4}) + retval.value.params = cfe({type="multi", value={}, label="Parameters", option={}, descr="Each selected parameter will be included in the group", seq=5}) + retval.value.editable = cfe({type="multi", value={}, label="Editable Parameters", option={}, descr="Each selected parameter will be user editable", seq=6}) + retval.value.override = cfe({type="multi", value={}, label="Overridden Parameters", option={}, descr="Each selected parameter will override the parameter default from the group defaults", seq=7}) + retval.value.defaults = cfe({type="group", value={}, label="Parameter Defaults", seq=8}) + local res, err = pcall(function() connected = databaseconnect(true) - -- First, let's get all the parameters to set up the params.options and defaults + -- Get all the parameters to set up the params.options and defaults local sql = "SELECT * FROM provisioning_params ORDER BY seq ASC, name ASC" local tmp = getselectresponse(sql) for i,p in ipairs(tmp) do - retval.params.option[#retval.params.option + 1] = {value=p.param_id, label=p.label} - retval.editable.option[#retval.editable.option + 1] = {value=p.param_id, label=p.label} - retval.override.option[#retval.override.option + 1] = {value=p.param_id, label=p.label} + retval.value.params.option[#retval.value.params.option + 1] = {value=p.param_id, label=p.label} + retval.value.editable.option[#retval.value.editable.option + 1] = {value=p.param_id, label=p.label} + retval.value.override.option[#retval.value.override.option + 1] = {value=p.param_id, label=p.label} p.seq = i if p.type == "select" then sql = "SELECT * FROM provisioning_options WHERE param_id='"..provdb.escape(p.param_id).."' ORDER BY seq ASC" @@ -1151,46 +1218,70 @@ mymodule.get_group = function(self, clientdata) p.value = (p.value == "true") end p.default = p.value - retval.defaults.value[p.param_id] = p + retval.value.defaults.value[p.param_id] = p end - if group_id and group_id ~= "" then + if connected then databasedisconnect() end + end) + if not res and err then + handlesqlexception(connected, err) + retval.errtxt = err + end + + self.handle_clientdata(retval, clientdata) + return retval +end + +mymodule.get_group = function(self, clientdata) + local connected + local retval = mymodule.get_new_group(self, clientdata) + retval.value.group_id = cfe({value=group_id or "", label="Group ID", seq=0}) + self.handle_clientdata(retval, clientdata) + retval.value.group_id.readonly=true + + local group_id = retval.value.group_id.value + if group_id ~= "" then + local res, err = pcall(function() + connected = databaseconnect(true) sql = "SELECT * FROM provisioning_groups WHERE group_id='"..provdb.escape(group_id).."'" tmp = getselectresponse(sql) if tmp and #tmp > 0 then for n,v in pairs(tmp[1]) do - if retval[n] then - retval[n].value = v + if retval.value[n] then + retval.value[n].value = v end end - end - -- Now, get the paramgroup-to-param mappings - sql = "SELECT * FROM param_groups_to_params WHERE group_id='"..provdb.escape(group_id).."'" - tmp = getselectresponse(sql) - for i,p in ipairs(tmp) do - retval.params.value[#retval.params.value + 1] = p.param_id - if (p.editable == "t") then - retval.editable.value[#retval.editable.value + 1] = p.param_id - end - if p.value then - retval.override.value[#retval.override.value + 1] = p.param_id - if retval.defaults.value[p.param_id].type == "boolean" then - retval.defaults.value[p.param_id].value = (p.value == "true") - else - retval.defaults.value[p.param_id].value = p.value + + -- Now, get the paramgroup-to-param mappings + sql = "SELECT * FROM param_groups_to_params WHERE group_id='"..provdb.escape(group_id).."'" + tmp = getselectresponse(sql) + for i,p in ipairs(tmp) do + retval.value.params.value[#retval.value.params.value + 1] = p.param_id + if (p.editable == "t") then + retval.value.editable.value[#retval.value.editable.value + 1] = p.param_id + end + if p.value then + retval.value.override.value[#retval.value.override.value + 1] = p.param_id + if retval.value.defaults.value[p.param_id].type == "boolean" then + retval.value.defaults.value[p.param_id].value = (p.value == "true") + else + retval.value.defaults.value[p.param_id].value = p.value + end end end + else + retval.errtxt = "Group does not exist" end - else - retval.group_id = nil + if connected then databasedisconnect() end + end) + if not res and err then + handlesqlexception(connected, err) + retval.errtxt = err end - if connected then databasedisconnect() end - end) - if not res and err then - handlesqlexception(connected, err) - errtxt = err + else + retval.errtxt = "Group does not exist" end - return cfe({ type="group", value=retval, label="Provisioning Parameter Group", errtxt=errtxt }) + return add_notify_devices(retval) end mymodule.create_group = function(self, group, action) @@ -1367,44 +1458,54 @@ mymodule.list_params = function() return cfe({ type="structure", value=retval, label="Parameters", errtxt=errtxt }) end +mymodule.get_new_param = function(self, clientdata) + local retval = cfe({ type="group", value={}, label="Provisioning Parameter" }) + retval.value.name = cfe({label="Name", seq=2}) + retval.value.type = cfe({type="select", label="Type", option={"text", "boolean", "select"}, seq=3}) + retval.value.label = cfe({label="Label", seq=4}) + retval.value.descr = cfe({label="Description", seq=5}) + retval.value.value = cfe({label="Default Value", descr="Warning, this value is not validated", seq=6}) + retval.value.regexp = cfe({label="Regular Expression", descr="Lua regular expression for validating the text parameter value", seq=7}) + retval.value.validate = cfe({type="longtext", label="Validation Code", descr="Lua code to validate the parameter value. Returns updated value and error text. Not used to validate group defaults.", seq=8}) + retval.value.seq = cfe({label="Sequence", seq=9}) + + self.handle_clientdata(retval, clientdata) + return retval +end + mymodule.get_param = function(self, clientdata) local connected - clientdata = clientdata or {} - local param_id = clientdata.param_id - local retval = {} - retval.param_id = cfe({value=param_id or "", label="Param ID", readonly=true, seq=1}) - retval.name = cfe({label="Name", seq=2}) - retval.type = cfe({type="select", label="Type", option={"text", "boolean", "select"}, seq=3}) - retval.label = cfe({label="Label", seq=4}) - retval.descr = cfe({label="Description", seq=5}) - retval.value = cfe({label="Default Value", descr="Warning, this value is not validated", seq=6}) - retval.regexp = cfe({label="Regular Expression", descr="Lua regular expression for validating the text parameter value", seq=7}) - retval.validate = cfe({type="longtext", label="Validation Code", descr="Lua code to validate the parameter value. Returns updated value and error text. Not used to validate group defaults.", seq=8}) - retval.seq = cfe({label="Sequence", seq=9}) - local errtxt - local res, err = pcall(function() - connected = databaseconnect(true) - if param_id and param_id ~= "" then + local retval = mymodule.get_new_param(self, clientdata) + retval.value.param_id = cfe({value=param_id or "", label="Param ID", seq=0}) + self.handle_clientdata(retval, clientdata) + retval.value.param_id.readonly=true + + local param_id = retval.value.param_id.value + if param_id ~= "" then + local res, err = pcall(function() + connected = databaseconnect(true) sql = "SELECT * FROM provisioning_params WHERE param_id='"..provdb.escape(param_id).."'" tmp = getselectresponse(sql) if tmp and #tmp > 0 then for n,v in pairs(tmp[1]) do - if retval[n] then - retval[n].value = v + if retval.value[n] then + retval.value[n].value = v end end + else + retval.errtxt = "Parameter does not exist" end - else - retval.param_id = nil + if connected then databasedisconnect() end + end) + if not res and err then + handlesqlexception(connected, err) + retval.errtxt = err end - if connected then databasedisconnect() end - end) - if not res and err then - handlesqlexception(connected, err) - errtxt = err + else + retval.errtxt = "Parameter does not exist" end - return cfe({ type="group", value=retval, label="Provisioning Parameter", errtxt=errtxt }) + return add_notify_devices(retval) end mymodule.create_param = function(self, param, action) @@ -1640,13 +1741,17 @@ mymodule.list_devices = function(self, clientdata) end mymodule.get_existing_device = function(self, clientdata) - clientdata = clientdata or {} - return get_device(clientdata.device_id, false) + local tmp = cfe({ type="group", value={device_id = cfe()} }) + self.handle_clientdata(tmp, clientdata) + retval = get_device(tmp.value.device_id.value, false) + self.handle_clientdata(retval, clientdata) + return add_notify_devices(retval) end mymodule.get_new_device = function(self, clientdata) - clientdata = clientdata or {} - return get_device(clientdata.device_id, true) + retval = get_device(nil, true) + self.handle_clientdata(retval, clientdata) + return retval end mymodule.create_device = function(self, device, action) @@ -1678,25 +1783,29 @@ mymodule.update_device = function(self, device, action, create) end end if success then - if not saved_devices[device.value.device_id.value] then get_device(device.value.device_id.value) end - if not saved_device_params[device.value.device_id.value] then get_device_params(device.value.device_id.value) end - + local device_id if create then sql = "SELECT nextval('provisioning_device_seq')" local tmp = getselectresponse(sql) if tmp and #tmp>0 then - device.value.device_id.value = tmp[1].nextval + device_id = tmp[1].nextval + -- Add to cfe so can use to redirect to editdeviceparams + device.value.device_id = cfe({value=device_id or "", label="Device ID", readonly=true, seq=0}) end - logcall("create_device "..device.value.device_id.value) + logcall("create_device "..device_id) else - logcall("update_device "..device.value.device_id.value) + device_id = device.value.device_id.value + if not saved_devices[device_id] then get_device(device_id) end + if not saved_device_params[device_id] then get_device_params(device_id) end + + logcall("update_device "..device_id) end - sql = "DELETE FROM devices_to_classes WHERE device_id='"..provdb.escape(device.value.device_id.value).."'" + sql = "DELETE FROM devices_to_classes WHERE device_id='"..provdb.escape(device_id).."'" runsqlcommand(sql) -- Insert the device to class entries for n,c in pairs(device.value.classes.value) do if c.value ~= "" then - sql = "INSERT INTO devices_to_classes VALUES('"..provdb.escape(device.value.device_id.value).."', '"..provdb.escape(c.value).."')" + sql = "INSERT INTO devices_to_classes VALUES('"..provdb.escape(device_id).."', '"..provdb.escape(c.value).."')" runsqlcommand(sql) end end @@ -1704,8 +1813,8 @@ mymodule.update_device = function(self, device, action, create) device.descr = "Device Created" -- Notify the device that its params might have changed (this will also validate) - local s = saved_device_params[device.value.device_id.value] - local r = set_device_params(get_device_params(device.value.device_id.value, false), false) + local s = saved_device_params[device_id] + local r = set_device_params(get_device_params(device_id, false), false) if r.errtxt then if create then device.descr = device.descr.."\nERROR: Failed to update params\n"..r:print_errtxt() @@ -1714,9 +1823,9 @@ mymodule.update_device = function(self, device, action, create) end end - callscript(updatedevicescriptfile, device, saved_devices[device.value.device_id.value], r, s) + callscript(updatedevicescriptfile, device, saved_devices[device_id], r, s) - saved_devices[device.value.device_id.value] = device + saved_devices[device_id] = device end if connected then databasedisconnect() end end) @@ -1780,21 +1889,26 @@ mymodule.delete_device = function(self, delreq) end mymodule.get_editable_device_params = function(self, clientdata, action) - clientdata = clientdata or {} - return get_device_params(clientdata.device_id, true) + local tmp = cfe({ type="group", value={device_id = cfe()} }) + self.handle_clientdata(tmp, clientdata) + retval = get_device_params(tmp.value.device_id.value, true) + self.handle_clientdata(retval, clientdata) + return add_notify_devices(retval) end mymodule.get_all_device_params = function(self, clientdata, action) - clientdata = clientdata or {} - return get_device_params(clientdata.device_id, false) + local tmp = cfe({ type="group", value={device_id = cfe()} }) + self.handle_clientdata(tmp, clientdata) + retval = get_device_params(tmp.value.device_id.value, false) + self.handle_clientdata(retval, clientdata) + return add_notify_devices(retval) end mymodule.get_class_options = function(self, clientdata) - clientdata = clientdata or {} - local class_id = clientdata.class_id - local retval = {} - retval.class_id = cfe({value=class_id or "", label="Class ID", seq=1}) - return cfe({ type="group", value=retval, label="Provisioning Class Values" }) + local retval = cfe({ type="group", value={}, label="Provisioning Class Values" }) + retval.value.class_id = cfe({label="Class ID", seq=1}) + self.handle_clientdata(retval, clientdata) + return retval end mymodule.get_class_values = function(self, retval) @@ -2362,11 +2476,10 @@ mymodule.delete_request = function(self, delreq) end mymodule.get_request = function(self, clientdata) - clientdata = clientdata or {} - local mac = clientdata.mac - local retval = {} - retval.mac = cfe({ value=mac or "", label="MAC Address" }) - return cfe({ type="group", value=retval, label="Create Device from Request" }) + local retval = cfe({ type="group", value={}, label="Create Device from Request" }) + retval.value.mac = cfe({ label="MAC Address" }) + self.handle_clientdata(retval, clientdata) + return add_notify_devices(retval) end mymodule.create_from_request = function(self, request) @@ -2425,14 +2538,20 @@ mymodule.create_from_request = function(self, request) end mymodule.get_bulk_create_request = function(self, clientdata) - local retval = {} - retval.bulkdevicedata = cfe({ type="list", value={}, label="Bulk device list", descr="List of devices as comma-separated fields (first row must contain column headers)" }) - return cfe({ type="group", value=retval, label="Create Multiple Devices" }) + local retval = cfe({ type="group", value={}, label="Create Multiple Devices" }) + retval.value.bulkdevicedata = cfe({ type="list", value={}, label="Bulk device list", descr="List of devices as comma-separated fields (first row must contain column headers)" }) + return add_notify_devices(retval) end mymodule.bulk_create_devices = function(self, devicelist) logcall("bulk_create_devices") local connected + + if #devicelist.value.bulkdevicedata.value == 0 then + devicelist.errtxt = "No devices specified" + return devicelist + end + -- To allow uploading a file, check the bulkdevicedata format -- Haserl will pass a temporary file name if a file is uploaded if #devicelist.value.bulkdevicedata.value == 1 and string.find(devicelist.value.bulkdevicedata.value[1], "^/tmp/[^.]+$") and fs.is_file(devicelist.value.bulkdevicedata.value[1]) then diff --git a/provisioning-scripts.lua b/provisioning-scripts.lua index 707348e..4f5b1c0 100644 --- a/provisioning-scripts.lua +++ b/provisioning-scripts.lua @@ -365,13 +365,13 @@ mymodule.classes_to_param_groups = { mymodule.provisioning_groups = { "CREATE TABLE provisioning_groups (group_id SERIAL PRIMARY KEY, name VARCHAR(255), label VARCHAR(255) UNIQUE, seq INTEGER)", "CREATE INDEX groups_name_idx ON provisioning_groups (name)", - "INSERT INTO provisioning_groups VALUES(default, 'device', 'Linksys ATA Device', '1')", - "INSERT INTO provisioning_groups VALUES(default, 'device', 'Cisco ATA Device', '1')", - "INSERT INTO provisioning_groups VALUES(default, 'device', 'Polycom Device', '1')", - "INSERT INTO provisioning_groups VALUES(default, 'device', 'Snom Device', '1')", - "INSERT INTO provisioning_groups VALUES(default, 'device', 'Algo 8180 Device', '1')", - "INSERT INTO provisioning_groups VALUES(default, 'device', 'CyberData Intercom Device', '1')", - "INSERT INTO provisioning_groups VALUES(default, 'device', 'Grandstream Device', '1')", + "INSERT INTO provisioning_groups VALUES(default, 'device', 'Linksys ATA Device', '5')", + "INSERT INTO provisioning_groups VALUES(default, 'device', 'Cisco ATA Device', '5')", + "INSERT INTO provisioning_groups VALUES(default, 'device', 'Polycom Device', '5')", + "INSERT INTO provisioning_groups VALUES(default, 'device', 'Snom Device', '5')", + "INSERT INTO provisioning_groups VALUES(default, 'device', 'Algo 8180 Device', '5')", + "INSERT INTO provisioning_groups VALUES(default, 'device', 'CyberData Intercom Device', '5')", + "INSERT INTO provisioning_groups VALUES(default, 'device', 'Grandstream Device', '5')", "INSERT INTO provisioning_groups VALUES(default, 'device', 'CyberData Paging Zone Controller Device', '1')", "INSERT INTO provisioning_groups VALUES(default, 'reg1', 'Registration 1 (Polycom)', '10')", "INSERT INTO provisioning_groups VALUES(default, 'reg1', 'Registration 1 (Linksys)', '10')", @@ -1233,6 +1233,7 @@ mymodule.param_groups_to_params = { mymodule.provisioning_params = { "CREATE TABLE provisioning_params (param_id SERIAL PRIMARY KEY, name VARCHAR(255) UNIQUE, type VARCHAR(255), label VARCHAR(255), descr VARCHAR(255), value VARCHAR(255), seq INTEGER, regexp VARCHAR(255), validate text)", "CREATE INDEX params_name_idx ON provisioning_params (name)", + "INSERT INTO provisioning_params VALUES(default, 'notifydevices', 'boolean', 'Notify Devices', 'Notify devices of changes (may cause reboot)', 'true', '1', '', null)", "INSERT INTO provisioning_params VALUES(default, 'mac', 'text', 'MAC Address', 'Capitalized hex digits with no punctuation', '', '1', '^%x%x%x%x%x%x%x%x%x%x%x%x$', E'local value, functions, params = ...\nvalue = string.upper(value)\nlocal others = functions.getselectresponse(\"SELECT count(*) FROM provisioning_values WHERE param_id=\\'\"..params.value.device.value.mac.param_id..\"\\' AND device_id!=\\'\"..params.value.device_id.value..\"\\' AND value=\\'\"..value..\"\\'\")\nif tonumber(others[1].count) > 0 then\n\treturn value, \"MAC Address must be unique\"\nend\nreturn value')", "INSERT INTO provisioning_params VALUES(default, 'template', 'select', 'Template', '', '', '2', '', null)", "INSERT INTO provisioning_params VALUES(default, 'registrar', 'text', 'SIP Registrar', '', '', '3', '', null)", diff --git a/upgradeprovisioning b/upgradeprovisioning index b06018f..73e046e 100755 --- a/upgradeprovisioning +++ b/upgradeprovisioning @@ -771,6 +771,8 @@ if [ "$version" -lt "12" ]; then psql -U postgres -c "INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='Public Phone'), (SELECT param_id FROM provisioning_params WHERE name='receivedcallhistoryenable'), 'true', false)" provisioning psql -U postgres -c "INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='Hotline'), (SELECT param_id FROM provisioning_params WHERE name='missedcallhistoryenable'), 'false', false)" provisioning psql -U postgres -c "INSERT INTO param_groups_to_params VALUES((SELECT group_id FROM provisioning_groups WHERE label='Hotline'), (SELECT param_id FROM provisioning_params WHERE name='receivedcallhistoryenable'), 'false', false)" provisioning + psql -U postgres -c "INSERT INTO provisioning_params VALUES(default, 'notifydevices', 'boolean', 'Notify Devices', 'Notify devices of changes (may cause reboot)', 'true', '1', '', null)" provisioning + psql -U postgres -c "UPDATE provisioning_groups SET (seq)=('5') WHERE name='device' AND seq='1'" provisioning # database psql -U postgres -c "UPDATE provisioning_params SET value='12' WHERE name='databaseversion'" provisioning |