Skip to content

Commit

Permalink
Merge pull request #183 from croessner/features
Browse files Browse the repository at this point in the history
Feat: Refactor backend server handling, unify connection methods
  • Loading branch information
croessner authored Dec 5, 2024
2 parents bedd513 + 463c00e commit 749911f
Show file tree
Hide file tree
Showing 11 changed files with 399 additions and 276 deletions.
17 changes: 11 additions & 6 deletions server/config/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,24 @@ func (r *RelayDomainsSection) String() string {
}

type BackendServer struct {
Protocol string `mapstructure:"protocol"`
IP string `mapstructure:"ip"`
Port int `mapstructure:"port"`
TLS bool `mapstructure:"tls"`
HAProxyV2 bool `mapstructure:"haproxy_v2"`
Protocol string `mapstructure:"protocol"`
Host string `mapstructure:"host"`
RequestURI string `mapstructure:"request_uri"`
TestUsername string `mapstructure:"test_username"`
TestPassword string `mapstructure:"test_password"`
Port int `mapstructure:"port"`
TLS bool `mapstructure:"tls"`
TLSSkipVerify bool `mapstructure:"tls_skip_verify"`
HAProxyV2 bool `mapstructure:"haproxy_v2"`
}

func (n *BackendServer) String() string {
if n == nil {
return "BackendServer: <nil>"
}

return fmt.Sprintf("BackendServers: {Protocol: %s, IP: %s, Port: %d}", n.Protocol, n.IP, n.Port)
return fmt.Sprintf("BackendServer: {Protocol: %s, Host: %s, RequestURI: %s, TestUsername: %s, TestPassword: <hidden>, Port: %d, TLS: %t, TLSSkipVerify: %t, HAProxyV2: %t}",
n.Protocol, n.Host, n.RequestURI, n.TestUsername, n.Port, n.TLS, n.TLSSkipVerify, n.HAProxyV2)
}

type BackendServerMonitoring struct {
Expand Down
2 changes: 1 addition & 1 deletion server/config/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func (f *File) GetBackendServerIP(protocol string) string {
}

if f.GetBackendServer(protocol) != nil {
return f.GetBackendServer(protocol).IP
return f.GetBackendServer(protocol).Host
}

return ""
Expand Down
7 changes: 2 additions & 5 deletions server/definitions/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,8 @@ const (
// LogKeyLuaScripttimeout represents timeout setting for lua scripts
LogKeyLuaScripttimeout = "lua_script_timeout"

// LogKeyBackendServerIP represents the IP address of the backend server.
LogKeyBackendServerIP = "backend_server_ip"

// LogKeyBackendServerPort represents the port of the backend server.
LogKeyBackendServerPort = "backend_server_port"
// LogKeyBackendServer represents the IP address of the backend server.
LogKeyBackendServer = "backend_server"

// NotAvailable is used when data for a particular field is not available.
NotAvailable = "N/A"
Expand Down
24 changes: 12 additions & 12 deletions server/lua-plugins.d/filters/monitoring.lua
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,14 @@ function nauthilus_call_filter(request)
if nauthilus_util.is_table(backend_servers) then
num_of_bs = nauthilus_util.table_length(backend_servers)

local server_ip = ""
local new_server_ip = ""
local server_host = ""
local new_server_host = ""

local session = get_dovecot_session()
if session then
local maybe_server = get_server_from_sessions(session)
if maybe_server then
server_ip = maybe_server
server_host = maybe_server
end
end

Expand All @@ -168,13 +168,13 @@ function nauthilus_call_filter(request)
local b = nauthilus_backend_result.new()

for _, server in ipairs(backend_servers) do
new_server_ip = server.ip
new_server_host = server.host

if server_ip == new_server_ip then
attributes["Proxy-Host"] = server_ip
if server_host == new_server_host then
attributes["Proxy-Host"] = server_host

add_session(session, server_ip)
nauthilus_builtin.custom_log_add(N .. "_backend_server_current", server_ip)
add_session(session, server_host)
nauthilus_builtin.custom_log_add(N .. "_backend_server_current", server_host)

b:attributes(attributes)
nauthilus_backend.apply_backend_result(b)
Expand All @@ -183,13 +183,13 @@ function nauthilus_call_filter(request)
end
end

if server_ip ~= new_server_ip then
if server_host ~= new_server_host then
-- Put your own logic here to select a proper server for the user. In this demo, the last server
-- available is always used.
attributes["Proxy-Host"] = new_server_ip
attributes["Proxy-Host"] = new_server_host

add_session(session, new_server_ip)
nauthilus_builtin.custom_log_add(N .. "_backend_server_new", new_server_ip)
add_session(session, new_server_host)
nauthilus_builtin.custom_log_add(N .. "_backend_server_new", new_server_host)

b:attributes(attributes)
nauthilus_backend.apply_backend_result(b)
Expand Down
3 changes: 2 additions & 1 deletion server/lualib/backendresult.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ func backendResultGetSetAttributes(L *lua.LState) int {
backendResult := checkBackendResult(L)

if L.GetTop() == 2 {
backendResult.Attributes = convert.LuaValueToGo(L.CheckTable(2)).(map[any]any)
attributes := convert.LuaValueToGo(L.CheckTable(2)).(map[any]any)
backendResult.Attributes = attributes

return 0
}
Expand Down
70 changes: 32 additions & 38 deletions server/lualib/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,56 +16,50 @@
package lualib

import (
"github.com/croessner/nauthilus/server/config"
"github.com/croessner/nauthilus/server/monitoring"
lua "github.com/yuin/gopher-lua"
)

// CheckBackendConnection is a Lua function that checks the connection to a backend server.
// It receives the server IP address, port number, a boolean flag indicating whether the server runs with HAProxy V2 protocol,
// and a boolean flag indicating whether TLS should be used.
// The function calls the CheckBackendConnection method of the provided monitoring.Monitor instance
// and returns an error message if there is an error, or nil if the connection is successful.
// getNumberFromTable retrieves an integer value from a Lua table for the given key. If the key is missing or nil, returns 0.
//
// Params:
// - monitor monitoring.Monitor : The monitoring.Monitor instance used to check the backend connection.
// Parameters:
// - table: The Lua table to search in.
// - key: The key to look for in the table.
//
// Returns:
// - int : The number of return values pushed to the Lua stack, always 1.
//
// Lua stack requirements:
// - 4 arguments are expected in the following order:
// 1. string : The server IP address.
// 2. int : The server port number.
// 3. boolean : Whether the server runs with HAProxy V2 protocol.
// 4. boolean : Whether TLS should be used.
// - The arguments should be of the expected types; otherwise, an error will be raised.
// - The function expects to have 1 return value on the stack - nil if the connection is successful,
// or a string with an error message if there is an error.
//
// Example:
//
// connection_error = check_backend_connection("192.168.0.1", 8080, false, true)
// if connection_error ~= nil then
// log("Connection failed: " .. connection_error)
// else
// log("Connection successful")
// end
//
// Note: The above example is in Lua language and should be executed in a Lua environment.
// - The integer value associated with the key, or 0 if the key is not present or value is nil.
func getNumberFromTable(table *lua.LTable, key string) int {
value := table.RawGet(lua.LString(key))

if value == nil {
return 0
}

return int(value.(lua.LNumber))
}

// CheckBackendConnection attempts to verify the connection to a backend server using the provided monitor.
// It extracts necessary configuration details such as protocol, IP address, port, and credentials from the given Lua table.
// The function then calls the monitor's CheckBackendConnection method to perform the actual connectivity check.
// If the connection check encounters an error, this error is pushed onto the Lua stack.
// If the connection check is successful, a nil value is pushed onto the Lua stack.
// It returns an integer indicating the number of results pushed onto the Lua stack.
func CheckBackendConnection(monitor monitoring.Monitor) lua.LGFunction {
return func(L *lua.LState) int {
if L.GetTop() != 4 {
L.RaiseError("Invalid number of arguments. Expected 4, got %d", L.GetTop())
table := L.CheckTable(1)

return 0
}
server := &config.BackendServer{}

server := L.CheckString(1)
port := L.CheckInt(2)
haproxyV2 := L.CheckBool(3)
tls := L.CheckBool(4)
server.Protocol = getStringFromTable(table, "protocol")
server.Host = getStringFromTable(table, "ip_address")
server.Port = getNumberFromTable(table, "port")
server.HAProxyV2 = getBoolFromTable(table, "haproxy_v2")
server.TLS = getBoolFromTable(table, "tls")
server.TestUsername = getStringFromTable(table, "test_username")
server.TestPassword = getStringFromTable(table, "test_password")

if err := monitor.CheckBackendConnection(server, port, haproxyV2, tls); err != nil {
if err := monitor.CheckBackendConnection(server); err != nil {
L.Push(lua.LString(err.Error()))

return 1
Expand Down
120 changes: 0 additions & 120 deletions server/lualib/connection_test.go

This file was deleted.

Loading

0 comments on commit 749911f

Please sign in to comment.