refactor: path from address (#5492)

Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
pull/5496/head^2
James Elliott 2023-05-30 18:21:19 +10:00 committed by GitHub
parent f90c369b45
commit 4577fce95b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 233 additions and 524 deletions

View File

@ -7,5 +7,5 @@
package cmd
const (
versionSwaggerUI = "4.18.3"
versionSwaggerUI = "4.19.0"
)

View File

@ -47,15 +47,12 @@ default_redirection_url: 'https://home.example.com/'
server:
## The address for the Main server to listen on in the address common syntax.
## Formats:
## - [<scheme>://]<hostname>[:<port>]
## - [<scheme>://][hostname]:<port>
## - [<scheme>://]<hostname>[:<port>][/<path>]
## - [<scheme>://][hostname]:<port>[/<path>]
## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', or 'unix'.
## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '9091'.
address: 'tcp://:9091'
## Set the single level path Authelia listens on.
## Must be alphanumeric chars and should not contain any slashes.
path: ''
## If the path is specified this configures the router to handle both the `/` path and the configured path.
address: 'tcp://:9091/'
## Set the path on disk to Authelia assets.
## Useful to allow overriding of specific static assets.
@ -162,11 +159,12 @@ telemetry:
## The address for the Metrics server to listen on in the address common syntax.
## Formats:
## - [<scheme>://]<hostname>[:<port>]
## - [<scheme>://][hostname]:<port>
## - [<scheme>://]<hostname>[:<port>][/<path>]
## - [<scheme>://][hostname]:<port>[/<path>]
## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', or 'unix'.
## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '9959'.
address: 'tcp://:9959'
## If the path is not specified it defaults to `/metrics`.
address: 'tcp://:9959/metrics'
## Metrics Server Buffers configuration.
# buffers:

View File

@ -21,8 +21,7 @@ aliases:
```yaml
server:
address: 'tcp://:9091'
path: ''
address: 'tcp://:9091/'
disable_healthcheck: false
tls:
key: ''
@ -59,19 +58,25 @@ server:
### address
{{< confkey type="address" default="tcp://:9091" required="no" >}}
{{< confkey type="address" default="tcp://:9091/" required="no" >}}
*__Reference Note:__ This configuration option uses the [address common syntax](../prologue/common.md#address). Please
see the [documentation](../prologue/common.md#address) on this format for more information.*
Configures the listener address for the Main HTTP Server. The address itself is a listener and the scheme must either be
the `unix` scheme or one of the `tcp` schemes.
the `unix` scheme or one of the `tcp` schemes. It can configure the host, port, and path the listener responds to. If
the path is configured to anything other than `/` Authelia will handle requests for both `/` and the configured path.
__Examples:__
```yaml
server:
address: tcp://127.0.0.1:9091
address: tcp://127.0.0.1:9091/
```
```yaml
server:
address: tcp://127.0.0.1:9091/subpath
```
```yaml
@ -79,34 +84,6 @@ server:
address: unix:///var/run/authelia.sock
```
### path
{{< confkey type="string " required="no" >}}
Authelia by default is served from the root `/` location, either via its own domain or subdomain.
Modifying this setting will allow you to serve Authelia out from a specified base path. Please note
that currently only a single level path is supported meaning slashes are not allowed, and only
alphanumeric characters are supported.
__Example:__
```yaml
server:
path: ""
```
*Works for https://auth.example.com/, https://example.com/, etc*.
__Example:__
```yaml
server:
path: authelia
```
*Works for https://auth.example.com/authelia/, https://example.com/authelia/, etc*.
### asset_path
{{< confkey type="string " required="no" >}}

View File

@ -88,7 +88,7 @@ Refer to the individual documentation for an option for clarity. In this format
are optional. The default for these when not provided varies.
```text
[<scheme>://]<hostname>[:<port>]
[<scheme>://]<hostname>[:<port>][/<path>]
```
##### Port
@ -99,7 +99,7 @@ hostname are optional. The default for the scheme when not provided varies, and
available addresses when not provided.
```text
[<scheme>://][hostname]:<port>
[<scheme>://][hostname]:<port>[/<path>]
```
##### Unix Domain Socket
@ -131,8 +131,11 @@ Various examples for these formats.
```text
0.0.0.0
tcp://0.0.0.0
tcp://0.0.0.0/subpath
tcp://0.0.0.0:9091
tcp://0.0.0.0:9091/subpath
tcp://:9091
tcp://:9091/subpath
0.0.0.0:9091
udp://0.0.0.0:123

View File

@ -22,7 +22,7 @@ toc: true
telemetry:
metrics:
enabled: false
address: 'tcp://:9959'
address: 'tcp://:9959/'
buffers:
read: 4096
write: 4096
@ -44,7 +44,7 @@ Determines if the [Prometheus] HTTP Metrics Exporter is enabled.
### address
{{< confkey type="address" default="tcp://:9959" required="no" >}}
{{< confkey type="address" default="tcp://:9959/" required="no" >}}
*__Reference Note:__ This configuration option uses the [address common syntax](../prologue/common.md#address). Please
see the [documentation](../prologue/common.md#address) on this format for more information.*

File diff suppressed because one or more lines are too long

View File

@ -47,15 +47,12 @@ default_redirection_url: 'https://home.example.com/'
server:
## The address for the Main server to listen on in the address common syntax.
## Formats:
## - [<scheme>://]<hostname>[:<port>]
## - [<scheme>://][hostname]:<port>
## - [<scheme>://]<hostname>[:<port>][/<path>]
## - [<scheme>://][hostname]:<port>[/<path>]
## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', or 'unix'.
## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '9091'.
address: 'tcp://:9091'
## Set the single level path Authelia listens on.
## Must be alphanumeric chars and should not contain any slashes.
path: ''
## If the path is specified this configures the router to handle both the `/` path and the configured path.
address: 'tcp://:9091/'
## Set the path on disk to Authelia assets.
## Useful to allow overriding of specific static assets.
@ -162,11 +159,12 @@ telemetry:
## The address for the Metrics server to listen on in the address common syntax.
## Formats:
## - [<scheme>://]<hostname>[:<port>]
## - [<scheme>://][hostname]:<port>
## - [<scheme>://]<hostname>[:<port>][/<path>]
## - [<scheme>://][hostname]:<port>[/<path>]
## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', or 'unix'.
## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '9959'.
address: 'tcp://:9959'
## If the path is not specified it defaults to `/metrics`.
address: 'tcp://:9959/metrics'
## Metrics Server Buffers configuration.
# buffers:

View File

@ -38,6 +38,8 @@ const (
errFmtDecodeHookCouldNotParse = "could not decode '%s' to a %s%s: %w"
errFmtDecodeHookCouldNotParseBasic = "could not decode to a %s%s: %w"
errFmtDecodeHookCouldNotParseEmptyValue = "could not decode an empty value to a %s%s: %w"
errFmtSpecialRemappedKey = "configuration key '%s' is deprecated in %s and has been replaced by '%s' when combined with the '%s' in the format of '%s': this should be automatically mapped for you but you will need to adjust your configuration to remove this message"
)
const (

View File

@ -187,7 +187,7 @@ var deprecations = map[string]Deprecation{
Keep: true,
MapFunc: nil,
ErrFunc: func(d Deprecation, _ map[string]any, _ any, val *schema.StructValidator) {
val.PushWarning(fmt.Errorf("configuration key 'server.host' is deprecated in %s and has been replaced by 'server.address' when combined with the 'server.port' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message", d.Version.String()))
val.PushWarning(fmt.Errorf("configuration key '%s' is deprecated in %s and has been replaced by '%s' when combined with the 'server.port' and 'server.path' in the format of %s: this should be automatically mapped for you but you will need to adjust your configuration to remove this message", d.Key, d.Version.String(), d.NewKey, "'[tcp[(4|6)]://]<hostname>[:<port>][/<path>]' or 'tcp[(4|6)://][hostname]:<port>[/<path>]'"))
},
},
"server.port": {
@ -198,7 +198,18 @@ var deprecations = map[string]Deprecation{
Keep: true,
MapFunc: nil,
ErrFunc: func(d Deprecation, _ map[string]any, _ any, val *schema.StructValidator) {
val.PushWarning(fmt.Errorf("configuration key 'server.port' is deprecated in %s and has been replaced by 'server.address' when combined with the 'server.host' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message", d.Version.String()))
val.PushWarning(fmt.Errorf("configuration key '%s' is deprecated in %s and has been replaced by '%s' when combined with the 'server.host' and 'server.path' in the format of %s: this should be automatically mapped for you but you will need to adjust your configuration to remove this message", d.Key, d.Version.String(), d.NewKey, "'[tcp[(4|6)]://]<hostname>[:<port>][/<path>]' or 'tcp[(4|6)://][hostname]:<port>[/<path>]'"))
},
},
"server.path": {
Version: model.SemanticVersion{Major: 4, Minor: 38},
Key: "server.path",
NewKey: "server.address",
AutoMap: false,
Keep: true,
MapFunc: nil,
ErrFunc: func(d Deprecation, _ map[string]any, _ any, val *schema.StructValidator) {
val.PushWarning(fmt.Errorf("configuration key '%s' is deprecated in %s and has been replaced by '%s' when combined with the 'server.host' and 'server.port' in the format of %s: this should be automatically mapped for you but you will need to adjust your configuration to remove this message", d.Key, d.Version.String(), d.NewKey, "'[tcp[(4|6)]://]<hostname>[:<port>][/<path>]' or 'tcp[(4|6)://][hostname]:<port>[/<path>]'"))
},
},
"storage.mysql.host": {
@ -209,7 +220,7 @@ var deprecations = map[string]Deprecation{
Keep: true,
MapFunc: nil,
ErrFunc: func(d Deprecation, _ map[string]any, _ any, val *schema.StructValidator) {
val.PushWarning(fmt.Errorf("configuration key 'storage.mysql.host' is deprecated in %s and has been replaced by 'storage.mysql.address' when combined with the 'storage.mysql.port' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message", d.Version.String()))
val.PushWarning(fmt.Errorf(errFmtSpecialRemappedKey, d.Key, d.Version.String(), d.NewKey, "storage.mysql.port", "[tcp://]<hostname>[:<port>]"))
},
},
"storage.mysql.port": {
@ -220,7 +231,7 @@ var deprecations = map[string]Deprecation{
Keep: true,
MapFunc: nil,
ErrFunc: func(d Deprecation, _ map[string]any, _ any, val *schema.StructValidator) {
val.PushWarning(fmt.Errorf("configuration key 'storage.mysql.port' is deprecated in %s and has been replaced by 'storage.mysql.address' when combined with the 'storage.mysql.host' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message", d.Version.String()))
val.PushWarning(fmt.Errorf(errFmtSpecialRemappedKey, d.Key, d.Version.String(), d.NewKey, "storage.mysql.host", "[tcp://]<hostname>[:<port>]"))
},
},
"storage.postgres.host": {
@ -231,7 +242,7 @@ var deprecations = map[string]Deprecation{
Keep: true,
MapFunc: nil,
ErrFunc: func(d Deprecation, _ map[string]any, _ any, val *schema.StructValidator) {
val.PushWarning(fmt.Errorf("configuration key 'storage.postgres.host' is deprecated in %s and has been replaced by 'storage.postgres.address' when combined with the 'storage.postgres.port' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message", d.Version.String()))
val.PushWarning(fmt.Errorf(errFmtSpecialRemappedKey, d.Key, d.Version.String(), d.NewKey, "storage.postgres.port", "[tcp://]<hostname>[:<port>]"))
},
},
"storage.postgres.port": {
@ -242,7 +253,29 @@ var deprecations = map[string]Deprecation{
Keep: true,
MapFunc: nil,
ErrFunc: func(d Deprecation, _ map[string]any, _ any, val *schema.StructValidator) {
val.PushWarning(fmt.Errorf("configuration key 'storage.postgres.port' is deprecated in %s and has been replaced by 'storage.postgres.address' when combined with the 'storage.postgres.host' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message", d.Version.String()))
val.PushWarning(fmt.Errorf(errFmtSpecialRemappedKey, d.Key, d.Version.String(), d.NewKey, "storage.postgres.host", "[tcp://]<hostname>[:<port>]"))
},
},
"notifier.smtp.host": {
Version: model.SemanticVersion{Major: 4, Minor: 38},
Key: "notifier.smtp.host",
NewKey: "notifier.smtp.address",
AutoMap: false,
Keep: true,
MapFunc: nil,
ErrFunc: func(d Deprecation, _ map[string]any, _ any, val *schema.StructValidator) {
val.PushWarning(fmt.Errorf(errFmtSpecialRemappedKey, d.Key, d.Version.String(), d.NewKey, "notifier.smtp.port", "[tcp://]<hostname>[:<port>]"))
},
},
"notifier.smtp.port": {
Version: model.SemanticVersion{Major: 4, Minor: 38},
Key: "notifier.smtp.port",
NewKey: "notifier.smtp.address",
AutoMap: false,
Keep: true,
MapFunc: nil,
ErrFunc: func(d Deprecation, _ map[string]any, _ any, val *schema.StructValidator) {
val.PushWarning(fmt.Errorf(errFmtSpecialRemappedKey, d.Key, d.Version.String(), d.NewKey, "notifier.smtp.host", "[tcp://]<hostname>[:<port>]"))
},
},
"authentication_backend.ldap.url": {

View File

@ -314,44 +314,24 @@ func TestShouldValidateDeprecatedEnvNamesWithDeprecatedKeys(t *testing.T) {
assert.Len(t, val.Errors(), 0)
warnings := val.Warnings()
require.Len(t, warnings, 3)
require.Len(t, warnings, 10)
sort.Sort(utils.ErrSliceSortAlphabetical(warnings))
assert.EqualError(t, warnings[0], "configuration key 'authentication_backend.ldap.url' is deprecated in 4.38.0 and has been replaced by 'authentication_backend.ldap.address': this has been automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[1], "configuration key 'storage.mysql.host' is deprecated in 4.38.0 and has been replaced by 'storage.mysql.address' when combined with the 'storage.mysql.port' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[2], "configuration key 'storage.mysql.port' is deprecated in 4.38.0 and has been replaced by 'storage.mysql.address' when combined with the 'storage.mysql.host' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[1], "configuration key 'notifier.smtp.host' is deprecated in 4.38.0 and has been replaced by 'notifier.smtp.address' when combined with the 'notifier.smtp.port' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[2], "configuration key 'notifier.smtp.port' is deprecated in 4.38.0 and has been replaced by 'notifier.smtp.address' when combined with the 'notifier.smtp.host' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[3], "configuration key 'server.host' is deprecated in 4.38.0 and has been replaced by 'server.address' when combined with the 'server.port' and 'server.path' in the format of '[tcp[(4|6)]://]<hostname>[:<port>][/<path>]' or 'tcp[(4|6)://][hostname]:<port>[/<path>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[4], "configuration key 'server.path' is deprecated in 4.38.0 and has been replaced by 'server.address' when combined with the 'server.host' and 'server.port' in the format of '[tcp[(4|6)]://]<hostname>[:<port>][/<path>]' or 'tcp[(4|6)://][hostname]:<port>[/<path>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[5], "configuration key 'server.port' is deprecated in 4.38.0 and has been replaced by 'server.address' when combined with the 'server.host' and 'server.path' in the format of '[tcp[(4|6)]://]<hostname>[:<port>][/<path>]' or 'tcp[(4|6)://][hostname]:<port>[/<path>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[6], "configuration key 'storage.mysql.host' is deprecated in 4.38.0 and has been replaced by 'storage.mysql.address' when combined with the 'storage.mysql.port' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[7], "configuration key 'storage.mysql.port' is deprecated in 4.38.0 and has been replaced by 'storage.mysql.address' when combined with the 'storage.mysql.host' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[8], "configuration key 'storage.postgres.host' is deprecated in 4.38.0 and has been replaced by 'storage.postgres.address' when combined with the 'storage.postgres.port' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[9], "configuration key 'storage.postgres.port' is deprecated in 4.38.0 and has been replaced by 'storage.postgres.address' when combined with the 'storage.postgres.host' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.Equal(t, "ldap://from-env:389", c.AuthenticationBackend.LDAP.Address.String())
}
func TestShouldValidateDeprecatedEnvNamesWithDeprecatedKeysAlt(t *testing.T) {
val := schema.NewStructValidator()
keys, c, err := Load(val, NewDefaultSources([]string{"./test_resources/config.deprecated.alt.yml"}, DefaultEnvPrefix, DefaultEnvDelimiter)...)
assert.NoError(t, err)
validator.ValidateKeys(keys, DefaultEnvPrefix, val)
assert.Len(t, val.Errors(), 0)
warnings := val.Warnings()
require.Len(t, warnings, 3)
sort.Sort(utils.ErrSliceSortAlphabetical(warnings))
assert.EqualError(t, warnings[0], "configuration key 'authentication_backend.ldap.url' is deprecated in 4.38.0 and has been replaced by 'authentication_backend.ldap.address': this has been automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[1], "configuration key 'storage.postgres.host' is deprecated in 4.38.0 and has been replaced by 'storage.postgres.address' when combined with the 'storage.postgres.port' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, warnings[2], "configuration key 'storage.postgres.port' is deprecated in 4.38.0 and has been replaced by 'storage.postgres.address' when combined with the 'storage.postgres.host' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
val.Clear()
validator.ValidateConfiguration(c, val)
require.NotNil(t, c.Storage.PostgreSQL.Address)
assert.Equal(t, "tcp://127.0.0.1:5432", c.Storage.PostgreSQL.Address.String())
}
func TestShouldRaiseErrOnInvalidNotifierSMTPSender(t *testing.T) {
val := schema.NewStructValidator()
keys, _, err := Load(val, NewDefaultSources([]string{"./test_resources/config_smtp_sender_invalid.yml"}, DefaultEnvPrefix, DefaultEnvDelimiter)...)
@ -495,7 +475,7 @@ func TestShouldLoadDirectoryConfiguration(t *testing.T) {
assert.Len(t, val.Errors(), 0)
require.Len(t, val.Warnings(), 1)
assert.EqualError(t, val.Warnings()[0], "configuration key 'server.port' is deprecated in 4.38.0 and has been replaced by 'server.address' when combined with the 'server.host' in the format of '[tcp://]<hostname>[:<port>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
assert.EqualError(t, val.Warnings()[0], "configuration key 'server.port' is deprecated in 4.38.0 and has been replaced by 'server.address' when combined with the 'server.host' and 'server.path' in the format of '[tcp[(4|6)]://]<hostname>[:<port>][/<path>]' or 'tcp[(4|6)://][hostname]:<port>[/<path>]': this should be automatically mapped for you but you will need to adjust your configuration to remove this message")
}
func testSetEnv(t *testing.T, key, value string) {

View File

@ -259,7 +259,6 @@ var Keys = []string{
"notifier.smtp.port",
"notifier.template_path",
"server.address",
"server.path",
"server.asset_path",
"server.disable_healthcheck",
"server.tls.certificate",
@ -279,6 +278,7 @@ var Keys = []string{
"server.timeouts.idle",
"server.host",
"server.port",
"server.path",
"telemetry.metrics.enabled",
"telemetry.metrics.address",
"telemetry.metrics.buffers.read",

View File

@ -8,7 +8,6 @@ import (
// ServerConfiguration represents the configuration of the http server.
type ServerConfiguration struct {
Address *AddressTCP `koanf:"address"`
Path string `koanf:"path"`
AssetPath string `koanf:"asset_path"`
DisableHealthcheck bool `koanf:"disable_healthcheck"`
@ -24,6 +23,9 @@ type ServerConfiguration struct {
// Deprecated: use address instead.
Port int `koanf:"port"`
// Deprecated: use address instead.
Path string `koanf:"path"`
}
// ServerEndpoints is the endpoints configuration for the HTTP server.
@ -60,7 +62,7 @@ type ServerHeaders struct {
// DefaultServerConfiguration represents the default values of the ServerConfiguration.
var DefaultServerConfiguration = ServerConfiguration{
Address: &AddressTCP{Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: ":9091"}}},
Address: &AddressTCP{Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: ":9091", Path: "/"}}},
Buffers: ServerBuffers{
Read: 4096,
Write: 4096,

View File

@ -21,7 +21,7 @@ type TelemetryMetricsConfig struct {
// DefaultTelemetryConfig is the default telemetry configuration.
var DefaultTelemetryConfig = TelemetryConfig{
Metrics: TelemetryMetricsConfig{
Address: &AddressTCP{Address{true, false, -1, 9959, &url.URL{Scheme: AddressSchemeTCP, Host: ":9959"}}},
Address: &AddressTCP{Address{true, false, -1, 9959, &url.URL{Scheme: AddressSchemeTCP, Host: ":9959", Path: "/metrics"}}},
Buffers: ServerBuffers{
Read: 4096,
Write: 4096,

View File

@ -336,6 +336,15 @@ func (a *Address) Path() string {
return a.url.Path
}
// SetPath sets the path.
func (a *Address) SetPath(path string) {
if !a.valid || a.url == nil {
return
}
a.url.Path = path
}
// SocketHostname returns the correct hostname for a socket connection.
func (a *Address) SocketHostname() string {
if !a.valid || a.url == nil {

View File

@ -1,173 +0,0 @@
---
default_redirection_url: https://home.example.com:8080/
server:
address: "tcp://127.0.0.1:9091"
endpoints:
authz:
forward-auth:
implementation: ForwardAuth
authn_strategies:
- name: HeaderProxyAuthorization
- name: CookieSession
ext-authz:
implementation: ExtAuthz
authn_strategies:
- name: HeaderProxyAuthorization
- name: CookieSession
auth-request:
implementation: AuthRequest
authn_strategies:
- name: HeaderAuthRequestProxyAuthorization
- name: CookieSession
legacy:
implementation: Legacy
log:
level: debug
totp:
issuer: authelia.com
duo_api:
hostname: api-123456789.example.com
integration_key: ABCDEF
authentication_backend:
ldap:
url: 'ldap://127.0.0.1'
tls:
private_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA6z1LOg1ZCqb0lytXWZ+MRBpMHEXOoTOLYgfZXt1IYyE3Z758
cyalk0NYQhY5cZDsXPYWPvAHiPMUxutWkoxFwby56S+AbIMa3/Is+ILrHRJs8Exn
ZkpyrYFxPX12app2kErdmAkHSx0Z5/kuXiz96PHs8S8/ZbyZolLHzdfLtSzjvRm5
Zue5iFzsf19NJz5CIBfv8g5lRwtE8wNJoRSpn1xq7fqfuA0weDNFPzjlNWRLy6aa
rK7qJexRkmkCs4sLgyl+9NODYJpvmN8E1yhyC27E0joI6rBFVW7Ihv+cSPCdDzGp
EWe81x3AeqAa3mjVqkiq4u4Z2i8JDgBaPboqJwIDAQABAoIBAAFdLZ58jVOefDSU
L8F5R1rtvBs93GDa56f926jNJ6pLewLC+/2+757W+SAI+PRLntM7Kg3bXm/Q2QH+
Q1Y+MflZmspbWCdI61L5GIGoYKyeers59i+FpvySj5GHtLQRiTZ0+Kv1AXHSDWBm
9XneUOqU3IbZe0ifu1RRno72/VtjkGXbW8Mkkw+ohyGbIeTx/0/JQ6sSNZTT3Vk7
8i4IXptq3HSF0/vqZuah8rShoeNq72pD1YLM9YPdL5by1QkDLnqATDiCpLBTCaNV
I8sqYEun+HYbQzBj8ZACG2JVZpEEidONWQHw5BPWO95DSZYrVnEkuCqeH+u5vYt7
CHuJ3AECgYEA+W3v5z+j91w1VPHS0VB3SCDMouycAMIUnJPAbt+0LPP0scUFsBGE
hPAKddC54pmMZRQ2KIwBKiyWfCrJ8Xz8Yogn7fJgmwTHidJBr2WQpIEkNGlK3Dzi
jXL2sh0yC7sHvn0DqiQ79l/e7yRbSnv2wrTJEczOOH2haD7/tBRyCYECgYEA8W+q
E9YyGvEltnPFaOxofNZ8LHVcZSsQI5b6fc0iE7fjxFqeXPXEwGSOTwqQLQRiHn9b
CfPmIG4Vhyq0otVmlPvUnfBZ2OK+tl5X2/mQFO3ROMdvpi0KYa994uqfJdSTaqLn
jjoKFB906UFHnDQDLZUNiV1WwnkTglgLc+xrd6cCgYEAqqthyv6NyBTM3Tm2gcio
Ra9Dtntl51LlXZnvwy3IkDXBCd6BHM9vuLKyxZiziGx+Vy90O1xI872cnot8sINQ
Am+dur/tAEVN72zxyv0Y8qb2yfH96iKy9gxi5s75TnOEQgAygLnYWaWR2lorKRUX
bHTdXBOiS58S0UzCFEslGIECgYBqkO4SKWYeTDhoKvuEj2yjRYyzlu28XeCWxOo1
otiauX0YSyNBRt2cSgYiTzhKFng0m+QUJYp63/wymB/5C5Zmxi0XtWIDADpLhqLj
HmmBQ2Mo26alQ5YkffBju0mZyhVzaQop1eZi8WuKFV1FThPlB7hc3E0SM5zv2Grd
tQnOWwKBgQC40yZY0PcjuILhy+sIc0Wvh7LUA7taSdTye149kRvbvsCDN7Jh75lM
USjhLXY0Nld2zBm9r8wMb81mXH29uvD+tDqqsICvyuKlA/tyzXR+QTr7dCVKVwu0
1YjCJ36UpTsLre2f8nOSLtNmRfDPtbOE2mkOoO9dD9UU0XZwnvn9xw==
-----END RSA PRIVATE KEY-----
base_dn: dc=example,dc=com
username_attribute: uid
additional_users_dn: ou=users
users_filter: (&({username_attribute}={input})(objectCategory=person)(objectClass=user))
additional_groups_dn: ou=groups
groups_filter: (&(member={dn})(objectClass=groupOfNames))
group_name_attribute: cn
mail_attribute: mail
user: cn=admin,dc=example,dc=com
access_control:
default_policy: deny
rules:
# Rules applied to everyone
- domain: public.example.com
policy: bypass
- domain: secure.example.com
policy: one_factor
# Network based rule, if not provided any network matches.
networks:
- 192.168.1.0/24
- domain: secure.example.com
policy: two_factor
- domain: [singlefactor.example.com, onefactor.example.com]
policy: one_factor
# Rules applied to 'admins' group
- domain: "mx2.mail.example.com"
subject: "group:admins"
policy: deny
- domain: "*.example.com"
subject: "group:admins"
policy: two_factor
# Rules applied to 'dev' group
- domain: dev.example.com
resources:
- "^/groups/dev/.*$"
subject: "group:dev"
policy: two_factor
# Rules applied to user 'john'
- domain: dev.example.com
resources:
- "^/users/john/.*$"
subject: "user:john"
policy: two_factor
# Rules applied to 'dev' group and user 'john'
- domain: dev.example.com
resources:
- "^/deny-all.*$"
subject: ["group:dev", "user:john"]
policy: deny
# Rules applied to user 'harry'
- domain: dev.example.com
resources:
- "^/users/harry/.*$"
subject: "user:harry"
policy: two_factor
# Rules applied to user 'bob'
- domain: "*.mail.example.com"
subject: "user:bob"
policy: two_factor
- domain: "dev.example.com"
resources:
- "^/users/bob/.*$"
subject: "user:bob"
policy: two_factor
session:
name: authelia_session
expiration: 3600000 # 1 hour
inactivity: 300000 # 5 minutes
domain: example.com
redis:
host: 127.0.0.1
port: 6379
high_availability:
sentinel_name: test
regulation:
max_retries: 3
find_time: 120
ban_time: 300
storage:
postgres:
host: 127.0.0.1
port: 5432
database: authelia
username: authelia
notifier:
smtp:
username: test
host: 127.0.0.1
port: 1025
sender: admin@example.com
disable_require_tls: true
...

View File

@ -1,173 +1,23 @@
---
default_redirection_url: https://home.example.com:8080/
server:
address: "tcp://127.0.0.1:9091"
endpoints:
authz:
forward-auth:
implementation: ForwardAuth
authn_strategies:
- name: HeaderProxyAuthorization
- name: CookieSession
ext-authz:
implementation: ExtAuthz
authn_strategies:
- name: HeaderProxyAuthorization
- name: CookieSession
auth-request:
implementation: AuthRequest
authn_strategies:
- name: HeaderAuthRequestProxyAuthorization
- name: CookieSession
legacy:
implementation: Legacy
log:
level: debug
totp:
issuer: authelia.com
duo_api:
hostname: api-123456789.example.com
integration_key: ABCDEF
host: '0.0.0.0'
port: 9091
path: "auth"
authentication_backend:
ldap:
url: 'ldap://127.0.0.1'
tls:
private_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA6z1LOg1ZCqb0lytXWZ+MRBpMHEXOoTOLYgfZXt1IYyE3Z758
cyalk0NYQhY5cZDsXPYWPvAHiPMUxutWkoxFwby56S+AbIMa3/Is+ILrHRJs8Exn
ZkpyrYFxPX12app2kErdmAkHSx0Z5/kuXiz96PHs8S8/ZbyZolLHzdfLtSzjvRm5
Zue5iFzsf19NJz5CIBfv8g5lRwtE8wNJoRSpn1xq7fqfuA0weDNFPzjlNWRLy6aa
rK7qJexRkmkCs4sLgyl+9NODYJpvmN8E1yhyC27E0joI6rBFVW7Ihv+cSPCdDzGp
EWe81x3AeqAa3mjVqkiq4u4Z2i8JDgBaPboqJwIDAQABAoIBAAFdLZ58jVOefDSU
L8F5R1rtvBs93GDa56f926jNJ6pLewLC+/2+757W+SAI+PRLntM7Kg3bXm/Q2QH+
Q1Y+MflZmspbWCdI61L5GIGoYKyeers59i+FpvySj5GHtLQRiTZ0+Kv1AXHSDWBm
9XneUOqU3IbZe0ifu1RRno72/VtjkGXbW8Mkkw+ohyGbIeTx/0/JQ6sSNZTT3Vk7
8i4IXptq3HSF0/vqZuah8rShoeNq72pD1YLM9YPdL5by1QkDLnqATDiCpLBTCaNV
I8sqYEun+HYbQzBj8ZACG2JVZpEEidONWQHw5BPWO95DSZYrVnEkuCqeH+u5vYt7
CHuJ3AECgYEA+W3v5z+j91w1VPHS0VB3SCDMouycAMIUnJPAbt+0LPP0scUFsBGE
hPAKddC54pmMZRQ2KIwBKiyWfCrJ8Xz8Yogn7fJgmwTHidJBr2WQpIEkNGlK3Dzi
jXL2sh0yC7sHvn0DqiQ79l/e7yRbSnv2wrTJEczOOH2haD7/tBRyCYECgYEA8W+q
E9YyGvEltnPFaOxofNZ8LHVcZSsQI5b6fc0iE7fjxFqeXPXEwGSOTwqQLQRiHn9b
CfPmIG4Vhyq0otVmlPvUnfBZ2OK+tl5X2/mQFO3ROMdvpi0KYa994uqfJdSTaqLn
jjoKFB906UFHnDQDLZUNiV1WwnkTglgLc+xrd6cCgYEAqqthyv6NyBTM3Tm2gcio
Ra9Dtntl51LlXZnvwy3IkDXBCd6BHM9vuLKyxZiziGx+Vy90O1xI872cnot8sINQ
Am+dur/tAEVN72zxyv0Y8qb2yfH96iKy9gxi5s75TnOEQgAygLnYWaWR2lorKRUX
bHTdXBOiS58S0UzCFEslGIECgYBqkO4SKWYeTDhoKvuEj2yjRYyzlu28XeCWxOo1
otiauX0YSyNBRt2cSgYiTzhKFng0m+QUJYp63/wymB/5C5Zmxi0XtWIDADpLhqLj
HmmBQ2Mo26alQ5YkffBju0mZyhVzaQop1eZi8WuKFV1FThPlB7hc3E0SM5zv2Grd
tQnOWwKBgQC40yZY0PcjuILhy+sIc0Wvh7LUA7taSdTye149kRvbvsCDN7Jh75lM
USjhLXY0Nld2zBm9r8wMb81mXH29uvD+tDqqsICvyuKlA/tyzXR+QTr7dCVKVwu0
1YjCJ36UpTsLre2f8nOSLtNmRfDPtbOE2mkOoO9dD9UU0XZwnvn9xw==
-----END RSA PRIVATE KEY-----
base_dn: dc=example,dc=com
username_attribute: uid
additional_users_dn: ou=users
users_filter: (&({username_attribute}={input})(objectCategory=person)(objectClass=user))
additional_groups_dn: ou=groups
groups_filter: (&(member={dn})(objectClass=groupOfNames))
group_name_attribute: cn
mail_attribute: mail
user: cn=admin,dc=example,dc=com
access_control:
default_policy: deny
rules:
# Rules applied to everyone
- domain: public.example.com
policy: bypass
- domain: secure.example.com
policy: one_factor
# Network based rule, if not provided any network matches.
networks:
- 192.168.1.0/24
- domain: secure.example.com
policy: two_factor
- domain: [singlefactor.example.com, onefactor.example.com]
policy: one_factor
# Rules applied to 'admins' group
- domain: "mx2.mail.example.com"
subject: "group:admins"
policy: deny
- domain: "*.example.com"
subject: "group:admins"
policy: two_factor
# Rules applied to 'dev' group
- domain: dev.example.com
resources:
- "^/groups/dev/.*$"
subject: "group:dev"
policy: two_factor
# Rules applied to user 'john'
- domain: dev.example.com
resources:
- "^/users/john/.*$"
subject: "user:john"
policy: two_factor
# Rules applied to 'dev' group and user 'john'
- domain: dev.example.com
resources:
- "^/deny-all.*$"
subject: ["group:dev", "user:john"]
policy: deny
# Rules applied to user 'harry'
- domain: dev.example.com
resources:
- "^/users/harry/.*$"
subject: "user:harry"
policy: two_factor
# Rules applied to user 'bob'
- domain: "*.mail.example.com"
subject: "user:bob"
policy: two_factor
- domain: "dev.example.com"
resources:
- "^/users/bob/.*$"
subject: "user:bob"
policy: two_factor
session:
name: authelia_session
expiration: 3600000 # 1 hour
inactivity: 300000 # 5 minutes
domain: example.com
redis:
host: 127.0.0.1
port: 6379
high_availability:
sentinel_name: test
regulation:
max_retries: 3
find_time: 120
ban_time: 300
storage:
mysql:
host: 127.0.0.1
port: 3306
database: authelia
username: authelia
postgres:
host: 127.0.0.1
port: 5432
notifier:
smtp:
username: test
host: 127.0.0.1
port: 1025
sender: admin@example.com
disable_require_tls: true
...

View File

@ -323,8 +323,9 @@ const (
errFmtServerAddressLegacyAndModern = "server: option 'host' and 'port' can't be configured at the same time as 'address'"
errFmtServerAddress = "server: option 'address' with value '%s' is invalid: %w"
errFmtServerPathNoForwardSlashes = "server: option 'path' must not contain any forward slashes"
errFmtServerPathAlphaNum = "server: option 'path' must only contain alpha numeric characters"
errFmtServerPathNoForwardSlashes = "server: option 'path' must not contain any forward slashes"
errFmtServerPathNotEndForwardSlash = "server: option 'address' must not and with a forward slash but it's configured as '%s'"
errFmtServerPathAlphaNum = "server: option 'path' must only contain alpha numeric characters"
errFmtServerEndpointsAuthzImplementation = "server: endpoints: authz: %s: option 'implementation' must be one of %s but it's configured as '%s'"
errFmtServerEndpointsAuthzStrategy = "server: endpoints: authz: %s: authn_strategies: option 'name' must be one of %s but it's configured as '%s'"

View File

@ -59,17 +59,6 @@ func ValidateServer(config *schema.Configuration, validator *schema.StructValida
ValidateServerAddress(config, validator)
ValidateServerTLS(config, validator)
switch {
case strings.Contains(config.Server.Path, "/"):
validator.Push(fmt.Errorf(errFmtServerPathNoForwardSlashes))
case !utils.IsStringAlphaNumeric(config.Server.Path):
validator.Push(fmt.Errorf(errFmtServerPathAlphaNum))
case config.Server.Path == "": // Don't do anything if it's blank.
break
default:
config.Server.Path = path.Clean("/" + config.Server.Path)
}
if config.Server.Buffers.Read <= 0 {
config.Server.Buffers.Read = schema.DefaultServerConfiguration.Buffers.Read
}
@ -96,11 +85,12 @@ func ValidateServer(config *schema.Configuration, validator *schema.StructValida
// ValidateServerAddress checks the configured server address is correct.
func ValidateServerAddress(config *schema.Configuration, validator *schema.StructValidator) {
if config.Server.Address == nil {
if config.Server.Host == "" && config.Server.Port == 0 { //nolint:staticcheck
if config.Server.Host == "" && config.Server.Port == 0 && config.Server.Path == "" { //nolint:staticcheck
config.Server.Address = schema.DefaultServerConfiguration.Address
} else {
host := config.Server.Host //nolint:staticcheck
port := config.Server.Port //nolint:staticcheck
host := config.Server.Host //nolint:staticcheck
port := config.Server.Port //nolint:staticcheck
subpath := config.Server.Path //nolint:staticcheck
if host == "" {
host = schema.DefaultServerConfiguration.Address.Hostname()
@ -110,7 +100,20 @@ func ValidateServerAddress(config *schema.Configuration, validator *schema.Struc
port = schema.DefaultServerConfiguration.Address.Port()
}
switch {
case strings.Contains(subpath, "/"):
validator.Push(fmt.Errorf(errFmtServerPathNoForwardSlashes))
case !utils.IsStringAlphaNumeric(config.Server.Path): //nolint:staticcheck
validator.Push(fmt.Errorf(errFmtServerPathAlphaNum))
case subpath == "":
subpath = schema.DefaultServerConfiguration.Address.Path()
default:
subpath = path.Clean("/" + config.Server.Path) //nolint:staticcheck
}
config.Server.Address = &schema.AddressTCP{Address: schema.NewAddressFromNetworkValues(schema.AddressSchemeTCP, host, port)}
config.Server.Address.SetPath(subpath)
}
} else {
if config.Server.Host != "" || config.Server.Port != 0 { //nolint:staticcheck
@ -123,6 +126,10 @@ func ValidateServerAddress(config *schema.Configuration, validator *schema.Struc
validator.Push(fmt.Errorf(errFmtServerAddress, config.Server.Address.String(), err))
}
}
if path := config.Server.Address.Path(); path != "/" && strings.HasSuffix(path, "/") {
validator.Push(fmt.Errorf(errFmtServerPathNotEndForwardSlash, path))
}
}
// ValidateServerEndpoints configures the default endpoints and checks the configuration of custom endpoints.

View File

@ -23,66 +23,97 @@ func TestShouldSetDefaultServerValues(t *testing.T) {
assert.Len(t, validator.Errors(), 0)
assert.Len(t, validator.Warnings(), 0)
assert.Equal(t, "", config.Server.Host) //nolint:staticcheck
assert.Equal(t, 0, config.Server.Port) //nolint:staticcheck
assert.Equal(t, schema.DefaultServerConfiguration.Address, config.Server.Address)
assert.Equal(t, schema.DefaultServerConfiguration.Buffers.Read, config.Server.Buffers.Read)
assert.Equal(t, schema.DefaultServerConfiguration.Buffers.Write, config.Server.Buffers.Write)
assert.Equal(t, schema.DefaultServerConfiguration.TLS.Key, config.Server.TLS.Key)
assert.Equal(t, schema.DefaultServerConfiguration.TLS.Certificate, config.Server.TLS.Certificate)
assert.Equal(t, schema.DefaultServerConfiguration.Path, config.Server.Path)
assert.Equal(t, schema.DefaultServerConfiguration.Endpoints.EnableExpvars, config.Server.Endpoints.EnableExpvars)
assert.Equal(t, schema.DefaultServerConfiguration.Endpoints.EnablePprof, config.Server.Endpoints.EnablePprof)
assert.Equal(t, schema.DefaultServerConfiguration.Endpoints.Authz, config.Server.Endpoints.Authz)
assert.Equal(t, "", config.Server.Host) //nolint:staticcheck
assert.Equal(t, 0, config.Server.Port) //nolint:staticcheck
assert.Equal(t, "", config.Server.Path) //nolint:staticcheck
}
func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) {
validator := schema.NewStructValidator()
config := &schema.Configuration{
Server: schema.ServerConfiguration{
Host: "abc",
Port: 123,
testCases := []struct {
name string
have schema.ServerConfiguration
expected schema.Address
}{
{
"ShouldParseAll",
schema.ServerConfiguration{
Host: "abc",
Port: 123,
Path: "subpath",
},
MustParseAddress("tcp://abc:123/subpath"),
},
{
"ShouldParseHostAndPort",
schema.ServerConfiguration{
Host: "abc",
Port: 123,
},
MustParseAddress("tcp://abc:123/"),
},
{
"ShouldParseHostAndPath",
schema.ServerConfiguration{
Host: "abc",
Path: "subpath",
},
MustParseAddress("tcp://abc:9091/subpath"),
},
{
"ShouldParsePortAndPath",
schema.ServerConfiguration{
Port: 123,
Path: "subpath",
},
MustParseAddress("tcp://:123/subpath"),
},
{
"ShouldParseHost",
schema.ServerConfiguration{
Host: "abc",
},
MustParseAddress("tcp://abc:9091/"),
},
{
"ShouldParsePort",
schema.ServerConfiguration{
Port: 123,
},
MustParseAddress("tcp://:123/"),
},
{
"ShouldParsePath",
schema.ServerConfiguration{
Path: "subpath",
},
MustParseAddress("tcp://:9091/subpath"),
},
}
ValidateServer(config, validator)
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
validator := schema.NewStructValidator()
config := &schema.Configuration{
Server: tc.have,
}
assert.Len(t, validator.Errors(), 0)
assert.Len(t, validator.Warnings(), 0)
ValidateServer(config, validator)
assert.Equal(t, "abc", config.Server.Host) //nolint:staticcheck
assert.Equal(t, 123, config.Server.Port) //nolint:staticcheck
assert.Equal(t, &schema.AddressTCP{Address: MustParseAddress("tcp://abc:123")}, config.Server.Address)
assert.Len(t, validator.Errors(), 0)
assert.Len(t, validator.Warnings(), 0)
config = &schema.Configuration{
Server: schema.ServerConfiguration{
Host: "abc",
},
assert.Equal(t, &schema.AddressTCP{Address: tc.expected}, config.Server.Address)
})
}
ValidateServer(config, validator)
assert.Len(t, validator.Errors(), 0)
assert.Len(t, validator.Warnings(), 0)
assert.Equal(t, "abc", config.Server.Host) //nolint:staticcheck
assert.Equal(t, 0, config.Server.Port) //nolint:staticcheck
assert.Equal(t, &schema.AddressTCP{Address: MustParseAddress("tcp://abc:9091")}, config.Server.Address)
config = &schema.Configuration{
Server: schema.ServerConfiguration{
Port: 123,
},
}
ValidateServer(config, validator)
assert.Len(t, validator.Errors(), 0)
assert.Len(t, validator.Warnings(), 0)
assert.Equal(t, "", config.Server.Host) //nolint:staticcheck
assert.Equal(t, 123, config.Server.Port) //nolint:staticcheck
assert.Equal(t, &schema.AddressTCP{Address: MustParseAddress("tcp://:123")}, config.Server.Address)
}
func TestShouldSetDefaultConfig(t *testing.T) {
@ -98,20 +129,20 @@ func TestShouldSetDefaultConfig(t *testing.T) {
assert.Equal(t, schema.DefaultServerConfiguration.Buffers.Write, config.Server.Buffers.Write)
}
func TestShouldParsePathCorrectly(t *testing.T) {
validator := schema.NewStructValidator()
func TestValidateSeverAddress(t *testing.T) {
config := &schema.Configuration{
Server: schema.ServerConfiguration{
Path: "apple",
Address: &schema.AddressTCP{Address: MustParseAddress("tcp://:9091/path/")},
},
}
validator := schema.NewStructValidator()
ValidateServer(config, validator)
assert.Len(t, validator.Errors(), 0)
require.Len(t, validator.Errors(), 1)
assert.Len(t, validator.Warnings(), 0)
assert.Equal(t, "/apple", config.Server.Path)
assert.EqualError(t, validator.Errors()[0], "server: option 'address' must not and with a forward slash but it's configured as '/path/'")
}
func TestValidateServerShouldCorrectlyIdentifyValidAddressSchemes(t *testing.T) {
@ -236,7 +267,7 @@ func TestShouldValidateAndUpdateAddress(t *testing.T) {
ValidateServer(&config, validator)
require.Len(t, validator.Errors(), 0)
assert.Equal(t, "tcp://:9091", config.Server.Address.String())
assert.Equal(t, "tcp://:9091/", config.Server.Address.String())
}
func TestShouldRaiseErrorOnLegacyAndModernValues(t *testing.T) {
@ -251,22 +282,6 @@ func TestShouldRaiseErrorOnLegacyAndModernValues(t *testing.T) {
assert.EqualError(t, validator.Errors()[0], "server: option 'host' and 'port' can't be configured at the same time as 'address'")
}
func TestShouldValidateAndUpdateAddressWithOldValues(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.Server.Address = nil
config.Server.Host = local25 //nolint:staticcheck
config.Server.Port = 9999 //nolint:staticcheck
ValidateServer(&config, validator)
assert.Len(t, validator.Errors(), 0)
assert.Len(t, validator.Warnings(), 0)
require.NotNil(t, config.Server.Address)
assert.Equal(t, "tcp://127.0.0.25:9999", config.Server.Address.String())
}
func TestShouldRaiseErrorWhenTLSCertWithoutKeyIsProvided(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()

View File

@ -20,6 +20,10 @@ func ValidateTelemetry(config *schema.Configuration, validator *schema.StructVal
config.Telemetry.Metrics.Address.SetPort(schema.DefaultTelemetryConfig.Metrics.Address.Port())
}
if config.Telemetry.Metrics.Address.Path() == "" {
config.Telemetry.Metrics.Address.SetPath(schema.DefaultTelemetryConfig.Metrics.Address.Path())
}
if config.Telemetry.Metrics.Buffers.Read <= 0 {
config.Telemetry.Metrics.Buffers.Read = schema.DefaultTelemetryConfig.Metrics.Buffers.Read
}

View File

@ -38,7 +38,7 @@ func TestValidateTelemetry(t *testing.T) {
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://0.0.0.0")}}},
&schema.Configuration{Telemetry: schema.TelemetryConfig{
Metrics: schema.TelemetryMetricsConfig{
Address: &schema.AddressTCP{Address: schema.NewAddressFromNetworkValues(schema.AddressSchemeTCP, "0.0.0.0", schema.DefaultTelemetryConfig.Metrics.Address.Port())},
Address: mustParseAddress("tcp://0.0.0.0:9959/metrics"),
Buffers: schema.ServerBuffers{
Read: 4096,
Write: 4096,
@ -55,7 +55,7 @@ func TestValidateTelemetry(t *testing.T) {
},
{
"ShouldSetDefaultPortAlt",
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://:0")}}},
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://:0/metrics")}}},
&schema.Configuration{Telemetry: schema.DefaultTelemetryConfig},
nil,
nil,
@ -63,14 +63,14 @@ func TestValidateTelemetry(t *testing.T) {
{
"ShouldSetDefaultPortWithCustomIP",
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://127.0.0.1")}}},
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://127.0.0.1:9959")}}},
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://127.0.0.1:9959/metrics")}}},
nil,
nil,
},
{
"ShouldNotValidateUDP",
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("udp://0.0.0.0")}}},
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("udp://0.0.0.0:9959")}}},
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("udp://0.0.0.0:9959/metrics")}}},
nil,
[]string{"telemetry: metrics: option 'address' with value 'udp://0.0.0.0:0' is invalid: scheme must be one of 'tcp', 'tcp4', 'tcp6', or 'unix' but is configured as 'udp'"},
},

View File

@ -395,8 +395,8 @@ func handleRouter(config *schema.Configuration, providers middlewares.Providers)
r.NotFound = handleNotFound(bridge(serveIndexHandler))
handler := middlewares.LogRequest(r.Handler)
if config.Server.Path != "" {
handler = middlewares.StripPath(config.Server.Path)(handler)
if config.Server.Address.Path() != "/" {
handler = middlewares.StripPath(config.Server.Address.Path())(handler)
}
handler = middlewares.Wrap(middlewares.NewMetricsRequest(providers.Metrics), handler)
@ -404,10 +404,10 @@ func handleRouter(config *schema.Configuration, providers middlewares.Providers)
return handler
}
func handleMetrics() fasthttp.RequestHandler {
func handleMetrics(path string) fasthttp.RequestHandler {
r := router.New()
r.GET("/metrics", fasthttpadaptor.NewFastHTTPHandler(promhttp.Handler()))
r.GET(path, fasthttpadaptor.NewFastHTTPHandler(promhttp.Handler()))
r.HandleMethodNotAllowed = true
r.MethodNotAllowed = handlers.Status(fasthttp.StatusMethodNotAllowed)

View File

@ -71,14 +71,14 @@ func CreateDefaultServer(config *schema.Configuration, providers middlewares.Pro
}
if err = writeHealthCheckEnv(config.Server.DisableHealthcheck, connectionScheme, config.Server.Address.Hostname(),
config.Server.Path, config.Server.Address.Port()); err != nil {
config.Server.Address.Path(), config.Server.Address.Port()); err != nil {
return nil, nil, nil, false, fmt.Errorf("unable to configure healthcheck: %w", err)
}
paths = []string{"/"}
if config.Server.Path != "" {
paths = append(paths, config.Server.Path)
if config.Server.Address.Path() != "/" {
paths = append(paths, config.Server.Address.Path())
}
return server, listener, paths, isTLS, nil
@ -93,7 +93,7 @@ func CreateMetricsServer(config *schema.Configuration, providers middlewares.Pro
server = &fasthttp.Server{
ErrorHandler: handleError(),
NoDefaultServerHeader: true,
Handler: handleMetrics(),
Handler: handleMetrics(config.Telemetry.Metrics.Address.Path()),
ReadBufferSize: config.Telemetry.Metrics.Buffers.Read,
WriteBufferSize: config.Telemetry.Metrics.Buffers.Write,
ReadTimeout: config.Telemetry.Metrics.Timeouts.Read,
@ -106,5 +106,5 @@ func CreateMetricsServer(config *schema.Configuration, providers middlewares.Pro
return nil, nil, nil, false, fmt.Errorf("error occurred while attempting to initialize metrics telemetry server listener for address '%s': %w", config.Telemetry.Metrics.Address.String(), err)
}
return server, listener, []string{"/metrics"}, false, nil
return server, listener, []string{config.Telemetry.Metrics.Address.Path()}, false, nil
}

View File

@ -256,6 +256,10 @@ func writeHealthCheckEnv(disabled bool, scheme, host, path string, port int) (er
host = "[" + host + "]"
}
if path == "/" {
path = ""
}
_, err = file.WriteString(fmt.Sprintf(healthCheckEnv, scheme, host, port, path))
return err

View File

@ -6,8 +6,7 @@
jwt_secret: unsecure_secret
server:
address: 'tcp://:9091'
path: 'auth'
address: 'tcp://:9091/auth'
tls:
certificate: /pki/public.backend.crt
key: /pki/private.backend.pem