refactor(configuration): umask from query (#5416)

Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
pull/5419/head
James Elliott 2023-05-09 21:25:56 +10:00 committed by GitHub
parent 3a752f5ac9
commit 6c472d8627
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 340 additions and 197 deletions

View File

@ -22,7 +22,6 @@ aliases:
```yaml ```yaml
server: server:
address: 'tcp://:9091' address: 'tcp://:9091'
umask: 0022
path: '' path: ''
disable_healthcheck: false disable_healthcheck: false
tls: tls:
@ -80,20 +79,6 @@ server:
address: unix:///var/run/authelia.sock address: unix:///var/run/authelia.sock
``` ```
### umask
{{< confkey type="int" required="no" >}}
If set temporarily changes the umask during the creation of the unix domain socket if configured as such in the
[address](#address). Typically this should be set before the process is actually running and users should not use this
option, however it's recognized in various specific scenarios this may not be completely adequate.
One such example is when you want the proxy to have permission to the socket but not the files, in which case running a
umask of `0077` by default is good, and running a umask of `0027` so that the group Authelia is running as has
permission to the socket.
This value should typically be prefixed with a `0` to ensure the relevant parsers handle it correctly.
### path ### path
{{< confkey type="string " required="no" >}} {{< confkey type="string " required="no" >}}

View File

@ -108,10 +108,22 @@ The following format represents the unix domain socket format. It's valid for bo
instances. Refer to the individual documentation for an option for clarity. In this format as per the notation there instances. Refer to the individual documentation for an option for clarity. In this format as per the notation there
are no optional portions. are no optional portions.
The Unix Domain Socket format also accepts a query string. The following query parameters control certain behaviour of
this address type.
| Parameter | Listeners | Connectors | Purpose |
|:---------:|:---------:|:----------:|:------------------------------------------------------------------------------------------------------------------------------------:|
| `umask` | Yes | No | Sets the umask prior to creating the socket and restores it after creating it. The value must be an octal number with 3 or 4 digits. |
```text ```text
unix://<path> unix://<path>
``` ```
```text
unix://<path>?umask=0022
```
##### Examples ##### Examples
Various examples for these formats. Various examples for these formats.

View File

@ -23,7 +23,6 @@ telemetry:
metrics: metrics:
enabled: false enabled: false
address: 'tcp://:9959' address: 'tcp://:9959'
umask: 0022
buffers: buffers:
read: 4096 read: 4096
write: 4096 write: 4096
@ -53,20 +52,6 @@ see the [documentation](../prologue/common.md#address) on this format for more i
Configures the listener address for the [Prometheus] Metrics Exporter HTTP Server. The address itself is a listener and Configures the listener address for the [Prometheus] Metrics Exporter HTTP Server. The address itself is a listener and
the scheme must either be the `unix` scheme or one of the `tcp` schemes. the scheme must either be the `unix` scheme or one of the `tcp` schemes.
### umask
{{< confkey type="int" required="no" >}}
If set temporarily changes the umask during the creation of the unix domain socket if configured as such in the
[address](#address). Typically this should be set before the process is actually running and users should not use this
option, however it's recognized in various specific scenarios this may not be completely adequate.
One such example is when you want the proxy to have permission to the socket but not the files, in which case running a
umask of `0077` by default is good, and running a umask of `0027` so that the group Authelia is running as has
permission to the socket.
This value should typically be prefixed with a `0` to ensure the relevant parsers handle it correctly.
### buffers ### buffers
*__Reference Note:__ This configuration option uses the *__Reference Note:__ This configuration option uses the

File diff suppressed because one or more lines are too long

View File

@ -103,9 +103,17 @@ const (
TOTPSecretSizeMinimum = 20 TOTPSecretSizeMinimum = 20
) )
// regexpHasScheme checks if a string has a scheme. Valid characters for schemes include alphanumeric, hyphen, var (
// period, and plus characters. // regexpHasScheme checks if a string has a scheme. Valid characters for schemes include alphanumeric, hyphen,
var regexpHasScheme = regexp.MustCompile(`^[-+.a-zA-Z\d]*(://|:$)`) // period, and plus characters.
regexpHasScheme = regexp.MustCompile(`^[-+.a-zA-Z\d]*(://|:$)`)
regexpIsUmask = regexp.MustCompile(`^[0-7]{3,4}$`)
)
const (
addressQueryParamUmask = "umask"
)
const ( const (
blockCERTIFICATE = "CERTIFICATE" blockCERTIFICATE = "CERTIFICATE"

View File

@ -239,7 +239,6 @@ var Keys = []string{
"notifier.smtp.port", "notifier.smtp.port",
"notifier.template_path", "notifier.template_path",
"server.address", "server.address",
"server.umask",
"server.path", "server.path",
"server.asset_path", "server.asset_path",
"server.disable_healthcheck", "server.disable_healthcheck",
@ -262,7 +261,6 @@ var Keys = []string{
"server.port", "server.port",
"telemetry.metrics.enabled", "telemetry.metrics.enabled",
"telemetry.metrics.address", "telemetry.metrics.address",
"telemetry.metrics.umask",
"telemetry.metrics.buffers.read", "telemetry.metrics.buffers.read",
"telemetry.metrics.buffers.write", "telemetry.metrics.buffers.write",
"telemetry.metrics.timeouts.read", "telemetry.metrics.timeouts.read",

View File

@ -44,7 +44,7 @@ type NotifierConfiguration struct {
// DefaultSMTPNotifierConfiguration represents default configuration parameters for the SMTP notifier. // DefaultSMTPNotifierConfiguration represents default configuration parameters for the SMTP notifier.
var DefaultSMTPNotifierConfiguration = SMTPNotifierConfiguration{ var DefaultSMTPNotifierConfiguration = SMTPNotifierConfiguration{
Address: &AddressSMTP{Address{true, false, 25, &url.URL{Scheme: AddressSchemeSMTP, Host: "localhost:25"}}}, Address: &AddressSMTP{Address{true, false, -1, 25, &url.URL{Scheme: AddressSchemeSMTP, Host: "localhost:25"}}},
Timeout: time.Second * 5, Timeout: time.Second * 5,
Subject: "[Authelia] {title}", Subject: "[Authelia] {title}",
Identifier: "localhost", Identifier: "localhost",

View File

@ -7,12 +7,10 @@ import (
// ServerConfiguration represents the configuration of the http server. // ServerConfiguration represents the configuration of the http server.
type ServerConfiguration struct { type ServerConfiguration struct {
Address *AddressTCP `koanf:"address"` Address *AddressTCP `koanf:"address"`
UMask *int `koanf:"umask"` Path string `koanf:"path"`
AssetPath string `koanf:"asset_path"`
Path string `koanf:"path"` DisableHealthcheck bool `koanf:"disable_healthcheck"`
AssetPath string `koanf:"asset_path"`
DisableHealthcheck bool `koanf:"disable_healthcheck"`
TLS ServerTLS `koanf:"tls"` TLS ServerTLS `koanf:"tls"`
Headers ServerHeaders `koanf:"headers"` Headers ServerHeaders `koanf:"headers"`
@ -62,7 +60,7 @@ type ServerHeaders struct {
// DefaultServerConfiguration represents the default values of the ServerConfiguration. // DefaultServerConfiguration represents the default values of the ServerConfiguration.
var DefaultServerConfiguration = ServerConfiguration{ var DefaultServerConfiguration = ServerConfiguration{
Address: &AddressTCP{Address{true, false, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: ":9091"}}}, Address: &AddressTCP{Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: ":9091"}}},
Buffers: ServerBuffers{ Buffers: ServerBuffers{
Read: 4096, Read: 4096,
Write: 4096, Write: 4096,

View File

@ -75,7 +75,7 @@ var DefaultMySQLStorageConfiguration = MySQLStorageConfiguration{
// DefaultPostgreSQLStorageConfiguration represents the default PostgreSQL configuration. // DefaultPostgreSQLStorageConfiguration represents the default PostgreSQL configuration.
var DefaultPostgreSQLStorageConfiguration = PostgreSQLStorageConfiguration{ var DefaultPostgreSQLStorageConfiguration = PostgreSQLStorageConfiguration{
SQLStorageConfiguration: SQLStorageConfiguration{ SQLStorageConfiguration: SQLStorageConfiguration{
Address: &AddressTCP{Address{true, false, 5432, &url.URL{Scheme: AddressSchemeTCP, Host: "localhost:5432"}}}, Address: &AddressTCP{Address{true, false, -1, 5432, &url.URL{Scheme: AddressSchemeTCP, Host: "localhost:5432"}}},
}, },
Schema: "public", Schema: "public",
TLS: &TLSConfig{ TLS: &TLSConfig{

View File

@ -12,10 +12,8 @@ type TelemetryConfig struct {
// TelemetryMetricsConfig represents the telemetry metrics config. // TelemetryMetricsConfig represents the telemetry metrics config.
type TelemetryMetricsConfig struct { type TelemetryMetricsConfig struct {
Enabled bool `koanf:"enabled"` Enabled bool `koanf:"enabled"`
Address *AddressTCP `koanf:"address"` Address *AddressTCP `koanf:"address"`
UMask *int `koanf:"umask"`
Buffers ServerBuffers `koanf:"buffers"` Buffers ServerBuffers `koanf:"buffers"`
Timeouts ServerTimeouts `koanf:"timeouts"` Timeouts ServerTimeouts `koanf:"timeouts"`
} }
@ -23,7 +21,7 @@ type TelemetryMetricsConfig struct {
// DefaultTelemetryConfig is the default telemetry configuration. // DefaultTelemetryConfig is the default telemetry configuration.
var DefaultTelemetryConfig = TelemetryConfig{ var DefaultTelemetryConfig = TelemetryConfig{
Metrics: TelemetryMetricsConfig{ Metrics: TelemetryMetricsConfig{
Address: &AddressTCP{Address{true, false, 9959, &url.URL{Scheme: AddressSchemeTCP, Host: ":9959"}}}, Address: &AddressTCP{Address{true, false, -1, 9959, &url.URL{Scheme: AddressSchemeTCP, Host: ":9959"}}},
Buffers: ServerBuffers{ Buffers: ServerBuffers{
Read: 4096, Read: 4096,
Write: 4096, Write: 4096,

View File

@ -21,7 +21,7 @@ func NewAddress(value string) (address *Address, err error) {
// else without a scheme is the schemeDefault scheme. // else without a scheme is the schemeDefault scheme.
func NewAddressDefault(value, schemeDefault, schemeDefaultPath string) (address *Address, err error) { func NewAddressDefault(value, schemeDefault, schemeDefaultPath string) (address *Address, err error) {
if len(value) == 0 { if len(value) == 0 {
return &Address{true, false, 0, &url.URL{Scheme: AddressSchemeTCP, Host: ":0"}}, nil return &Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeTCP, Host: ":0"}}, nil
} }
var u *url.URL var u *url.URL
@ -71,12 +71,17 @@ func NewAddressFromNetworkValuesDefault(value string, port int, schemeDefault, s
// NewAddressUnix returns an *Address from a path value. // NewAddressUnix returns an *Address from a path value.
func NewAddressUnix(path string) Address { func NewAddressUnix(path string) Address {
return Address{true, true, 0, &url.URL{Scheme: AddressSchemeUnix, Path: path}} return Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeUnix, Path: path}}
} }
// NewAddressFromNetworkValues returns an *Address from network values. // NewAddressFromNetworkValues returns an *Address from network values.
func NewAddressFromNetworkValues(network, host string, port int) Address { func NewAddressFromNetworkValues(network, host string, port int) Address {
return Address{true, false, port, &url.URL{Scheme: network, Host: fmt.Sprintf("%s:%d", host, port)}} return NewAddressFromNetworkPathValues(network, host, port, "")
}
// NewAddressFromNetworkPathValues returns an *Address from network values and a path.
func NewAddressFromNetworkPathValues(network, host string, port int, path string) Address {
return Address{true, false, -1, port, &url.URL{Scheme: network, Host: fmt.Sprintf("%s:%d", host, port), Path: path}}
} }
// NewSMTPAddress returns an *AddressSMTP from SMTP values. // NewSMTPAddress returns an *AddressSMTP from SMTP values.
@ -103,13 +108,14 @@ func NewSMTPAddress(scheme, host string, port int) *AddressSMTP {
} }
} }
return &AddressSMTP{Address: Address{true, false, port, &url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%d", host, port)}}} return &AddressSMTP{Address: Address{true, false, -1, port, &url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%d", host, port)}}}
} }
// NewAddressFromURL returns an *Address and error depending on the ability to parse the *url.URL as an Address. // NewAddressFromURL returns an *Address and error depending on the ability to parse the *url.URL as an Address.
func NewAddressFromURL(u *url.URL) (addr *Address, err error) { func NewAddressFromURL(u *url.URL) (addr *Address, err error) {
addr = &Address{ addr = &Address{
url: u, url: u,
umask: -1,
} }
if err = addr.validate(); err != nil { if err = addr.validate(); err != nil {
@ -143,6 +149,7 @@ type AddressSMTP struct {
type Address struct { type Address struct {
valid bool valid bool
socket bool socket bool
umask int
port int port int
url *url.URL url *url.URL
@ -153,6 +160,15 @@ func (a *Address) Valid() bool {
return a.valid return a.valid
} }
// Umask returns the formatted umask or an empty string.
func (a *Address) Umask() string {
if a.umask == -1 {
return ""
}
return fmt.Sprintf("%04s", strconv.FormatInt(int64(a.umask), 8))
}
// IsUnixDomainSocket returns true if the address has been determined to be a Unix Domain Socket. // IsUnixDomainSocket returns true if the address has been determined to be a Unix Domain Socket.
func (a *Address) IsUnixDomainSocket() bool { func (a *Address) IsUnixDomainSocket() bool {
return a.socket return a.socket
@ -257,16 +273,6 @@ func (a *Address) String() string {
return a.url.String() return a.url.String()
} }
// Network returns the Scheme() if it's appropriate for the net packages network arguments otherwise it returns tcp.
func (a *Address) Network() string {
switch scheme := a.Scheme(); scheme {
case AddressSchemeTCP, AddressSchemeTCP4, AddressSchemeTCP6, AddressSchemeUDP, AddressSchemeUDP4, AddressSchemeUDP6, AddressSchemeUnix:
return scheme
default:
return AddressSchemeTCP
}
}
// Scheme returns the *url.URL Scheme field. // Scheme returns the *url.URL Scheme field.
func (a *Address) Scheme() string { func (a *Address) Scheme() string {
if !a.valid || a.url == nil { if !a.valid || a.url == nil {
@ -276,6 +282,15 @@ func (a *Address) Scheme() string {
return a.url.Scheme return a.url.Scheme
} }
// Host returns the *url.URL Host field.
func (a *Address) Host() string {
if !a.valid || a.url == nil {
return ""
}
return a.url.Host
}
// Hostname returns the output of the *url.URL Hostname func. // Hostname returns the output of the *url.URL Hostname func.
func (a *Address) Hostname() string { func (a *Address) Hostname() string {
if !a.valid || a.url == nil { if !a.valid || a.url == nil {
@ -285,19 +300,6 @@ func (a *Address) Hostname() string {
return a.url.Hostname() return a.url.Hostname()
} }
// SocketHostname returns the correct hostname for a socket connection.
func (a *Address) SocketHostname() string {
if !a.valid || a.url == nil {
return ""
}
if a.socket {
return a.url.Path
}
return a.url.Hostname()
}
// SetHostname sets the hostname preserving the port. // SetHostname sets the hostname preserving the port.
func (a *Address) SetHostname(hostname string) { func (a *Address) SetHostname(hostname string) {
if !a.valid || a.url == nil { if !a.valid || a.url == nil {
@ -325,13 +327,36 @@ func (a *Address) SetPort(port int) {
a.setport(port) a.setport(port)
} }
// Host returns the *url.URL Host field. // Path returns the path.
func (a *Address) Host() string { func (a *Address) Path() string {
if !a.valid || a.url == nil { if !a.valid || a.url == nil {
return "" return ""
} }
return a.url.Host return a.url.Path
}
// SocketHostname returns the correct hostname for a socket connection.
func (a *Address) SocketHostname() string {
if !a.valid || a.url == nil {
return ""
}
if a.socket {
return a.url.Path
}
return a.url.Hostname()
}
// Network returns the Scheme() if it's appropriate for the net packages network arguments otherwise it returns tcp.
func (a *Address) Network() string {
switch scheme := a.Scheme(); scheme {
case AddressSchemeTCP, AddressSchemeTCP4, AddressSchemeTCP6, AddressSchemeUDP, AddressSchemeUDP4, AddressSchemeUDP6, AddressSchemeUnix:
return scheme
default:
return AddressSchemeTCP
}
} }
// NetworkAddress returns a string representation of the Address with just the host and port. // NetworkAddress returns a string representation of the Address with just the host and port.
@ -348,46 +373,33 @@ func (a *Address) NetworkAddress() string {
} }
// Listener creates and returns a net.Listener. // Listener creates and returns a net.Listener.
func (a *Address) Listener() (net.Listener, error) { func (a *Address) Listener() (ln net.Listener, err error) {
return a.listener() if a.url == nil {
return nil, fmt.Errorf("address url is nil")
}
if a.socket && a.umask != -1 {
umask := syscall.Umask(a.umask)
ln, err = net.Listen(a.Network(), a.NetworkAddress())
_ = syscall.Umask(umask)
return ln, err
}
return net.Listen(a.Network(), a.NetworkAddress())
} }
// Dial creates and returns a dialed net.Conn. // Dial creates and returns a dialed net.Conn.
func (a *Address) Dial() (net.Conn, error) { func (a *Address) Dial() (net.Conn, error) {
if a.url == nil { if !a.valid || a.url == nil {
return nil, fmt.Errorf("address url is nil") return nil, fmt.Errorf("address url is nil")
} }
return net.Dial(a.Network(), a.NetworkAddress()) return net.Dial(a.Network(), a.NetworkAddress())
} }
// ListenerWithUMask creates and returns a net.Listener with a temporary UMask if the scheme is `unix`.
func (a *Address) ListenerWithUMask(umask int) (ln net.Listener, err error) {
if !a.socket {
return a.listener()
}
if a.url == nil {
return nil, fmt.Errorf("address url is nil")
}
umask = syscall.Umask(umask)
ln, err = net.Listen(a.Network(), a.NetworkAddress())
_ = syscall.Umask(umask)
return ln, err
}
func (a *Address) listener() (net.Listener, error) {
if a.url == nil {
return nil, fmt.Errorf("address url is nil")
}
return net.Listen(a.Network(), a.NetworkAddress())
}
func (a *Address) setport(port int) { func (a *Address) setport(port int) {
a.port = port a.port = port
a.url.Host = net.JoinHostPort(a.url.Hostname(), strconv.Itoa(port)) a.url.Host = net.JoinHostPort(a.url.Hostname(), strconv.Itoa(port))
@ -399,8 +411,8 @@ func (a *Address) validate() (err error) {
} }
switch { switch {
case a.url.RawQuery != "": case a.url.RawQuery != "" && a.url.Scheme != AddressSchemeUnix:
return fmt.Errorf("error validating the address: the url '%s' appears to have a query but this is not valid for addresses", a.url.String()) return fmt.Errorf("error validating the address: the url '%s' appears to have a query but this is not valid for addresses with the '%s' scheme", a.url.String(), a.url.Scheme)
case a.url.RawFragment != "", a.url.Fragment != "": case a.url.RawFragment != "", a.url.Fragment != "":
return fmt.Errorf("error validating the address: the url '%s' appears to have a fragment but this is not valid for addresses", a.url.String()) return fmt.Errorf("error validating the address: the url '%s' appears to have a fragment but this is not valid for addresses", a.url.String())
case a.url.User != nil: case a.url.User != nil:
@ -469,6 +481,8 @@ func (a *Address) validateTCPUDP() (err error) {
} }
func (a *Address) validateUnixSocket() (err error) { func (a *Address) validateUnixSocket() (err error) {
umask := -1
switch { switch {
case a.url.Path == "" && a.url.Scheme != AddressSchemeLDAPI: case a.url.Path == "" && a.url.Scheme != AddressSchemeLDAPI:
return fmt.Errorf("error validating the unix socket address: could not determine path from '%s'", a.url.String()) return fmt.Errorf("error validating the unix socket address: could not determine path from '%s'", a.url.String())
@ -476,7 +490,22 @@ func (a *Address) validateUnixSocket() (err error) {
return fmt.Errorf("error validating the unix socket address: the url '%s' appears to have a host but this is not valid for unix sockets: this may occur if you omit the leading forward slash from the socket path", a.url.String()) return fmt.Errorf("error validating the unix socket address: the url '%s' appears to have a host but this is not valid for unix sockets: this may occur if you omit the leading forward slash from the socket path", a.url.String())
} }
if a.url.Query().Has(addressQueryParamUmask) {
v := a.url.Query().Get(addressQueryParamUmask)
if !regexpIsUmask.MatchString(v) {
return fmt.Errorf("error validating the unix socket address: could not parse address '%s': the address has a umask value of '%s' which does not appear to be a valid octal string", a.url.String(), v)
}
var p int64
p, _ = strconv.ParseInt(v, 8, 0)
umask = int(p)
}
a.socket = true a.socket = true
a.umask = umask
return nil return nil
} }

View File

@ -1,6 +1,7 @@
package schema package schema
import ( import (
"fmt"
"net" "net"
"net/url" "net/url"
"path/filepath" "path/filepath"
@ -20,7 +21,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldParseBasicAddress", "ShouldParseBasicAddress",
"tcp://0.0.0.0:9091", "tcp://0.0.0.0:9091",
&Address{true, false, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}}, &Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}},
"0.0.0.0:9091", "0.0.0.0:9091",
"tcp://0.0.0.0:9091", "tcp://0.0.0.0:9091",
"", "",
@ -28,7 +29,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldParseEmptyAddress", "ShouldParseEmptyAddress",
"", "",
&Address{true, false, 0, &url.URL{Scheme: AddressSchemeTCP, Host: ":0"}}, &Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeTCP, Host: ":0"}},
":0", ":0",
"tcp://:0", "tcp://:0",
"", "",
@ -36,7 +37,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldParseAddressMissingScheme", "ShouldParseAddressMissingScheme",
"0.0.0.0:9091", "0.0.0.0:9091",
&Address{true, false, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}}, &Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}},
"0.0.0.0:9091", "0.0.0.0:9091",
"tcp://0.0.0.0:9091", "tcp://0.0.0.0:9091",
"", "",
@ -44,7 +45,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldParseUnixAddressMissingScheme", "ShouldParseUnixAddressMissingScheme",
"/var/run/example.sock", "/var/run/example.sock",
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/var/run/example.sock"}}, &Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/var/run/example.sock"}},
"/var/run/example.sock", "/var/run/example.sock",
"unix:///var/run/example.sock", "unix:///var/run/example.sock",
"", "",
@ -52,15 +53,23 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldParseAddressMissingPort", "ShouldParseAddressMissingPort",
"tcp://0.0.0.0", "tcp://0.0.0.0",
&Address{true, false, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:0"}}, &Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:0"}},
"0.0.0.0:0", "0.0.0.0:0",
"tcp://0.0.0.0:0", "tcp://0.0.0.0:0",
"", "",
}, },
{
"ShouldNotParseAddressWithQuery",
"tcp://0.0.0.0?umask=0022",
nil,
"0.0.0.0:0",
"tcp://0.0.0.0:0",
"error validating the address: the url 'tcp://0.0.0.0?umask=0022' appears to have a query but this is not valid for addresses with the 'tcp' scheme",
},
{ {
"ShouldParseUnixSocket", "ShouldParseUnixSocket",
"unix:///path/to/a/socket.sock", "unix:///path/to/a/socket.sock",
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/path/to/a/socket.sock"}}, &Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/path/to/a/socket.sock"}},
"/path/to/a/socket.sock", "/path/to/a/socket.sock",
"unix:///path/to/a/socket.sock", "unix:///path/to/a/socket.sock",
"", "",
@ -82,12 +91,12 @@ func TestNewAddressFromString(t *testing.T) {
"error validating the unix socket address: could not determine path from 'unix://nopath.com'", "error validating the unix socket address: could not determine path from 'unix://nopath.com'",
}, },
{ {
"ShouldNotParseUnixSocketWithQuery", "ShouldParseUnixSocketWithQuery",
"unix:///path/to/a/socket.sock?q=yes", "unix:///path/to/a/socket.sock?umask=0022",
nil, &Address{true, true, 18, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/path/to/a/socket.sock", RawQuery: "umask=0022"}},
"/path/to/a/socket.sock",
"unix:///path/to/a/socket.sock?umask=0022",
"", "",
"",
"error validating the address: the url 'unix:///path/to/a/socket.sock?q=yes' appears to have a query but this is not valid for addresses",
}, },
{ {
"ShouldNotParseUnixSocketWithFragment", "ShouldNotParseUnixSocketWithFragment",
@ -108,7 +117,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldParseUnknownScheme", "ShouldParseUnknownScheme",
"a://0.0.0.0", "a://0.0.0.0",
&Address{true, false, 0, &url.URL{Scheme: "a", Host: "0.0.0.0"}}, &Address{true, false, -1, 0, &url.URL{Scheme: "a", Host: "0.0.0.0"}},
"0.0.0.0", "0.0.0.0",
"a://0.0.0.0", "a://0.0.0.0",
"", "",
@ -140,7 +149,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldSetDefaultPortLDAP", "ShouldSetDefaultPortLDAP",
"ldap://127.0.0.1", "ldap://127.0.0.1",
&Address{true, false, 389, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1:389"}}, &Address{true, false, -1, 389, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1:389"}},
"127.0.0.1:389", "127.0.0.1:389",
"ldap://127.0.0.1:389", "ldap://127.0.0.1:389",
"", "",
@ -148,7 +157,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldSetDefaultPortLDAPS", "ShouldSetDefaultPortLDAPS",
"ldaps://127.0.0.1", "ldaps://127.0.0.1",
&Address{true, false, 636, &url.URL{Scheme: AddressSchemeLDAPS, Host: "127.0.0.1:636"}}, &Address{true, false, -1, 636, &url.URL{Scheme: AddressSchemeLDAPS, Host: "127.0.0.1:636"}},
"127.0.0.1:636", "127.0.0.1:636",
"ldaps://127.0.0.1:636", "ldaps://127.0.0.1:636",
"", "",
@ -156,7 +165,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldAllowLDAPI", "ShouldAllowLDAPI",
"ldapi:///abc", "ldapi:///abc",
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: "/abc"}}, &Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: "/abc"}},
"/abc", "/abc",
"ldapi:///abc", "ldapi:///abc",
"", "",
@ -164,7 +173,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldAllowImplicitLDAPI", "ShouldAllowImplicitLDAPI",
"ldapi://", "ldapi://",
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: ""}}, &Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: ""}},
"", "",
"ldapi:", "ldapi:",
"", "",
@ -172,7 +181,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldAllowImplicitLDAPINoSlash", "ShouldAllowImplicitLDAPINoSlash",
"ldapi:", "ldapi:",
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: ""}}, &Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeLDAPI, Path: ""}},
"", "",
"ldapi:", "ldapi:",
"", "",
@ -180,7 +189,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldSetDefaultPortSMTP", "ShouldSetDefaultPortSMTP",
"smtp://127.0.0.1", "smtp://127.0.0.1",
&Address{true, false, 25, &url.URL{Scheme: AddressSchemeSMTP, Host: "127.0.0.1:25"}}, &Address{true, false, -1, 25, &url.URL{Scheme: AddressSchemeSMTP, Host: "127.0.0.1:25"}},
"127.0.0.1:25", "127.0.0.1:25",
"smtp://127.0.0.1:25", "smtp://127.0.0.1:25",
"", "",
@ -188,7 +197,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldSetDefaultPortSUBMISSION", "ShouldSetDefaultPortSUBMISSION",
"submission://127.0.0.1", "submission://127.0.0.1",
&Address{true, false, 587, &url.URL{Scheme: AddressSchemeSUBMISSION, Host: "127.0.0.1:587"}}, &Address{true, false, -1, 587, &url.URL{Scheme: AddressSchemeSUBMISSION, Host: "127.0.0.1:587"}},
"127.0.0.1:587", "127.0.0.1:587",
"submission://127.0.0.1:587", "submission://127.0.0.1:587",
"", "",
@ -196,7 +205,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldSetDefaultPortSUBMISSIONS", "ShouldSetDefaultPortSUBMISSIONS",
"submissions://127.0.0.1", "submissions://127.0.0.1",
&Address{true, false, 465, &url.URL{Scheme: AddressSchemeSUBMISSIONS, Host: "127.0.0.1:465"}}, &Address{true, false, -1, 465, &url.URL{Scheme: AddressSchemeSUBMISSIONS, Host: "127.0.0.1:465"}},
"127.0.0.1:465", "127.0.0.1:465",
"submissions://127.0.0.1:465", "submissions://127.0.0.1:465",
"", "",
@ -204,7 +213,7 @@ func TestNewAddressFromString(t *testing.T) {
{ {
"ShouldNotOverridePort", "ShouldNotOverridePort",
"ldap://127.0.0.1:123", "ldap://127.0.0.1:123",
&Address{true, false, 123, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1:123"}}, &Address{true, false, -1, 123, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1:123"}},
"127.0.0.1:123", "127.0.0.1:123",
"ldap://127.0.0.1:123", "ldap://127.0.0.1:123",
"", "",
@ -239,7 +248,7 @@ func TestAddress_ValidateErrors(t *testing.T) {
}{ }{
{ {
"ShouldValidateLDAPAddress", "ShouldValidateLDAPAddress",
&Address{true, false, 0, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1"}}, &Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeLDAP, Host: "127.0.0.1"}},
"", "",
"scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'ldap'", "scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'ldap'",
"scheme must be one of 'tcp', 'tcp4', 'tcp6', or 'unix' but is configured as 'ldap'", "scheme must be one of 'tcp', 'tcp4', 'tcp6', or 'unix' but is configured as 'ldap'",
@ -248,7 +257,7 @@ func TestAddress_ValidateErrors(t *testing.T) {
}, },
{ {
"ShouldValidateSMTPAddress", "ShouldValidateSMTPAddress",
&Address{true, false, 0, &url.URL{Scheme: AddressSchemeSMTP, Host: "127.0.0.1"}}, &Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeSMTP, Host: "127.0.0.1"}},
"scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'smtp'", "scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'smtp'",
"", "",
"scheme must be one of 'tcp', 'tcp4', 'tcp6', or 'unix' but is configured as 'smtp'", "scheme must be one of 'tcp', 'tcp4', 'tcp6', or 'unix' but is configured as 'smtp'",
@ -257,7 +266,7 @@ func TestAddress_ValidateErrors(t *testing.T) {
}, },
{ {
"ShouldValidateTCPAddress", "ShouldValidateTCPAddress",
&Address{true, false, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "127.0.0.1"}}, &Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "127.0.0.1"}},
"scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'tcp'", "scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'tcp'",
"scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'tcp'", "scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'tcp'",
"", "",
@ -266,7 +275,7 @@ func TestAddress_ValidateErrors(t *testing.T) {
}, },
{ {
"ShouldValidateUnixSocket", "ShouldValidateUnixSocket",
&Address{true, true, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/path/to/socket"}}, &Address{true, true, -1, 0, &url.URL{Scheme: AddressSchemeUnix, Path: "/path/to/socket"}},
"scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'unix'", "scheme must be one of 'ldap', 'ldaps', or 'ldapi' but is configured as 'unix'",
"scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'unix'", "scheme must be one of 'smtp', 'submission', or 'submissions' but is configured as 'unix'",
"", "",
@ -311,7 +320,7 @@ func TestAddress_ValidateErrors(t *testing.T) {
} }
func TestAddress_SetHostname(t *testing.T) { func TestAddress_SetHostname(t *testing.T) {
address := &Address{true, false, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0"}} address := &Address{true, false, -1, 0, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0"}}
assert.Equal(t, "tcp://0.0.0.0", address.String()) assert.Equal(t, "tcp://0.0.0.0", address.String())
@ -320,32 +329,6 @@ func TestAddress_SetHostname(t *testing.T) {
assert.Equal(t, "tcp://127.0.0.1", address.String()) assert.Equal(t, "tcp://127.0.0.1", address.String())
} }
func TestAddress_ListenerWithUMask(t *testing.T) {
dir := t.TempDir()
address := &Address{true, true, 0, &url.URL{Scheme: AddressSchemeUnix, Path: filepath.Join(dir, "example.sock")}}
ln, err := address.ListenerWithUMask(600)
assert.NotNil(t, ln)
assert.NoError(t, err)
assert.NoError(t, ln.Close())
address = &Address{true, true, 0, nil}
ln, err = address.ListenerWithUMask(600)
assert.Nil(t, ln)
assert.EqualError(t, err, "address url is nil")
address = &Address{true, false, 0, nil}
ln, err = address.ListenerWithUMask(600)
assert.Nil(t, ln)
assert.EqualError(t, err, "address url is nil")
}
func TestAddressOutputValues(t *testing.T) { func TestAddressOutputValues(t *testing.T) {
var ( var (
address *Address address *Address
@ -356,7 +339,7 @@ func TestAddressOutputValues(t *testing.T) {
address = &Address{} address = &Address{}
assert.EqualError(t, address.validate(), "error validating the address: address url was nil") assert.EqualError(t, address.validate(), "error validating the address: address url was nil")
address = &Address{false, false, 0, nil} address = &Address{false, false, -1, 0, nil}
assert.Equal(t, "", address.String()) assert.Equal(t, "", address.String())
assert.Equal(t, "", address.Scheme()) assert.Equal(t, "", address.Scheme())
@ -370,7 +353,7 @@ func TestAddressOutputValues(t *testing.T) {
assert.Nil(t, listener) assert.Nil(t, listener)
assert.EqualError(t, err, "address url is nil") assert.EqualError(t, err, "address url is nil")
address = &Address{true, false, 8080, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:8080"}} address = &Address{true, false, -1, 8080, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:8080"}}
assert.Equal(t, "tcp://0.0.0.0:8080", address.String()) assert.Equal(t, "tcp://0.0.0.0:8080", address.String())
assert.Equal(t, "tcp", address.Scheme()) assert.Equal(t, "tcp", address.Scheme())
@ -384,7 +367,7 @@ func TestAddressOutputValues(t *testing.T) {
assert.NotNil(t, listener) assert.NotNil(t, listener)
assert.NoError(t, err) assert.NoError(t, err)
address = &Address{true, false, 0, nil} address = &Address{true, false, -1, 0, nil}
assert.Equal(t, "", address.String()) assert.Equal(t, "", address.String())
assert.Equal(t, "", address.Scheme()) assert.Equal(t, "", address.Scheme())
@ -413,7 +396,7 @@ func TestAddressOutputValues(t *testing.T) {
assert.Nil(t, listener) assert.Nil(t, listener)
assert.EqualError(t, err, "address url is nil") assert.EqualError(t, err, "address url is nil")
address = &Address{true, false, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}} address = &Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: "0.0.0.0:9091"}}
assert.Equal(t, "tcp://0.0.0.0:9091", address.String()) assert.Equal(t, "tcp://0.0.0.0:9091", address.String())
assert.Equal(t, "tcp", address.Scheme()) assert.Equal(t, "tcp", address.Scheme())
@ -570,6 +553,132 @@ func TestNewSMTPAddress(t *testing.T) {
} }
} }
func TestAddress_Dial(t *testing.T) {
testCases := []struct {
name string
have Address
success bool
err string
}{
{
"ShouldNotDialNil",
Address{true, false, -1, 0, nil},
false,
"address url is nil",
},
{
"ShouldNotDialInvalid",
Address{false, false, -1, 0, &url.URL{}},
false,
"address url is nil",
},
{
"ShouldNotDialInvalidAddress",
Address{true, false, -1, 0, &url.URL{Scheme: "abc", Host: "127.0.0.1:0"}},
false,
"dial tcp 127.0.0.1:0: connect: connection refused",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
conn, err := tc.have.Dial()
defer func(c net.Conn) {
if c == nil {
return
}
conn.Close()
}(conn)
if tc.success {
} else {
assert.Nil(t, conn)
if tc.err != "" {
assert.EqualError(t, err, tc.err)
} else {
assert.NotNil(t, err)
}
}
})
}
}
func TestAddress_UnixDomainSocket(t *testing.T) {
dir := t.TempDir()
testCases := []struct {
name string
have string
socket bool
path string
strUmask string
umask int
err string
}{
{
"ShouldNotBeSocket",
"tcp://:9091",
false,
"",
"",
-1,
"",
},
{
"ShouldParseSocket",
fmt.Sprintf("unix://%s", filepath.Join(dir, "example.sock")),
true,
filepath.Join(dir, "example.sock"),
"",
-1,
"",
},
{
"ShouldParseSocketWithUmask",
fmt.Sprintf("unix://%s?umask=0022", filepath.Join(dir, "example.sock")),
true,
filepath.Join(dir, "example.sock"),
"0022",
18,
"",
},
{
"ShouldParseSocketWithBadUmask",
fmt.Sprintf("unix://%s?umask=abc", filepath.Join(dir, "example.sock")),
true,
"",
"",
-1,
fmt.Sprintf("error validating the unix socket address: could not parse address 'unix://%s?umask=abc': the address has a umask value of 'abc' which does not appear to be a valid octal string", filepath.Join(dir, "example.sock")),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
actual, err := NewAddress(tc.have)
if tc.err == "" {
assert.Equal(t, tc.socket, actual.IsUnixDomainSocket())
assert.Equal(t, tc.path, actual.Path())
assert.Equal(t, tc.strUmask, actual.Umask())
assert.Equal(t, tc.umask, actual.umask)
ln, err := actual.Listener()
assert.NoError(t, err)
assert.NotNil(t, ln)
assert.NoError(t, ln.Close())
} else {
assert.EqualError(t, err, tc.err)
}
})
}
}
func TestAddress_SocketHostname(t *testing.T) { func TestAddress_SocketHostname(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
@ -578,22 +687,22 @@ func TestAddress_SocketHostname(t *testing.T) {
}{ }{
{ {
"ShouldReturnHostname", "ShouldReturnHostname",
Address{true, false, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "examplea:80"}}, Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "examplea:80"}},
"examplea", "examplea",
}, },
{ {
"ShouldReturnPath", "ShouldReturnPath",
Address{true, true, 80, &url.URL{Scheme: AddressSchemeUnix, Path: "/abc/123"}}, Address{true, true, -1, 80, &url.URL{Scheme: AddressSchemeUnix, Path: "/abc/123"}},
"/abc/123", "/abc/123",
}, },
{ {
"ShouldReturnNothing", "ShouldReturnNothing",
Address{false, true, 80, &url.URL{Scheme: AddressSchemeUnix, Path: "/abc/123"}}, Address{false, true, -1, 80, &url.URL{Scheme: AddressSchemeUnix, Path: "/abc/123"}},
"", "",
}, },
{ {
"ShouldReturnNothingNil", "ShouldReturnNothingNil",
Address{true, true, 80, nil}, Address{true, true, -1, 80, nil},
"", "",
}, },
} }
@ -605,6 +714,41 @@ func TestAddress_SocketHostname(t *testing.T) {
} }
} }
func TestAddress_Path(t *testing.T) {
testCases := []struct {
name string
have Address
expected string
}{
{
"ShouldReturnEmptyPath",
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "tcphosta"}},
"",
},
{
"ShouldReturnPath",
Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "tcphosta", Path: "/apath"}},
"/apath",
},
{
"ShouldNotReturnPathInvalid",
Address{false, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "tcphosta", Path: "/apath"}},
"",
},
{
"ShouldNotReturnPathNil",
Address{true, false, -1, 80, nil},
"",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.expected, tc.have.Path())
})
}
}
func TestAddress_IsTCP_IsUDP(t *testing.T) { func TestAddress_IsTCP_IsUDP(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
@ -614,49 +758,49 @@ func TestAddress_IsTCP_IsUDP(t *testing.T) {
}{ }{
{ {
"ShouldReturnTrueTCP", "ShouldReturnTrueTCP",
Address{true, false, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "tcphosta"}}, Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP, Host: "tcphosta"}},
true, true,
false, false,
}, },
{ {
"ShouldReturnTrueTCP4", "ShouldReturnTrueTCP4",
Address{true, false, 80, &url.URL{Scheme: AddressSchemeTCP4, Host: "tcphostb"}}, Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP4, Host: "tcphostb"}},
true, true,
false, false,
}, },
{ {
"ShouldReturnTrueTCP6", "ShouldReturnTrueTCP6",
Address{true, false, 80, &url.URL{Scheme: AddressSchemeTCP6, Host: "tcphostc"}}, Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeTCP6, Host: "tcphostc"}},
true, true,
false, false,
}, },
{ {
"ShouldReturnFalseUDP", "ShouldReturnFalseUDP",
Address{true, false, 80, &url.URL{Scheme: AddressSchemeUDP, Host: "tcphostd"}}, Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeUDP, Host: "tcphostd"}},
false, false,
true, true,
}, },
{ {
"ShouldReturnFalseUDP4", "ShouldReturnFalseUDP4",
Address{true, false, 80, &url.URL{Scheme: AddressSchemeUDP4, Host: "tcphoste"}}, Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeUDP4, Host: "tcphoste"}},
false, false,
true, true,
}, },
{ {
"ShouldReturnFalseUDP6", "ShouldReturnFalseUDP6",
Address{true, false, 80, &url.URL{Scheme: AddressSchemeUDP6, Host: "tcphostf"}}, Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeUDP6, Host: "tcphostf"}},
false, false,
true, true,
}, },
{ {
"ShouldReturnFalseSMTP", "ShouldReturnFalseSMTP",
Address{true, false, 80, &url.URL{Scheme: AddressSchemeSMTP, Host: "tcphostg"}}, Address{true, false, -1, 80, &url.URL{Scheme: AddressSchemeSMTP, Host: "tcphostg"}},
false, false,
false, false,
}, },
{ {
"ShouldReturnFalseUnix", "ShouldReturnFalseUnix",
Address{true, true, 80, &url.URL{Scheme: AddressSchemeUnix, Host: "tcphosth"}}, Address{true, true, -1, 80, &url.URL{Scheme: AddressSchemeUnix, Host: "tcphosth"}},
false, false,
false, false,
}, },

View File

@ -37,14 +37,7 @@ func CreateDefaultServer(config *schema.Configuration, providers middlewares.Pro
connectionScheme = schemeHTTP connectionScheme = schemeHTTP
) )
switch config.Server.UMask { if listener, err = config.Server.Address.Listener(); err != nil {
case nil:
listener, err = config.Server.Address.Listener()
default:
listener, err = config.Server.Address.ListenerWithUMask(*config.Server.UMask)
}
if err != nil {
return nil, nil, nil, false, fmt.Errorf("error occurred while attempting to initialize main server listener for address '%s': %w", config.Server.Address.String(), err) return nil, nil, nil, false, fmt.Errorf("error occurred while attempting to initialize main server listener for address '%s': %w", config.Server.Address.String(), err)
} }
@ -109,14 +102,7 @@ func CreateMetricsServer(config *schema.Configuration, providers middlewares.Pro
Logger: logging.LoggerPrintf(logrus.DebugLevel), Logger: logging.LoggerPrintf(logrus.DebugLevel),
} }
switch config.Telemetry.Metrics.UMask { if listener, err = config.Telemetry.Metrics.Address.Listener(); err != nil {
case nil:
listener, err = config.Telemetry.Metrics.Address.Listener()
default:
listener, err = config.Telemetry.Metrics.Address.ListenerWithUMask(*config.Telemetry.Metrics.UMask)
}
if err != nil {
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 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)
} }