Commit 72bc4233 authored by ale's avatar ale

Read service definitions from standalone .yml files

Introduces the *services_dir* configuration parameter.
parent 0c751fc0
Pipeline #967 passed with stages
in 1 minute 3 seconds
......@@ -47,6 +47,11 @@ The YAML file should contain a dictionary with the following attributes:
* `services` is a dictionary describing all known services and their
authentication parameters. See the *Service definition* section below
* `services_dir` (optional) points at a directory containing service
configuration. Besides describing services in the main configuration
file (using the `services` attribute), it is possible to define
additional services in YAML-encoded files (having a *.yml*
extension), which is more automation-friendly.
* `rate_limits` defines the global rate limiters and blacklists. See
the *Rate limiting* section below.
* `enabled_backends` is the list of user backends that should be
......
......@@ -210,6 +210,9 @@ type Config struct {
// Service-specific configuration.
Services map[string]*ServiceConfig `yaml:"services"`
// If set, load more service definitions from *.yml files in this directory.
ServicesDir string `yaml:"services_dir"`
// Named rate limiter configurations.
RateLimiters map[string]*authRatelimiterConfig `yaml:"rate_limits"`
......@@ -288,6 +291,20 @@ func (c *Config) compile() error {
return nil
}
// Load a standalone service configuration: a YAML-encoded file that
// may contain one or more ServiceConfig definitions.
func loadStandaloneServiceConfig(path string) (map[string]*ServiceConfig, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
var out map[string]*ServiceConfig
if err = yaml.Unmarshal(data, &out); err != nil {
return nil, err
}
return out, nil
}
// LoadConfig loads the configuration from a YAML-encoded file.
func LoadConfig(path string) (*Config, error) {
data, err := ioutil.ReadFile(path)
......@@ -295,9 +312,28 @@ func LoadConfig(path string) (*Config, error) {
return nil, err
}
config := Config{path: path}
if err := yaml.Unmarshal(data, &config); err != nil {
if err = yaml.Unmarshal(data, &config); err != nil {
return nil, err
}
// Load service definitions from a directory if necessary, and
// merge them into config.Services.
if config.ServicesDir != "" {
files, _ := filepath.Glob(filepath.Join(config.ServicesDir, "*.yml"))
for _, f := range files {
if strings.HasPrefix(filepath.Base(f), ".") {
continue
}
tmp, err := loadStandaloneServiceConfig(f)
if err != nil {
return nil, fmt.Errorf("%s: %v", f, err)
}
for name, svc := range tmp {
config.Services[name] = svc
}
}
}
if err := config.compile(); err != nil {
return nil, err
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment