Allow Hosts field to be set on an ingress config entry
- Validate that this cannot be set on a 'tcp' listener nor on a wildcard service. - Add Hosts field to api and test in consul config write CLI - xds: Configure envoy with user-provided hosts from ingress gateways
This commit is contained in:
parent
837d2aa7d2
commit
210dda5682
|
@ -2542,6 +2542,7 @@ func (s *Store) ingressConfigGatewayServices(tx *memdb.Txn, gateway structs.Serv
|
|||
Gateway: gateway,
|
||||
Service: service.ToServiceID(),
|
||||
GatewayKind: structs.ServiceKindIngressGateway,
|
||||
Hosts: service.Hosts,
|
||||
Port: listener.Port,
|
||||
Protocol: listener.Protocol,
|
||||
}
|
||||
|
|
|
@ -4997,6 +4997,7 @@ func TestStateStore_GatewayServices_Ingress(t *testing.T) {
|
|||
require.Len(results, 2)
|
||||
require.Equal("ingress1", results[0].Gateway.ID)
|
||||
require.Equal("service1", results[0].Service.ID)
|
||||
require.Len(results[0].Hosts, 1)
|
||||
require.Equal(1111, results[0].Port)
|
||||
require.Equal("ingress1", results[1].Gateway.ID)
|
||||
require.Equal("service2", results[1].Service.ID)
|
||||
|
@ -5218,6 +5219,7 @@ func setupIngressState(t *testing.T, s *Store) memdb.WatchSet {
|
|||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "service1",
|
||||
Hosts: []string{"test.example.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1355,6 +1355,7 @@ func makeUpstream(g *structs.GatewayService, bindAddr string) structs.Upstream {
|
|||
DestinationName: g.Service.ID,
|
||||
DestinationNamespace: g.Service.NamespaceOrDefault(),
|
||||
LocalBindPort: g.Port,
|
||||
IngressHosts: g.Hosts,
|
||||
// Pass the protocol that was configured on the ingress listener in order
|
||||
// to force that protocol on the Envoy listener.
|
||||
Config: map[string]interface{}{
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
)
|
||||
|
||||
// IngressGatewayConfigEntry manages the configuration for an ingress service
|
||||
|
@ -51,6 +52,15 @@ type IngressService struct {
|
|||
// protocol and means that the listener will forward traffic to all services.
|
||||
Name string
|
||||
|
||||
// Hosts is a list of hostnames which should be associated to this service on
|
||||
// the defined listener. Only allowed on layer 7 protocols, this will be used
|
||||
// to route traffic to the service by matching the Host header of the HTTP
|
||||
// request.
|
||||
//
|
||||
// This cannot be specified when using the wildcard specifier, "*", or when
|
||||
// using a "tcp" listener.
|
||||
Hosts []string
|
||||
|
||||
EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
|
||||
}
|
||||
|
||||
|
@ -109,18 +119,6 @@ func (e *IngressGatewayConfigEntry) Validate() error {
|
|||
return fmt.Errorf("Protocol must be either 'http' or 'tcp', '%s' is an unsupported protocol.", listener.Protocol)
|
||||
}
|
||||
|
||||
for _, s := range listener.Services {
|
||||
if s.Name == WildcardSpecifier && listener.Protocol != "http" {
|
||||
return fmt.Errorf("Wildcard service name is only valid for protocol = 'http' (listener on port %d)", listener.Port)
|
||||
}
|
||||
if s.Name == "" {
|
||||
return fmt.Errorf("Service name cannot be blank (listener on port %d)", listener.Port)
|
||||
}
|
||||
if s.NamespaceOrDefault() == WildcardSpecifier {
|
||||
return fmt.Errorf("Wildcard namespace is not supported for ingress services (listener on port %d)", listener.Port)
|
||||
}
|
||||
}
|
||||
|
||||
if len(listener.Services) == 0 {
|
||||
return fmt.Errorf("No service declared for listener with port %d", listener.Port)
|
||||
}
|
||||
|
@ -130,6 +128,35 @@ func (e *IngressGatewayConfigEntry) Validate() error {
|
|||
return fmt.Errorf("Multiple services per listener are only supported for protocol = 'http' (listener on port %d)",
|
||||
listener.Port)
|
||||
}
|
||||
|
||||
declaredHosts := make(map[string]bool)
|
||||
for _, s := range listener.Services {
|
||||
if listener.Protocol == "tcp" {
|
||||
if s.Name == WildcardSpecifier {
|
||||
return fmt.Errorf("Wildcard service name is only valid for protocol = 'http' (listener on port %d)", listener.Port)
|
||||
}
|
||||
if len(s.Hosts) != 0 {
|
||||
return fmt.Errorf("Associating hosts to a service is not supported for the %s protocol (listener on port %d)", listener.Protocol, listener.Port)
|
||||
}
|
||||
}
|
||||
if s.Name == "" {
|
||||
return fmt.Errorf("Service name cannot be blank (listener on port %d)", listener.Port)
|
||||
}
|
||||
if s.Name == WildcardSpecifier && len(s.Hosts) != 0 {
|
||||
return fmt.Errorf("Associating hosts to a wildcard service is not supported (listener on port %d)", listener.Port)
|
||||
}
|
||||
if s.NamespaceOrDefault() == WildcardSpecifier {
|
||||
return fmt.Errorf("Wildcard namespace is not supported for ingress services (listener on port %d)", listener.Port)
|
||||
}
|
||||
|
||||
// TODO(ingress): Validate Hosts are valid?
|
||||
for _, h := range s.Hosts {
|
||||
if declaredHosts[h] {
|
||||
return fmt.Errorf("Hosts must be unique within a specific listener (listener on port %d)", listener.Port)
|
||||
}
|
||||
declaredHosts[h] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -296,6 +323,7 @@ type GatewayService struct {
|
|||
GatewayKind ServiceKind
|
||||
Port int
|
||||
Protocol string
|
||||
Hosts []string
|
||||
CAFile string
|
||||
CertFile string
|
||||
KeyFile string
|
||||
|
@ -312,6 +340,7 @@ func (g *GatewayService) IsSame(o *GatewayService) bool {
|
|||
g.GatewayKind == o.GatewayKind &&
|
||||
g.Port == o.Port &&
|
||||
g.Protocol == o.Protocol &&
|
||||
lib.StringSliceEqual(g.Hosts, o.Hosts) &&
|
||||
g.CAFile == o.CAFile &&
|
||||
g.CertFile == o.CertFile &&
|
||||
g.KeyFile == o.KeyFile &&
|
||||
|
@ -326,6 +355,8 @@ func (g *GatewayService) Clone() *GatewayService {
|
|||
GatewayKind: g.GatewayKind,
|
||||
Port: g.Port,
|
||||
Protocol: g.Protocol,
|
||||
// See https://github.com/go101/go101/wiki/How-to-efficiently-clone-a-slice%3F
|
||||
Hosts: append(g.Hosts[:0:0], g.Hosts...),
|
||||
CAFile: g.CAFile,
|
||||
CertFile: g.CertFile,
|
||||
KeyFile: g.KeyFile,
|
||||
|
|
|
@ -252,6 +252,70 @@ func TestIngressConfigEntry_Validate(t *testing.T) {
|
|||
},
|
||||
expectErr: "Protocol must be either 'http' or 'tcp', 'asdf' is an unsupported protocol.",
|
||||
},
|
||||
{
|
||||
name: "hosts cannot be set on a tcp listener",
|
||||
entry: IngressGatewayConfigEntry{
|
||||
Kind: "ingress-gateway",
|
||||
Name: "ingress-web",
|
||||
Listeners: []IngressListener{
|
||||
{
|
||||
Port: 1111,
|
||||
Protocol: "tcp",
|
||||
Services: []IngressService{
|
||||
{
|
||||
Name: "db",
|
||||
Hosts: []string{"db.example.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectErr: "Associating hosts to a service is not supported for the tcp protocol",
|
||||
},
|
||||
{
|
||||
name: "hosts cannot be set on a wildcard specifier",
|
||||
entry: IngressGatewayConfigEntry{
|
||||
Kind: "ingress-gateway",
|
||||
Name: "ingress-web",
|
||||
Listeners: []IngressListener{
|
||||
{
|
||||
Port: 1111,
|
||||
Protocol: "http",
|
||||
Services: []IngressService{
|
||||
{
|
||||
Name: "*",
|
||||
Hosts: []string{"db.example.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectErr: "Associating hosts to a wildcard service is not supported",
|
||||
},
|
||||
{
|
||||
name: "hosts must be unique per listener",
|
||||
entry: IngressGatewayConfigEntry{
|
||||
Kind: "ingress-gateway",
|
||||
Name: "ingress-web",
|
||||
Listeners: []IngressListener{
|
||||
{
|
||||
Port: 1111,
|
||||
Protocol: "http",
|
||||
Services: []IngressService{
|
||||
{
|
||||
Name: "db",
|
||||
Hosts: []string{"test.example.com"},
|
||||
},
|
||||
{
|
||||
Name: "api",
|
||||
Hosts: []string{"test.example.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectErr: "Hosts must be unique within a specific listener",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range cases {
|
||||
|
|
|
@ -545,6 +545,7 @@ func TestDecodeConfigEntry(t *testing.T) {
|
|||
services = [
|
||||
{
|
||||
name = "web"
|
||||
hosts = ["test.example.com", "test2.example.com"]
|
||||
},
|
||||
{
|
||||
name = "db"
|
||||
|
@ -581,6 +582,7 @@ func TestDecodeConfigEntry(t *testing.T) {
|
|||
Services = [
|
||||
{
|
||||
Name = "web"
|
||||
Hosts = ["test.example.com", "test2.example.com"]
|
||||
},
|
||||
{
|
||||
Name = "db"
|
||||
|
@ -617,6 +619,7 @@ func TestDecodeConfigEntry(t *testing.T) {
|
|||
Services: []IngressService{
|
||||
IngressService{
|
||||
Name: "web",
|
||||
Hosts: []string{"test.example.com", "test2.example.com"},
|
||||
},
|
||||
IngressService{
|
||||
Name: "db",
|
||||
|
|
|
@ -247,6 +247,10 @@ type Upstream struct {
|
|||
|
||||
// MeshGateway is the configuration for mesh gateway usage of this upstream
|
||||
MeshGateway MeshGatewayConfig `json:",omitempty"`
|
||||
|
||||
// IngressHosts are a list of hosts that should route to this upstream from
|
||||
// an ingress gateway
|
||||
IngressHosts []string `json:"-" bexpr:"-"`
|
||||
}
|
||||
|
||||
func (t *Upstream) UnmarshalJSON(data []byte) (err error) {
|
||||
|
|
|
@ -49,14 +49,14 @@ func routesFromSnapshotConnectProxy(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.M
|
|||
if chain == nil || chain.IsDefault() {
|
||||
// TODO(rb): make this do the old school stuff too
|
||||
} else {
|
||||
virtualHost, err := makeUpstreamRouteForDiscoveryChain(upstreamID, chain, "*")
|
||||
virtualHost, err := makeUpstreamRouteForDiscoveryChain(upstreamID, chain, []string{"*"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
route := &envoy.RouteConfiguration{
|
||||
Name: upstreamID,
|
||||
VirtualHosts: []envoyroute.VirtualHost{*virtualHost},
|
||||
VirtualHosts: []envoyroute.VirtualHost{virtualHost},
|
||||
ValidateClusters: makeBoolValue(true),
|
||||
}
|
||||
resources = append(resources, route)
|
||||
|
@ -91,21 +91,31 @@ func routesFromSnapshotIngressGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto
|
|||
for _, u := range upstreams {
|
||||
upstreamID := u.Identifier()
|
||||
chain := cfgSnap.IngressGateway.DiscoveryChain[upstreamID]
|
||||
if chain != nil {
|
||||
domain := fmt.Sprintf("%s.*", chain.ServiceName)
|
||||
if chain == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var domains []string
|
||||
switch {
|
||||
case len(upstreams) == 1:
|
||||
// Don't require a service prefix on the domain if there is only 1
|
||||
// upstream. This makes it a smoother experience when only having a
|
||||
// single service associated to a listener, which is probably a common
|
||||
// case when demoing/testing
|
||||
if len(upstreams) == 1 {
|
||||
domain = "*"
|
||||
domains = []string{"*"}
|
||||
case len(u.IngressHosts) > 0:
|
||||
// If a user has specified hosts, do not add the default
|
||||
// "<service-name>.*" prefix
|
||||
domains = u.IngressHosts
|
||||
default:
|
||||
domains = []string{fmt.Sprintf("%s.*", chain.ServiceName)}
|
||||
}
|
||||
virtualHost, err := makeUpstreamRouteForDiscoveryChain(upstreamID, chain, domain)
|
||||
|
||||
virtualHost, err := makeUpstreamRouteForDiscoveryChain(upstreamID, chain, domains)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
upstreamRoute.VirtualHosts = append(upstreamRoute.VirtualHosts, *virtualHost)
|
||||
}
|
||||
upstreamRoute.VirtualHosts = append(upstreamRoute.VirtualHosts, virtualHost)
|
||||
}
|
||||
|
||||
result = append(result, upstreamRoute)
|
||||
|
@ -117,8 +127,8 @@ func routesFromSnapshotIngressGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto
|
|||
func makeUpstreamRouteForDiscoveryChain(
|
||||
routeName string,
|
||||
chain *structs.CompiledDiscoveryChain,
|
||||
serviceDomain string,
|
||||
) (*envoyroute.VirtualHost, error) {
|
||||
serviceDomains []string,
|
||||
) (envoyroute.VirtualHost, error) {
|
||||
var routes []envoyroute.Route
|
||||
|
||||
startNode := chain.Nodes[chain.StartNode]
|
||||
|
@ -143,14 +153,14 @@ func makeUpstreamRouteForDiscoveryChain(
|
|||
case structs.DiscoveryGraphNodeTypeSplitter:
|
||||
routeAction, err = makeRouteActionForSplitter(nextNode.Splits, chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return envoyroute.VirtualHost{}, err
|
||||
}
|
||||
|
||||
case structs.DiscoveryGraphNodeTypeResolver:
|
||||
routeAction = makeRouteActionForSingleCluster(nextNode.Resolver.Target, chain)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected graph node after route %q", nextNode.Type)
|
||||
return envoyroute.VirtualHost{}, fmt.Errorf("unexpected graph node after route %q", nextNode.Type)
|
||||
}
|
||||
|
||||
// TODO(rb): Better help handle the envoy case where you need (prefix=/foo/,rewrite=/) and (exact=/foo,rewrite=/) to do a full rewrite
|
||||
|
@ -197,7 +207,7 @@ func makeUpstreamRouteForDiscoveryChain(
|
|||
case structs.DiscoveryGraphNodeTypeSplitter:
|
||||
routeAction, err := makeRouteActionForSplitter(startNode.Splits, chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return envoyroute.VirtualHost{}, err
|
||||
}
|
||||
|
||||
defaultRoute := envoyroute.Route{
|
||||
|
@ -221,9 +231,9 @@ func makeUpstreamRouteForDiscoveryChain(
|
|||
panic("unknown first node in discovery chain of type: " + startNode.Type)
|
||||
}
|
||||
|
||||
host := &envoyroute.VirtualHost{
|
||||
host := envoyroute.VirtualHost{
|
||||
Name: routeName,
|
||||
Domains: []string{serviceDomain},
|
||||
Domains: serviceDomains,
|
||||
Routes: routes,
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ func TestRoutesFromSnapshot(t *testing.T) {
|
|||
{
|
||||
DestinationName: "foo",
|
||||
LocalBindPort: 8080,
|
||||
IngressHosts: []string{"test1.example.com", "test2.example.com"},
|
||||
},
|
||||
{
|
||||
DestinationName: "bar",
|
||||
|
|
|
@ -47,7 +47,8 @@
|
|||
{
|
||||
"name": "foo",
|
||||
"domains": [
|
||||
"foo.*"
|
||||
"test1.example.com",
|
||||
"test2.example.com"
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
|
|
|
@ -57,6 +57,15 @@ type IngressService struct {
|
|||
// protocol and means that the listener will forward traffic to all services.
|
||||
Name string
|
||||
|
||||
// Hosts is a list of hostnames which should be associated to this service on
|
||||
// the defined listener. Only allowed on layer 7 protocols, this will be used
|
||||
// to route traffic to the service by matching the Host header of the HTTP
|
||||
// request.
|
||||
//
|
||||
// This cannot be specified when using the wildcard specifier, "*", or when
|
||||
// using a "tcp" listener.
|
||||
Hosts []string
|
||||
|
||||
// Namespace is the namespace where the service is located.
|
||||
// Namespacing is a Consul Enterprise feature.
|
||||
Namespace string `json:",omitempty"`
|
||||
|
|
|
@ -51,10 +51,11 @@ func TestAPI_ConfigEntries_IngressGateway(t *testing.T) {
|
|||
ingress1.Listeners = []IngressListener{
|
||||
{
|
||||
Port: 2222,
|
||||
Protocol: "tcp",
|
||||
Protocol: "http",
|
||||
Services: []IngressService{
|
||||
{
|
||||
Name: "asdf",
|
||||
Hosts: []string{"test.example.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1395,6 +1395,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
services = [
|
||||
{
|
||||
name = "web"
|
||||
hosts = ["test.example.com"]
|
||||
},
|
||||
{
|
||||
name = "db"
|
||||
|
@ -1414,6 +1415,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
Services = [
|
||||
{
|
||||
Name = "web"
|
||||
Hosts = ["test.example.com"]
|
||||
},
|
||||
{
|
||||
Name = "db"
|
||||
|
@ -1433,7 +1435,8 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
"protocol": "http",
|
||||
"services": [
|
||||
{
|
||||
"name": "web"
|
||||
"name": "web",
|
||||
"hosts": ["test.example.com"]
|
||||
},
|
||||
{
|
||||
"name": "db",
|
||||
|
@ -1454,7 +1457,8 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
"Protocol": "http",
|
||||
"Services": [
|
||||
{
|
||||
"Name": "web"
|
||||
"Name": "web",
|
||||
"Hosts": ["test.example.com"]
|
||||
},
|
||||
{
|
||||
"Name": "db",
|
||||
|
@ -1475,6 +1479,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
Services: []api.IngressService{
|
||||
{
|
||||
Name: "web",
|
||||
Hosts: []string{"test.example.com"},
|
||||
},
|
||||
{
|
||||
Name: "db",
|
||||
|
|
|
@ -31,28 +31,10 @@ load helpers
|
|||
}
|
||||
|
||||
@test "ingress should be able to connect to s1 via configured path" {
|
||||
run retry_default curl -s -f localhost:9999/s1/debug?env=dump
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
GOT=$(echo "$output" | grep -E "^FORTIO_NAME=")
|
||||
EXPECT_NAME="s1"
|
||||
|
||||
if [ "$GOT" != "FORTIO_NAME=${EXPECT_NAME}" ]; then
|
||||
echo "expected name: $EXPECT_NAME, actual name: $GOT" 1>&2
|
||||
return 1
|
||||
fi
|
||||
assert_expected_fortio_name s1 localhost 9999 /s1
|
||||
}
|
||||
|
||||
@test "ingress should be able to connect to s2 via configured path" {
|
||||
run retry_default curl -s -f localhost:9999/s2/debug?env=dump
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
GOT=$(echo "$output" | grep -E "^FORTIO_NAME=")
|
||||
EXPECT_NAME="s2"
|
||||
|
||||
if [ "$GOT" != "FORTIO_NAME=${EXPECT_NAME}" ]; then
|
||||
echo "expected name: $EXPECT_NAME, actual name: $GOT" 1>&2
|
||||
return 1
|
||||
fi
|
||||
assert_expected_fortio_name s2 localhost 9999 /s2
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,16 @@ config_entries {
|
|||
name = "*"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
port = 9998
|
||||
protocol = "http"
|
||||
services = [
|
||||
{
|
||||
name = "s1"
|
||||
hosts = ["test.example.com"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -31,28 +31,13 @@ load helpers
|
|||
}
|
||||
|
||||
@test "ingress should be able to connect to s1 using Host header" {
|
||||
run retry_default curl -H"Host: s1.example.consul" -s -f localhost:9999/debug?env=dump
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
GOT=$(echo "$output" | grep -E "^FORTIO_NAME=")
|
||||
EXPECT_NAME="s1"
|
||||
|
||||
if [ "$GOT" != "FORTIO_NAME=${EXPECT_NAME}" ]; then
|
||||
echo "expected name: $EXPECT_NAME, actual name: $GOT" 1>&2
|
||||
return 1
|
||||
fi
|
||||
assert_expected_fortio_name s1 s1.example.consul 9999
|
||||
}
|
||||
|
||||
@test "ingress should be able to connect to s2 using Host header" {
|
||||
run retry_default curl -H"Host: s2.example.consul" -s -f localhost:9999/debug?env=dump
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
GOT=$(echo "$output" | grep -E "^FORTIO_NAME=")
|
||||
EXPECT_NAME="s2"
|
||||
|
||||
if [ "$GOT" != "FORTIO_NAME=${EXPECT_NAME}" ]; then
|
||||
echo "expected name: $EXPECT_NAME, actual name: $GOT" 1>&2
|
||||
return 1
|
||||
fi
|
||||
assert_expected_fortio_name s2 s2.example.consul 9999
|
||||
}
|
||||
|
||||
@test "ingress should be able to connect to s1 using a user-specified Host" {
|
||||
assert_expected_fortio_name s1 test.example.com 9998
|
||||
}
|
||||
|
|
|
@ -646,15 +646,21 @@ function set_ttl_check_state {
|
|||
}
|
||||
|
||||
function get_upstream_fortio_name {
|
||||
run retry_default curl -v -s -f localhost:5000/debug?env=dump
|
||||
local HOST=$1
|
||||
local PORT=$2
|
||||
local PREFIX=$3
|
||||
run retry_default curl -v -s -f -H"Host: ${HOST}" "localhost:${PORT}${PREFIX}/debug?env=dump"
|
||||
[ "$status" == 0 ]
|
||||
echo "$output" | grep -E "^FORTIO_NAME="
|
||||
}
|
||||
|
||||
function assert_expected_fortio_name {
|
||||
local EXPECT_NAME=$1
|
||||
local HOST=${2:-"localhost"}
|
||||
local PORT=${3:-5000}
|
||||
local URL_PREFIX=${4:-""}
|
||||
|
||||
GOT=$(get_upstream_fortio_name)
|
||||
GOT=$(get_upstream_fortio_name ${HOST} ${PORT} ${URL_PREFIX})
|
||||
|
||||
if [ "$GOT" != "FORTIO_NAME=${EXPECT_NAME}" ]; then
|
||||
echo "expected name: $EXPECT_NAME, actual name: $GOT" 1>&2
|
||||
|
|
Loading…
Reference in New Issue