aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorNiall Sheridan <nsheridan@gmail.com>2017-01-24 23:43:28 +0000
committerNiall Sheridan <nsheridan@gmail.com>2017-01-25 00:02:37 +0000
commitf635033e3e953e74d67b76a520c9760786330af5 (patch)
tree8e41d7d07c489edbfb45f1d4ffff921b2f6bc265 /server
parent0f4344348419ed6c3ee4236188e456d79e2d51b4 (diff)
Switch to scl, an extension of hcl
Diffstat (limited to 'server')
-rw-r--r--server/config/config.go105
-rw-r--r--server/config/config_test.go8
-rw-r--r--server/config/testdata/config.go48
-rw-r--r--server/config/testdata/empty.config0
-rw-r--r--server/config/testdata/test.config42
5 files changed, 82 insertions, 121 deletions
diff --git a/server/config/config.go b/server/config/config.go
index eec6d73..9ac4a7d 100644
--- a/server/config/config.go
+++ b/server/config/config.go
@@ -3,26 +3,24 @@ package config
import (
"bytes"
"fmt"
- "io"
"log"
"os"
"strconv"
"strings"
"github.com/hashicorp/go-multierror"
- "github.com/mitchellh/mapstructure"
+ "github.com/homemade/scl"
"github.com/nsheridan/cashier/server/helpers/vault"
"github.com/pkg/errors"
- "github.com/spf13/viper"
)
// Config holds the final server configuration.
type Config struct {
- Server *Server `mapstructure:"server"`
- Auth *Auth `mapstructure:"auth"`
- SSH *SSH `mapstructure:"ssh"`
- AWS *AWS `mapstructure:"aws"`
- Vault *Vault `mapstructure:"vault"`
+ Server *Server `hcl:"server"`
+ Auth *Auth `hcl:"auth"`
+ SSH *SSH `hcl:"ssh"`
+ AWS *AWS `hcl:"aws"`
+ Vault *Vault `hcl:"vault"`
}
// Database holds database configuration.
@@ -30,51 +28,51 @@ type Database map[string]string
// Server holds the configuration specific to the web server and sessions.
type Server struct {
- UseTLS bool `mapstructure:"use_tls"`
- TLSKey string `mapstructure:"tls_key"`
- TLSCert string `mapstructure:"tls_cert"`
- LetsEncryptServername string `mapstructure:"letsencrypt_servername"`
- LetsEncryptCache string `mapstructure:"letsencrypt_cachedir"`
- Addr string `mapstructure:"address"`
- Port int `mapstructure:"port"`
- User string `mapstructure:"user"`
- CookieSecret string `mapstructure:"cookie_secret"`
- CSRFSecret string `mapstructure:"csrf_secret"`
- HTTPLogFile string `mapstructure:"http_logfile"`
- Database Database `mapstructure:"database"`
- Datastore string `mapstructure:"datastore"` // Deprecated. TODO: remove.
+ UseTLS bool `hcl:"use_tls"`
+ TLSKey string `hcl:"tls_key"`
+ TLSCert string `hcl:"tls_cert"`
+ LetsEncryptServername string `hcl:"letsencrypt_servername"`
+ LetsEncryptCache string `hcl:"letsencrypt_cachedir"`
+ Addr string `hcl:"address"`
+ Port int `hcl:"port"`
+ User string `hcl:"user"`
+ CookieSecret string `hcl:"cookie_secret"`
+ CSRFSecret string `hcl:"csrf_secret"`
+ HTTPLogFile string `hcl:"http_logfile"`
+ Database Database `hcl:"database"`
+ Datastore string `hcl:"datastore"` // Deprecated. TODO: remove.
}
// Auth holds the configuration specific to the OAuth provider.
type Auth struct {
- OauthClientID string `mapstructure:"oauth_client_id"`
- OauthClientSecret string `mapstructure:"oauth_client_secret"`
- OauthCallbackURL string `mapstructure:"oauth_callback_url"`
- Provider string `mapstructure:"provider"`
- ProviderOpts map[string]string `mapstructure:"provider_opts"`
- UsersWhitelist []string `mapstructure:"users_whitelist"`
+ OauthClientID string `hcl:"oauth_client_id"`
+ OauthClientSecret string `hcl:"oauth_client_secret"`
+ OauthCallbackURL string `hcl:"oauth_callback_url"`
+ Provider string `hcl:"provider"`
+ ProviderOpts map[string]string `hcl:"provider_opts"`
+ UsersWhitelist []string `hcl:"users_whitelist"`
}
// SSH holds the configuration specific to signing ssh keys.
type SSH struct {
- SigningKey string `mapstructure:"signing_key"`
- AdditionalPrincipals []string `mapstructure:"additional_principals"`
- MaxAge string `mapstructure:"max_age"`
- Permissions []string `mapstructure:"permissions"`
+ SigningKey string `hcl:"signing_key"`
+ AdditionalPrincipals []string `hcl:"additional_principals"`
+ MaxAge string `hcl:"max_age"`
+ Permissions []string `hcl:"permissions"`
}
// AWS holds Amazon AWS configuration.
// AWS can also be configured using SDK methods.
type AWS struct {
- Region string `mapstructure:"region"`
- AccessKey string `mapstructure:"access_key"`
- SecretKey string `mapstructure:"secret_key"`
+ Region string `hcl:"region"`
+ AccessKey string `hcl:"access_key"`
+ SecretKey string `hcl:"secret_key"`
}
// Vault holds Hashicorp Vault configuration.
type Vault struct {
- Address string `mapstructure:"address"`
- Token string `mapstructure:"token"`
+ Address string `hcl:"address"`
+ Token string `hcl:"token"`
}
func verifyConfig(c *Config) error {
@@ -186,38 +184,11 @@ func setFromVault(c *Config) error {
return errors.Wrap(errs, "errors reading from vault")
}
-// Unmarshal the config into a *Config
-func decode() (*Config, error) {
- var errs error
- config := &Config{}
- configPieces := map[string]interface{}{
- "auth": &config.Auth,
- "aws": &config.AWS,
- "server": &config.Server,
- "ssh": &config.SSH,
- "vault": &config.Vault,
- }
- for key, val := range configPieces {
- conf, ok := viper.Get(key).([]map[string]interface{})
- if !ok {
- continue
- }
- if err := mapstructure.WeakDecode(conf[0], val); err != nil {
- errs = multierror.Append(errs, err)
- }
- }
- return config, errs
-}
-
// ReadConfig parses a hcl configuration file into a Config struct.
-func ReadConfig(r io.Reader) (*Config, error) {
- viper.SetConfigType("hcl")
- if err := viper.ReadConfig(r); err != nil {
- return nil, errors.Wrap(err, "unable to read config")
- }
- config, err := decode()
- if err != nil {
- return nil, errors.Wrap(err, "unable to parse config")
+func ReadConfig(f string) (*Config, error) {
+ config := &Config{}
+ if err := scl.DecodeFile(config, f); err != nil {
+ return nil, errors.Wrapf(err, "unable to load config from file %s", f)
}
if err := setFromVault(config); err != nil {
return nil, err
diff --git a/server/config/config_test.go b/server/config/config_test.go
index 399e143..182436a 100644
--- a/server/config/config_test.go
+++ b/server/config/config_test.go
@@ -1,10 +1,8 @@
package config
import (
- "bytes"
"testing"
- "github.com/nsheridan/cashier/server/config/testdata"
"github.com/stretchr/testify/assert"
)
@@ -21,7 +19,6 @@ var (
CSRFSecret: "supersecret",
HTTPLogFile: "cashierd.log",
Database: Database{"type": "mysql", "username": "user", "password": "passwd", "address": "localhost:3306"},
- Datastore: "mysql:user:passwd:localhost:3306",
},
Auth: &Auth{
OauthClientID: "client_id",
@@ -50,7 +47,7 @@ var (
)
func TestConfigParser(t *testing.T) {
- c, err := ReadConfig(bytes.NewBuffer(testdata.Config))
+ c, err := ReadConfig("testdata/test.config")
if err != nil {
t.Error(err)
}
@@ -58,8 +55,7 @@ func TestConfigParser(t *testing.T) {
}
func TestConfigVerify(t *testing.T) {
- bad := bytes.NewBuffer([]byte(""))
- _, err := ReadConfig(bad)
+ _, err := ReadConfig("testdata/empty.config")
assert.Contains(t, err.Error(), "missing ssh config section", "missing server config section", "missing auth config section")
}
diff --git a/server/config/testdata/config.go b/server/config/testdata/config.go
deleted file mode 100644
index 27cffcc..0000000
--- a/server/config/testdata/config.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package testdata
-
-var Config = []byte(`
- server {
- use_tls = true
- tls_key = "server.key"
- tls_cert = "server.crt"
- address = "127.0.0.1"
- port = 443
- user = "nobody"
- cookie_secret = "supersecret"
- csrf_secret = "supersecret"
- http_logfile = "cashierd.log"
- datastore = "mysql:user:passwd:localhost:3306"
- database {
- type = "mysql"
- username = "user"
- password = "passwd"
- address = "localhost:3306"
- }
- datastore = "mysql:user:passwd:localhost:3306"
- }
- auth {
- provider = "google"
- oauth_client_id = "client_id"
- oauth_client_secret = "secret"
- oauth_callback_url = "https://sshca.example.com/auth/callback"
- provider_opts {
- domain = "example.com"
- }
- users_whitelist = ["a_user"]
- }
- ssh {
- signing_key = "signing_key"
- additional_principals = ["ec2-user", "ubuntu"]
- max_age = "720h"
- permissions = ["permit-pty", "permit-X11-forwarding", "permit-port-forwarding", "permit-user-rc"]
- }
- aws {
- region = "us-east-1"
- access_key = "abcdef"
- secret_key = "omg123"
- }
- vault {
- address = "https://vault:8200"
- token = "abc-def-456-789"
- }
-`)
diff --git a/server/config/testdata/empty.config b/server/config/testdata/empty.config
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/server/config/testdata/empty.config
diff --git a/server/config/testdata/test.config b/server/config/testdata/test.config
new file mode 100644
index 0000000..96899e7
--- /dev/null
+++ b/server/config/testdata/test.config
@@ -0,0 +1,42 @@
+server {
+ use_tls = true
+ tls_key = "server.key"
+ tls_cert = "server.crt"
+ address = "127.0.0.1"
+ port = 443
+ user = "nobody"
+ cookie_secret = "supersecret"
+ csrf_secret = "supersecret"
+ http_logfile = "cashierd.log"
+ database {
+ type = "mysql"
+ username = "user"
+ password = "passwd"
+ address = "localhost:3306"
+ }
+}
+auth {
+ provider = "google"
+ oauth_client_id = "client_id"
+ oauth_client_secret = "secret"
+ oauth_callback_url = "https://sshca.example.com/auth/callback"
+ provider_opts {
+ domain = "example.com"
+ }
+ users_whitelist = ["a_user"]
+}
+ssh {
+ signing_key = "signing_key"
+ additional_principals = ["ec2-user", "ubuntu"]
+ max_age = "720h"
+ permissions = ["permit-pty", "permit-X11-forwarding", "permit-port-forwarding", "permit-user-rc"]
+}
+aws {
+ region = "us-east-1"
+ access_key = "abcdef"
+ secret_key = "omg123"
+}
+vault {
+ address = "https://vault:8200"
+ token = "abc-def-456-789"
+}