Add aggregate configuration support and update documentation
- Introduced AggregateConfig to manage aggregation settings in the gateway configuration. - Added validation for reserved alias 'agg' and included tests for aggregate alias handling. - Updated config.example.yaml to demonstrate aggregate configuration options. - Enhanced README.md to include information about the new aggregation endpoint and its usage. - Modified gateway.go to integrate the new aggregate handler for processing aggregation requests.
This commit is contained in:
@@ -15,11 +15,18 @@ var aliasRe = regexp.MustCompile(`^[a-z0-9][a-z0-9_-]*$`)
|
||||
|
||||
// Config is the gateway YAML configuration.
|
||||
type Config struct {
|
||||
Listen string `yaml:"listen"`
|
||||
AllowAll bool `yaml:"allow_all"`
|
||||
WhitelistCIDRs []string `yaml:"whitelist_cidrs"`
|
||||
TrustedProxies []string `yaml:"trusted_proxies"`
|
||||
Servers []Server `yaml:"servers"`
|
||||
Listen string `yaml:"listen"`
|
||||
AllowAll bool `yaml:"allow_all"`
|
||||
WhitelistCIDRs []string `yaml:"whitelist_cidrs"`
|
||||
TrustedProxies []string `yaml:"trusted_proxies"`
|
||||
Servers []Server `yaml:"servers"`
|
||||
Aggregate *AggregateConfig `yaml:"aggregate"`
|
||||
}
|
||||
|
||||
// AggregateConfig controls default scope of /api/agg/* (optional).
|
||||
type AggregateConfig struct {
|
||||
// IncludeAliases limits aggregation to these server aliases; empty means all servers.
|
||||
IncludeAliases []string `yaml:"include_aliases"`
|
||||
}
|
||||
|
||||
// Server maps a URL alias to an upstream base URL.
|
||||
@@ -63,6 +70,9 @@ func (c *Config) Validate() error {
|
||||
if _, ok := seen[s.Alias]; ok {
|
||||
return fmt.Errorf("duplicate alias %q", s.Alias)
|
||||
}
|
||||
if s.Alias == "agg" {
|
||||
return fmt.Errorf("servers[%d]: alias %q is reserved for /api/agg/", i, s.Alias)
|
||||
}
|
||||
seen[s.Alias] = struct{}{}
|
||||
if s.BaseURL == "" {
|
||||
return fmt.Errorf("servers[%d]: base_url is required", i)
|
||||
@@ -92,6 +102,17 @@ func (c *Config) Validate() error {
|
||||
return fmt.Errorf("trusted_proxies[%d]: %w", i, err)
|
||||
}
|
||||
}
|
||||
if c.Aggregate != nil {
|
||||
for i, a := range c.Aggregate.IncludeAliases {
|
||||
a = strings.TrimSpace(a)
|
||||
if a == "" {
|
||||
return fmt.Errorf("aggregate.include_aliases[%d]: empty entry", i)
|
||||
}
|
||||
if !seen[a] {
|
||||
return fmt.Errorf("aggregate.include_aliases[%d]: unknown server alias %q", i, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -62,3 +62,39 @@ func TestValidateDuplicateAlias(t *testing.T) {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateReservedAggAlias(t *testing.T) {
|
||||
c := &Config{
|
||||
Servers: []Server{
|
||||
{Alias: "agg", BaseURL: "http://x:1"},
|
||||
},
|
||||
}
|
||||
if err := c.Validate(); err == nil {
|
||||
t.Fatal("expected error for reserved alias agg")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAggregateIncludeAliases(t *testing.T) {
|
||||
c := &Config{
|
||||
Servers: []Server{
|
||||
{Alias: "a", BaseURL: "http://x:1"},
|
||||
},
|
||||
Aggregate: &AggregateConfig{
|
||||
IncludeAliases: []string{"a"},
|
||||
},
|
||||
}
|
||||
if err := c.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
c2 := &Config{
|
||||
Servers: []Server{
|
||||
{Alias: "a", BaseURL: "http://x:1"},
|
||||
},
|
||||
Aggregate: &AggregateConfig{
|
||||
IncludeAliases: []string{"nope"},
|
||||
},
|
||||
}
|
||||
if err := c2.Validate(); err == nil {
|
||||
t.Fatal("expected error for unknown include alias")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user