290 lines
7.0 KiB
Go
290 lines
7.0 KiB
Go
|
package expose
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
|
||
|
"github.com/hashicorp/consul/agent"
|
||
|
"github.com/hashicorp/consul/api"
|
||
|
"github.com/hashicorp/consul/testrpc"
|
||
|
"github.com/mitchellh/cli"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func TestConnectExpose(t *testing.T) {
|
||
|
t.Parallel()
|
||
|
require := require.New(t)
|
||
|
a := agent.NewTestAgent(t, ``)
|
||
|
client := a.Client()
|
||
|
defer a.Shutdown()
|
||
|
|
||
|
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
|
||
|
{
|
||
|
ui := cli.NewMockUi()
|
||
|
c := New(ui)
|
||
|
args := []string{
|
||
|
"-http-addr=" + a.HTTPAddr(),
|
||
|
"-service=foo",
|
||
|
"-ingress-gateway=ingress",
|
||
|
"-port=8888",
|
||
|
"-protocol=tcp",
|
||
|
}
|
||
|
|
||
|
code := c.Run(args)
|
||
|
if code != 0 {
|
||
|
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Make sure the config entry and intention have been created.
|
||
|
entry, _, err := client.ConfigEntries().Get(api.IngressGateway, "ingress", nil)
|
||
|
require.NoError(err)
|
||
|
expected := &api.IngressGatewayConfigEntry{
|
||
|
Kind: api.IngressGateway,
|
||
|
Name: "ingress",
|
||
|
Listeners: []api.IngressListener{
|
||
|
{
|
||
|
Port: 8888,
|
||
|
Protocol: "tcp",
|
||
|
Services: []api.IngressService{
|
||
|
{
|
||
|
Name: "foo",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
expected.CreateIndex = entry.GetCreateIndex()
|
||
|
expected.ModifyIndex = entry.GetModifyIndex()
|
||
|
require.Equal(expected, entry)
|
||
|
|
||
|
ixns, _, err := client.Connect().Intentions(nil)
|
||
|
require.NoError(err)
|
||
|
require.Len(ixns, 1)
|
||
|
require.Equal("ingress", ixns[0].SourceName)
|
||
|
require.Equal("foo", ixns[0].DestinationName)
|
||
|
|
||
|
// Run the command again with a different port, make sure the config entry
|
||
|
// and intentions aren't modified.
|
||
|
{
|
||
|
ui := cli.NewMockUi()
|
||
|
c := New(ui)
|
||
|
args := []string{
|
||
|
"-http-addr=" + a.HTTPAddr(),
|
||
|
"-service=foo",
|
||
|
"-ingress-gateway=ingress",
|
||
|
"-port=7777",
|
||
|
"-protocol=tcp",
|
||
|
}
|
||
|
|
||
|
code := c.Run(args)
|
||
|
if code != 0 {
|
||
|
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||
|
}
|
||
|
|
||
|
// Make sure the config entry/intention weren't affected.
|
||
|
entry, _, err = client.ConfigEntries().Get(api.IngressGateway, "ingress", nil)
|
||
|
require.NoError(err)
|
||
|
require.Equal(expected, entry)
|
||
|
|
||
|
ixns, _, err = client.Connect().Intentions(nil)
|
||
|
require.NoError(err)
|
||
|
require.Len(ixns, 1)
|
||
|
require.Equal("ingress", ixns[0].SourceName)
|
||
|
require.Equal("foo", ixns[0].DestinationName)
|
||
|
}
|
||
|
|
||
|
// Run the command again with a conflicting protocol, should exit with an error and
|
||
|
// cause no changes to config entry/intentions.
|
||
|
{
|
||
|
ui := cli.NewMockUi()
|
||
|
c := New(ui)
|
||
|
args := []string{
|
||
|
"-http-addr=" + a.HTTPAddr(),
|
||
|
"-service=bar",
|
||
|
"-ingress-gateway=ingress",
|
||
|
"-port=8888",
|
||
|
"-protocol=http",
|
||
|
}
|
||
|
|
||
|
code := c.Run(args)
|
||
|
if code != 1 {
|
||
|
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||
|
}
|
||
|
require.Contains(ui.ErrorWriter.String(), `conflicting protocol "tcp"`)
|
||
|
|
||
|
// Make sure the config entry/intention weren't affected.
|
||
|
entry, _, err = client.ConfigEntries().Get(api.IngressGateway, "ingress", nil)
|
||
|
require.NoError(err)
|
||
|
require.Equal(expected, entry)
|
||
|
|
||
|
ixns, _, err = client.Connect().Intentions(nil)
|
||
|
require.NoError(err)
|
||
|
require.Len(ixns, 1)
|
||
|
require.Equal("ingress", ixns[0].SourceName)
|
||
|
require.Equal("foo", ixns[0].DestinationName)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestConnectExpose_invalidFlags(t *testing.T) {
|
||
|
t.Parallel()
|
||
|
require := require.New(t)
|
||
|
a := agent.NewTestAgent(t, ``)
|
||
|
defer a.Shutdown()
|
||
|
|
||
|
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
|
||
|
t.Run("missing service", func(t *testing.T) {
|
||
|
ui := cli.NewMockUi()
|
||
|
c := New(ui)
|
||
|
args := []string{
|
||
|
"-http-addr=" + a.HTTPAddr(),
|
||
|
}
|
||
|
|
||
|
code := c.Run(args)
|
||
|
if code != 1 {
|
||
|
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||
|
}
|
||
|
require.Contains(ui.ErrorWriter.String(), "A service name must be given")
|
||
|
})
|
||
|
t.Run("missing gateway", func(t *testing.T) {
|
||
|
ui := cli.NewMockUi()
|
||
|
c := New(ui)
|
||
|
args := []string{
|
||
|
"-http-addr=" + a.HTTPAddr(),
|
||
|
"-service=foo",
|
||
|
}
|
||
|
|
||
|
code := c.Run(args)
|
||
|
if code != 1 {
|
||
|
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||
|
}
|
||
|
require.Contains(ui.ErrorWriter.String(), "An ingress gateway service must be given")
|
||
|
})
|
||
|
t.Run("missing port", func(t *testing.T) {
|
||
|
ui := cli.NewMockUi()
|
||
|
c := New(ui)
|
||
|
args := []string{
|
||
|
"-http-addr=" + a.HTTPAddr(),
|
||
|
"-service=foo",
|
||
|
"-ingress-gateway=ingress",
|
||
|
}
|
||
|
|
||
|
code := c.Run(args)
|
||
|
if code != 1 {
|
||
|
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||
|
}
|
||
|
require.Contains(ui.ErrorWriter.String(), "A port must be provided")
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestConnectExpose_existingConfig(t *testing.T) {
|
||
|
t.Parallel()
|
||
|
require := require.New(t)
|
||
|
a := agent.NewTestAgent(t, ``)
|
||
|
client := a.Client()
|
||
|
defer a.Shutdown()
|
||
|
|
||
|
// Create some service config entries to set their protocol.
|
||
|
for _, service := range []string{"bar", "zoo"} {
|
||
|
_, _, err := client.ConfigEntries().Set(&api.ServiceConfigEntry{
|
||
|
Kind: "service-defaults",
|
||
|
Name: service,
|
||
|
Protocol: "http",
|
||
|
}, nil)
|
||
|
require.NoError(err)
|
||
|
}
|
||
|
|
||
|
// Create an existing ingress config entry with some services.
|
||
|
ingressConf := &api.IngressGatewayConfigEntry{
|
||
|
Kind: api.IngressGateway,
|
||
|
Name: "ingress",
|
||
|
Listeners: []api.IngressListener{
|
||
|
{
|
||
|
Port: 8888,
|
||
|
Protocol: "tcp",
|
||
|
Services: []api.IngressService{
|
||
|
{
|
||
|
Name: "foo",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Port: 9999,
|
||
|
Protocol: "http",
|
||
|
Services: []api.IngressService{
|
||
|
{
|
||
|
Name: "bar",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
_, _, err := client.ConfigEntries().Set(ingressConf, nil)
|
||
|
require.NoError(err)
|
||
|
|
||
|
// Add a service on a new port.
|
||
|
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
|
||
|
{
|
||
|
ui := cli.NewMockUi()
|
||
|
c := New(ui)
|
||
|
args := []string{
|
||
|
"-http-addr=" + a.HTTPAddr(),
|
||
|
"-service=baz",
|
||
|
"-ingress-gateway=ingress",
|
||
|
"-port=10000",
|
||
|
"-protocol=tcp",
|
||
|
}
|
||
|
|
||
|
code := c.Run(args)
|
||
|
if code != 0 {
|
||
|
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||
|
}
|
||
|
|
||
|
// Make sure the ingress config was updated and existing services preserved.
|
||
|
entry, _, err := client.ConfigEntries().Get(api.IngressGateway, "ingress", nil)
|
||
|
require.NoError(err)
|
||
|
|
||
|
ingressConf.Listeners = append(ingressConf.Listeners, api.IngressListener{
|
||
|
Port: 10000,
|
||
|
Protocol: "tcp",
|
||
|
Services: []api.IngressService{
|
||
|
{
|
||
|
Name: "baz",
|
||
|
},
|
||
|
},
|
||
|
})
|
||
|
ingressConf.CreateIndex = entry.GetCreateIndex()
|
||
|
ingressConf.ModifyIndex = entry.GetModifyIndex()
|
||
|
require.Equal(ingressConf, entry)
|
||
|
}
|
||
|
|
||
|
// Add an service on a port shared with an existing listener.
|
||
|
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
|
||
|
{
|
||
|
ui := cli.NewMockUi()
|
||
|
c := New(ui)
|
||
|
args := []string{
|
||
|
"-http-addr=" + a.HTTPAddr(),
|
||
|
"-service=zoo",
|
||
|
"-ingress-gateway=ingress",
|
||
|
"-port=9999",
|
||
|
"-protocol=http",
|
||
|
}
|
||
|
|
||
|
code := c.Run(args)
|
||
|
if code != 0 {
|
||
|
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||
|
}
|
||
|
|
||
|
// Make sure the ingress config was updated and existing services preserved.
|
||
|
entry, _, err := client.ConfigEntries().Get(api.IngressGateway, "ingress", nil)
|
||
|
require.NoError(err)
|
||
|
|
||
|
ingressConf.Listeners[1].Services = append(ingressConf.Listeners[1].Services, api.IngressService{
|
||
|
Name: "zoo",
|
||
|
})
|
||
|
ingressConf.CreateIndex = entry.GetCreateIndex()
|
||
|
ingressConf.ModifyIndex = entry.GetModifyIndex()
|
||
|
require.Equal(ingressConf, entry)
|
||
|
}
|
||
|
}
|