Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VAULT-6368 Metrics-only listener for Agent #18101

Merged
merged 8 commits into from
Nov 25, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog/18101.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
agent: Agent listeners can now be configured to be a `metrics_only_listener`, serving only metrics, as part of the listener's telemetry configuration .
```
10 changes: 6 additions & 4 deletions command/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -700,18 +700,20 @@ func (c *AgentCommand) Run(args []string) int {
// Parse 'require_request_header' listener config option, and wrap
// the request handler if necessary
muxHandler := cacheHandler
if lnConfig.RequireRequestHeader {
if lnConfig.RequireRequestHeader && !lnConfig.Telemetry.MetricsOnlyListener {
muxHandler = verifyRequestHeader(muxHandler)
}

// Create a muxer and add paths relevant for the lease cache layer
mux := http.NewServeMux()
quitEnabled := lnConfig.AgentAPI != nil && lnConfig.AgentAPI.EnableQuit

mux.Handle(consts.AgentPathCacheClear, leaseCache.HandleCacheClear(ctx))
mux.Handle(consts.AgentPathQuit, c.handleQuit(quitEnabled))
mux.Handle(consts.AgentPathMetrics, c.handleMetrics())
mux.Handle("/", muxHandler)
if !lnConfig.Telemetry.MetricsOnlyListener {
mux.Handle(consts.AgentPathCacheClear, leaseCache.HandleCacheClear(ctx))
mux.Handle(consts.AgentPathQuit, c.handleQuit(quitEnabled))
mux.Handle("/", muxHandler)
}

scheme := "https://"
if tlsConf == nil {
Expand Down
8 changes: 8 additions & 0 deletions command/agent/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ func TestLoadConfigFile_AgentCache(t *testing.T) {
Address: "127.0.0.1:8300",
TLSDisable: true,
},
{
Type: "tcp",
Address: "127.0.0.1:3000",
TLSDisable: true,
Telemetry: configutil.ListenerTelemetry{
MetricsOnlyListener: true,
},
},
{
Type: "tcp",
Address: "127.0.0.1:8400",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ listener {
tls_disable = true
}

listener {
type = "tcp"
address = "127.0.0.1:3000"
tls_disable = true
telemetry {
metrics_only_listener = true
}
}

listener {
type = "tcp"
address = "127.0.0.1:8400"
Expand Down
9 changes: 9 additions & 0 deletions command/agent/config/test-fixtures/config-cache.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ listener "tcp" {
tls_disable = true
}

listener {
type = "tcp"
address = "127.0.0.1:3000"
tls_disable = true
telemetry {
metrics_only_listener = true
}
}

listener "tcp" {
address = "127.0.0.1:8400"
tls_key_file = "/path/to/cakey.pem"
Expand Down
22 changes: 2 additions & 20 deletions internalshared/configutil/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package configutil

import (
"fmt"
"io/ioutil"
"time"

"github.com/hashicorp/go-secure-stdlib/parseutil"
Expand All @@ -21,6 +20,8 @@ type SharedConfig struct {

Listeners []*Listener `hcl:"-"`

MetricsListeners []*Listener `hcl:"metric_listener"`

UserLockouts []*UserLockout `hcl:"-"`

Seals []*KMS `hcl:"-"`
Expand All @@ -47,25 +48,6 @@ type SharedConfig struct {
ClusterName string `hcl:"cluster_name"`
}

// LoadConfigFile loads the configuration from the given file.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two functions were not used anywhere, so I cleaned them up.

func LoadConfigFile(path string) (*SharedConfig, error) {
// Read the file
d, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return ParseConfig(string(d))
}

func LoadConfigKMSes(path string) ([]*KMS, error) {
// Read the file
d, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return ParseKMSes(string(d))
}

func ParseConfig(d string) (*SharedConfig, error) {
// Parse!
obj, err := hcl.Parse(d)
Expand Down
10 changes: 10 additions & 0 deletions internalshared/configutil/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type ListenerTelemetry struct {
UnusedKeys UnusedKeyMap `hcl:",unusedKeyPositions"`
UnauthenticatedMetricsAccess bool `hcl:"-"`
UnauthenticatedMetricsAccessRaw interface{} `hcl:"unauthenticated_metrics_access,alias:UnauthenticatedMetricsAccess"`
MetricsOnlyListener bool `hcl:"-"`
MetricsOnlyListenerAccessRaw interface{} `hcl:"metrics_only_listener,alias:MetricsOnlyListener"`
VioletHynes marked this conversation as resolved.
Show resolved Hide resolved
}

type ListenerProfiling struct {
Expand Down Expand Up @@ -348,6 +350,14 @@ func ParseListeners(result *SharedConfig, list *ast.ObjectList) error {

l.Telemetry.UnauthenticatedMetricsAccessRaw = nil
}

if l.Telemetry.MetricsOnlyListenerAccessRaw != nil {
if l.Telemetry.MetricsOnlyListener, err = parseutil.ParseBool(l.Telemetry.MetricsOnlyListenerAccessRaw); err != nil {
return multierror.Prefix(fmt.Errorf("invalid value for telemetry.metrcs_only_listener: %w", err), fmt.Sprintf("listeners.%d", i))
VioletHynes marked this conversation as resolved.
Show resolved Hide resolved
}

l.Telemetry.MetricsOnlyListenerAccessRaw = nil
}
}

// Profiling
Expand Down
2 changes: 1 addition & 1 deletion sdk/helper/consts/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package consts
// endpoint.
const AgentPathCacheClear = "/agent/v1/cache-clear"

// AgentPathMetrics is the path the the agent will use to expose its internal
// AgentPathMetrics is the path the agent will use to expose its internal
// metrics.
const AgentPathMetrics = "/agent/v1/metrics"

Expand Down
14 changes: 12 additions & 2 deletions website/content/docs/agent/caching/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,9 @@ These are common configuration values that live within the `persist` block:
There can be one or more `listener` blocks at the top level. These configuration
values are common to both `tcp` and `unix` listener blocks. Blocks of type
`tcp` support the standard `tcp` [listener](/docs/configuration/listener/tcp)
options.
options. Additionally, the `metrics_only_listener` boolean option is available
as part of the listener `telemetry` block, enabling you to have a listener that
only serves metrics.

- `type` `(string: required)` - The type of the listener to use. Valid values
are `tcp` and `unix`.
Expand All @@ -249,7 +251,7 @@ options.

### Example Configuration

Here is an example of a cache configuration.
Here is an example of a cache configuration alongside a listener that only serves metrics.

```hcl
# Other Vault Agent configuration blocks
Expand All @@ -258,6 +260,14 @@ Here is an example of a cache configuration.
cache {
use_auto_auth_token = true
}

listener "tcp" {
address = "127.0.0.1:3000"
tls_disable = true
telemetry {
metrics_only_listener = true
}
}
```

## Tutorial
Expand Down