Implement Route RESTful API 53/4053/4
authorLe Yao <le.yao@intel.com>
Thu, 14 Jan 2021 07:54:13 +0000 (07:54 +0000)
committerLe Yao <le.yao@intel.com>
Mon, 18 Jan 2021 07:15:33 +0000 (07:15 +0000)
Offer the Route add/del/replace APIs for users

Signed-off-by: Le Yao <le.yao@intel.com>
Change-Id: I43c44f0de048e40a254cab370a872616ecd28ad2

platform/cnf/src/Dockerfile_1806_mwan3.tpl
platform/cnf/src/Dockerfile_1806_mwan3_noproxy.tpl
platform/cnf/src/rest_v1/index.lua
platform/cnf/src/rest_v1/route_rest.lua [new file with mode: 0644]
platform/cnf/src/route_cr.info [new file with mode: 0644]

index 12ebd8a..8e937d2 100644 (file)
@@ -21,6 +21,7 @@ COPY ipsec_exec /etc/init.d/ipsec
 COPY sdewan.user /etc/sdewan.user
 COPY sdewan_svc.info /etc/sdewan_svc.info
 COPY app_cr.info /etc/app_cr.info
+COPY route_cr.info /etc/route_cr.info
 COPY default_firewall /etc/config/firewall
 COPY rest_v1 /usr/lib/lua/luci/controller/rest_v1
 COPY 10-default.conf /etc/sysctl.d/10-default.conf
index 6b33c47..f180084 100644 (file)
@@ -18,6 +18,7 @@ COPY ipsec_exec /etc/init.d/ipsec
 COPY sdewan.user /etc/sdewan.user
 COPY sdewan_svc.info /etc/sdewan_svc.info
 COPY app_cr.info /etc/app_cr.info
+COPY route_cr.info /etc/route_cr.info
 COPY default_firewall /etc/config/firewall
 COPY rest_v1 /usr/lib/lua/luci/controller/rest_v1
 COPY 10-default.conf /etc/sysctl.d/10-default.conf
index f320983..86786d1 100644 (file)
@@ -11,6 +11,8 @@ function index()
     entry({"sdewan", "ipsec", ver}, call("help")).dependent = false
     entry({"sdewan", "service", ver}, call("help")).dependent = false
     entry({"sdewan", "application", ver}, call("help")).dependent = false
+    entry({"sdewan", "route", ver}, call("help")).dependent = false
+
 end
 
 function help()
diff --git a/platform/cnf/src/rest_v1/route_rest.lua b/platform/cnf/src/rest_v1/route_rest.lua
new file mode 100644 (file)
index 0000000..25f1f59
--- /dev/null
@@ -0,0 +1,247 @@
+-- Copyright 2020 Intel Corporation, Inc
+-- Licensed to the public under the Apache License 2.0.
+
+module("luci.controller.rest_v1.route_rest", package.seeall)
+
+local uci = require "luci.model.uci"
+
+json = require "luci.jsonc"
+io = require "io"
+sys = require "luci.sys"
+utils = require "luci.controller.rest_v1.utils"
+
+function index()
+    ver = "v1"
+    configuration = "route"
+    entry({"sdewan", configuration, ver, "routes"}, call("handle_request")).leaf = true
+end
+
+-- Request Handler
+function handle_request()
+    local method = utils.get_req_method()
+    if method == "PUT" then
+        return update_route()
+    elseif method == "POST" then
+        return create_route()
+    elseif method == "DELETE" then
+        return delete_route()
+    elseif method == "GET" then
+        return get_route()
+    else
+        utils.response_error(405, "Method Not Allowed")
+    end
+end
+
+-- Post
+function create_route()
+    local obj = utils.get_request_body_object()
+    if obj == nil then
+        utils.response_error(400, "No Route Data")
+        return
+    end
+    if is_duplicated(obj.name, obj.dst) then
+        utils.response_error(409, "Duplicated Route Configuration")
+        return
+    end
+    if not utils.is_valid_ip(obj.dst) then
+        utils.response_error(400, "Invalid Destination IP Address")
+        return
+    end
+    if not utils.is_valid_ip_address(obj.gw) then
+        utils.response_error(400, "Invalid gateway IP Address")
+        return
+    end
+
+    local iface = get_dev_name(obj.dev)
+    if obj.table == "default" then
+        local comm = "ip route add "..obj.dst.." via "..obj.gw.." dev "..iface
+        os.execute(comm)
+    elseif obj.table == "cnf" then
+        local comm = "ip route add table 40 "..obj.dst.." via "..obj.gw.." dev "..iface
+        os.execute(comm)
+    else
+        utils.response_error(400, "Bad route table")
+        return
+    end
+    local file = io.open("/etc/route_cr.info", "a+")
+    file:write(obj.name, " ", obj.dst, " ", obj.gw, " ", obj.dev, " ", obj.table, "\n")
+    file:close()
+    luci.http.prepare_content("application/json")
+    luci.http.write_json(obj)
+end
+
+-- Delete
+function delete_route()
+    local uri_list = utils.get_URI_list(7)
+    if uri_list == nil then
+        return
+    end
+    local name = uri_list[#uri_list]
+    local file = io.open("/etc/route_cr.info", "r")
+    content = {}
+    for line in file:lines() do
+        local message = split(line, ' ')
+        if name ~= message[1] then
+            content[#content+1] = line
+        else
+           local iface = get_dev_name(message[4])
+            if message[5] == "cnf" then
+                local comm = "ip route del table 40 "..message[2].." via "..message[3].." dev "..iface
+                os.execute(comm)
+            else
+                local comm = "ip route del "..message[2].." via "..message[3].." dev "..iface
+                os.execute(comm)
+            end
+        end
+    end
+    file:close()
+    local file = io.open("/etc/route_cr.info", "w+")
+    for i = 1, #content do
+        file:write(content[i])
+    end
+    file:close()
+end
+
+-- Update
+function update_route()
+    local uri_list = utils.get_URI_list(7)
+    if uri_list == nil then
+        return
+    end
+    local name = uri_list[#uri_list]
+    local obj = utils.get_request_body_object()
+    if obj == nil then
+        utils.response_error(400, "Route CR not found")
+        return
+    end
+    if obj.name ~= name then
+        utils.response_error(400, "Route CR name mismatch")
+        return
+    end
+    if not utils.is_valid_ip(obj.dst) then
+        utils.response_error(400, "Invalid Destination IP Address")
+        return
+    end
+    if not utils.is_valid_ip_address(obj.gw) then
+        utils.response_error(400, "Invalid gateway IP Address")
+        return
+    end
+
+    local file = io.open("/etc/route_cr.info", "r")
+    content = {}
+    for line in file:lines() do
+        local message = split(line, ' ')
+        if name ~= message[1] then
+            content[#content+1] = line
+        else
+            if obj.dst ~= message[2] or obj.table ~= message[5] then
+                utils.response_error(400, "Route CR mismatch")
+               file:close()
+                return
+            end
+           local iface = get_dev_name(obj.dev)
+            if obj.table == "default" then
+                local comm = "ip route replace "..obj.dst.." via "..obj.gw.." dev "..iface
+                os.execute(comm)
+            elseif obj.table == "cnf" then
+                local comm = "ip route replace table 40 "..obj.dst.." via "..obj.gw.." dev "..iface
+                os.execute(comm)
+            else
+                utils.response_error(400, "Bad route table")
+                return
+            end
+            content[#content+1] = obj.name.." "..obj.dst.." "..obj.gw.." "..obj.dev.." "..obj.table.."\n"
+        end
+    end
+    file:close()
+    local file = io.open("/etc/route_cr.info", "w+")
+    for i = 1, #content do
+        file:write(content[i])
+    end
+    file:close()
+    luci.http.prepare_content("application/json")
+    luci.http.write_json(obj)
+end
+
+-- Get
+function get_route()
+    local uri_list = utils.get_URI_list()
+    local file = io.open("/etc/route_cr.info", "r")
+    if #uri_list == 6 then
+        local objs = {}
+        objs["routes"] = {}
+        for line in file:lines() do
+            local message = split(line, ' ')
+            local obj = {}
+            obj["name"] = message[1]
+            obj["dst"] = message[2]
+            obj["gw"] = message[3]
+            obj["dev"] = message[4]
+            obj["table"] = message[5]
+            table.insert(objs["routes"], obj)
+        end
+        luci.http.prepare_content("application/json")
+        luci.http.write_json(objs)
+    elseif #uri_list == 7 then
+        local name = uri_list[#uri_list]
+        local no = true
+        for line in file:lines() do
+            local message = split(line, ' ')
+            if name == message[1] then
+                no = false
+                local obj = {}
+                obj["name"] = message[1]
+                obj["dst"] = message[2]
+                obj["gw"] = message[3]
+                obj["dev"] = message[4]
+                obj["table"] = message[5]
+                luci.http.prepare_content("application/json")
+                luci.http.write_json(obj)
+                break
+            end
+        end
+        if no then
+            utils.response_error(404, "Cannot find ".."Route CR ".."[".. name.."]" )
+        end
+    else
+        utils.response_error(400, "Bad request URI")
+    end
+    file:close()
+end
+
+-- Sync and validate
+function split(str,reps)
+    local arr = {}
+    string.gsub(str,'[^'..reps..']+',function(w)
+        table.insert(arr, w)
+    end)
+    return arr
+end
+
+function is_duplicated(name, dst)
+    local file = io.open("/etc/route_cr.info", "r")
+    local judge = false
+    for line in file:lines() do
+        local message = split(line, ' ')
+        if name == message[1] then
+            judge = true
+            break
+        end
+        if dst == message[2] then
+            judge = true
+            break
+        end
+    end
+    file:close()
+    return judge
+end
+
+function get_dev_name(name)
+    --TODO
+    return name
+end
+
+function strict_subnet(ip)
+    --TODO
+    return true
+end
diff --git a/platform/cnf/src/route_cr.info b/platform/cnf/src/route_cr.info
new file mode 100644 (file)
index 0000000..e69de29