Skip to content
This repository was archived by the owner on Oct 2, 2022. It is now read-only.

Commit dedf1ef

Browse files
author
Janos Pasztor
committed
0.9.6: Added Validate()
This release adds a `Validate()` method to the configuration that allows for check the configuration on loading.
1 parent 831390e commit dedf1ef

File tree

11 files changed

+146
-115
lines changed

11 files changed

+146
-115
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.9.6: Added Validate()
4+
5+
This release adds a `Validate()` method to the configuration that allows for check the configuration on loading.
6+
37
## 0.9.5: Security configuration
48

59
This release adds support for the new [security library](https://github.com/containerssh/security). It also adds a metric for config server requests and updates several libraries to their latest versions.

appconfig.go

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package configuration
22

33
import (
4+
"fmt"
5+
46
"github.com/containerssh/auditlog"
57
"github.com/containerssh/auth"
68
"github.com/containerssh/docker"
@@ -16,42 +18,49 @@ import (
1618
//goland:noinspection GoDeprecation
1719
type AppConfig struct {
1820
// Listen is an alias for ssh.listen. Its usage is deprecated.
21+
// swagger:ignore
22+
// deprecated: use SSH.Listen instead
1923
Listen string `json:"listen,omitempty" yaml:"listen,omitempty" default:""`
2024
// SSH contains the configuration for the SSH server.
2125
// swagger:ignore
22-
SSH sshserver.Config `json:"ssh" yaml:"ssh" comment:"SSH configuration"`
26+
SSH sshserver.Config `json:"ssh" yaml:"ssh"`
2327
// ConfigServer contains the settings for fetching the user-specific configuration.
2428
// swagger:ignore
25-
ConfigServer ClientConfig `json:"configserver" yaml:"configserver" comment:"Configuration server settings"`
29+
ConfigServer ClientConfig `json:"configserver" yaml:"configserver"`
2630
// Auth contains the configuration for user authentication.
2731
// swagger:ignore
28-
Auth auth.ClientConfig `json:"auth" yaml:"auth" comment:"Authentication server configuration"`
32+
Auth auth.ClientConfig `json:"auth" yaml:"auth"`
2933
// Log contains the configuration for the logging level.
3034
// swagger:ignore
31-
Log log.Config `json:"log" yaml:"log" comment:"Log configuration"`
35+
Log log.Config `json:"log" yaml:"log"`
3236
// Metrics contains the configuration for the metrics server.
3337
// swagger:ignore
34-
Metrics metrics.Config `json:"metrics" yaml:"metrics" comment:"Metrics configuration."`
38+
Metrics metrics.Config `json:"metrics" yaml:"metrics"`
3539
// GeoIP contains the configuration for the GeoIP lookups.
3640
// swagger:ignore
37-
GeoIP geoip.Config `json:"geoip" yaml:"geoip" comment:"GeoIP database"`
41+
GeoIP geoip.Config `json:"geoip" yaml:"geoip"`
3842
// Audit contains the configuration for audit logging and log upload.
3943
// swagger:ignore
40-
Audit auditlog.Config `json:"audit" yaml:"audit" comment:"Audit configuration"`
41-
42-
// Security contains the security restrictions on what can be executed.
43-
Security security.Config `json:"security" yaml:"security" comment:"Security configuration"`
44+
Audit auditlog.Config `json:"audit" yaml:"audit"`
4445

46+
// Security contains the security restrictions on what can be executed. This option can be changed from the config
47+
// server.
48+
Security security.Config `json:"security" yaml:"security"`
4549
// Backend defines which backend to use. This option can be changed from the config server.
46-
Backend string `json:"backend" yaml:"backend" default:"dockerrun" comment:"Backend module to use"`
47-
// Docker contains the configuration for the docker backend.
48-
Docker docker.Config `json:"docker,omitempty" yaml:"docker" comment:"Docker configuration to use when the Docker backend is used."`
49-
// DockerRun contains the configuration for the deprecated dockerrun backend.
50-
DockerRun docker.DockerRunConfig `json:"dockerrun,omitempty" yaml:"dockerrun" comment:"Docker configuration to use when the Docker run backend is used."`
51-
// Kubernetes contains the configuration for the kubernetes backend.
52-
Kubernetes kubernetes.Config `json:"kubernetes,omitempty" yaml:"kubernetes" comment:"Kubernetes configuration to use when the kubernetes run backend is used."`
53-
// KubeRun contains the configuration for the deprecated kuberun backend.
54-
KubeRun kubernetes.KubeRunConfig `json:"kuberun,omitempty" yaml:"kuberun" comment:"Kubernetes configuration to use when the kuberun run backend is used."`
50+
Backend string `json:"backend" yaml:"backend" default:"docker"`
51+
// Docker contains the configuration for the docker backend. This option can be changed from the config server.
52+
Docker docker.Config `json:"docker,omitempty" yaml:"docker"`
53+
// DockerRun contains the configuration for the deprecated dockerrun backend. This option can be changed from the
54+
// config server.
55+
// deprecated: use Docker instead
56+
DockerRun docker.DockerRunConfig `json:"dockerrun,omitempty" yaml:"dockerrun"`
57+
// Kubernetes contains the configuration for the kubernetes backend. This option can be changed from the config
58+
// server.
59+
Kubernetes kubernetes.Config `json:"kubernetes,omitempty" yaml:"kubernetes"`
60+
// KubeRun contains the configuration for the deprecated kuberun backend. This option can be changed from the config
61+
// server.
62+
// deprecated: use Kubernetes instead
63+
KubeRun kubernetes.KubeRunConfig `json:"kuberun,omitempty" yaml:"kuberun"`
5564
}
5665

5766
// FixCompatibility moves deprecated options to their new places and issues warnings.
@@ -67,3 +76,64 @@ func (cfg *AppConfig) FixCompatibility(logger log.Logger) error {
6776
}
6877
return nil
6978
}
79+
80+
// Validate validates the configuration structure and returns an error if it is invalid.
81+
//
82+
// - dynamic enables the validation for dynamically configurable options.
83+
func (cfg *AppConfig) Validate(dynamic bool) error {
84+
queue := newValidationQueue()
85+
queue.add("SSH", &cfg.SSH)
86+
queue.add("config server", &cfg.ConfigServer)
87+
queue.add("authentication", &cfg.Auth)
88+
queue.add("logging", &cfg.Log)
89+
queue.add("metrics", &cfg.Metrics)
90+
queue.add("GeoIP", &cfg.GeoIP)
91+
queue.add("audit log", &cfg.Audit)
92+
93+
if cfg.ConfigServer.URL != "" && !dynamic {
94+
return queue.Validate()
95+
}
96+
queue.add("security configuration", &cfg.Security)
97+
switch cfg.Backend {
98+
case "docker":
99+
queue.add("Docker", &cfg.Docker)
100+
case "dockerrun":
101+
queue.add("DockerRun", &cfg.DockerRun)
102+
case "kubernetes":
103+
queue.add("Kubernetes", &cfg.Kubernetes)
104+
case "kuberun":
105+
queue.add("KubeRun", &cfg.KubeRun)
106+
case "":
107+
return fmt.Errorf("no backend configured")
108+
default:
109+
return fmt.Errorf("invalid backend: %s", cfg.Backend)
110+
}
111+
return queue.Validate()
112+
}
113+
114+
type validatable interface {
115+
Validate() error
116+
}
117+
118+
func newValidationQueue() *validationQueue {
119+
return &validationQueue{
120+
items: map[string]validatable{},
121+
}
122+
}
123+
124+
type validationQueue struct {
125+
items map[string]validatable
126+
}
127+
128+
func (v *validationQueue) add(name string, item validatable) {
129+
v.items[name] = item
130+
}
131+
132+
func (v *validationQueue) Validate() error {
133+
for name, item := range v.items {
134+
if err := item.Validate(); err != nil {
135+
return fmt.Errorf("invalid %s configuration (%w)", name, err)
136+
}
137+
}
138+
return nil
139+
}

client_config.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,11 @@ import (
88
type ClientConfig struct {
99
http.ClientConfiguration `yaml:",inline"`
1010
}
11+
12+
// Validate validates the client configuration.
13+
func (c *ClientConfig) Validate() error {
14+
if c.ClientConfiguration.URL == "" {
15+
return nil
16+
}
17+
return c.ClientConfiguration.Validate()
18+
}

compatibility_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"testing"
77

88
"github.com/containerssh/log"
9+
"github.com/containerssh/structutils"
910
"github.com/stretchr/testify/assert"
1011

1112
"github.com/containerssh/configuration"
@@ -35,6 +36,7 @@ func Test03Compatibility(t *testing.T) {
3536
assert.NoError(t, err)
3637

3738
config := configuration.AppConfig{}
39+
structutils.Defaults(&config)
3840
err = reader.Load(context.Background(), &config)
3941
assert.NoError(t, err)
4042

data/0.3.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ configserver:
2525
cert: ""
2626
key: ""
2727
auth:
28-
url: ""
28+
url: "http://localhost:8080"
2929
cacert: ""
3030
timeout: 2s
3131
cert: ""

go.mod

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ module github.com/containerssh/configuration
33
go 1.14
44

55
require (
6-
github.com/containerssh/auditlog v0.9.5
6+
github.com/containerssh/auditlog v0.9.6
77
github.com/containerssh/auth v0.9.3
8-
github.com/containerssh/docker v0.9.5
9-
github.com/containerssh/geoip v0.9.3
10-
github.com/containerssh/http v0.9.4
11-
github.com/containerssh/kubernetes v0.9.2
12-
github.com/containerssh/log v0.9.7
8+
github.com/containerssh/docker v0.9.6
9+
github.com/containerssh/geoip v0.9.4
10+
github.com/containerssh/http v0.9.5
11+
github.com/containerssh/kubernetes v0.9.3
12+
github.com/containerssh/log v0.9.8
1313
github.com/containerssh/metrics v0.9.5
14-
github.com/containerssh/security v0.9.0
14+
github.com/containerssh/security v0.9.2
1515
github.com/containerssh/service v0.9.0
1616
github.com/containerssh/sshserver v0.9.14
1717
github.com/containerssh/structutils v0.9.0

0 commit comments

Comments
 (0)