admin/index.html: Display config as yaml

This commit is contained in:
Tom Wiesing 2023-02-26 19:21:42 +01:00
parent 2edd0f2fe2
commit eec8b89e06
No known key found for this signature in database
3 changed files with 41 additions and 209 deletions

View file

@ -2,13 +2,12 @@
package config
import (
"fmt"
"hash/fnv"
"math/rand"
"reflect"
"time"
"github.com/tkw1536/pkglib/pools"
"github.com/tkw1536/pkglib/reflectx"
"github.com/tkw1536/pkglib/yamlx"
"gopkg.in/yaml.v3"
@ -42,7 +41,7 @@ type Config struct {
PublicSSHPort uint16 `yaml:"ssh_port" default:"2222" validate:"port"`
// session secret holds the secret for login
SessionSecret string `yaml:"session_secret" validate:"nonempty"`
SessionSecret string `yaml:"session_secret" validate:"nonempty" sensitive:"true"`
// interval to trigger distillery cron tasks in
CronInterval time.Duration `yaml:"cron_interval" default:"10m" validate:"duration"`
@ -51,6 +50,34 @@ type Config struct {
ConfigPath string `yaml:"-"`
}
func zeroSensitive(v reflect.Value) {
reflectx.IterateFields(v.Type(), func(field reflect.StructField, index int) (stop bool) {
// if we set the recurse tag, recurse into it
if _, ok := field.Tag.Lookup("recurse"); ok {
zeroSensitive(v.FieldByName(field.Name))
}
// if the field is sensitive, set the zero value!
if _, ok := field.Tag.Lookup("sensitive"); ok {
v.FieldByName(field.Name).Set(reflect.Zero(field.Type))
}
return false
})
}
func (config Config) MarshalSensitive() string {
// zero out all the sensitive fields
zeroSensitive(reflect.ValueOf(&config).Elem())
// marshal the result
result, err := Marshal(&config, nil)
if err != nil {
return ""
}
return string(result)
}
//go:embed config.yml
var configBytes []byte
@ -100,28 +127,3 @@ func (config *Config) CSRFSecret() []byte {
rand.Read(secret)
return secret
}
// String serializes this configuration into a string
func (config Config) String() string {
builder := pools.GetBuilder()
defer pools.ReleaseBuilder(builder)
vConfig := reflect.ValueOf(config)
tConfig := vConfig.Type()
// iterate over the types
numValues := tConfig.NumField()
for i := 0; i < numValues; i++ {
tField := tConfig.Field(i)
vField := vConfig.FieldByName(tField.Name)
env := tField.Tag.Get("env")
if env == "" {
continue
}
fmt.Fprintf(builder, "%s=%v\n", env, vField.Interface())
}
return builder.String()
}

View file

@ -4,7 +4,7 @@ type DatabaseConfig struct {
// Credentials for the admin user.
// Is automatically created if it does not exist.
AdminUsername string `yaml:"username" default:"admin" validate:"nonempty"`
AdminPassword string `yaml:"password" validate:"nonempty"`
AdminPassword string `yaml:"password" validate:"nonempty" sensitive:"****"`
// Prefix for new users and data setss
UserPrefix string `yaml:"user_prefix" default:"wisski-distillery-" validate:"slug"`

View file

@ -1,183 +1,3 @@
<div class="pure-u-1-1">
<h2 id="overview">Distillery Configuration</h2>
</div>
<div class="pure-u-1 pure-u-xl-1-3">
<div class="padding">
<div class="overflow">
<table class="pure-table pure-table-bordered">
<thead>
<tr>
<th colspan="2">
Domains
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Primary
</td>
<td>
<code>{{.Config.DefaultDomain}}</code>
</td>
</tr>
<tr>
<td>
Extra
</td>
<td>
{{ range .Config.SelfExtraDomains }}
<code>{{.}}</code><br />
{{ end }}
</td>
</tr>
<tr>
<td>
Email <small>(HTTPS)</small>
</td>
<td>
<code>{{.Config.CertbotEmail}}</code>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="pure-u-1 pure-u-xl-1-3">
<div class="padding">
<div class="overflow">
<table class="pure-table pure-table-bordered">
<thead>
<tr>
<th colspan="2">
Database Settings
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
MySQL User Prefix
</td>
<td>
<code>{{.Config.MysqlUserPrefix}}</code>
</td>
</tr>
<tr>
<td>
MySQL Database Prefix
</td>
<td>
<code>{{.Config.MysqlDatabasePrefix}}</code>
</td>
</tr>
<tr>
<td>
GraphDB User Prefix
</td>
<td>
<code>{{.Config.GraphDBUserPrefix}}</code>
</td>
</tr>
<tr>
<td>
GraphDB Database Prefix
</td>
<td>
<code>{{.Config.GraphDBRepoPrefix}}</code>
</td>
</tr>
<tr>
<td>
Bookkeeping Database
</td>
<td>
<code>{{.Config.DistilleryDatabase}}</code>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="pure-u-1 pure-u-xl-1-3">
<div class="padding">
<div class="overflow">
<table class="pure-table pure-table-bordered">
<thead>
<tr>
<th colspan="2">
Directory Settings
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>root</code>
</td>
<td>
<code>{{.Config.Paths.Root}}</code>
</td>
</tr>
<tr>
<td>
<code>config</code>
</td>
<td>
<code>{{.Config.ConfigPath}}</code>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="pure-u-1 pure-u-xl-2-5">
<div class="padding">
<div class="overflow">
<table class="pure-table pure-table-bordered">
<thead>
<tr>
<th colspan="2">
Misc Settings
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Homepage
</td>
<td>
<a href="{{.Config.SelfRedirect}}" target="_blank" rel="noopener noreferrer">{{.Config.SelfRedirect}}</a>
</td>
</tr>
<tr>
<td>
Docker Network Name
</td>
<td>
<code>{{.Config.Docker.Network}}</code>
</td>
</tr>
<tr>
<td>
Backup Age
</td>
<td>
<code>{{.Config.MaxBackupAge}}</code> Day(s)
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="pure-u-1-1">
<h2 id="backups">Backups</h2>
<p>
@ -211,3 +31,13 @@
</tbody>
</table>
</div>
<div class="pure-u-1-1">
<h2 id="overview">Distillery Configuration</h2>
</div>
<div class="pure-u-1-1">
<code>
<pre>{{ .Config.MarshalSensitive }}</pre>
</code>
</div>