diff --git a/.changelog/15659.txt b/.changelog/15659.txt new file mode 100644 index 0000000000..05559f3b1e --- /dev/null +++ b/.changelog/15659.txt @@ -0,0 +1,3 @@ +```release-note:improvement +connect: Add support for ConsulResolver to specifies a filter expression +``` diff --git a/connect/resolver.go b/connect/resolver.go index 54ca272674..68d56cc7b9 100644 --- a/connect/resolver.go +++ b/connect/resolver.go @@ -78,6 +78,9 @@ type ConsulResolver struct { // Datacenter to resolve in, empty indicates agent's local DC. Datacenter string + + // Specifies the expression used to filter the queries results prior to returning the data. + Filter string } // Resolve performs service discovery against the local Consul agent and returns @@ -173,6 +176,7 @@ func (cr *ConsulResolver) queryOptions(ctx context.Context) *api.QueryOptions { // For prepared queries Connect: true, + Filter: cr.Filter, } return q.WithContext(ctx) } diff --git a/connect/resolver_test.go b/connect/resolver_test.go index ba082c96bb..e84ea1f2b9 100644 --- a/connect/resolver_test.go +++ b/connect/resolver_test.go @@ -68,6 +68,9 @@ func TestConsulResolver_Resolve(t *testing.T) { Proxy: &api.AgentServiceConnectProxyConfig{ DestinationServiceName: "web", }, + Meta: map[string]string{ + "MetaKey": "MetaValue", + }, } err = client.Agent().ServiceRegister(regProxy) require.Nil(t, err) @@ -75,6 +78,7 @@ func TestConsulResolver_Resolve(t *testing.T) { // And another proxy so we can test handling with multiple endpoints returned regProxy.Port = 9091 regProxy.ID = "web-proxy-2" + regProxy.Meta = map[string]string{} err = client.Agent().ServiceRegister(regProxy) require.Nil(t, err) @@ -110,6 +114,7 @@ func TestConsulResolver_Resolve(t *testing.T) { Name string Type int Datacenter string + Filter string } tests := []struct { name string @@ -145,6 +150,32 @@ func TestConsulResolver_Resolve(t *testing.T) { wantCertURI: connect.TestSpiffeIDServiceWithHost(t, "db", ""), wantErr: false, }, + { + name: "service discovery with filter", + fields: fields{ + Namespace: "default", + Name: "web", + Type: ConsulResolverTypeService, + Filter: "Service.Meta[`MetaKey`] == `MetaValue`", + }, + // Want empty host since we don't enforce trust domain outside of TLS and + // don't need to load the current one this way. + wantCertURI: connect.TestSpiffeIDServiceWithHost(t, "web", ""), + wantErr: false, + addrs: []string{ + agent.Config.AdvertiseAddrLAN.String() + ":9090", + }, + }, + { + name: "service discovery with filter", + fields: fields{ + Namespace: "default", + Name: "web", + Type: ConsulResolverTypeService, + Filter: "`AnotherMetaValue` in Service.Meta.MetaKey", + }, + wantErr: true, + }, { name: "Bad Type errors", fields: fields{ @@ -206,6 +237,7 @@ func TestConsulResolver_Resolve(t *testing.T) { Name: tt.fields.Name, Type: tt.fields.Type, Datacenter: tt.fields.Datacenter, + Filter: tt.fields.Filter, } // WithCancel just to have a cancel func in scope to assign in the if // clause.