Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit 0b970e2

Browse files
committed
feat: server configuration
1 parent e794096 commit 0b970e2

File tree

5 files changed

+122
-3
lines changed

5 files changed

+122
-3
lines changed

Documentation/introduction/cli-configuration.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ This file is used to configure which StackHead modules to use.
77
You may define additional module configurations within the `modules_config` key.
88
See example below for setting the setting _server_names_hash_bucket_size_ for the Nginx proxy module.
99

10+
{% hint style="warning" %}
11+
The `modules`, `modules_config` and `terraform` settings may be overwritten via server configuration.
12+
The server configuration is located in `/stackhead/config.yml` (if it exists).
13+
{% endhint %}
14+
1015
## Full annotated configuration
1116

1217
```yaml

commands/prepare_context.go

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,71 @@
11
package commands
22

33
import (
4+
"github.com/knadh/koanf/maps"
5+
xfs "github.com/saitho/golang-extended-fs/v2"
6+
logger "github.com/sirupsen/logrus"
7+
"github.com/spf13/cast"
48
"github.com/spf13/viper"
9+
"gopkg.in/yaml.v3"
10+
11+
"github.com/getstackhead/stackhead/config"
12+
"github.com/getstackhead/stackhead/project"
13+
"github.com/getstackhead/stackhead/system"
514

615
container_docker "github.com/getstackhead/stackhead/modules/container/docker"
716
dns_cloudflare "github.com/getstackhead/stackhead/modules/dns/cloudflare"
817
plugin_portainer "github.com/getstackhead/stackhead/modules/plugin/portainer"
918
proxy_caddy "github.com/getstackhead/stackhead/modules/proxy/caddy"
1019
proxy_nginx "github.com/getstackhead/stackhead/modules/proxy/nginx"
11-
"github.com/getstackhead/stackhead/project"
12-
"github.com/getstackhead/stackhead/system"
1320
)
1421

22+
func EnforceSimpleValueOption(name string, value map[string]interface{}) {
23+
stringMap := viper.GetStringMap(name)
24+
for mapKey, mapValue := range value {
25+
stringMap[mapKey] = mapValue
26+
logger.Warnf("Enforcing setting \"%s.%s=%v\" via remote server configuration", name, mapKey, mapValue)
27+
}
28+
viper.Set(name, stringMap)
29+
}
30+
31+
func EnforceNestedValueOption(name string, value map[string]interface{}) {
32+
modulesConfigMap := viper.GetStringMap(name)
33+
for moduleName, moduleConfig := range cast.ToStringMap(value) {
34+
remoteSettings := cast.ToStringMap(moduleConfig)
35+
logMessage := "Enforcing module settings for \"" + moduleName + "\" via remote server configuration"
36+
// todo: uncomment when we can sanitize secrets in CLI output
37+
//for k, v := range remoteSettings {
38+
// logMessage += fmt.Sprintf("\n"+k+"=%v", v)
39+
//}
40+
logger.Warn(logMessage)
41+
newMap := cast.ToStringMap(modulesConfigMap[moduleName])
42+
maps.Merge(remoteSettings, newMap)
43+
modulesConfigMap[moduleName] = newMap
44+
}
45+
viper.Set(name, modulesConfigMap)
46+
}
47+
1548
func PrepareContext(host string, action string, projectDefinition *project.Project) {
1649
system.InitializeContext(host, action, projectDefinition)
1750

51+
// Check remote config on server
52+
hasFile, _ := xfs.HasFile("ssh://" + config.GetServerConfigFilePath())
53+
if hasFile {
54+
fileContent, err := xfs.ReadFile("ssh://" + config.GetServerConfigFilePath())
55+
if err != nil {
56+
panic("Found remote config file but was unable to read it: " + err.Error())
57+
}
58+
var c map[string]interface{}
59+
if err = yaml.Unmarshal([]byte(fileContent), &c); err != nil {
60+
panic("Found remote config file but was unable to parse it: " + err.Error())
61+
}
62+
63+
// Enforce remote configurations on viper
64+
EnforceSimpleValueOption("modules", cast.ToStringMap(c["modules"]))
65+
EnforceNestedValueOption("modules_config", cast.ToStringMap(c["modules_config"]))
66+
EnforceSimpleValueOption("terraform", cast.ToStringMap(c["terraform"]))
67+
}
68+
1869
// set proxy
1970
switch viper.GetStringMapString("modules")["proxy"] {
2071
case "nginx":

config/paths.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ var RootDirectory = "/stackhead"
1111
var RootTerraformDirectory = RootDirectory + "/terraform"
1212
var ProjectsRootDirectory = RootDirectory + "/projects"
1313

14+
func GetServerConfigFilePath() string {
15+
return path.Join(RootDirectory, "config.yml")
16+
}
17+
1418
func GetLocalStackHeadConfigDir() string {
1519
configDirs := configdir.New("getstackhead", "stackhead")
1620
folders := configDirs.QueryFolders(configdir.Global)

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ require (
1818
github.com/google/go-cmp v0.5.8
1919
github.com/gookit/event v1.0.6
2020
github.com/hairyhenderson/gomplate/v3 v3.11.2
21+
github.com/knadh/koanf v1.4.4
2122
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
2223
github.com/saitho/golang-extended-fs/v2 v2.0.2
2324
github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0
2425
github.com/sirupsen/logrus v1.8.1
26+
github.com/spf13/cast v1.3.1
2527
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
2628
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
2729
gopkg.in/yaml.v3 v3.0.1
@@ -134,7 +136,6 @@ require (
134136
github.com/sergi/go-diff v1.2.0 // indirect
135137
github.com/shopspring/decimal v1.2.0 // indirect
136138
github.com/spf13/afero v1.8.2 // indirect
137-
github.com/spf13/cast v1.3.1 // indirect
138139
github.com/spf13/jwalterweatherman v1.1.0 // indirect
139140
github.com/spf13/pflag v1.0.5 // indirect
140141
github.com/subosito/gotenv v1.2.0 // indirect

0 commit comments

Comments
 (0)