diff options
-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 |