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 6 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 to be the `metrics_only` role, serving only metrics, as part of the listener's new top level `role` option.
```
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 && !("metrics_only" == lnConfig.Role) {
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 !("metrics_only" == lnConfig.Role) {
mux.Handle(consts.AgentPathCacheClear, leaseCache.HandleCacheClear(ctx))
mux.Handle(consts.AgentPathQuit, c.handleQuit(quitEnabled))
mux.Handle("/", muxHandler)
}

scheme := "https://"
if tlsConf == nil {
Expand Down
7 changes: 7 additions & 0 deletions command/agent/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,15 @@ func TestLoadConfigFile_AgentCache(t *testing.T) {
Address: "127.0.0.1:8300",
TLSDisable: true,
},
{
Type: "tcp",
Address: "127.0.0.1:3000",
Role: "metrics_only",
TLSDisable: true,
},
{
Type: "tcp",
Role: "default",
Address: "127.0.0.1:8400",
TLSKeyFile: "/path/to/cakey.pem",
TLSCertFile: "/path/to/cacert.pem",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ listener {

listener {
type = "tcp"
address = "127.0.0.1:3000"
tls_disable = true
role = "metrics_only"
}

listener {
type = "tcp"
role = "default"
address = "127.0.0.1:8400"
tls_key_file = "/path/to/cakey.pem"
tls_cert_file = "/path/to/cacert.pem"
Expand Down
8 changes: 8 additions & 0 deletions command/agent/config/test-fixtures/config-cache.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,15 @@ listener "tcp" {
tls_disable = true
}

listener {
type = "tcp"
address = "127.0.0.1:3000"
tls_disable = true
role = "metrics_only"
}

listener "tcp" {
role = "default"
address = "127.0.0.1:8400"
tls_key_file = "/path/to/cakey.pem"
tls_cert_file = "/path/to/cacert.pem"
Expand Down
20 changes: 0 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 Down Expand Up @@ -47,25 +46,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
8 changes: 8 additions & 0 deletions internalshared/configutil/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Listener struct {
Type string
Purpose []string `hcl:"-"`
PurposeRaw interface{} `hcl:"purpose"`
Role string `hcl:"role"`

Address string `hcl:"address"`
ClusterAddress string `hcl:"cluster_address"`
Expand Down Expand Up @@ -182,6 +183,13 @@ func ParseListeners(result *SharedConfig, list *ast.ObjectList) error {

l.PurposeRaw = nil
}

switch l.Role {
case "default", "metrics_only", "":
result.found(l.Type, l.Type)
default:
return multierror.Prefix(fmt.Errorf("unsupported listener role %q", l.Role), fmt.Sprintf("listeners.%d:", i))
}
}

// Request Parameters
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
12 changes: 10 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 `role` string option is available as part of the top level
of the `listener` block, which can be configured to `metrics_only` to serve only metrics,
the default role, `default`, serves everything (including 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,12 @@ 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
role = "metrics_only"
}
```

## Tutorial
Expand Down