Add config export via flag and API

This commit is contained in:
Daniel 2021-01-19 15:38:10 +01:00
parent 11e8271d41
commit 40c2849bab
3 changed files with 62 additions and 0 deletions

24
api/endpoints_config.go Normal file
View file

@ -0,0 +1,24 @@
package api
import (
"github.com/safing/portbase/config"
)
func registerConfigEndpoints() error {
if err := RegisterEndpoint(Endpoint{
Path: "config/options",
Read: PermitAnyone,
MimeType: MimeTypeJSON,
StructFunc: listConfig,
Name: "Export Configuration Options",
Description: "Returns a list of all registered configuration options and their metadata. This does not include the current active or default settings.",
}); err != nil {
return err
}
return nil
}
func listConfig(ar *Request) (i interface{}, err error) {
return config.ExportOptions(), nil
}

View file

@ -1,7 +1,9 @@
package config package config
import ( import (
"encoding/json"
"errors" "errors"
"flag"
"os" "os"
"path/filepath" "path/filepath"
@ -17,6 +19,8 @@ const (
var ( var (
module *modules.Module module *modules.Module
dataRoot *utils.DirStructure dataRoot *utils.DirStructure
exportConfig bool
) )
// SetDataRoot sets the data root from which the updates module derives its paths. // SetDataRoot sets the data root from which the updates module derives its paths.
@ -29,6 +33,8 @@ func SetDataRoot(root *utils.DirStructure) {
func init() { func init() {
module = modules.Register("config", prep, start, nil, "database") module = modules.Register("config", prep, start, nil, "database")
module.RegisterEvent(configChangeEvent) module.RegisterEvent(configChangeEvent)
flag.BoolVar(&exportConfig, "export-config-options", false, "export configuration registry and exit")
} }
func prep() error { func prep() error {
@ -37,6 +43,10 @@ func prep() error {
return errors.New("data root is not set") return errors.New("data root is not set")
} }
if exportConfig {
modules.SetCmdLineOperation(exportConfigCmd)
}
return nil return nil
} }
@ -54,3 +64,13 @@ func start() error {
} }
return nil return nil
} }
func exportConfigCmd() error {
data, err := json.MarshalIndent(ExportOptions(), "", " ")
if err != nil {
return err
}
_, err = os.Stdout.Write(data)
return err
}

View file

@ -3,6 +3,7 @@ package config
import ( import (
"fmt" "fmt"
"regexp" "regexp"
"sort"
"strings" "strings"
"sync" "sync"
) )
@ -29,6 +30,23 @@ func ForEachOption(fn func(opt *Option) error) error {
return nil return nil
} }
// ExportOptions exports the registered options. The returned data must be
// treated as immutable.
// The data does not include the current active or default settings.
func ExportOptions() []*Option {
optionsLock.RLock()
defer optionsLock.RUnlock()
// Copy the map into a slice.
opts := make([]*Option, 0, len(options))
for _, opt := range options {
opts = append(opts, opt)
}
sort.Sort(sortByKey(opts))
return opts
}
// GetOption returns the option with name or an error // GetOption returns the option with name or an error
// if the option does not exist. The caller should lock // if the option does not exist. The caller should lock
// the returned option itself for further processing. // the returned option itself for further processing.