git mv Ingress ingress
This commit is contained in:
parent
34b949c134
commit
3da4e74e5a
2185 changed files with 754743 additions and 0 deletions
229
controllers/nginx-third-party/lua/ingress.lua
vendored
Normal file
229
controllers/nginx-third-party/lua/ingress.lua
vendored
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
local _M = {}
|
||||
|
||||
local cjson = require "cjson"
|
||||
local trie = require "trie"
|
||||
local http = require "resty.http"
|
||||
local cache = require "resty.dns.cache"
|
||||
local os = require "os"
|
||||
|
||||
local encode = cjson.encode
|
||||
local decode = cjson.decode
|
||||
|
||||
local table_concat = table.concat
|
||||
|
||||
local trie_get = trie.get
|
||||
local match = string.match
|
||||
local gsub = string.gsub
|
||||
local lower = string.lower
|
||||
|
||||
|
||||
-- we "cache" the config local to each worker
|
||||
local ingressConfig = nil
|
||||
|
||||
local cluster_domain = "cluster.local"
|
||||
|
||||
local def_backend = nil
|
||||
|
||||
local custom_error = nil
|
||||
|
||||
local dns_cache_options = nil
|
||||
|
||||
function get_ingressConfig(ngx)
|
||||
local d = ngx.shared["ingress"]
|
||||
local value, flags, stale = d:get_stale("ingressConfig")
|
||||
if not value then
|
||||
-- nothing we can do
|
||||
return nil, "config not set"
|
||||
end
|
||||
ingressConfig = decode(value)
|
||||
return ingressConfig, nil
|
||||
end
|
||||
|
||||
function worker_cache_config(ngx)
|
||||
local _, err = get_ingressConfig(ngx)
|
||||
if err then
|
||||
ngx.log(ngx.ERR, "unable to get ingressConfig: ", err)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function _M.content(ngx)
|
||||
local host = ngx.var.host
|
||||
|
||||
-- strip off any port
|
||||
local h = match(host, "^(.+):?")
|
||||
if h then
|
||||
host = h
|
||||
end
|
||||
|
||||
host = lower(host)
|
||||
|
||||
local config, err = get_ingressConfig(ngx)
|
||||
if err then
|
||||
ngx.log(ngx.ERR, "unable to get config: ", err)
|
||||
return ngx.exit(503)
|
||||
end
|
||||
|
||||
-- this assumes we only allow exact host matches
|
||||
local paths = config[host]
|
||||
if not paths then
|
||||
ngx.log(ngx.ERR, "No server for host "..host.." returning 404")
|
||||
if custom_error then
|
||||
openCustomErrorURL(404, custom_error)
|
||||
return
|
||||
else
|
||||
openURL(404, def_backend)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local backend = trie_get(paths, ngx.var.uri)
|
||||
|
||||
if not backend then
|
||||
ngx.log(ngx.ERR, "No server for host "..host.." and path "..ngx.var.uri.." returning 404")
|
||||
if custom_error then
|
||||
openCustomErrorURL(404, custom_error)
|
||||
return
|
||||
else
|
||||
openURL(404, def_backend)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local address = backend.host
|
||||
ngx.var.upstream_port = backend.port or 80
|
||||
|
||||
if dns_cache_options then
|
||||
local dns = cache.new(dns_cache_options)
|
||||
local answer, err, stale = dns:query(address, { qtype = 1 })
|
||||
if err or (not answer) then
|
||||
if stale then
|
||||
answer = stale
|
||||
else
|
||||
answer = nil
|
||||
end
|
||||
end
|
||||
if answer and answer[1] then
|
||||
local ans = answer[1]
|
||||
if ans.address then
|
||||
address = ans.address
|
||||
end
|
||||
else
|
||||
ngx.log(ngx.ERR, "dns failed for ", address, " with ", err, " => ", encode(answer or ""))
|
||||
end
|
||||
end
|
||||
|
||||
ngx.var.upstream_host = address
|
||||
return
|
||||
end
|
||||
|
||||
function _M.init_worker(ngx)
|
||||
end
|
||||
|
||||
function _M.init(ngx, options)
|
||||
-- ngx.log(ngx.OK, "options: "..encode(options))
|
||||
def_backend = options.def_backend
|
||||
custom_error = options.custom_error
|
||||
|
||||
-- try to create a dns cache
|
||||
local resolvers = options.resolvers
|
||||
if resolvers then
|
||||
cache.init_cache(512)
|
||||
local servers = trie.strsplit(" ", resolvers)
|
||||
dns_cache_options =
|
||||
{
|
||||
dict = "dns_cache",
|
||||
negative_ttl = nil,
|
||||
max_stale = 900,
|
||||
normalise_ttl = false,
|
||||
resolver = {
|
||||
nameservers = {servers[1]}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- dump config. This is the raw config (including trie) for now
|
||||
function _M.config(ngx)
|
||||
ngx.header.content_type = "application/json"
|
||||
local config = {
|
||||
ingress = ingressConfig
|
||||
}
|
||||
local val = encode(config)
|
||||
ngx.print(val)
|
||||
end
|
||||
|
||||
function _M.update_ingress(ngx)
|
||||
ngx.header.content_type = "application/json"
|
||||
|
||||
if ngx.req.get_method() ~= "POST" then
|
||||
ngx.print(encode({
|
||||
message = "only POST request"
|
||||
}))
|
||||
ngx.exit(400)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.req.read_body()
|
||||
local data = ngx.req.get_body_data()
|
||||
local val = decode(data)
|
||||
|
||||
if not val then
|
||||
ngx.log(ngx.ERR, "failed to decode body")
|
||||
return
|
||||
end
|
||||
|
||||
config = {}
|
||||
|
||||
for _, ingress in ipairs(val) do
|
||||
local namespace = ingress.metadata.namespace
|
||||
|
||||
local spec = ingress.spec
|
||||
-- we do not allow default ingress backends right now.
|
||||
for _, rule in ipairs(spec.rules) do
|
||||
local host = rule.host
|
||||
local paths = config[host]
|
||||
if not paths then
|
||||
paths = trie.new()
|
||||
config[host] = paths
|
||||
end
|
||||
rule.http = rule.http or { paths = {}}
|
||||
for _, path in ipairs(rule.http.paths) do
|
||||
local hostname = table_concat(
|
||||
{
|
||||
path.backend.serviceName,
|
||||
namespace,
|
||||
"svc",
|
||||
cluster_domain
|
||||
}, ".")
|
||||
local backend = {
|
||||
host = hostname,
|
||||
port = path.backend.servicePort
|
||||
}
|
||||
|
||||
paths:add(path.path, backend)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local d = ngx.shared["ingress"]
|
||||
local ok, err, _ = d:set("ingressConfig", encode(config))
|
||||
if not ok then
|
||||
ngx.log(ngx.ERR, "Error: "..err)
|
||||
local res = encode({
|
||||
message = "Error updating Ingress rules: "..err
|
||||
})
|
||||
ngx.print(res)
|
||||
return ngx.exit(500)
|
||||
end
|
||||
|
||||
ingressConfig = config
|
||||
|
||||
local res = encode({
|
||||
message = "Ingress rules updated"
|
||||
})
|
||||
ngx.print(res)
|
||||
end
|
||||
|
||||
return _M
|
||||
Loading…
Add table
Add a link
Reference in a new issue