platform: modularize api/gui, add docs-tests-web foundation, and refresh root config
This commit is contained in:
59
selective-vpn-api/app/cli/autoloop.go
Normal file
59
selective-vpn-api/app/cli/autoloop.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type AutoloopParams struct {
|
||||
Iface string
|
||||
Table string
|
||||
MTU int
|
||||
StateDir string
|
||||
DefaultLocation string
|
||||
}
|
||||
|
||||
type AutoloopDeps struct {
|
||||
StateDirDefault string
|
||||
ResolveIface func(flagIface string) string
|
||||
Run func(params AutoloopParams)
|
||||
Stderr io.Writer
|
||||
}
|
||||
|
||||
func RunAutoloop(args []string, deps AutoloopDeps) int {
|
||||
if deps.ResolveIface == nil || deps.Run == nil {
|
||||
return 1
|
||||
}
|
||||
stderr := deps.Stderr
|
||||
if stderr == nil {
|
||||
stderr = os.Stderr
|
||||
}
|
||||
|
||||
fs := flag.NewFlagSet("autoloop", flag.ContinueOnError)
|
||||
fs.SetOutput(stderr)
|
||||
iface := fs.String("iface", "", "VPN interface (empty/auto = detect active)")
|
||||
table := fs.String("table", "agvpn", "routing table name")
|
||||
mtu := fs.Int("mtu", 1380, "MTU for default route")
|
||||
stateDir := fs.String("state-dir", deps.StateDirDefault, "state directory")
|
||||
defaultLoc := fs.String("default-location", "Austria", "default location")
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return 2
|
||||
}
|
||||
|
||||
resolvedIface := deps.ResolveIface(*iface)
|
||||
if resolvedIface == "" {
|
||||
fmt.Fprintln(stderr, "autoloop: cannot resolve VPN interface (set --iface or preferred iface)")
|
||||
return 1
|
||||
}
|
||||
|
||||
deps.Run(AutoloopParams{
|
||||
Iface: resolvedIface,
|
||||
Table: *table,
|
||||
MTU: *mtu,
|
||||
StateDir: *stateDir,
|
||||
DefaultLocation: *defaultLoc,
|
||||
})
|
||||
return 0
|
||||
}
|
||||
47
selective-vpn-api/app/cli/routes_clear.go
Normal file
47
selective-vpn-api/app/cli/routes_clear.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RoutesClearDeps struct {
|
||||
Clear func() (ok bool, message string)
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
}
|
||||
|
||||
func RunRoutesClear(args []string, deps RoutesClearDeps) int {
|
||||
if deps.Clear == nil {
|
||||
return 1
|
||||
}
|
||||
stdout := deps.Stdout
|
||||
if stdout == nil {
|
||||
stdout = os.Stdout
|
||||
}
|
||||
stderr := deps.Stderr
|
||||
if stderr == nil {
|
||||
stderr = os.Stderr
|
||||
}
|
||||
|
||||
fs := flag.NewFlagSet("routes-clear", flag.ContinueOnError)
|
||||
fs.SetOutput(stderr)
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return 2
|
||||
}
|
||||
|
||||
ok, message := deps.Clear()
|
||||
if ok {
|
||||
fmt.Fprintln(stdout, strings.TrimSpace(message))
|
||||
return 0
|
||||
}
|
||||
msg := strings.TrimSpace(message)
|
||||
if msg == "" {
|
||||
msg = "routes clear failed"
|
||||
}
|
||||
fmt.Fprintln(stderr, msg)
|
||||
return 1
|
||||
}
|
||||
65
selective-vpn-api/app/cli/routes_update.go
Normal file
65
selective-vpn-api/app/cli/routes_update.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type RoutesUpdateDeps struct {
|
||||
LockFile string
|
||||
Update func(iface string) (ok bool, message string)
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
}
|
||||
|
||||
func RunRoutesUpdate(args []string, deps RoutesUpdateDeps) int {
|
||||
if deps.Update == nil || deps.LockFile == "" {
|
||||
return 1
|
||||
}
|
||||
stdout := deps.Stdout
|
||||
if stdout == nil {
|
||||
stdout = os.Stdout
|
||||
}
|
||||
stderr := deps.Stderr
|
||||
if stderr == nil {
|
||||
stderr = os.Stderr
|
||||
}
|
||||
|
||||
fs := flag.NewFlagSet("routes-update", flag.ContinueOnError)
|
||||
fs.SetOutput(stderr)
|
||||
iface := fs.String("iface", "", "VPN interface (empty/auto = detect active)")
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return 2
|
||||
}
|
||||
|
||||
lock, err := os.OpenFile(deps.LockFile, os.O_CREATE|os.O_RDWR, 0o644)
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "lock open error: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
defer lock.Close()
|
||||
|
||||
if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
|
||||
fmt.Fprintln(stdout, "routes update already running")
|
||||
return 0
|
||||
}
|
||||
defer func() {
|
||||
_ = syscall.Flock(int(lock.Fd()), syscall.LOCK_UN)
|
||||
}()
|
||||
|
||||
ok, message := deps.Update(*iface)
|
||||
if ok {
|
||||
fmt.Fprintln(stdout, strings.TrimSpace(message))
|
||||
return 0
|
||||
}
|
||||
msg := strings.TrimSpace(message)
|
||||
if msg == "" {
|
||||
msg = "routes update failed"
|
||||
}
|
||||
fmt.Fprintln(stderr, msg)
|
||||
return 1
|
||||
}
|
||||
Reference in New Issue
Block a user