From bdc03ed540d64d5896fad01780e9c8d66f7a4331 Mon Sep 17 00:00:00 2001 From: Olli Janatuinen Date: Tue, 25 Nov 2025 20:05:14 +0100 Subject: [PATCH] plugin/nomad: Support service filtering (#7724) Signed-off-by: Olli Janatuinen --- plugin/nomad/README.md | 3 +++ plugin/nomad/nomad.go | 3 ++- plugin/nomad/setup.go | 6 ++++++ plugin/nomad/setup_test.go | 23 ++++++++++++++--------- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/plugin/nomad/README.md b/plugin/nomad/README.md index 9c3dd20f6..d13859bfd 100644 --- a/plugin/nomad/README.md +++ b/plugin/nomad/README.md @@ -80,6 +80,7 @@ With only the plugin specified, the *nomad* plugin will default to `service.noma ~~~ txt nomad [ZONE] { address URL + filter FILTER token TOKEN ttl DURATION } @@ -87,6 +88,8 @@ nomad [ZONE] { * `address` The address where a Nomad agent (server) is available. **URL** defaults to `http://127.0.0.1:4646`. +* `filter` allows you to filter Nomad services. **FILTER** defaults to `""`. Uses [filtering](https://developer.hashicorp.com/nomad/api-docs#filtering) syntax. + * `token` The SecretID of an ACL token to use to authenticate API requests with if the Nomad cluster has ACL enabled. **TOKEN** defaults to `""`. * `ttl` allows you to set a custom TTL for responses. **DURATION** defaults to `30 seconds`. The minimum TTL allowed is `0` seconds, and the maximum is capped at `3600` seconds. Setting TTL to 0 will prevent records from being cached. The unit for the value is seconds. diff --git a/plugin/nomad/nomad.go b/plugin/nomad/nomad.go index c39c445ee..5a0042c4f 100644 --- a/plugin/nomad/nomad.go +++ b/plugin/nomad/nomad.go @@ -29,6 +29,7 @@ type Nomad struct { Zone string clients []*api.Client current int + filter string } func (n *Nomad) Name() string { @@ -103,7 +104,7 @@ func fetchServiceRegistrations(n Nomad, serviceName, namespace string) ([]*api.S if err != nil { return nil, nil, err } - return nc.Services().Get(serviceName, (&api.QueryOptions{Namespace: namespace})) + return nc.Services().Get(serviceName, (&api.QueryOptions{Namespace: namespace, Filter: n.filter})) } func handleServiceLookupError(w dns.ResponseWriter, m *dns.Msg, ctx context.Context, namespace string) (int, error) { diff --git a/plugin/nomad/setup.go b/plugin/nomad/setup.go index 94e2178ab..40aa4692f 100644 --- a/plugin/nomad/setup.go +++ b/plugin/nomad/setup.go @@ -77,6 +77,12 @@ func parse(c *caddy.Controller, n *Nomad) error { return c.Err("at least one address is required") } addresses = append(addresses, args...) + case "filter": + args := c.RemainingArgs() + if len(args) != 1 { + return c.Err("exactly one filter is required") + } + n.filter = args[0] case "token": args := c.RemainingArgs() if len(args) != 1 { diff --git a/plugin/nomad/setup_test.go b/plugin/nomad/setup_test.go index 880997b3b..9422dde2a 100644 --- a/plugin/nomad/setup_test.go +++ b/plugin/nomad/setup_test.go @@ -10,10 +10,11 @@ import ( func TestSetupNomad(t *testing.T) { tests := []struct { - name string - config string - shouldErr bool - expectedTTL uint32 + name string + config string + shouldErr bool + expectedFilter string + expectedTTL uint32 }{ { name: "valid_config_default_ttl", @@ -22,19 +23,22 @@ nomad service.nomad { address http://127.0.0.1:4646 token test-token }`, - shouldErr: false, - expectedTTL: uint32(defaultTTL), + shouldErr: false, + expectedFilter: "", + expectedTTL: uint32(defaultTTL), }, { - name: "valid_config_custom_ttl", + name: "valid_config_custom_filter_and_ttl", config: ` nomad service.nomad { address http://127.0.0.1:4646 + filter "Tags not contains candidate" token test-token ttl 60 }`, - shouldErr: false, - expectedTTL: 60, + shouldErr: false, + expectedFilter: "Tags not contains candidate", + expectedTTL: 60, }, { name: "invalid_ttl_negative", @@ -85,6 +89,7 @@ nomad service.nomad { ttl: uint32(defaultTTL), clients: make([]*nomad.Client, 0), current: -1, + filter: "", } err := parse(c, n)