2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2023-02-16 19:42:36 +00:00
|
|
|
package proxycfg
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-02-17 17:46:03 +00:00
|
|
|
|
2023-07-10 21:08:06 +00:00
|
|
|
"github.com/mitchellh/go-testing-interface"
|
|
|
|
|
2023-02-16 19:42:36 +00:00
|
|
|
"github.com/hashicorp/consul/agent/connect"
|
|
|
|
"github.com/hashicorp/consul/agent/consul/discoverychain"
|
|
|
|
|
2023-03-30 14:08:38 +00:00
|
|
|
"github.com/hashicorp/consul/agent/configentry"
|
2023-02-16 19:42:36 +00:00
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestConfigSnapshotAPIGateway(
|
|
|
|
t testing.T,
|
|
|
|
variation string,
|
|
|
|
nsFn func(ns *structs.NodeService),
|
|
|
|
configFn func(entry *structs.APIGatewayConfigEntry, boundEntry *structs.BoundAPIGatewayConfigEntry),
|
|
|
|
routes []structs.BoundRoute,
|
2023-02-17 17:46:03 +00:00
|
|
|
certificates []structs.InlineCertificateConfigEntry,
|
2023-02-16 19:42:36 +00:00
|
|
|
extraUpdates []UpdateEvent,
|
|
|
|
additionalEntries ...structs.ConfigEntry,
|
|
|
|
) *ConfigSnapshot {
|
|
|
|
roots, placeholderLeaf := TestCerts(t)
|
|
|
|
|
|
|
|
entry := &structs.APIGatewayConfigEntry{
|
|
|
|
Kind: structs.APIGateway,
|
|
|
|
Name: "api-gateway",
|
|
|
|
}
|
|
|
|
boundEntry := &structs.BoundAPIGatewayConfigEntry{
|
|
|
|
Kind: structs.BoundAPIGateway,
|
|
|
|
Name: "api-gateway",
|
|
|
|
}
|
|
|
|
|
|
|
|
if configFn != nil {
|
|
|
|
configFn(entry, boundEntry)
|
|
|
|
}
|
|
|
|
|
|
|
|
baseEvents := []UpdateEvent{
|
|
|
|
{
|
|
|
|
CorrelationID: rootsWatchID,
|
|
|
|
Result: roots,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
CorrelationID: leafWatchID,
|
|
|
|
Result: placeholderLeaf,
|
|
|
|
},
|
|
|
|
{
|
2023-07-10 21:08:06 +00:00
|
|
|
CorrelationID: apiGatewayConfigWatchID,
|
2023-02-16 19:42:36 +00:00
|
|
|
Result: &structs.ConfigEntryResponse{
|
|
|
|
Entry: entry,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2023-07-10 21:08:06 +00:00
|
|
|
CorrelationID: boundGatewayConfigWatchID,
|
2023-02-16 19:42:36 +00:00
|
|
|
Result: &structs.ConfigEntryResponse{
|
|
|
|
Entry: boundEntry,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, route := range routes {
|
|
|
|
// Add the watch event for the route.
|
|
|
|
watch := UpdateEvent{
|
|
|
|
CorrelationID: routeConfigWatchID,
|
|
|
|
Result: &structs.ConfigEntryResponse{
|
|
|
|
Entry: route,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
baseEvents = append(baseEvents, watch)
|
|
|
|
|
|
|
|
// Add the watch event for the discovery chain.
|
|
|
|
entries := []structs.ConfigEntry{
|
|
|
|
&structs.ProxyConfigEntry{
|
|
|
|
Kind: structs.ProxyDefaults,
|
|
|
|
Name: structs.ProxyConfigGlobal,
|
|
|
|
Config: map[string]interface{}{
|
|
|
|
"protocol": route.GetProtocol(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&structs.ServiceResolverConfigEntry{
|
|
|
|
Kind: structs.ServiceResolver,
|
|
|
|
Name: "api-gateway",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-03-30 14:08:38 +00:00
|
|
|
set := configentry.NewDiscoveryChainSet()
|
|
|
|
set.AddEntries(entries...)
|
|
|
|
|
2023-02-16 19:42:36 +00:00
|
|
|
// Add a discovery chain watch event for each service.
|
|
|
|
for _, serviceName := range route.GetServiceNames() {
|
|
|
|
discoChain := UpdateEvent{
|
|
|
|
CorrelationID: fmt.Sprintf("discovery-chain:%s", UpstreamIDString("", "", serviceName.Name, &serviceName.EnterpriseMeta, "")),
|
|
|
|
Result: &structs.DiscoveryChainResponse{
|
2023-03-30 14:08:38 +00:00
|
|
|
Chain: discoverychain.TestCompileConfigEntries(t, serviceName.Name, "default", "default", "dc1", connect.TestClusterID+".consul", nil, set),
|
2023-02-16 19:42:36 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
baseEvents = append(baseEvents, discoChain)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-17 17:46:03 +00:00
|
|
|
for _, certificate := range certificates {
|
|
|
|
inlineCertificate := certificate
|
|
|
|
baseEvents = append(baseEvents, UpdateEvent{
|
|
|
|
CorrelationID: inlineCertificateConfigWatchID,
|
|
|
|
Result: &structs.ConfigEntryResponse{
|
|
|
|
Entry: &inlineCertificate,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-03-22 18:56:18 +00:00
|
|
|
upstreams := structs.TestUpstreams(t, false)
|
2023-02-16 19:42:36 +00:00
|
|
|
|
|
|
|
baseEvents = testSpliceEvents(baseEvents, setupTestVariationConfigEntriesAndSnapshot(
|
2023-03-24 20:40:19 +00:00
|
|
|
t, variation, false, upstreams, additionalEntries...,
|
2023-02-16 19:42:36 +00:00
|
|
|
))
|
|
|
|
|
|
|
|
return testConfigSnapshotFixture(t, &structs.NodeService{
|
|
|
|
Kind: structs.ServiceKindAPIGateway,
|
|
|
|
Service: "api-gateway",
|
|
|
|
Address: "1.2.3.4",
|
|
|
|
Meta: nil,
|
|
|
|
TaggedAddresses: nil,
|
|
|
|
}, nsFn, nil, testSpliceEvents(baseEvents, extraUpdates))
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestConfigSnapshotAPIGateway_NilConfigEntry is used to test when
|
|
|
|
// the update event for the config entry returns nil
|
|
|
|
// since this always happens on the first watch if it doesn't exist.
|
|
|
|
func TestConfigSnapshotAPIGateway_NilConfigEntry(
|
|
|
|
t testing.T,
|
|
|
|
) *ConfigSnapshot {
|
|
|
|
roots, _ := TestCerts(t)
|
|
|
|
|
|
|
|
baseEvents := []UpdateEvent{
|
|
|
|
{
|
|
|
|
CorrelationID: rootsWatchID,
|
|
|
|
Result: roots,
|
|
|
|
},
|
|
|
|
{
|
2023-07-10 21:08:06 +00:00
|
|
|
CorrelationID: apiGatewayConfigWatchID,
|
2023-02-16 19:42:36 +00:00
|
|
|
Result: &structs.ConfigEntryResponse{
|
|
|
|
Entry: nil, // The first watch on a config entry will return nil if the config entry doesn't exist.
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2023-07-10 21:08:06 +00:00
|
|
|
CorrelationID: boundGatewayConfigWatchID,
|
2023-02-16 19:42:36 +00:00
|
|
|
Result: &structs.ConfigEntryResponse{
|
|
|
|
Entry: nil, // The first watch on a config entry will return nil if the config entry doesn't exist.
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
return testConfigSnapshotFixture(t, &structs.NodeService{
|
|
|
|
Kind: structs.ServiceKindAPIGateway,
|
|
|
|
Service: "api-gateway",
|
|
|
|
Address: "1.2.3.4",
|
|
|
|
Meta: nil,
|
|
|
|
TaggedAddresses: nil,
|
|
|
|
}, nil, nil, testSpliceEvents(baseEvents, nil))
|
|
|
|
}
|