From: Huifeng Le Date: Tue, 17 Mar 2020 06:21:46 +0000 (+0800) Subject: SDEWAN API update X-Git-Tag: v1.0~37 X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;h=2c83952c8e0e7fa282c229fb18a3592123d54006;p=icn%2Fsdwan.git SDEWAN API update update SDEWAN Rest API with plural format Signed-off-by: Huifeng Le Change-Id: I83eb6ff24e4bb571162eb0a42df798da01ced7da --- diff --git a/cnf/build/rest_v1/firewall_rest.lua b/cnf/build/rest_v1/firewall_rest.lua index d1531c8..28afdfd 100644 --- a/cnf/build/rest_v1/firewall_rest.lua +++ b/cnf/build/rest_v1/firewall_rest.lua @@ -94,14 +94,10 @@ zone_checker = { function index() ver = "v1" configuration = "firewall" - entry({"sdewan", configuration, ver, "zones"}, call("get_zones")) - entry({"sdewan", configuration, ver, "redirects"}, call("get_redirects")) - entry({"sdewan", configuration, ver, "rules"}, call("get_rules")) - entry({"sdewan", configuration, ver, "forwardings"}, call("get_forwardings")) - entry({"sdewan", configuration, ver, "zone"}, call("handle_request")).leaf = true - entry({"sdewan", configuration, ver, "redirect"}, call("handle_request")).leaf = true - entry({"sdewan", configuration, ver, "rule"}, call("handle_request")).leaf = true - entry({"sdewan", configuration, ver, "forwarding"}, call("handle_request")).leaf = true + entry({"sdewan", configuration, ver, "zones"}, call("handle_request")).leaf = true + entry({"sdewan", configuration, ver, "redirects"}, call("handle_request")).leaf = true + entry({"sdewan", configuration, ver, "rules"}, call("handle_request")).leaf = true + entry({"sdewan", configuration, ver, "forwardings"}, call("handle_request")).leaf = true end function is_network_interface_available(interface) @@ -215,11 +211,6 @@ function is_zone_available(name) return true, name end --- get /zones -function get_zones() - utils.handle_get_objects("zones", uci_conf, "zone", zone_validator) -end - -- delete a zone function delete_zone(name, check_used) -- check whether zone is defined @@ -259,27 +250,9 @@ end function update_zone(zone) local name = zone.name res, code, msg = delete_zone(name, false) - if res == true then + if res == true or code == 404 then return utils.create_object(_M, firewall_processor, "zone", zone) end return false, code, msg -end - --- Redirect APIs --- get /redirects -function get_redirects() - utils.handle_get_objects("redirects", uci_conf, "redirect", redirect_validator) -end - --- Rule APIs --- get /rules -function get_rules() - utils.handle_get_objects("rules", uci_conf, "rule", rule_validator) -end - --- Forwarding APIs --- get /forwardings -function get_forwardings() - utils.handle_get_objects("forwardings", uci_conf, "forwarding", forwarding_validator) -end +end \ No newline at end of file diff --git a/cnf/build/rest_v1/ipsec_rest.lua b/cnf/build/rest_v1/ipsec_rest.lua index a158941..244249c 100644 --- a/cnf/build/rest_v1/ipsec_rest.lua +++ b/cnf/build/rest_v1/ipsec_rest.lua @@ -74,10 +74,8 @@ proposal_checker = { function index() ver = "v1" configuration = "ipsec" - entry({"sdewan", configuration, ver, "proposals"}, call("get_proposals")) - entry({"sdewan", configuration, ver, "sites"}, call("get_sites")) - entry({"sdewan", configuration, ver, "proposal"}, call("handle_request")).leaf = true - entry({"sdewan", configuration, ver, "site"}, call("handle_request")).leaf = true + entry({"sdewan", configuration, ver, "proposals"}, call("handle_request")).leaf = true + entry({"sdewan", configuration, ver, "sites"}, call("handle_request")).leaf = true end -- Request Handler @@ -169,12 +167,6 @@ function save_connection(value) return true, ret_value end --- Site APIs --- get /sites -function get_sites() - utils.handle_get_objects("sites", uci_conf, "remote", site_validator) -end - -- Proposal APIs -- check if proposal is used by connection, site function is_proposal_used(name) @@ -186,10 +178,12 @@ function is_proposal_used(name) uci:foreach(uci_conf, section_name, function(section) for j=1, #checker do - for k=1, #section[checker[j]] do - if name == section[checker[j]][k] then - is_used = true - return false + if section[checker[j]] ~= nil then + for k=1, #section[checker[j]] do + if name == section[checker[j]][k] then + is_used = true + return false + end end end end @@ -213,11 +207,6 @@ function is_proposal_available(name) return true, name end --- get /proposals -function get_proposals() - utils.handle_get_objects("proposals", uci_conf, "proposal", proposal_validator) -end - -- delete a proposal function delete_proposal(name, check_used) -- check whether proposal is defined @@ -257,7 +246,7 @@ end function update_proposal(proposal) local name = proposal.name res, code, msg = delete_proposal(name, false) - if res == true then + if res == true or code == 404 then return utils.create_object(_M, ipsec_processor, "proposal", proposal) end diff --git a/cnf/build/rest_v1/mwan3_rest.lua b/cnf/build/rest_v1/mwan3_rest.lua index dd801b0..05902fd 100644 --- a/cnf/build/rest_v1/mwan3_rest.lua +++ b/cnf/build/rest_v1/mwan3_rest.lua @@ -34,17 +34,16 @@ rule_validator = { } mwan3_processor = { - policy={get="get_policy", update="update_policy", create="create_policy", delete="delete_policy", validator=policy_validator}, + get_type=function(value) if value == "policies" then return "policy" elseif value == "rules" then return "rule" else return "" end end, + policy={gets="get_policies",get="get_policy", update="update_policy", create="create_policy", delete="delete_policy", validator=policy_validator}, rule={validator=rule_validator}, configuration="mwan3" } function index() ver = "v1" - entry({"sdewan", "mwan3", ver, "policies"}, call("get_policies")) - entry({"sdewan", "mwan3", ver, "rules"}, call("get_rules")) - entry({"sdewan", "mwan3", ver, "policy"}, call("handle_request")).leaf = true - entry({"sdewan", "mwan3", ver, "rule"}, call("handle_request")).leaf = true + entry({"sdewan", "mwan3", ver, "policies"}, call("handle_request")).leaf = true + entry({"sdewan", "mwan3", ver, "rules"}, call("handle_request")).leaf = true end -- Request Handler @@ -84,6 +83,9 @@ function get_policy(name) if members == nil then return nil end + if members[".type"] ~= "policy" then + return nil + end members = members["use_member"] local policy = {} @@ -124,7 +126,7 @@ function get_policies() end ) - utils.response_object(res) + return res end -- create a policy @@ -223,15 +225,9 @@ end function update_policy(policy) local name = policy.name res, code, msg = delete_policy(name, false) - if res == true then + if res == true or code == 404 then return create_policy(policy) end return false, code, msg -end - --- Rule APIs --- get /rules -function get_rules() - utils.handle_get_objects("rules", "mwan3", "rule", rule_validator) -end +end \ No newline at end of file diff --git a/cnf/build/rest_v1/utils.lua b/cnf/build/rest_v1/utils.lua index 5e35951..f3627aa 100644 --- a/cnf/build/rest_v1/utils.lua +++ b/cnf/build/rest_v1/utils.lua @@ -26,6 +26,10 @@ function start_with(s, prefix) return (string.find(s, "^" .. prefix) ~= nil) end +function end_with(s, postfix) + return (string.find(s, postfix .. "$") ~= nil) +end + -- check ip function is_match(s, reg) local ret = string.match(s, reg) @@ -195,6 +199,9 @@ function get_uci_section(configuration, validator, object_type, name) return nil end else + if object_data[".type"] ~= object_type then + return nil + end -- name is defined as section name local obj = {} obj["name"] = name @@ -245,7 +252,7 @@ function set_data(configuration, data_validator, src, target) else if v["validator"] ~= nil and type(v["validator"]) == "table" then if value.section ~= nil then - target[name] = get_uci_section(configuration, value.section, value.name) + target[name] = get_uci_section(configuration, v["validator"], value.section, value.name) else target[name] = get_uci_section(configuration, v["validator"], get_validator_type(v["validator"]), value) end @@ -259,30 +266,11 @@ function set_data(configuration, data_validator, src, target) end -- get -function get_objects(type_names, configuration, type_name, validator) - local res = {} - res[type_names] = {} - - local index = 1 - uci:foreach(configuration, type_name, - function (section) - local obj = {} - obj["name"] = section[".name"] - set_data(configuration, validator, section, obj) - res[type_names][index] = obj - index = index + 1 - end - ) - - return res -end - -function handle_get_objects(type_names, configuration, type_name, validator) - if not (validate_req_method("GET")) then - return +function get_object_type(value) + if end_with(value, "s") then + return string.sub(value, 1, string.len(value)-1) end - - response_object(get_objects(type_names, configuration, type_name, validator)) + return value end function get_object(module_table, processors, object_type, name) @@ -291,26 +279,80 @@ function get_object(module_table, processors, object_type, name) and module_table[processors[object_type]["get"]] ~= nil then return module_table[processors[object_type]["get"]](name) else - return get_uci_section(processors["configuration"], processors[object_type].validator, object_type, name) + local object_conf_type = get_validator_type(processors[object_type].validator) + if object_conf_type == nil then + object_conf_type = object_type + end + return get_uci_section(processors["configuration"], processors[object_type].validator, object_conf_type, name) + end +end + +function get_objects(module_table, processors, object_types, object_type) + if processors ~= nil and processors[object_type] ~= nil + and processors[object_type]["gets"] ~= nil + and module_table[processors[object_type]["gets"]] ~= nil then + return module_table[processors[object_type]["gets"]]() + else + local res = {} + res[object_types] = {} + + local index = 1 + local object_conf_type = get_validator_type(processors[object_type].validator) + if object_conf_type == nil then + object_conf_type = object_type + end + uci:foreach(processors["configuration"], object_conf_type, + function (section) + local obj = {} + obj["name"] = section[".name"] + set_data(processors["configuration"], processors[object_type].validator, section, obj) + res[object_types][index] = obj + index = index + 1 + end + ) + + return res end end function handle_get(module_table, processors) - local uri_list = get_URI_list(7) + local uri_list = get_URI_list() if uri_list == nil then return end - local object_type = uri_list[#uri_list-1] - local name = uri_list[#uri_list] - local obj = get_object(module_table, processors, object_type, name) + if #uri_list == 6 then + -- get objects + local object_types = uri_list[#uri_list] + local object_type = get_object_type(object_types) + if processors["get_type"] ~= nil and type(processors["get_type"]) == "function" then + object_type = processors["get_type"](object_types) + end + local objs = get_objects(module_table, processors, object_types, object_type) + if objs == nil then + response_error(404, "Cannot find " .. object_type) + return + end + response_object(objs) + elseif #uri_list == 7 then + -- get object + local object_types = uri_list[#uri_list-1] + local object_type = get_object_type(object_types) + if processors["get_type"] ~= nil and type(processors["get_type"]) == "function" then + object_type = processors["get_type"](object_types) + end + local name = uri_list[#uri_list] + local obj = get_object(module_table, processors, object_type, name) - if obj == nil then - response_error(404, "Cannot find " .. object_type .. "[" .. name .. "]" ) + if obj == nil then + response_error(404, "Cannot find " .. object_type .. "[" .. name .. "]" ) + return + end + response_object(obj) + else + response_error(400, "Bad request URI") return end - - response_object(obj) end -- put @@ -322,7 +364,7 @@ function update_object(module_table, processors, object_type, obj) else local name = obj.name res, code, msg = delete_object(module_table, processors, object_type, name) - if res == true then + if res == true or code == 404 then return create_object(module_table, processors, object_type, obj) end @@ -336,7 +378,12 @@ function handle_put(module_table, processors) return end - local object_type = uri_list[#uri_list-1] + local object_types = uri_list[#uri_list-1] + local object_type = get_object_type(object_types) + if processors["get_type"] ~= nil and type(processors["get_type"]) == "function" then + object_type = processors["get_type"](object_types) + end + local name = uri_list[#uri_list] -- check content and get object local obj = get_and_validate_body_object(processors[object_type].validator) @@ -474,7 +521,12 @@ function handle_post(module_table, processors) return end - local object_type = uri_list[#uri_list] + local object_types = uri_list[#uri_list] + local object_type = get_object_type(object_types) + if processors["get_type"] ~= nil and type(processors["get_type"]) == "function" then + object_type = processors["get_type"](object_types) + end + -- check content and get policy object local obj = get_and_validate_body_object(processors[object_type].validator) if obj == nil then @@ -516,14 +568,16 @@ function delete_uci_section(configuration, validator, obj, object_type) -- delete depedency uci section for i,v in pairs(validator) do if(type(v) == "table") then - if v["item_validator"] ~= nil and type(v["item_validator"]) == "table" then - for j=1, #obj[v["name"]] do - local sub_obj = obj[v["name"]][j] - delete_uci_section(configuration, v["item_validator"], obj[v["name"]][j], v["name"]) - end - else - if v["validator"] ~= nil and type(v["validator"]) == "table" then - delete_uci_section(configuration, v["validator"], obj[v["name"]], v["name"]) + if obj[v["name"]] ~= nil then + if v["item_validator"] ~= nil and type(v["item_validator"]) == "table" then + for j=1, #obj[v["name"]] do + local sub_obj = obj[v["name"]][j] + delete_uci_section(configuration, v["item_validator"], obj[v["name"]][j], v["name"]) + end + else + if v["validator"] ~= nil and type(v["validator"]) == "table" then + delete_uci_section(configuration, v["validator"], obj[v["name"]], v["name"]) + end end end end @@ -573,7 +627,11 @@ function handle_delete(module_table, processors) return end - local object_type = uri_list[#uri_list-1] + local object_types = uri_list[#uri_list-1] + local object_type = get_object_type(object_types) + if processors["get_type"] ~= nil and type(processors["get_type"]) == "function" then + object_type = processors["get_type"](object_types) + end local name = uri_list[#uri_list] res, code, msg = delete_object(module_table, processors, object_type, name) @@ -692,7 +750,7 @@ end function get_URI_list(required_lenth) local uri = luci.http.getenv("REQUEST_URI") local uri_list = split_and_trim(uri, "/") - if not (#uri_list == required_lenth) then + if (required_lenth ~= nil) and (not (#uri_list == required_lenth)) then response_error(400, "Bad request URI") return nil end diff --git a/openwrt/mwan3.go b/openwrt/mwan3.go index 5860e3d..8d6c6a2 100644 --- a/openwrt/mwan3.go +++ b/openwrt/mwan3.go @@ -104,7 +104,7 @@ func (m *Mwan3Client) GetPolicies() (*SdewanPolicies, error) { // get policy func (m *Mwan3Client) GetPolicy(policy_name string) (*SdewanPolicy, error) { - response, err := m.OpenwrtClient.Get(mwan3BaseURL + "policy/" + policy_name) + response, err := m.OpenwrtClient.Get(mwan3BaseURL + "policies/" + policy_name) if err != nil { return nil, err } @@ -121,7 +121,7 @@ func (m *Mwan3Client) GetPolicy(policy_name string) (*SdewanPolicy, error) { // create policy func (m *Mwan3Client) CreatePolicy(policy SdewanPolicy) (*SdewanPolicy, error) { policy_obj, _ := json.Marshal(policy) - response, err := m.OpenwrtClient.Post(mwan3BaseURL+"policy", string(policy_obj)) + response, err := m.OpenwrtClient.Post(mwan3BaseURL+"policies", string(policy_obj)) if err != nil { return nil, err } @@ -137,7 +137,7 @@ func (m *Mwan3Client) CreatePolicy(policy SdewanPolicy) (*SdewanPolicy, error) { // delete policy func (m *Mwan3Client) DeletePolicy(policy_name string) error { - _, err := m.OpenwrtClient.Delete(mwan3BaseURL + "policy/" + policy_name) + _, err := m.OpenwrtClient.Delete(mwan3BaseURL + "policies/" + policy_name) if err != nil { return err } @@ -149,7 +149,7 @@ func (m *Mwan3Client) DeletePolicy(policy_name string) error { func (m *Mwan3Client) UpdatePolicy(policy SdewanPolicy) (*SdewanPolicy, error) { policy_obj, _ := json.Marshal(policy) policy_name := policy.Name - response, err := m.OpenwrtClient.Put(mwan3BaseURL+"policy/"+policy_name, string(policy_obj)) + response, err := m.OpenwrtClient.Put(mwan3BaseURL+"policies/"+policy_name, string(policy_obj)) if err != nil { return nil, err } @@ -182,7 +182,7 @@ func (m *Mwan3Client) GetRules() (*SdewanRules, error) { // get rule func (m *Mwan3Client) GetRule(rule string) (*SdewanRule, error) { - response, err := m.OpenwrtClient.Get(mwan3BaseURL + "rule/" + rule) + response, err := m.OpenwrtClient.Get(mwan3BaseURL + "rules/" + rule) if err != nil { return nil, err } @@ -199,7 +199,7 @@ func (m *Mwan3Client) GetRule(rule string) (*SdewanRule, error) { // create rule func (m *Mwan3Client) CreateRule(rule SdewanRule) (*SdewanRule, error) { rule_obj, _ := json.Marshal(rule) - response, err := m.OpenwrtClient.Post(mwan3BaseURL+"rule", string(rule_obj)) + response, err := m.OpenwrtClient.Post(mwan3BaseURL+"rules", string(rule_obj)) if err != nil { return nil, err } @@ -215,7 +215,7 @@ func (m *Mwan3Client) CreateRule(rule SdewanRule) (*SdewanRule, error) { // delete rule func (m *Mwan3Client) DeleteRule(rule_name string) error { - _, err := m.OpenwrtClient.Delete(mwan3BaseURL + "rule/" + rule_name) + _, err := m.OpenwrtClient.Delete(mwan3BaseURL + "rules/" + rule_name) if err != nil { return err } @@ -227,7 +227,7 @@ func (m *Mwan3Client) DeleteRule(rule_name string) error { func (m *Mwan3Client) UpdateRule(rule SdewanRule) (*SdewanRule, error) { rule_obj, _ := json.Marshal(rule) rule_name := rule.Name - response, err := m.OpenwrtClient.Put(mwan3BaseURL+"rule/"+rule_name, string(rule_obj)) + response, err := m.OpenwrtClient.Put(mwan3BaseURL+"rules/"+rule_name, string(rule_obj)) if err != nil { return nil, err } diff --git a/openwrt/openwrtclient.go b/openwrt/openwrtclient.go index a187da0..b80f09a 100644 --- a/openwrt/openwrtclient.go +++ b/openwrt/openwrtclient.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "net/http" + "runtime" "strings" ) @@ -24,6 +25,11 @@ type openwrtClient struct { token string } +func CloseClient(o *openwrtClient) { + o.logout() + runtime.SetFinalizer(o, nil) +} + func NewOpenwrtClient(ip string, user string, password string) *openwrtClient { client := &openwrtClient{ ip: ip, @@ -32,6 +38,7 @@ func NewOpenwrtClient(ip string, user string, password string) *openwrtClient { token: "", } + runtime.SetFinalizer(client, CloseClient) return client } @@ -89,6 +96,17 @@ func (o *openwrtClient) login() error { return nil } +// logout to openwrt http server +func (o *openwrtClient) logout() error { + if o.token != "" { + _, err:= o.Get("admin/logout") + o.token = "" + return err + } + + return nil +} + // call openwrt restful API func (o *openwrtClient) call(method string, url string, request string) (string, error) { for i := 0; i < 2; i++ {