Add API for CNF's status information query 42/4042/3
authorHuifeng Le <huifeng.le@intel.com>
Thu, 7 Jan 2021 06:48:45 +0000 (06:48 +0000)
committerHuifeng Le <huifeng.le@intel.com>
Mon, 11 Jan 2021 07:45:02 +0000 (07:45 +0000)
Signed-off-by: Huifeng Le <huifeng.le@intel.com>
Change-Id: Ieb564cfda4cabb8994a311f0fc6a47ecf337da29
Signed-off-by: Huifeng Le <huifeng.le@intel.com>
platform/cnf/src/rest_v1/modules/interface.lua [new file with mode: 0644]
platform/cnf/src/rest_v1/modules/wan.lua [new file with mode: 0644]
platform/cnf/src/rest_v1/status_rest.lua [new file with mode: 0644]

diff --git a/platform/cnf/src/rest_v1/modules/interface.lua b/platform/cnf/src/rest_v1/modules/interface.lua
new file mode 100644 (file)
index 0000000..e59311b
--- /dev/null
@@ -0,0 +1,103 @@
+-- Copyright 2020 Intel Corporation, Inc
+-- Licensed to the public under the Apache License 2.0.
+
+module("luci.controller.rest_v1.modules.interface", package.seeall)
+
+NX = require("nixio")
+sys = require "luci.sys"
+util = require "luci.util"
+utils = require "luci.controller.rest_v1.utils"
+
+fields_table = {
+    {field="ip_address", key="inet addr", type="array"},
+    {field="ip6_address", key="inet6 addr", type="array"},
+    {field="mac_address", key="HWaddr"},
+    {field="received_packets", key="RX packets"},
+    {field="send_packets", key="TX packets"},
+    {field="status", key=function(data) if string.match(data, "[%s]UP[%s]") ~= nil then return "UP" else return "DOWN" end end},
+}
+
+function register()
+    return "interface", _M["get_interface_info"]
+end
+
+function get_field(data, key, field_type)
+    if type(key) == "function" then
+        return key(data)
+    end
+
+    local reg = {
+        key .. ":[^%s]+[%s]",
+        key .. " [^%s]+[%s]",
+        key .. ": [^%s]+[%s]",
+    }
+
+    local ret = nil
+    for index=1, #reg do
+        for item in string.gmatch(data, reg[index]) do
+            local value = nil
+            local i,j = string.find(item, key .. ": ")
+            if i ~= nil then
+                value = string.sub(item, j+1, string.len(item)-1)
+            else
+                i,j = string.find(item, key .. ":")
+                if i ~= nil then
+                    value = string.sub(item, j+1, string.len(item)-1)
+                else
+                    i,j = string.find(item, key .. " ")
+                    if i ~= nil then
+                        value = string.sub(item, j+1, string.len(item)-1)
+                    end
+                end
+            end
+            if value ~= nil then
+                if field_type == "array" then
+                    if ret == nil then
+                        ret = {value}
+                    else
+                        ret[#ret+1] = value
+                    end
+                else
+                    ret = value
+                    break
+                end
+            end
+        end
+    end
+    return ret
+end
+
+function get_interface(interface)
+    local ret = {}
+    local data = util.exec("ifconfig " .. interface)
+    if data == nil then
+        for j=1, 3 do
+            utils.log("ifconfig failed, retrying ... ")
+            NX.nanosleep(1)
+            data = util.exec("ifconfig " .. interface)
+            if data ~= nil then
+                break
+            end
+        end
+    end
+    ret["name"] = interface
+    for i,v in pairs(fields_table) do
+        local value = get_field(data, v["key"], v["type"])
+        if value ~= nil then
+            ret[v["field"]] = value
+        end
+    end
+    return ret
+end
+
+function get_interface_info()
+    local ret = {}
+    local index = 1
+    for interface in util.execi("ifconfig | awk '/^[^ \t]+/{print $1}'") do
+        if interface ~= "lo" then
+           ret[index] = get_interface(interface)
+           index = index + 1
+        end
+    end
+    return ret
+end
diff --git a/platform/cnf/src/rest_v1/modules/wan.lua b/platform/cnf/src/rest_v1/modules/wan.lua
new file mode 100644 (file)
index 0000000..548de7a
--- /dev/null
@@ -0,0 +1,14 @@
+-- Copyright 2020 Intel Corporation, Inc
+-- Licensed to the public under the Apache License 2.0.
+
+module("luci.controller.rest_v1.modules.wan", package.seeall)
+
+util = require "luci.util"
+
+function register()
+    return "wan", _M["get_wan_info"]
+end
+
+function get_wan_info()
+    return util.ubus("mwan3", "status", {})
+end
\ No newline at end of file
diff --git a/platform/cnf/src/rest_v1/status_rest.lua b/platform/cnf/src/rest_v1/status_rest.lua
new file mode 100644 (file)
index 0000000..c05001a
--- /dev/null
@@ -0,0 +1,115 @@
+-- Copyright 2020 Intel Corporation, Inc
+-- Licensed to the public under the Apache License 2.0.
+
+module("luci.controller.rest_v1.status_rest", package.seeall)
+
+utils = require "luci.controller.rest_v1.utils"
+local fs = require "nixio.fs"
+local deb = require "debug"
+
+local module_list = {}
+local module_list_updated_time = 0
+__file__ = deb.getinfo(1, 'S').source:sub(2)
+
+function index()
+    ver = "v1"
+    entry({"sdewan", ver, "status"}, call("handle_request")).leaf = true
+end
+
+-- base path
+function basepath()
+    return fs.dirname(__file__)
+end
+
+-- create module list
+function create_module_list(cur)
+    module_list_updated_time = cur
+
+    local base = basepath() .. "/modules/"
+    for mfile in (fs.glob(base .. "*.lua")) do
+        local mname = "luci.controller.rest_v1.modules." .. mfile:sub(#base+1, #mfile-4):gsub("/", ".")
+        local s, mod = pcall(require, mname)
+        if s then
+            local reg_func = mod.register
+            if type(reg_func) == "function" then
+                local name, qfunc = reg_func()
+                module_list[#module_list + 1] = {name = name, func = qfunc}
+            else
+                utils.log("Function register is not found in " .. mname)
+            end
+        else
+            utils.log("Error to load module " .. mname)
+        end
+    end
+end
+
+-- refresh module list
+function refresh_module_list()
+    local cur = os.time()
+    if #module_list == 0 or (cur - module_list_updated_time) >= 10 then
+        module_list = {}
+        create_module_list(cur)
+    end
+end
+
+function get_status()
+    utils.log("Query all module status")
+    refresh_module_list()
+
+    local objs = {}
+    for i=1, #module_list do
+        local obj = {}
+        obj["name"] = module_list[i].name
+        obj["status"] = module_list[i].func()
+        objs[#objs + 1] = obj
+    end
+
+    return objs
+end
+
+function get_module_status(module_name)
+       utils.log("Query module status: %s" % module_name)
+    refresh_module_list()
+
+    local obj = {}
+    for i=1, #module_list do
+        if module_name == module_list[i].name then
+            obj["name"] = module_name
+            obj["status"] = module_list[i].func()
+            return obj
+        end
+    end
+
+    return nil
+end
+
+-- Request Handler
+function handle_request()
+    if not (utils.validate_req_method("GET")) then
+        return
+    end
+
+    local uri_list = utils.get_URI_list()
+    if uri_list == nil then
+        return
+    end
+
+    if #uri_list == 5 then
+        -- get all status
+        local objs = get_status()
+        utils.response_object(objs)
+    else
+        if #uri_list == 6 then
+            -- get module status
+            local module_name = uri_list[#uri_list]
+            local obj = get_module_status(module_name)
+            if obj == nil then
+                utils.response_error(400, "Bad request URI: " .. module_name .. " is not supported")
+            else
+                utils.response_object(obj)
+            end
+        else
+            utils.response_error(400, "Bad request URI")
+        end
+    end
+end