File: http_bridge_conf_utils.lua

package info (click to toggle)
ntopng 5.2.1%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 121,832 kB
  • sloc: javascript: 143,431; cpp: 71,175; ansic: 11,108; sh: 4,687; makefile: 911; python: 587; sql: 512; pascal: 234; perl: 118; ruby: 52; exp: 4
file content (205 lines) | stat: -rw-r--r-- 7,829 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
--
-- (C) 2017-22 - ntop.org
--

-- ######################################################################################
-- ################### HTTP HOST POOLS CONFIGURATION ####################################
-- ######################################################################################

dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path

if(ntop.isPro()) then
   package.path = dirs.installdir .. "/pro/scripts/lua/modules/?.lua;" .. package.path
   package.path = dirs.installdir .. "/pro/scripts/callbacks/?.lua;" .. package.path
end

if ntop.isnEdge() then
   package.path = dirs.installdir .. "/pro/scripts/lua/nedge/modules/?.lua;" .. package.path
end

require "lua_utils"
local json = require "dkjson"
local host_pools_nedge = require "host_pools_nedge"
local users_utils = require("users_utils")
local shaper_utils

if(ntop.isPro()) then
   shaper_utils = require "shaper_utils"
end

local http_bridge_conf_utils = {}

-- set to a non-empty value to enable HTTP configuration, e.g.,
--http_bridge_conf_utils.HTTP_BRIDGE_CONFIGURATION_URL = "localhost:8000"
http_bridge_conf_utils.HTTP_BRIDGE_CONFIGURATION_URL = ""

function http_bridge_conf_utils.configureBridge()
   if not isEmptyString(http_bridge_conf_utils.HTTP_BRIDGE_CONFIGURATION_URL) then
      -- CLEANUP
      shaper_utils.clearShapers()
      -- empty pool members but don't delete pools
      host_pools_nedge.emptyPools()

      -- BASIC INITIALIZATION
      host_pools_nedge.initPools()
      shaper_utils.initShapers()

      -- RETRIEVE BRIDGE CONFIGURATION
      -- EXAMPLE RESPONSE STRUCTURE:
      local rsp = {
	 -- ["users"] = {
         --    ["Not Assigned"] = {
	 --       ["default_policy"] = "drop",
         --       ["policies"] = {
	 -- 	     ["ConnectivityCheck"] = "pass"
	 --       }
	 --    },
	 --    ["maina"] = {
	 --       ["full_name"] = "Maina Fast",
	 --       ["password"] = "ntop0101",
	 --       ["default_policy"] = "pass",
	 --       ["policies"] = {
	 -- 	     [10] = "slow_pass", ["Facebook"] = "slower_pass",  ["YouTube"] = "drop"
	 --       }
	 --    },
	 --    ["simon"] = {
	 --       ["full_name"] = "Simon Speed",
	 --       ["password"] = "ntop0202",
	 --       ["default_policy"] = "drop",
	 --       ["policies"] = {
	 -- 	     ["MyCustomProtocol"]="pass", [20] = "slow_pass", [22] = "slower_pass"
	 --       }
	 --    }
	 -- }
      }
      local rsp = ntop.httpGet(http_bridge_conf_utils.HTTP_BRIDGE_CONFIGURATION_URL)

      if rsp == nil then
	 host_pools_nedge.traceHostPoolEvent(TRACE_ERROR, "Unable to obtain a valid configuration from "..http_bridge_conf_utils.HTTP_BRIDGE_CONFIGURATION_URL)
	 return
      end

      if rsp["CONTENT"] then rsp = rsp["CONTENT"] end
      if not rsp then rsp = {} end

      if type(rsp) == "string" then
	 rsp = json.decode(rsp)

	 if rsp == nil then
	    print("Unable to decode response as valid JSON")
	 end
      end

      -- Read supported protocols
      local ndpi_protocols = {}
      for proto_name, proto_id in pairs(interface.getnDPIProtocols()) do
	 -- case-insensitive
	 ndpi_protocols[string.lower(proto_name)] = proto_id
      end

      -- Read supported categories
      local ndpi_categories = {}
      for cat_name, cat_id in pairs(interface.getnDPICategories()) do
	 ndpi_categories[string.lower(cat_name)] = cat_id
      end

      local nedge_shapers = {}
      for _, shaper in ipairs(shaper_utils.nedge_shapers) do
	 nedge_shapers[string.lower(shaper.name)] = shaper
      end
      
      -- FOR EACH INTERFACE...
      for _, ifname in pairs(interface.getIfNames()) do
	 interface.select(ifname)
	 local ifid = getInterfaceId(ifname)

	 -- SETUP HOST POOLS
	 for username, user_config in pairs(rsp["users"] or {}) do
            if username ~= host_pools_nedge.DEFAULT_POOL_NAME then
              users_utils.addUserIfNotExists(ifid, username, user_config["password"] or "", user_config["full_name"] or "")
            end

	    local pool_id = host_pools_nedge.usernameToPoolId(username) or host_pools_nedge.DEFAULT_POOL_ID
	    host_pools_nedge.traceHostPoolEvent(TRACE_NORMAL, ifname..": creating user: "..username.. " pool id: "..pool_id)

	    if not isEmptyString(user_config["default_policy"]) then
	       local default_policy = string.lower(user_config["default_policy"])

	       if nedge_shapers[default_policy] and default_policy ~= "default" then -- default can't be default :)
		  host_pools_nedge.traceHostPoolEvent(TRACE_NORMAL, ifname..": setting default policy '"..default_policy.."' for user: "..username.. " pool id: "..pool_id)
		  shaper_utils.setPoolShaper(ifid, pool_id, nedge_shapers[default_policy].id)
	       end

	       for proto, policy in pairs(user_config["policies"] or {}) do
		  local proto_name = proto
		  local proto_id_or_category = proto

		  policy = nedge_shapers[string.lower(policy)]

		  if tonumber(proto_id_or_category) == nil then
		     -- proto_id_or_category is not a proto id, check for proto name or category
		     local lowercase_name = string.lower(proto)

		     if ndpi_protocols[lowercase_name] then
			proto_id_or_category = ndpi_protocols[lowercase_name]
			proto_name = string.format("Protocol %s/%d", proto, ndpi_protocols[lowercase_name])
		     elseif ndpi_categories[lowercase_name] then
                        proto_id_or_category = "cat_"..ndpi_categories[lowercase_name]
			proto_name = string.format("Category %s/%d", proto, ndpi_categories[lowercase_name])
		     else
			host_pools_nedge.traceHostPoolEvent(TRACE_ERROR, ifname..": unable to find protocol '"..proto.."' among known protocols for user: "..username.. " pool id: "..pool_id)
                        proto_id_or_category = nil
		     end
		  end

		  if policy and proto_id_or_category then
		     if (policy.name == "DEFAULT") and no_quota then
			shaper_utils.deleteProtocol(ifid, pool_id, proto_id_or_category)
		     else
			shaper_utils.setProtocolShapers(ifid, pool_id, proto_id_or_category,
							policy.id, policy.id,
							0 --[[traffic_quota--]], 0--[[time_quota--]])
			host_pools_nedge.traceHostPoolEvent(TRACE_NORMAL, ifname..": setting '"..proto_name.."' policy '"..policy.name.."' for user: "..username.. " pool id: "..pool_id)
		     end
		  end
	       end
	    end
	 end

	 -- must leave it here as well to make sure the C part has updated with the new pools
	 ntop.reloadHostPools()

	 -- SETUP ASSOCIATIONS
	 for member, info in pairs(rsp["associations"] or {}) do
	    local pool = info["group"]
	    local connectivity = info["connectivity"]

	    local pool_id = host_pools_nedge.usernameToPoolId(pool)

	    if pool == host_pools_nedge.DEFAULT_POOL_NAME then
	       host_pools_nedge.traceHostPoolEvent(TRACE_ERROR, ifname..": members are associated automatically with default pool "..host_pools_nedge.DEFAULT_POOL_NAME.." skipping association with member: "..member)
	    elseif not pool_id then
	       host_pools_nedge.traceHostPoolEvent(TRACE_ERROR, ifname..": pool: "..pool.. " not existing. Unable to set association with: "..member)
	    else
	       if connectivity == "pass" then
		  if host_pools_nedge.addPoolMember(pool_id, member) == true then
		     host_pools_nedge.traceHostPoolEvent(TRACE_NORMAL, ifname..": member  "..member.. " successfully associated to pool: "..pool)
		  else
		     host_pools_nedge.traceHostPoolEvent(TRACE_ERROR, ifname..": Unable to associate member "..member.. " to pool: "..pool)
		  end
	       end
	    end
	 end
      end

      ntop.reloadHostPools()
   end

end

return http_bridge_conf_utils

-- ######################################################################################
-- ######################################################################################
-- ######################################################################################