summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Trask <ttrask01@yahoo.com>2012-12-05 03:59:31 +0000
committerTed Trask <ttrask01@yahoo.com>2012-12-05 03:59:31 +0000
commitbf240e45183c7a1aff68a39b59b09638cae7e7e3 (patch)
tree944dc3564f43876a03e6c45430d1a3174ef035c4
parentf8e81a44e9229f72b73582be8f8e1548632dc0f4 (diff)
downloadacf-alpine-baselayout-bf240e45183c7a1aff68a39b59b09638cae7e7e3.tar.bz2
acf-alpine-baselayout-bf240e45183c7a1aff68a39b59b09638cae7e7e3.tar.xz
Interfaces - reorganize iface structure and always return full interface structure
The model should report the entire form, not pieces at a time. The view can determine which options to show. Modified the validation and writing to interfaces file to only consider the valid options for given family/method.
-rw-r--r--interfaces-model.lua228
1 files changed, 124 insertions, 104 deletions
diff --git a/interfaces-model.lua b/interfaces-model.lua
index 8b7e878..59e16ba 100644
--- a/interfaces-model.lua
+++ b/interfaces-model.lua
@@ -13,92 +13,94 @@ local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
local array
-- iface is a local table with cfes for the various parts of interface definitions
-local iface = { tags = { comment = {type="longtext", label="Comments", seq=2},
- auto = {type="boolean", value=false, label="Auto bring-up", seq=3},
- name = {label="Interface Name", seq=1},
- family = {type="select", label="Address Family", option={"inet", "ipx", "inet6"}, seq=4},
- ['pre-up'] = {type="longtext", label="'pre-up' actions", seq=6},
- up = {type="longtext", label="'up' actions", seq=7},
- down = {type="longtext", label="'down' actions", seq=8},
- ['post-down'] = {type="longtext", label="'post-down' actions", seq=9} },
- method_tag = {type="select", label="Method", seq=5},
- family_methods = { inet = {"loopback", "static", "manual",
- "dhcp", "bootp", "ppp", "wvdial"},
- ipx = {"static", "dynamic"},
- inet6 = {"loopback", "static", "manual", "v4tunnel"} },
- method_options = {inet = {loopback = {},
- static = {address = {label="Address"},
- netmask = {label="Netmask"},
- broadcast = {label="Broadcast address"},
- network = {label="Network address"},
- metric = {label="Routing metric"},
- gateway = {label="Default gateway"},
- pointopoint = {label="Point-to-point address"},
- media = {label="Medium type"},
- hwaddress = {label="Hardware address"},
- mtu = {label="MTU size"} },
- manual = {},
- dhcp = {hostname = {label="Hostname"},
- leasehours = {label="Preferred lease time (hours)"},
- leasetime = {label="Preferred lease time (seconds)"},
- vendor = {label="Vendor class identifier"},
- client = {label="Client identifier"},
- hwaddress = {label="Hardware address"} },
- bootp = {bootfile = {label="Boot file"},
- server = {label="Server address"},
- hwaddr = {label="Hardware address"} },
- ppp = {provider = {label="Provider name"} },
- wvdial = {provider = {label="Provider name"} },
- },
- ipx = { static = {frame = {label="Ethernet frame type"},
- netnum = {label="Network number"} },
- dynamic = {frame = {label="Ethernet frame type"} },
- },
- inet6 ={loopback = {},
- static = {address = {label="Address"},
- netmask = {label="Netmask"},
- gateway = {label="Default gateway"},
- media = {label="Medium type"},
- hwaddress = {label="Hardware address"},
- mtu = {label="MTU size"} },
- manual = {},
- v4tunnel = {address = {label="Address"},
- netmask = {label="Netmask"},
- endpoint = {label="Endpoint address"},
- ['local'] = {label="Local address"},
- gateway = {label="Default gateway"},
- ttl = {label="TTL setting"} },
- },
- },
- }
-
-
-local get_iface_type = function (family, method)
+-- Depending on the address family and corresponding method, different options are valid
+local iface = {
+ required = {
+ comment = {type="longtext", label="Comments", seq=2},
+ auto = {type="boolean", value=false, label="Auto bring-up", seq=3},
+ name = {label="Interface Name", seq=1},
+ family = {type="select", label="Address Family", option={"inet", "ipx", "inet6"}, seq=4},
+ method = {type="select", label="Method", option={"loopback", "static", "manual", "dhcp", "bootp", "ppp", "wvdial", "dynamic", "v4tunnel"}, seq=5},
+ ['pre-up'] = {type="longtext", label="'pre-up' actions", seq=100},
+ up = {type="longtext", label="'up' actions", seq=101},
+ down = {type="longtext", label="'down' actions", seq=102},
+ ['post-down'] = {type="longtext", label="'post-down' actions", seq=103},
+ },
+ family_methods = {
+ inet = {"loopback", "static", "manual", "dhcp", "bootp", "ppp", "wvdial"},
+ ipx = {"static", "dynamic"},
+ inet6 = {"loopback", "static", "manual", "v4tunnel"},
+ },
+ method_options = {
+ inet = {
+ static = {"address", "netmask", "broadcast", "network", "metric", "gateway", "pointopoint", "media", "hwaddress", "mtu"},
+ dhcp = {"hostname", "leasehours", "leasetime", "vendor", "client", "hwaddress"},
+ bootp = {"bootfile", "server", "hwaddr"},
+ ppp = {"provider"},
+ wvdial = {"provider"},
+ },
+ ipx = {
+ static = {"frame", "netnum"},
+ dynamic = {"frame"},
+ },
+ inet6 ={
+ static = {"address", "netmask", "gateway", "media", "hwaddress", "mtu"},
+ v4tunnel = {"address", "netmask", "endpoint", "local", "gateway", "ttl"},
+ },
+ },
+ optional = {
+ address = {label="Address", seq=6},
+ netmask = {label="Netmask", seq=7},
+ endpoint = {label="Endpoint address", seq=8},
+ ['local'] = {label="Local address", seq=9},
+ broadcast = {label="Broadcast address", seq=10},
+ network = {label="Network address", seq=11},
+ metric = {label="Routing metric", seq=12},
+ gateway = {label="Default gateway", seq=13},
+ pointopoint = {label="Point-to-point address", seq=14},
+ media = {label="Medium type", seq=15},
+ hostname = {label="Hostname", seq=16},
+ leasehours = {label="Preferred lease time (hours)", seq=17},
+ leasetime = {label="Preferred lease time (seconds)", seq=18},
+ vendor = {label="Vendor class identifier", seq=19},
+ client = {label="Client identifier", seq=20},
+ hwaddress = {label="Hardware address", seq=21},
+ mtu = {label="MTU size", seq=22},
+ bootfile = {label="Boot file", seq=23},
+ server = {label="Server address", seq=24},
+ hwaddr = {label="Hardware address", seq=25},
+ provider = {label="Provider name", seq=26},
+ frame = {label="Ethernet frame type", seq=27},
+ netnum = {label="Network number", seq=28},
+ ttl = {label="TTL setting", seq=29},
+ },
+}
+
+-- Create an interface structure with all options
+local get_blank_iface = function ()
local f = {}
- for name,table in pairs(iface.tags) do
+ for name,table in pairs(iface.required) do
f[name] = cfe(table)
end
- f.family.value = family or ""
- if family and iface.family_methods[family] then
- f.method = cfe(iface.method_tag)
- f.method.option = iface.family_methods[family]
- f.method.value = method or ""
-
- if method and iface.method_options[family][method] then
- for name,table in pairs(iface.method_options[family][method]) do
- f[name] = cfe(table)
- end
- elseif method then
- f.method.errtxt = "Invalid method"
- end
- elseif family then
- f.family.errtxt = "Invalid family"
+ for name,table in pairs(iface.optional) do
+ f[name] = cfe(table)
end
return cfe({ type="group", value=f, label="Interface description" })
end
+-- Get a reverse list of options valid for a given family / method
+local get_options = function (family, method)
+ local optional = {}
+ if iface.method_options[family] and iface.method_options[family][method] then
+ for i,o in ipairs(iface.method_options[family][method]) do
+ optional[o] = true
+ end
+ end
+ return optional
+end
+
-- return true or false + the index of array entry matching "name"
local arrayindex = function (name)
if name and #name > 0 then
@@ -162,11 +164,13 @@ local unpack_interfaces = function ()
auto[name] = true
elseif string.match(line, "^iface") then
local name, family, method = string.match(line, "%S+%s+(%S+)%s+(%S+)%s+(%S+)")
- array[#array + 1] = get_iface_type(family, method)
+ array[#array + 1] = get_blank_iface()
local interface = array[#array].value
interface.comment.value = comment
comment = ""
interface.name.value = name or ""
+ interface.family.value = family or ""
+ interface.method.value = method or ""
elseif #array then
-- it must be some kind of parameter
local param, val =
@@ -195,10 +199,17 @@ local unpack_interfaces = function ()
return array
end
--- This function takes array and writes the interfaces file
+-- This function takes array and writes the interfaces file (only writing options valid for the family/method combo)
local commit_interfaces = function()
local str = ""
local strings = {}
+ local required = {}
+ for name,value in pairs(iface.required) do
+ -- Check for the ones handled by other means
+ if name~="comment" and name~="name" and name~="family" and name~="method" and name~="auto" then
+ required[name] = true
+ end
+ end
for n,int in ipairs(array) do
local me = int.value
if me.comment.value ~= "" then
@@ -209,9 +220,9 @@ local commit_interfaces = function()
end
strings[#strings+1] = string.format("iface %s %s %s", me.name.value,
me.family.value, me.method.value)
+ local optional = get_options(me.family.value, me.method.value)
for name,entry in pairs(me) do
- if name~="comment" and name~="name" and name~="family" and name~="method" and name~="auto"
- and entry.value ~= "" then
+ if (required[name] or optional[name]) and entry.value ~= "" then
strings[#strings+1] = expandentry(entry.value, "\t"..name)
end
end
@@ -222,37 +233,47 @@ local commit_interfaces = function()
fs.write_file(filename, filecontent)
end
+-- Validate the interface (assuming valid family / method, will only validate the appropriate options)
local validate_interface = function (def)
local success = true
- -- since the structure is different depending on the family and method ...
- local method = ""
- if def.value.method then method = def.value.method.value end
- local newdef = get_iface_type(def.value.family.value, method)
- for name,option in pairs(newdef.value) do
- if option.errtxt then
- success = false
+ local optional = {}
+
+ -- since the structure is different depending on the family and method, check them first
+ success = modelfunctions.validateselect(def.value.family) and success
+ success = modelfunctions.validateselect(def.value.method) and success
+ if success then
+ -- Validate the method (given the family)
+ local method = cfe(iface.required.method)
+ method.value = def.value.method.value
+ method.option = {}
+ if iface.family_methods[def.value.family.value] then
+ method.option = iface.family_methods[def.value.family.value]
end
- if def.value[name] then
- option.value = def.value[name].value
+ if not modelfunctions.validateselect(method) then
+ def.value.method.errtxt = "Invalid method for this address family"
+ success = false
end
- end
- -- Now, start to validate (family and method already validated)
- if #newdef.value.name.value == 0 then
- newdef.value.name.errtxt = "The interface must have a name"
+ -- Determine the list of valid options
+ optional = get_options(def.value.family.value, def.value.method.value)
+ end
+
+ if #def.value.name.value == 0 then
+ def.value.name.errtxt = "The interface must have a name"
success = false
- elseif string.find(newdef.value.name.value, "%s") then
- newdef.value.name.errtxt = "Cannot contain spaces"
+ elseif string.find(def.value.name.value, "%s") then
+ def.value.name.errtxt = "Cannot contain spaces"
success = false
end
+
-- More validation tests go here ---
- --
+ -- for optional fields, first check optional[name] to see if it should be validated
if not success then
- newdef.errtxt = "Failed validation"
+ def.errtxt = "Failed validation"
end
- return success, newdef
+ return success
end
local list_interfaces = function()
@@ -279,7 +300,7 @@ get_iface_by_name = function(self, clientdata)
unpack_interfaces()
local rc, idx = arrayindex(clientdata.name or "")
if rc == false then
- local ret = get_iface_type()
+ local ret = get_blank_iface()
ret.value.name.value = name
ret.value.name.errtxt = "Interface does not exist"
return ret
@@ -288,14 +309,13 @@ get_iface_by_name = function(self, clientdata)
end
get_iface = function(self, clientdata)
- unpack_interfaces()
- return get_iface_type(clientdata.family, clientdata.method)
+ return get_blank_iface()
end
create_iface = function(self, def)
unpack_interfaces()
local rc
- rc, def = validate_interface( def )
+ rc = validate_interface( def )
if rc then
idx = #array
@@ -315,7 +335,7 @@ update_iface = function(self, def)
if rc == false then
def.value.name.errtxt = "This is an invalid interface name"
else
- rc, def = validate_interface( def )
+ rc = validate_interface( def )
end
if rc then