diff options
author | Ted Trask <ttrask01@yahoo.com> | 2008-06-26 19:16:25 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2008-06-26 19:16:25 +0000 |
commit | 337584d2a16c3a22551ab31c6eff7beb1c942815 (patch) | |
tree | af0e254f7f4ba070f087fa722b9c513152f9e55c | |
parent | 30aaf3f8be724ddbf38dfe5c67b0123cd07d7e1d (diff) | |
download | acf-dnscache-337584d2a16c3a22551ab31c6eff7beb1c942815.tar.bz2 acf-dnscache-337584d2a16c3a22551ab31c6eff7beb1c942815.tar.xz |
Rewrite of DNScache.
git-svn-id: svn://svn.alpinelinux.org/acf/dnscache/trunk@1262 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rw-r--r-- | dnscache-config-html.lsp | 23 | ||||
-rw-r--r-- | dnscache-controller.lua | 181 | ||||
-rw-r--r-- | dnscache-createdomain-html.lsp | 17 | ||||
-rw-r--r-- | dnscache-editdomain-html.lsp | 17 | ||||
-rw-r--r-- | dnscache-editips-html.lsp | 15 | ||||
-rw-r--r-- | dnscache-expert-html.lsp | 72 | ||||
-rw-r--r-- | dnscache-listdomains-html.lsp | 34 | ||||
-rw-r--r-- | dnscache-logfile-html.lsp | 31 | ||||
-rw-r--r-- | dnscache-model.lua | 349 | ||||
-rw-r--r-- | dnscache-startstop-html.lsp | 26 | ||||
-rw-r--r-- | dnscache-status-html.lsp | 44 | ||||
-rw-r--r-- | dnscache.menu | 4 | ||||
-rw-r--r-- | dnscache.roles | 4 |
13 files changed, 483 insertions, 334 deletions
diff --git a/dnscache-config-html.lsp b/dnscache-config-html.lsp new file mode 100644 index 0000000..d1e414d --- /dev/null +++ b/dnscache-config-html.lsp @@ -0,0 +1,23 @@ +<? local form, viewlibrary = ... +require("viewfunctions") +?> +<? +--[[ DEBUG INFORMATION +io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") +io.write(html.cfe_unpack(form)) +io.write("</span>") +--]] +?> + +<? if viewlibrary and viewlibrary.dispatch_component then + viewlibrary.dispatch_component("status") +end ?> + +<H1>Config</H1> +<? + displayform(form) +?> + +<? if viewlibrary and viewlibrary.dispatch_component then + viewlibrary.dispatch_component("startstop") +end ?> diff --git a/dnscache-controller.lua b/dnscache-controller.lua index 0cc4d92..d50fb63 100644 --- a/dnscache-controller.lua +++ b/dnscache-controller.lua @@ -3,115 +3,108 @@ module(..., package.seeall) -- Load libraries require("format") --- Set variables -local newrecordtxt = "[New]" - --- ################################################################################ --- LOCAL FUNCTIONS - -local function displaycmdmanagement(pidofstatus) - -- Add a management buttons - local management = {} - management.start = cfe({ name="cmdmanagement", - label="Program control-panel", - value="Start", - type="submit", - }) - management.stop = cfe({ name="cmdmanagement", - label="Program control-panel", - value="Stop", - type="submit", - }) - management.restart = cfe({ name="cmdmanagement", - label="Program control-panel", - value="Restart", - type="submit", - }) - -- next CFE can be used to present the result of the previous action - management.actionresult = cfe({ name="actionresult", - label="Previous action result", - }) - - -- Disable management buttons based on if the process is running or not - if (pidofstatus) then - management.start.disabled = "yes" - else - management.stop.disabled = "yes" - management.restart.disabled = "yes" +local function handle_form(getFunction, setFunction, clientdata, option, label, descr) + local form = getFunction() + + if clientdata[option] then + form.errtxt = nil + for name,value in pairs(form.value) do + value.errtxt = nil + if value.type == "boolean" then + value.value = (clientdata[name] ~= nil) + elseif value.type == "list" then + value.value = {} + if clientdata[name] and clientdata[name] ~= "" then + for ip in string.gmatch(clientdata[name].."\n", "%s*(%S[^\n]*%S)%s*\n") do + table.insert(value.value, ip) + end + end + else + value.value = clientdata[name] or value.value + end + end + form = setFunction(form) + if not form.errtxt then + form.descr = descr + end end - return management -end + form.type = "form" + form.option = option + form.label = label --- ################################################################################ --- PUBLIC FUNCTIONS + return form +end default_action = "status" function status(self) - return { status=self.model.getstatus() } + return self.model.getstatus() end -function expert(self) - local modifications = self.clientdata.filecontent or "" - if ( self.clientdata.cmdsave ) then - modifications = self.model:update_filecontent(modifications) +function startstop(self) + local result + if self.clientdata.action then + result = self.model.startstop_service(self.clientdata.action) + self.sessiondata.dnscachestartstopresult = result + self.redirect_to_referrer(self) end - local url = self.conf.script .. self.conf.prefix .. self.conf.controller - - -- Start/Stop/Restart process - local cmdmanagement, actionresult - if ( self.clientdata.cmdmanagement) then - cmdmanagement = cfe({ - name="cmdmanagement", - label="Previous action result", - action=cfe({ - name="cmdmanagement", - value=string.lower(self.clientdata.cmdmanagement), -- This row contains start/stop/restart (one of these commands) - }), - }) - actionresult, cmdmanagement = self.model:startstop_service( cmdmanagement.action ) + + local status = self.model.getstatus() + status = status.value.status + if self.sessiondata.dnscachestartstopresult then + result = self.sessiondata.dnscachestartstopresult + self.sessiondata.dnscachestartstopresult = nil end - local status=self.model.getstatus() - local file = self.model:get_filedetails() - - -- Add buttons - file.cmdsave = cfe ({ - name="cmdsave", - label="Apply settings", - value="Apply", - type="submit", - }) - if (self.clientdata.cmdsave) then - file.cmdsave.descr="* Changes has been saved!" - end - - -- Management buttons (Hide/show buttons - local pidofstatus - if (string.lower(status.status.value) == "enabled" ) then pidofstatus = true end - management = displaycmdmanagement(pidofstatus) - if (actionresult) then - management.actionresult.descr=cmdmanagement.descr - management.actionresult.errtxt=cmdmanagement.errtxt + return cfe({ type="group", value={status=status, result=result} }) +end + +function config(self) + return handle_form(self.model.getconfig, self.model.setconfig, self.clientdata, "Save", "Edit Config", "Configuration Set") +end + +function expert(self) + local filedetails + if self.clientdata.Save then + filedetails = self.model.setconfigfile(self.clientdata.filecontent) + if not filedetails.errtxt then + filedetails.descr = "Config file set" + end + else + filedetails = self.model.getconfigfile() end - - return ( { - status = status, - file = file, - modifications = modifications, - management = management, - url = url, } ) + + filedetails.type = "form" + filedetails.option = "Save" + filedetails.label = "Set config file" + + return filedetails +end + +function editips(self) + return handle_form(self.model.getIPs, self.model.setIPs, self.clientdata, "Save", "Edit IP List", "IP List Set") end -function logfile(self) +function listdomains(self) + return self.model.getDomains() +end - local status=self.model.getstatus() - local logfile = self.model:get_logfile() +function createdomain(self) + local cmdresult = handle_form(self.model.getNewDomain, self.model.setNewDomain, self.clientdata, "Create", "Create new domain", "New domain created") + if cmdresult.descr then + redirect_to_referrer(self) + end + return cmdresult +end + +function editdomain(self) + return handle_form(function(form) return self.model.getDomain(self.clientdata.domain) end, + self.model.setDomain, self.clientdata, "Save", "Edit domain entry", "Domain saved") +end - return ({ - status = status, - logfile = logfile, - url = url, - }) +function deletedomain(self) + local cmdresult = self.model.deleteDomain(self.clientdata.domain) + redirect_to_referrer(self) + return cmdresult end diff --git a/dnscache-createdomain-html.lsp b/dnscache-createdomain-html.lsp new file mode 100644 index 0000000..4347fc0 --- /dev/null +++ b/dnscache-createdomain-html.lsp @@ -0,0 +1,17 @@ +<? local form, viewlibrary = ... +require("viewfunctions") +?> +<? +--[[ DEBUG INFORMATION +io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") +io.write(html.cfe_unpack(form)) +io.write("</span>") +--]] +?> + +<H1><?= form.label ?></H1> +<? + form.action = "createdomain" + local order = { } + displayform(form, order) +?> diff --git a/dnscache-editdomain-html.lsp b/dnscache-editdomain-html.lsp new file mode 100644 index 0000000..34ba902 --- /dev/null +++ b/dnscache-editdomain-html.lsp @@ -0,0 +1,17 @@ +<? local form, viewlibrary = ... +require("viewfunctions") +?> +<? +--[[ DEBUG INFORMATION +io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") +io.write(html.cfe_unpack(form)) +io.write("</span>") +--]] +?> + +<H1><?= form.label ?></H1> +<? + form.value.domain.contenteditable = false + local order = { "domain", "iplist" } + displayform(form, order) +?> diff --git a/dnscache-editips-html.lsp b/dnscache-editips-html.lsp new file mode 100644 index 0000000..b88e2c4 --- /dev/null +++ b/dnscache-editips-html.lsp @@ -0,0 +1,15 @@ +<? local form, viewlibrary = ... +require("viewfunctions") +?> +<? +--[[ DEBUG INFORMATION +io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") +io.write(html.cfe_unpack(form)) +io.write("</span>") +--]] +?> + +<H1><?= form.label ?></H1> +<? + displayform(form) +?> diff --git a/dnscache-expert-html.lsp b/dnscache-expert-html.lsp index 4f77e5e..c4ad955 100644 --- a/dnscache-expert-html.lsp +++ b/dnscache-expert-html.lsp @@ -1,6 +1,5 @@ -<? local form = ... -require("viewfunctions") -?> +<? local form, viewlibrary = ... ?> +<? require("viewfunctions") ?> <? --[[ DEBUG INFORMATION io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") @@ -9,50 +8,43 @@ io.write("</span>") --]] ?> -<H1>SYSTEM INFO</H1> -<DL> -<? -local myform = form.status -local tags = { "status", "version", "autostart", } -displayinfo(myform,tags,"viewonly") -?> -</DL> +<? ---[[ ?> +<? if viewlibrary and viewlibrary.dispatch_component then + viewlibrary.dispatch_component("status") +end ?> +<? --]] ?> -<form name="myform" action="" method="POST"> -<h1>CONFIGURATION</h1> -<H2>Expert config</H2> -<h3>File details</h3> +<H1>Configuration</H1> +<H2>Expert Configuration</H2> +<H3>File Details</H3> <DL> <? -local myform = form.file -local tags = { "filename", "filesize", "mtime", "sumerrors", } -displayinfo(myform,tags,"viewonly") +displayitem(form.value.filename) +displayitem(form.value.filesize) +displayitem(form.value.mtime) ?> </DL> -<H3>FILE CONTENT</H3> -<? -local myform = form.file -io.write(html.form[myform.filecontent.type](myform.filecontent)) -?> +<H3>File Content</H3> +<? if form.descr then ?><P CLASS='descr'><?= string.gsub(form.descr, "\n", "<BR>") ?></P><? end ?> +<? if form.errtxt then ?><P CLASS='error'><?= string.gsub(form.errtxt, "\n", "<BR>") ?></P><? end ?> +<form action="" method="POST"> +<textarea name="filecontent"> +<?= form.value.filecontent.value ?> +</textarea> +<? if form.value.filecontent.errtxt then ?><P CLASS='error'><?= string.gsub(form.value.filecontent.errtxt, "\n", "<BR>") ?></P><? end ?> -<H2>SAVE AND APPLY ABOVE SETTINGS</H2> -<DL> -<? -local tags = { "cmdsave", } -displayinfo(myform,tags) -?> -</DL> +<DL><DT></DT><DD><input class="submit" type="submit" name="<?= form.option ?>" value="Save"></DD></DL> +</form> + +<? if viewlibrary and viewlibrary.dispatch_component then + viewlibrary.dispatch_component("startstop") +end ?> <? --- Management buttons -local myform = form.management -local tags = { "start", "stop", "restart" } -if (myform) then - io.write("<H1>MANAGEMENT</H1>\n<DL>") - displaymanagement(myform,tags) - io.write("</DL>") -end +--[[ DEBUG INFORMATION +io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") +io.write(html.cfe_unpack(form)) +io.write("</span>") +--]] ?> -</form> - diff --git a/dnscache-listdomains-html.lsp b/dnscache-listdomains-html.lsp new file mode 100644 index 0000000..9c7ba20 --- /dev/null +++ b/dnscache-listdomains-html.lsp @@ -0,0 +1,34 @@ +<? local data, viewlibrary = ... +require("viewfunctions") +?> +<? +--[[ DEBUG INFORMATION +io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") +io.write(html.cfe_unpack(data)) +io.write("</span>") +--]] +?> + +<h1>Configuration</h1> +<h2>Edit/View DNS server entries</h2> +<TABLE> + <TR style="background:#eee;font-weight:bold;"> + <TD style="padding-right:20px;white-space:nowrap;text-align:left;" class="header">Action</TD> + <TD style="white-space:nowrap;text-align:left;" class="header">Domain</TD> + </TR> +<? for i,domain in ipairs(data.value) do ?> + <TR> + <TD style="padding-right:20px;white-space:nowrap;"> + <? io.write(html.link{value = "editdomain?domain=" .. domain, label="Edit " }) ?> + <? if domain ~= "@" then + io.write(html.link{value = "deletedomain?domain=" .. domain, label="Delete " }) + end ?> + </TD> + <TD style="white-space:nowrap;" width="90%"><?= domain ?></TD> + </TR> +<? end ?> +</TABLE> + +<? if viewlibrary and viewlibrary.dispatch_component then + viewlibrary.dispatch_component("createdomain") +end ?> diff --git a/dnscache-logfile-html.lsp b/dnscache-logfile-html.lsp deleted file mode 100644 index aa0b6e5..0000000 --- a/dnscache-logfile-html.lsp +++ /dev/null @@ -1,31 +0,0 @@ -<? local form = ... ?> -<? -require("viewfunctions") -?> - -<H1>SYSTEM INFO</H1> -<DL> -<? -local myform = form.status -local tags = { "status", "version", "autostart", } -displayinfo(myform,tags,"viewonly") -?> -</DL> - -<form name="myform" action="" method="POST"> -<h1>LOGFILE</h1> -<h2>Details</h2> -<DL> -<? -local myform = form.logfile -local tags = { "filename", "filesize", "mtime", "sumerrors", } -displayinfo(myform,tags,"viewonly") -?> -</DL> - -<H3>FILE CONTENT</H3> -<? -io.write(html.form[myform.filecontent.type](myform.filecontent)) -?> - -</form> diff --git a/dnscache-model.lua b/dnscache-model.lua index 649fcc5..fc41cc6 100644 --- a/dnscache-model.lua +++ b/dnscache-model.lua @@ -30,180 +30,271 @@ local function process_status_text(procname) end end -local function humanreadable(value) - local myvalue = tonumber(value) - if not (myvalue) then - return false - end - if ( myvalue > 1073741824 ) then - myvalue=((myvalue/1073741824) - (myvalue/1073741824%0.1)) .. "G" - elseif ( myvalue > 1048576 ) then - myvalue=((myvalue/1048576) - (myvalue/1048576%0.1)) .. "M" - elseif ( myvalue > 1024 ) then - myvalue=((myvalue/1024) - (myvalue/1024%0.1)) .. "k" - end - return myvalue -end - -local function list_servers() - local serverlist = {} - local serverdetails = {} - for k,v in pairs(posix.dir(baseurl .. "servers")) do - if not string.match(v, "^%.") then - if (fs.is_file(baseurl .. "servers/" .. v)) then - table.insert(serverlist, v) - serverdetails[v] = fs.read_file_as_array(baseurl .. "servers/" .. v) - end +local function validateconfig(config) + local success = true + if config.value.IPSEND and not validator.is_ipv4(config.value.IPSEND.value) then + config.value.IPSEND.errtxt = "Invalid IP address" + success = false + end + if config.value.CACHESIZE and not validator.is_integer(config.value.CACHESIZE.value) then + config.value.CACHESIZE.errtxt = "Must be an integer" + success = false + end + if config.value.IP and not validator.is_ipv4(config.value.IP.value) then + config.value.IP.errtxt = "Invalid IP address" + success = false + end + return success, config +end + +local function getfiledetails(file) + local filename = cfe({ value=file, label="File name" }) + local filecontent = cfe({ type="longtext", label="File content" }) + local filesize = cfe({ value="0", label="File size" }) + local mtime = cfe({ value="---", label="File date" }) + if fs.is_file(file) then + local filedetails = fs.stat(file) + filecontent.value = fs.read_file(file) + filesize.value = filedetails.size + mtime.value = filedetails.mtime + else + filename.errtxt = "File not found" + end + return cfe({ type="group", value={filename=filename, filecontent=filecontent, filesize=filesize, mtime=mtime}, label="Config file details" }) +end + +local function validatedomain(domain) + local success = false + local domains = getDomains() + domain.value.domain.errtxt = "Invalid domain" + for i,name in ipairs(domains.value) do + if name == domain.value.domain.value then + domain.value.domain.errtxt = nil + success = true + break + end + end + for i,name in ipairs(domain.value.iplist.value) do + if not validator.is_ipv4(name) then + domain.value.iplist.errtxt = "Invalid IP address" + success = false + break end end - return serverlist, serverdetails + return success, domain end + -- ################################################################################ -- PUBLIC FUNCTIONS -function startstop_service ( self, action ) - local cmd = action.value - local cmdresult,cmdmessage,cmderror,cmdaction = daemoncontrol.daemoncontrol(processname, cmd) - action.descr=cmdmessage - action.errtxt=cmderror - return cmdresult,action +function startstop_service(action) + -- action is validated in daemoncontrol + local cmdresult,cmdmessage,cmderror,cmdaction = daemoncontrol.daemoncontrol(processname, action) + return cfe({ type="boolean", value=cmdresult, descr=cmdmessage, errtxt=cmderror, label="Start/Stop result" }) end function getstatus() local status = {} - local config = getconfig() + local value, errtxt = processinfo.package_version(packagename) - status.version = cfe({ name = "version", + status.version = cfe({ label="Program version", value=value, errtxt=errtxt, }) - status.status = cfe({ name="status", + status.status = cfe({ label="Program status", value=process_status_text(processname), }) local autostart_sequense, autostart_errtxt = processinfo.process_botsequence(processname) - status.autostart = cfe({ name="autostart", + status.autostart = cfe({ label="Autostart sequence", value=autostart_sequense, errtxt=autostart_errtxt, }) + + return cfe({ type="group", value=status, label="DNS Cache Status" }) +end - status.ip = cfe({ name="ip", - label="Listening on", - value=config.IP or "", - }) +function getconfig() + local conf = getopts.getoptsfromfile(configfile, "") or {} + local output = {} + output.IPSEND = cfe({ value = conf.IPSEND or "", label="IP address for requests", + descr="Use 0.0.0.0 for default address" }) + output.CACHESIZE = cfe({ value=conf.CACHESIZE or "0", label="Cache size" }) + output.IP = cfe({ value=conf.IP or "", label="IP address to listen on" }) + output.FORWARDONLY = cfe({ type="boolean", value=(conf.FORWARDONLY and conf.FORWARDONLY ~= ""), + label="Forward only", descr="Servers are parent caches, not root servers" }) + return cfe({ type="group", value=output, label="DNS Cache Config" }) +end - status.cachesize = cfe({ name="cachesize", - label="Cache size", - value=humanreadable(config.CACHESIZE or ""), - }) +function setconfig(config) + local success, config = validateconfig(config) - local serverlist, serverdetails = list_servers() - status.servers = cfe({ name="servers", - label="Configured DNS-servers", - value=serverlist, - option=serverdetails, - }) + if success then + local file = fs.read_file(configfile) + getopts.setoptsinfile(file,"","IPSEND",config.value.IPSEND.value) + getopts.setoptsinfile(file,"","CACHESIZE",config.value.CACHESIZE.value) + getopts.setoptsinfile(file,"","IP",config.value.IP.value) + if config.value.IPSEND.value then + getopts.setoptsinfile(file,"","FORWARDONLY",config.value.IPSEND.value) + else + getopts.setoptsinfile(file,"","FORWARDONLY","") + end + fs.write_file(configfile, file) + else + config.errtxt = "Failed to set config" + end - return status + return config end -function get_logfile () - local file = {} - local cmdtxt = "grep ".. processname .. " /var/log/messages" - local cmd, error = io.popen(cmdtxt ,r) - local cmdoutput = cmd:read("*a") - cmd:close() +function getconfigfile() + local config = getfiledetails(configfile) + return config +end - file["filename"] = cfe({ - name="filename", - label="File name", - value=cmdtxt, - }) +function setconfigfile(modifications) + local configcontent = string.gsub(format.dostounix(modifications), "\n*$", "") + local config + if fs.is_file(configfile) then + fs.write_file(configfile, configcontent) + config = getfile(configfile) + else + config = getfile(configfile) + config.value.filecontent.value = configcontent + config.errtxt = "Failed to set config" + end - file["filecontent"] = cfe({ - type="longtext", - name="filecontent", - label="File content", - value=cmdoutput, - }) + return config +end + +function getIPs() + local ipdir = baseurl.."ip" + local iplist = cfe({ type="list", value={}, label="IPs to listen for" }) + if fs.is_dir(ipdir) then + for i,name in ipairs(posix.dir(ipdir)) do + if not string.match(name, "^%.") then + if (fs.is_file(ipdir.."/"..name)) then + table.insert(iplist.value, name) + end + end + end + end + return cfe({ type="group", value={iplist=iplist} }) +end - return file +function setIPs(iplist) + local reverseIPs = {} + for i,name in ipairs(iplist.value.iplist.value) do + -- check if a valid (or partial) ip + if not validator.is_partial_ipv4(name) then + iplist.value.iplist.errtxt = "Invalid IP address" + iplist.errtxt = "Failed to set IP list" + break + end + reverseIPs[name] = i + end + if not iplist.errtxt then + local currentIPlist = getIPs() + for i,name in ipairs(currentIPlist.value.iplist.value) do + if reverseIPs[name] then + reverseIPs[name] = nil + else + -- need to delete the file + local f = io.popen("rm "..baseurl.."ip/"..name) + f:close() + end + end + for name in pairs(reverseIPs) do + -- need to create the file + local f = io.popen("touch "..baseurl.."ip/"..name) + f:close() + end + end + return iplist end -function getconfig() - if (fs.is_file(configfile)) then - return getopts.getoptsfromfile(configfile, "") or {} +function getDomains() + local domaindir = baseurl.."servers" + local domainlist = cfe({ type="list", value={}, label="DNS Server Domains" }) + if fs.is_dir(domaindir) then + for i,name in ipairs(posix.dir(domaindir)) do + if not string.match(name, "^%.") then + if (fs.is_file(domaindir.."/"..name)) then + table.insert(domainlist.value, name) + end + end + end end - return {} + return domainlist end -function get_filedetails(self,num) - local path - if (num == "2") then - path = configfile2 - else - path = configfile - end - local file = {} - local filedetails = {} - local config = {} - local filenameerrtxt - if (path) and (fs.is_file(path)) then - filedetails = fs.stat(path) - config = getconfig(path) +function getNewDomain() + local domain = cfe({ label="Domain" }) + return cfe({ type="group", value={domain=domain} }) +end + +function setNewDomain(domain) + if "" ~= string.gsub(domain.value.domain.value..".", "%w+%.", "") then + domain.value.domain.errtxt = "Invalid domain" + domain.errtxt = "Failed to create domain" + elseif fs.is_file(baseurl.."servers/"..domain.value.domain.value) then + domain.value.domain.errtxt = "Domain already exists" + domain.errtxt = "Failed to create domain" else - config = {} - config.filename = {} - config["filename"]["errtxt"]="Config file '".. path .. "' is missing!" + local f = io.popen("touch "..baseurl.."servers/"..domain.value.domain.value) + f:close() + domain.descr = "Created domain" end + return domain +end - file["filename" .. (num or "")] = cfe({ - name="filename" .. (num or ""), - label="File name", - value=path, - errtxt=filenameerrtxt - }) - file["filesize" .. (num or "")] = cfe({ - name="filesize" .. (num or ""), - label="File size", - value=filedetails.size or 0, - }) - file["mtime" .. (num or "")] = cfe({ - name="mtime" .. (num or ""), - label="File date", - value=filedetails.mtime or "---", - }) - file["filecontent" .. (num or "")] = cfe({ - type="longtext", - name="filecontent" .. (num or ""), - label="File content", - value=fs.read_file(path), - }) - - -- Sum all errors into one cfe - local sumerrors = "" - for k,v in pairs(config) do - if (config[k]) and (config[k]["errtxt"]) and (config[k]["errtxt"] ~= "") then - sumerrors = sumerrors .. config[k]["errtxt"] .. "\n" +function getDomain(getdomainname) + local domain = cfe({ value=getdomainname, label="Domain", errtxt="Invalid domain" }) + local iplist = cfe({ type="list", value={}, label="List of DNS servers" }) + local domains = getDomains() + for i,name in ipairs(domains.value) do + if name == getdomainname then + domain.errtxt = nil + break end end - if (sumerrors ~= "") then - file["sumerrors" .. (num or "")] = cfe ({ - name="sumerrors" .. (num or ""), - label = "Configuration errors", - errtxt = string.match(sumerrors, "(.-)\n$"), - }) + if not domain.errtxt then + local content = fs.read_file(baseurl.."servers/"..getdomainname) + for name in string.gmatch(content.."\n", "([^\n]+)\n") do + table.insert(iplist.value, name) + end end - - return file + return cfe({ type="group", value={domain=domain, iplist=iplist} }) end -function update_filecontent (self, modifications) - local path = configfile - local file_result,err = fs.write_file(path, format.dostounix(modifications)) - return file_result + +function setDomain(domain) + local success, domain = validatedomain(domain) + if success then + fs.write_file(baseurl.."servers/"..domain.value.domain.value, + table.concat(domain.value.iplist.value, "\n") ) + end + return domain end +function deleteDomain(domainname) + local cmdresult = cfe({ value="Domain not deleted", label="Delete domain result", errtxt="Invalid domain" }) + local domains = getDomains() + if domainname == "@" then + cmdresult.errtxt = "Cannot delete root domain" + else + for i,name in ipairs(domains.value) do + if name == domainname then + local f = io.popen("rm "..baseurl.."servers/"..name) + f:close() + cmdresult.errtxt = nil + cmdresult.value = "Domain deleted" + break + end + end + end + return cmdresult +end diff --git a/dnscache-startstop-html.lsp b/dnscache-startstop-html.lsp new file mode 100644 index 0000000..f963d3b --- /dev/null +++ b/dnscache-startstop-html.lsp @@ -0,0 +1,26 @@ +<? local data = ... ?> +<? --[[ +io.write(html.cfe_unpack(data)) +--]] ?> + +<H1>Management</H1> +<DL> +<form action="startstop" method="POST"> +<DT>Program control-panel</DT> +<DD> +<input class="submit" type="submit" name="action" value="Start" <? if data.value.status.value== "Enabled" then io.write("disabled") end ?>> +<input class="submit" type="submit" name="action" value="Stop" <? if data.value.status.value== "Disabled" then io.write("disabled") end ?>> +<input class="submit" type="submit" name="action" value="Restart" <? if data.value.status.value== "Disabled" then io.write("disabled") end ?>> +</DD> +</form> + +<? if data.value.result then ?> +<DT>Previous action result</DT> +<DD> +<? if data.value.result.descr then ?> +<P CLASS='descr'><?= string.gsub(data.value.result.descr, "\n", "<BR>") ?></P> +<? end if data.value.result.errtxt then ?> +<P CLASS='error'><?= string.gsub(data.value.result.errtxt, "\n", "<BR>") ?></P> +<? end end ?> +</DD> +</DL> diff --git a/dnscache-status-html.lsp b/dnscache-status-html.lsp index 40e4ee4..05b4a7a 100644 --- a/dnscache-status-html.lsp +++ b/dnscache-status-html.lsp @@ -1,49 +1,19 @@ -<? local form = ... +<? local data = ... require("viewfunctions") ?> <? --[[ DEBUG INFORMATION io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") -io.write(html.cfe_unpack(form)) +io.write(html.cfe_unpack(data)) io.write("</span>") --]] ?> -<H1>SYSTEM INFO</H1> +<H1>System Info</H1> <DL> -<? -local myform = form.status -local tags = { "status", "version", "autostart", } -displayinfo(myform,tags,"viewonly") -?> -</DL> - -<H2>PROGRAM SPECIFIC OPTIONS/INFORMATION</H2> -<DL> -<? -local myform = form.status -local tags = { "ip", "cachesize", } -displayinfo(myform,tags,"viewonly") -?> - -<? -local myform = form.status.servers -io.write("\t<DT") -if (myform.errtxt) then io.write(" class='error'") end -io.write(">" .. myform.label .. "</DT>\n") -io.write("\t\t<DD>\n") -for k,v in pairs(myform.value or {}) do - io.write("\t\t\t<TABLE STYLE='margin-bottom:10px;'>") - io.write("\n\t\t\t<TR><TD STYLE='font-weight:bold;border:none;'><IMG SRC='/skins/static/tango/16x16/status/network-idle.png' width='16' height='16' alt> " .. v .. "</TD><TD STYLE='border:none;'></TD></TR>\n") - for k1,v1 in pairs(myform.option[v]) do - io.write("\n\t\t\t<TR STYLE='padding-bottom:10px;'><TD WIDTH='150px' STYLE='padding-left:30px;border:none;'>"..v1) - end - - io.write("\t\t\t</TABLE>") -end -io.write("\t\t</DD>\n") +<? +displayitem(data.value.status) +displayitem(data.value.version) +displayitem(data.value.autostart) ?> - - </DL> - diff --git a/dnscache.menu b/dnscache.menu index c8a0d32..698225d 100644 --- a/dnscache.menu +++ b/dnscache.menu @@ -1,5 +1,7 @@ #CAT GROUP/DESC TAB ACTION Networking 11DNScache Status status +Networking 11DNScache Config config +Networking 11DNScache IPs editips +Networking 11DNScache DNS_Server_Entries listdomains Networking 11DNScache Expert expert -Networking 11DNScache Logfile logfile diff --git a/dnscache.roles b/dnscache.roles index 74c0431..a4f82fc 100644 --- a/dnscache.roles +++ b/dnscache.roles @@ -1,2 +1,2 @@ -READ=dnscache:status,dnscache:logfile -UPDATE=dnscache:expert +READ=dnscache:status +UPDATE=dnscache:config,dnscache:expert,dnscache:startstop,dnscache:editips,dnscache:listdomains,dnscache:createdomain,dnscache:editdomain,dnscache:deletedomain |