diff --git a/agent/consul/state/config_entry.go b/agent/consul/state/config_entry.go index 195cc3b913..e2cd8600f1 100644 --- a/agent/consul/state/config_entry.go +++ b/agent/consul/state/config_entry.go @@ -603,6 +603,10 @@ func validateProposedConfigEntryInServiceGraph( wildcardEntMeta := kindName.WithWildcardNamespace() switch kindName.Kind { + case structs.ExportedServices, structs.MeshConfig: + // Exported services and mesh config do not influence discovery chains. + return nil + case structs.ProxyDefaults: // Check anything that has a discovery chain entry. In the future we could // somehow omit the ones that have a default protocol configured. @@ -1414,52 +1418,6 @@ func configEntryWithOverridesTxn( return configEntryTxn(tx, ws, kind, name, entMeta) } -// getExportedServicesConfigEntriesTxn fetches exported-service config entries and -// filters their exported services to only those that match serviceName and entMeta. -// Because the resulting config entries may have had their exported services modified, -// they *should not* be used in subsequent writes. -func getExportedServiceConfigEntriesTxn( - tx ReadTxn, - ws memdb.WatchSet, - serviceName string, - entMeta *acl.EnterpriseMeta, -) (uint64, []*structs.ExportedServicesConfigEntry, error) { - var exportedServicesEntries []*structs.ExportedServicesConfigEntry - // slice of names to match config entries against - matchCandidates := getExportedServicesMatchServiceNames(serviceName, entMeta) - // matcher func generator for currying the matcher func over EnterpriseMeta values - // from the associated config entry - matchFunc := func(matchMeta *acl.EnterpriseMeta) func(structs.ExportedService) bool { - return func(exportedService structs.ExportedService) bool { - matchSvcName := structs.NewServiceName(exportedService.Name, matchMeta) - for _, candidate := range matchCandidates { - if candidate.Matches(matchSvcName) { - return true - } - } - return false - } - } - idx, entries, err := configEntriesByKindTxn(tx, ws, structs.ExportedServices, entMeta) - if err != nil { - return 0, nil, err - } - for _, entry := range entries { - esEntry, ok := entry.(*structs.ExportedServicesConfigEntry) - if !ok { - return 0, nil, fmt.Errorf("type %T is not a %s config entry", esEntry, structs.ExportedServices) - } - // get a copy of the config entry with Services filtered to match serviceName - newEntry := filterExportedServices(esEntry, matchFunc(entry.GetEnterpriseMeta())) - // the filter will return a new entry, so checking to see if its services is empty says that there - // were matches and that we should include it in the results - if len(newEntry.Services) > 0 { - exportedServicesEntries = append(exportedServicesEntries, newEntry) - } - } - return idx, exportedServicesEntries, nil -} - // protocolForService returns the service graph protocol associated to the // provided service, checking all relevant config entries. func protocolForService( @@ -1502,23 +1460,6 @@ func protocolForService( return maxIdx, chain.Protocol, nil } -// filterExportedServices returns the slice of ExportedService that matc ffor matching service names -// returning a copy of entry with only the services that match one of the -// services in candidates. -func filterExportedServices( - entry *structs.ExportedServicesConfigEntry, - testFunc func(structs.ExportedService) bool, -) *structs.ExportedServicesConfigEntry { - newEntry := *entry - newEntry.Services = []structs.ExportedService{} - for _, ceSvc := range entry.Services { - if testFunc(ceSvc) { - newEntry.Services = append(newEntry.Services, ceSvc) - } - } - return &newEntry -} - func newConfigEntryQuery(c structs.ConfigEntry) configentry.KindName { return configentry.NewKindName(c.GetKind(), c.GetName(), c.GetEnterpriseMeta()) } diff --git a/agent/consul/state/config_entry_oss_test.go b/agent/consul/state/config_entry_oss_test.go index 9f6a1ef44d..4d121ba32d 100644 --- a/agent/consul/state/config_entry_oss_test.go +++ b/agent/consul/state/config_entry_oss_test.go @@ -40,120 +40,124 @@ func testIndexerTableConfigEntries() map[string]indexerTestCase { } } -func TestStore_ExportedServices(t *testing.T) { +func TestStore_peersForService(t *testing.T) { + queryName := "foo" + type testCase struct { name string - write []structs.ConfigEntry - query string - expect []*structs.ExportedServicesConfigEntry + write structs.ConfigEntry + expect []string } cases := []testCase{ { name: "empty everything", - write: []structs.ConfigEntry{}, - query: "foo", - expect: []*structs.ExportedServicesConfigEntry{}, + expect: nil, }, { - name: "no matching exported services", - write: []structs.ConfigEntry{ - &structs.ProxyConfigEntry{Name: "foo"}, - &structs.ProxyConfigEntry{Name: "bar"}, - &structs.ExportedServicesConfigEntry{ - Name: "baz", - Services: []structs.ExportedService{ - {Name: "baz"}, + name: "service is not exported", + write: &structs.ExportedServicesConfigEntry{ + Name: "default", + Services: []structs.ExportedService{ + { + Name: "not-" + queryName, + Consumers: []structs.ServiceConsumer{ + { + PeerName: "zip", + }, + }, }, }, }, - query: "foo", - expect: []*structs.ExportedServicesConfigEntry{}, + expect: nil, }, { - name: "exact match service name", - write: []structs.ConfigEntry{ - &structs.ExportedServicesConfigEntry{ - Name: "foo", - Services: []structs.ExportedService{ - {Name: "foo"}, + name: "wildcard name matches", + write: &structs.ExportedServicesConfigEntry{ + Name: "default", + Services: []structs.ExportedService{ + { + Name: "not-" + queryName, + Consumers: []structs.ServiceConsumer{ + { + PeerName: "zip", + }, + }, }, - }, - &structs.ExportedServicesConfigEntry{ - Name: "bar", - Services: []structs.ExportedService{ - {Name: "bar"}, - }, - }, - }, - query: "bar", - expect: []*structs.ExportedServicesConfigEntry{ - { - Name: "bar", - Services: []structs.ExportedService{ - {Name: "bar"}, + { + Name: structs.WildcardSpecifier, + Consumers: []structs.ServiceConsumer{ + { + PeerName: "bar", + }, + { + PeerName: "baz", + }, + }, }, }, }, + expect: []string{"bar", "baz"}, }, { - name: "wildcard match on service name", - write: []structs.ConfigEntry{ - &structs.ExportedServicesConfigEntry{ - Name: "foo", - Services: []structs.ExportedService{ - {Name: "foo"}, + name: "exact name takes precedence over wildcard", + write: &structs.ExportedServicesConfigEntry{ + Name: "default", + Services: []structs.ExportedService{ + { + Name: queryName, + Consumers: []structs.ServiceConsumer{ + { + PeerName: "baz", + }, + }, }, - }, - &structs.ExportedServicesConfigEntry{ - Name: "wildcard", - Services: []structs.ExportedService{ - {Name: structs.WildcardSpecifier}, - }, - }, - }, - query: "foo", - expect: []*structs.ExportedServicesConfigEntry{ - { - Name: "foo", - Services: []structs.ExportedService{ - {Name: "foo"}, - }, - }, - { - Name: "wildcard", - Services: []structs.ExportedService{ - {Name: structs.WildcardSpecifier}, + { + Name: structs.WildcardSpecifier, + Consumers: []structs.ServiceConsumer{ + { + PeerName: "zip", + }, + }, }, }, }, + expect: []string{"baz"}, }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { s := testStateStore(t) + var lastIdx uint64 - // Write the entries. - for idx, entry := range tc.write { - require.NoError(t, s.EnsureConfigEntry(uint64(idx+1), entry)) + // Write the entry. + if tc.write != nil { + require.NoError(t, tc.write.Normalize()) + require.NoError(t, tc.write.Validate()) + + lastIdx++ + require.NoError(t, s.EnsureConfigEntry(lastIdx, tc.write)) } // Read the entries back. tx := s.db.ReadTxn() defer tx.Abort() - idx, entries, err := getExportedServiceConfigEntriesTxn(tx, nil, tc.query, acl.DefaultEnterpriseMeta()) + + idx, peers, err := peersForServiceTxn(tx, nil, queryName, acl.DefaultEnterpriseMeta()) require.NoError(t, err) - require.Equal(t, uint64(len(tc.write)), idx) + + // This is a little weird, but when there are no results, the index returned should be the max index for the + // config entries table so that the caller can watch for changes to it + if len(peers) == 0 { + require.Equal(t, maxIndexTxn(tx, tableConfigEntries), idx) + } else { + require.Equal(t, lastIdx, idx) + } // Verify the result. - require.Len(t, entries, len(tc.expect)) - for idx, got := range entries { - // ignore raft fields - got.ModifyIndex = 0 - got.CreateIndex = 0 - require.Equal(t, tc.expect[idx], got) - } + require.Len(t, peers, len(tc.expect)) + require.Equal(t, tc.expect, peers) }) } } diff --git a/agent/consul/state/peering.go b/agent/consul/state/peering.go index e566532b68..835e9642dc 100644 --- a/agent/consul/state/peering.go +++ b/agent/consul/state/peering.go @@ -439,35 +439,37 @@ func (s *Store) exportedServicesForPeerTxn(ws memdb.WatchSet, tx ReadTxn, peerin // PeeringsForService returns the list of peerings that are associated with the service name provided in the query. // This is used to configure connect proxies for a given service. The result is generated by querying for exported // service config entries and filtering for those that match the given service. +// // TODO(peering): this implementation does all of the work on read to materialize this list of peerings, we should explore // writing to a separate index that has service peerings prepared ahead of time should this become a performance bottleneck. func (s *Store) PeeringsForService(ws memdb.WatchSet, serviceName string, entMeta acl.EnterpriseMeta) (uint64, []*pbpeering.Peering, error) { tx := s.db.ReadTxn() defer tx.Abort() - // short-circuit if the service does not exist in the context of the query -- this prevents "leaking" services + // Short-circuit if the service does not exist in the context of the query -- this prevents "leaking" services // when there are wildcard rules in place. if svcIdx, svcExists, err := serviceExists(tx, ws, serviceName, &entMeta, ""); err != nil { return 0, nil, fmt.Errorf("failed to check if service exists: %w", err) + } else if !svcExists { - // if the service does not exist, return the max index for the services table so caller can watch for changes + // If the service does not exist, return the max index for the services table so caller can watch for changes. return svcIdx, nil, nil + } - // config entries must be defined in the default namespace, so we only need the partition here - meta := structs.DefaultEnterpriseMetaInPartition(entMeta.PartitionOrDefault()) - // return the idx of the config entry that was last modified so caller can watch for changes - idx, peeredServices, err := readPeeredServicesFromConfigEntriesTxn(tx, ws, serviceName, meta) + + // Return the idx of the config entry so the caller can watch for changes. + idx, peerNames, err := peersForServiceTxn(tx, ws, serviceName, &entMeta) if err != nil { - return 0, nil, fmt.Errorf("failed to read peered services for service name: %w", err) + return 0, nil, fmt.Errorf("failed to read peers for service name %q: %w", serviceName, err) } var peerings []*pbpeering.Peering - // lookup the peering for each matching peered service - for _, peeredService := range peeredServices { + // Lookup and return the peering corresponding to each name. + for _, name := range peerNames { readQuery := Query{ - Value: peeredService.PeerName, - EnterpriseMeta: peeredService.Name.EnterpriseMeta, + Value: name, + EnterpriseMeta: *structs.NodeEnterpriseMetaInPartition(entMeta.PartitionOrDefault()), } _, peering, err := peeringReadTxn(tx, ws, readQuery) if err != nil { @@ -478,7 +480,6 @@ func (s *Store) PeeringsForService(ws memdb.WatchSet, serviceName string, entMet } peerings = append(peerings, peering) } - // see note above about idx return idx, peerings, nil } @@ -597,50 +598,80 @@ func (r *Restore) PeeringTrustBundle(ptb *pbpeering.PeeringTrustBundle) error { return nil } -// readPeeredServicesFromConfigEntriesTxn queries exported-service config entries to return peers for serviceName -// in the form of a []structs.PeeredService. -func readPeeredServicesFromConfigEntriesTxn( +// peersForServiceTxn returns the names of all peers that a service is exported to. +func peersForServiceTxn( tx ReadTxn, ws memdb.WatchSet, serviceName string, entMeta *acl.EnterpriseMeta, -) (uint64, []structs.PeeredService, error) { - var results []structs.PeeredService +) (uint64, []string, error) { + // Exported service config entries are scoped to partitions so they are in the default namespace. + partitionMeta := structs.DefaultEnterpriseMetaInPartition(entMeta.PartitionOrDefault()) - // Get all exported-service config entries for that have exports for serviceName. This assumes the result - // has exported services filtered to only those matching serviceName so no futher filtering is needed. - idx, exportedServicesEntries, err := getExportedServiceConfigEntriesTxn(tx, ws, serviceName, entMeta) + idx, rawEntry, err := configEntryTxn(tx, ws, structs.ExportedServices, partitionMeta.PartitionOrDefault(), partitionMeta) if err != nil { return 0, nil, err } + if rawEntry == nil { + return idx, nil, err + } - // dedupe results by peer name - resultSet := make(map[string]struct{}) - // filter entries to only those that have a peer consumer defined - for _, entry := range exportedServicesEntries { - for _, service := range entry.Services { - // entries must have consumers - if service.Consumers == nil || len(service.Consumers) == 0 { - continue - } - for _, consumer := range service.Consumers { - // and consumers must have a peer - if consumer.PeerName == "" { - continue - } - // if we get here, we have a peer consumer, but we should dedupe peer names, so skip if it's already in the set - if _, ok := resultSet[consumer.PeerName]; ok { - continue - } + entry, ok := rawEntry.(*structs.ExportedServicesConfigEntry) + if !ok { + return 0, nil, fmt.Errorf("unexpected type %T for pbpeering.Peering index", rawEntry) + } - // if we got here, we can add to the result set - resultSet[consumer.PeerName] = struct{}{} - result := structs.PeeredService{ - Name: structs.NewServiceName(serviceName, entry.GetEnterpriseMeta()), - PeerName: consumer.PeerName, - } - results = append(results, result) - } + var ( + wildcardNamespaceIdx = -1 + wildcardServiceIdx = -1 + exactMatchIdx = -1 + ) + + // Ensure the metadata is defaulted since we make assertions against potentially empty values below. + // In OSS this is a no-op. + if entMeta == nil { + entMeta = acl.DefaultEnterpriseMeta() + } + entMeta.Normalize() + + // Services can be exported via wildcards or by their exact name: + // Namespace: *, Service: * + // Namespace: Exact, Service: * + // Namespace: Exact, Service: Exact + for i, service := range entry.Services { + switch { + case service.Namespace == structs.WildcardSpecifier: + wildcardNamespaceIdx = i + + case service.Name == structs.WildcardSpecifier && service.Namespace == entMeta.NamespaceOrEmpty(): + wildcardServiceIdx = i + + case service.Name == serviceName && service.Namespace == entMeta.NamespaceOrEmpty(): + exactMatchIdx = i + } + } + + var results []string + + // Prefer the exact match over the wildcard match. This matches how we handle intention precedence. + var targetIdx int + switch { + case exactMatchIdx >= 0: + targetIdx = exactMatchIdx + + case wildcardServiceIdx >= 0: + targetIdx = wildcardServiceIdx + + case wildcardNamespaceIdx >= 0: + targetIdx = wildcardNamespaceIdx + + default: + return idx, results, nil + } + + for _, c := range entry.Services[targetIdx].Consumers { + if c.PeerName != "" { + results = append(results, c.PeerName) } } return idx, results, nil diff --git a/agent/consul/state/peering_test.go b/agent/consul/state/peering_test.go index 53b80cb9c8..018cf81642 100644 --- a/agent/consul/state/peering_test.go +++ b/agent/consul/state/peering_test.go @@ -907,7 +907,7 @@ func TestStateStore_PeeringsForService(t *testing.T) { name string services []structs.ServiceName peerings []*pbpeering.Peering - entries []*structs.ExportedServicesConfigEntry + entry *structs.ExportedServicesConfigEntry query []string expect [][]*pbpeering.Peering expectIdx uint64 @@ -945,9 +945,10 @@ func TestStateStore_PeeringsForService(t *testing.T) { } // Write the config entries. - for _, entry := range tc.entries { + if tc.entry != nil { lastIdx++ - require.NoError(t, s.EnsureConfigEntry(lastIdx, entry)) + require.NoError(t, tc.entry.Normalize()) + require.NoError(t, s.EnsureConfigEntry(lastIdx, tc.entry)) } // Query for peers. @@ -976,7 +977,7 @@ func TestStateStore_PeeringsForService(t *testing.T) { {Name: "foo"}, }, peerings: []*pbpeering.Peering{}, - entries: []*structs.ExportedServicesConfigEntry{}, + entry: nil, query: []string{"foo"}, expect: [][]*pbpeering.Peering{{}}, }, @@ -986,7 +987,7 @@ func TestStateStore_PeeringsForService(t *testing.T) { {Name: "foo"}, }, peerings: []*pbpeering.Peering{}, - entries: []*structs.ExportedServicesConfigEntry{}, + entry: nil, query: []string{"bar"}, expect: [][]*pbpeering.Peering{{}}, expectIdx: uint64(2), // catalog services max index @@ -1001,24 +1002,22 @@ func TestStateStore_PeeringsForService(t *testing.T) { {Name: "peer1", State: pbpeering.PeeringState_INITIAL}, {Name: "peer2", State: pbpeering.PeeringState_INITIAL}, }, - entries: []*structs.ExportedServicesConfigEntry{ - { - Name: "ce1", - Services: []structs.ExportedService{ - { - Name: "foo", - Consumers: []structs.ServiceConsumer{ - { - PeerName: "peer1", - }, + entry: &structs.ExportedServicesConfigEntry{ + Name: "default", + Services: []structs.ExportedService{ + { + Name: "foo", + Consumers: []structs.ServiceConsumer{ + { + PeerName: "peer1", }, }, - { - Name: "bar", - Consumers: []structs.ServiceConsumer{ - { - PeerName: "peer2", - }, + }, + { + Name: "bar", + Consumers: []structs.ServiceConsumer{ + { + PeerName: "peer2", }, }, }, @@ -1046,27 +1045,25 @@ func TestStateStore_PeeringsForService(t *testing.T) { {Name: "peer2", State: pbpeering.PeeringState_INITIAL}, {Name: "peer3", State: pbpeering.PeeringState_INITIAL}, }, - entries: []*structs.ExportedServicesConfigEntry{ - { - Name: "ce1", - Services: []structs.ExportedService{ - { - Name: "*", - Consumers: []structs.ServiceConsumer{ - { - PeerName: "peer1", - }, - { - PeerName: "peer2", - }, + entry: &structs.ExportedServicesConfigEntry{ + Name: "default", + Services: []structs.ExportedService{ + { + Name: "*", + Consumers: []structs.ServiceConsumer{ + { + PeerName: "peer1", + }, + { + PeerName: "peer2", }, }, - { - Name: "bar", - Consumers: []structs.ServiceConsumer{ - { - PeerName: "peer3", - }, + }, + { + Name: "bar", + Consumers: []structs.ServiceConsumer{ + { + PeerName: "peer3", }, }, }, @@ -1079,8 +1076,6 @@ func TestStateStore_PeeringsForService(t *testing.T) { {Name: "peer2", State: pbpeering.PeeringState_INITIAL}, }, { - {Name: "peer1", State: pbpeering.PeeringState_INITIAL}, - {Name: "peer2", State: pbpeering.PeeringState_INITIAL}, {Name: "peer3", State: pbpeering.PeeringState_INITIAL}, }, }, diff --git a/agent/rpc/peering/service_test.go b/agent/rpc/peering/service_test.go index 0d30987da5..c1bb121ec0 100644 --- a/agent/rpc/peering/service_test.go +++ b/agent/rpc/peering/service_test.go @@ -359,24 +359,22 @@ func TestPeeringService_TrustBundleRead(t *testing.T) { } func TestPeeringService_TrustBundleListByService(t *testing.T) { - // test executes the following scenario: - // 0 - initial setup test server, state store, RPC client, verify empty results - // 1 - create a service, verify results still empty - // 2 - create a peering, verify results still empty - // 3 - create a config entry, verify results still empty - // 4 - create trust bundles, verify bundles are returned - // 5 - delete the config entry, verify results empty - // 6 - restore config entry, verify bundles are returned - // 7 - add peering, trust bundles, wildcard config entry, verify updated results are present - // 8 - delete first config entry, verify bundles are returned - // 9 - delete the service, verify results empty + // Test executes the following scenario: + // 0 - Initial setup test server, state store, RPC client, verify empty results + // 1 - Create a service, verify results still empty + // 2 - Create a peering, verify results still empty + // 3 - Create a config entry, verify results still empty + // 4 - Create trust bundles, verify bundles are returned + // 5 - Delete the config entry, verify results empty + // 6 - Restore config entry, verify bundles are returned + // 7 - Add a second peering that the test service is not exported to + // 8 - Export the service to the new peering + // 9 - Delete the service // Note: these steps are dependent on each other by design so that we can verify that // combinations of services, peerings, trust bundles, and config entries all affect results - // fixed for the test nodeName := "test-node" - // keep track of index across steps var lastIdx uint64 // Create test server @@ -445,6 +443,7 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { // Write any config entries for _, entry := range deps.entries { idx++ + require.NoError(t, entry.Normalize()) require.NoError(t, store.EnsureConfigEntry(idx, entry)) } @@ -460,6 +459,8 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { // TODO(peering): see note on newTestServer, once we have a better server mock, // we should add functionality here to verify errors from backend verify := func(t *testing.T, tc *testCase) { + t.Helper() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) t.Cleanup(cancel) @@ -478,7 +479,7 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { // Execute scenario steps // ---------------------- - // 0 - initial empty state + // 0 - Initial empty state. // ----------------------- verify(t, &testCase{ req: &pbpeering.TrustBundleListByServiceRequest{ @@ -489,7 +490,7 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { }, }) - // 1 - create a service, verify results still empty + // 1 - Create a service, verify results still empty. // ------------------------------------------------ lastIdx = setup(t, lastIdx, testDeps{services: []string{"foo"}}) verify(t, &testCase{ @@ -501,7 +502,7 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { }, }) - // 2 - create a peering, verify results still empty + // 2 - Create a peering, verify results still empty. // ------------------------------------------------ lastIdx = setup(t, lastIdx, testDeps{ peerings: []*pbpeering.Peering{ @@ -522,12 +523,12 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { }, }) - // 3 - create a config entry, verify results still empty + // 3 - Create a config entry, verify results still empty. // ----------------------------------------------------- lastIdx = setup(t, lastIdx, testDeps{ entries: []*structs.ExportedServicesConfigEntry{ { - Name: "export-foo", + Name: "default", Services: []structs.ExportedService{ { Name: "foo", @@ -550,7 +551,7 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { }, }) - // 4 - create trust bundles, verify bundles are returned + // 4 - Create trust bundles, verify bundles are returned. // ----------------------------------------------------- lastIdx = setup(t, lastIdx, testDeps{ bundles: []*pbpeering.PeeringTrustBundle{ @@ -576,10 +577,10 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { }, }) - // 5 - delete the config entry, verify results empty + // 5 - Delete the config entry, verify results empty. // ------------------------------------------------- lastIdx++ - require.NoError(t, store.DeleteConfigEntry(lastIdx, structs.ExportedServices, "export-foo", nil)) + require.NoError(t, store.DeleteConfigEntry(lastIdx, structs.ExportedServices, "default", nil)) verify(t, &testCase{ req: &pbpeering.TrustBundleListByServiceRequest{ ServiceName: "foo", @@ -589,12 +590,12 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { }, }) - // 6 - restore config entry, verify bundles are returned + // 6 - Restore config entry, verify bundles are returned. // ----------------------------------------------------- lastIdx = setup(t, lastIdx, testDeps{ entries: []*structs.ExportedServicesConfigEntry{ { - Name: "export-foo", + Name: "default", Services: []structs.ExportedService{ { Name: "foo", @@ -621,10 +622,9 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { }, }) - // 7 - add peering, trust bundles, wildcard config entry, verify updated results are present + // 7 - Add new peer and trust bundle. It should be ignored because foo is not exported to it. // ----------------------------------------------------------------------------------------- lastIdx = setup(t, lastIdx, testDeps{ - services: []string{"bar"}, peerings: []*pbpeering.Peering{ { Name: "peer2", @@ -633,20 +633,6 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { PeerServerAddresses: []string{"peer2-addr"}, }, }, - entries: []*structs.ExportedServicesConfigEntry{ - { - Name: "export-all", - Services: []structs.ExportedService{ - { - Name: structs.WildcardSpecifier, - Consumers: []structs.ServiceConsumer{ - {PeerName: "peer1"}, - {PeerName: "peer2"}, - }, - }, - }, - }, - }, bundles: []*pbpeering.PeeringTrustBundle{ { TrustDomain: "peer2.com", @@ -666,18 +652,28 @@ func TestPeeringService_TrustBundleListByService(t *testing.T) { PeerName: "peer1", RootPEMs: []string{"peer1-root-1"}, }, - { - TrustDomain: "peer2.com", - PeerName: "peer2", - RootPEMs: []string{"peer2-root-1"}, - }, }, }, }) - // 8 - delete first config entry, verify bundles are returned - lastIdx++ - require.NoError(t, store.DeleteConfigEntry(lastIdx, structs.ExportedServices, "export-foo", nil)) + // 8 - Replace config entry to export all services to both peers + // ----------------------------------------------------------------------------------------- + lastIdx = setup(t, lastIdx, testDeps{ + entries: []*structs.ExportedServicesConfigEntry{ + { + Name: "default", + Services: []structs.ExportedService{ + { + Name: structs.WildcardSpecifier, + Consumers: []structs.ServiceConsumer{ + {PeerName: "peer1"}, + {PeerName: "peer2"}, + }, + }, + }, + }, + }, + }) verify(t, &testCase{ req: &pbpeering.TrustBundleListByServiceRequest{ ServiceName: "foo", diff --git a/agent/structs/peering.go b/agent/structs/peering.go index bd0351bb36..1cf74bdaad 100644 --- a/agent/structs/peering.go +++ b/agent/structs/peering.go @@ -8,12 +8,6 @@ type PeeringToken struct { PeerID string } -// PeeredService is a service that has been configured with an exported-service config entry to be exported to a peer. -type PeeredService struct { - Name ServiceName - PeerName string -} - // NOTE: this is not serialized via msgpack so it can be changed without concern. type ExportedServiceList struct { // Services is a list of exported services that apply to both standard