105 lines
2.3 KiB
Go
105 lines
2.3 KiB
Go
package backend
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"git.thequux.com/thequux/ipasso/util/startup"
|
|
"go.uber.org/zap"
|
|
"net/url"
|
|
"os"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
var backendUrl = flag.String("backend", "help://", "URL of backend. Use help:// for a list, or help://[backend] for details on a particular backend")
|
|
|
|
var SessionStore Backend
|
|
|
|
type backendRecord struct {
|
|
description string
|
|
help string
|
|
factory Factory
|
|
}
|
|
|
|
// Factory for backend objects. You don't need this unless you're working on
|
|
// initialization machinery or implementing a backend
|
|
type Factory func(url *url.URL) (Backend, error)
|
|
|
|
var sessionLogger *zap.Logger
|
|
|
|
var registry = make(map[string]backendRecord)
|
|
|
|
func RegisterBackendFactory(scheme string, description string, help string, factory Factory) {
|
|
scheme = strings.ToLower(scheme)
|
|
_, exist := registry[scheme]
|
|
if exist {
|
|
panic("Scheme " + scheme + " registered multiple times")
|
|
}
|
|
|
|
registry[scheme] = backendRecord{
|
|
description: description,
|
|
help: help,
|
|
factory: factory,
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
// register the help factory
|
|
RegisterBackendFactory("help", "Help on backends", `
|
|
Usage:
|
|
help:// List available backends
|
|
help://backend Print help on a specific backend
|
|
`,
|
|
backendHelp,
|
|
)
|
|
|
|
startup.Logger.Add(func() {
|
|
sessionLogger = zap.L().Named("session")
|
|
})
|
|
startup.PostFlags.Add(func() {
|
|
parsed, err := url.Parse(*backendUrl)
|
|
if err != nil {
|
|
sessionLogger.Fatal("Invalid backend spec", zap.Error(err))
|
|
}
|
|
backend, ok := registry[parsed.Scheme]
|
|
if !ok {
|
|
sessionLogger.Fatal("Unknown backend type", zap.String("scheme", parsed.Scheme))
|
|
}
|
|
SessionStore, err = backend.factory(parsed)
|
|
if err != nil {
|
|
sessionLogger.Fatal("Failed to initialize backend", zap.Error(err))
|
|
}
|
|
|
|
})
|
|
}
|
|
|
|
func backendHelp(url *url.URL) (Backend, error) {
|
|
|
|
scheme := url.Hostname()
|
|
if scheme != "" {
|
|
backend, ok := registry[scheme]
|
|
if ok {
|
|
fmt.Println(strings.TrimPrefix(backend.help, "\n"))
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
var backendList []string
|
|
|
|
var maxLen = 0
|
|
for name := range registry {
|
|
backendList = append(backendList, name)
|
|
if len(name) > maxLen {
|
|
maxLen = len(name)
|
|
}
|
|
}
|
|
sort.Strings(backendList)
|
|
|
|
fmt.Println("Available backends:")
|
|
for _, name := range backendList {
|
|
fmt.Printf("%*s %s\n", maxLen, name, registry[name].description)
|
|
}
|
|
os.Exit(1)
|
|
return nil, nil
|
|
}
|