diff options
author | Ted Trask <ttrask01@yahoo.com> | 2012-12-05 03:59:31 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2012-12-05 03:59:31 +0000 |
commit | bf240e45183c7a1aff68a39b59b09638cae7e7e3 (patch) | |
tree | 944dc3564f43876a03e6c45430d1a3174ef035c4 | |
parent | f8e81a44e9229f72b73582be8f8e1548632dc0f4 (diff) | |
download | acf-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.lua | 228 |
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 |