open-consul/agent/proxycfg-glue/gateway_services_test.go
Daniel Upton a5a6102a3b proxycfg-glue: server-local implementation of GatewayServices
This is the OSS portion of enterprise PR 2259.

This PR provides a server-local implementation of the proxycfg.GatewayServices
interface based on blocking queries.
2022-07-14 18:22:12 +01:00

156 lines
4.2 KiB
Go

package proxycfgglue
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/consul/state"
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/sdk/testutil"
)
func TestServerGatewayServices(t *testing.T) {
const index uint64 = 123
t.Run("ingress gateway", func(t *testing.T) {
store := state.NewStateStore(nil)
authz := policyAuthorizer(t, `
service "igw" { policy = "read" }
service "web" { policy = "read" }
service "db" { policy = "read" }
`)
require.NoError(t, store.EnsureConfigEntry(index, &structs.IngressGatewayConfigEntry{
Name: "igw",
Listeners: []structs.IngressListener{
{
Protocol: "tcp",
Services: []structs.IngressService{
{Name: "web"},
},
},
{
Protocol: "tcp",
Services: []structs.IngressService{
{Name: "db"},
},
},
{
Protocol: "tcp",
Services: []structs.IngressService{
{Name: "no-access"},
},
},
},
}))
dataSource := ServerGatewayServices(ServerDataSourceDeps{
ACLResolver: newStaticResolver(authz),
GetStore: func() Store { return store },
})
eventCh := make(chan proxycfg.UpdateEvent)
require.NoError(t, dataSource.Notify(context.Background(), &structs.ServiceSpecificRequest{ServiceName: "igw"}, "", eventCh))
testutil.RunStep(t, "initial state", func(t *testing.T) {
result := getEventResult[*structs.IndexedGatewayServices](t, eventCh)
require.Len(t, result.Services, 2)
})
testutil.RunStep(t, "remove service mapping", func(t *testing.T) {
require.NoError(t, store.EnsureConfigEntry(index+1, &structs.IngressGatewayConfigEntry{
Name: "igw",
Listeners: []structs.IngressListener{
{
Protocol: "tcp",
Services: []structs.IngressService{
{Name: "web"},
},
},
},
}))
result := getEventResult[*structs.IndexedGatewayServices](t, eventCh)
require.Len(t, result.Services, 1)
})
})
t.Run("terminating gateway", func(t *testing.T) {
store := state.NewStateStore(nil)
authz := policyAuthorizer(t, `
service "tgw" { policy = "read" }
service "web" { policy = "read" }
service "db" { policy = "read" }
`)
require.NoError(t, store.EnsureConfigEntry(index, &structs.TerminatingGatewayConfigEntry{
Name: "tgw",
Services: []structs.LinkedService{
{Name: "web"},
{Name: "db"},
{Name: "no-access"},
},
}))
dataSource := ServerGatewayServices(ServerDataSourceDeps{
ACLResolver: newStaticResolver(authz),
GetStore: func() Store { return store },
})
eventCh := make(chan proxycfg.UpdateEvent)
require.NoError(t, dataSource.Notify(context.Background(), &structs.ServiceSpecificRequest{ServiceName: "tgw"}, "", eventCh))
testutil.RunStep(t, "initial state", func(t *testing.T) {
result := getEventResult[*structs.IndexedGatewayServices](t, eventCh)
require.Len(t, result.Services, 2)
})
testutil.RunStep(t, "remove service mapping", func(t *testing.T) {
require.NoError(t, store.EnsureConfigEntry(index+1, &structs.TerminatingGatewayConfigEntry{
Name: "tgw",
Services: []structs.LinkedService{
{Name: "web"},
},
}))
result := getEventResult[*structs.IndexedGatewayServices](t, eventCh)
require.Len(t, result.Services, 1)
})
})
t.Run("no access to gateway", func(t *testing.T) {
store := state.NewStateStore(nil)
authz := policyAuthorizer(t, `
service "tgw" { policy = "deny" }
service "web" { policy = "read" }
service "db" { policy = "read" }
`)
require.NoError(t, store.EnsureConfigEntry(index, &structs.TerminatingGatewayConfigEntry{
Name: "tgw",
Services: []structs.LinkedService{
{Name: "web"},
{Name: "db"},
},
}))
dataSource := ServerGatewayServices(ServerDataSourceDeps{
ACLResolver: newStaticResolver(authz),
GetStore: func() Store { return store },
})
eventCh := make(chan proxycfg.UpdateEvent)
require.NoError(t, dataSource.Notify(context.Background(), &structs.ServiceSpecificRequest{ServiceName: "tgw"}, "", eventCh))
err := getEventError(t, eventCh)
require.True(t, acl.IsErrPermissionDenied(err), "expected permission denied error")
})
}