Skip to content

Commit 14965b7

Browse files
authored
Merge pull request #1940 from hashicorp/partitions-func
2 parents dda754c + d4c801b commit 14965b7

16 files changed

+721
-73
lines changed

dependency/catalog_datacenters.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var (
1919

2020
// CatalogDatacentersQuerySleepTime is the amount of time to sleep between
2121
// queries, since the endpoint does not support blocking queries.
22-
CatalogDatacentersQuerySleepTime = 15 * time.Second
22+
CatalogDatacentersQuerySleepTime = DefaultNonBlockingQuerySleepTime
2323
)
2424

2525
// CatalogDatacentersQuery is the dependency to query all datacenters

dependency/catalog_services.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ var (
1818
// Ensure implements
1919
_ Dependency = (*CatalogServicesQuery)(nil)
2020

21-
// CatalogServicesQueryRe is the regular expression to use for CatalogNodesQuery.
21+
// CatalogServicesQueryRe is the regular expression to use for CatalogServicesQuery.
2222
CatalogServicesQueryRe = regexp.MustCompile(`\A` + queryRe + dcRe + `\z`)
2323
)
2424

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package dependency
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net/url"
7+
"slices"
8+
9+
capi "github.com/hashicorp/consul/api"
10+
)
11+
12+
const exportedServicesEndpointLabel = "list.exportedServices"
13+
14+
// Ensure implements
15+
var _ Dependency = (*ListExportedServicesQuery)(nil)
16+
17+
// ListExportedServicesQuery is the representation of a requested exported services
18+
// dependency from inside a template.
19+
type ListExportedServicesQuery struct {
20+
stopCh chan struct{}
21+
partition string
22+
}
23+
24+
type ExportedService struct {
25+
// Name of the service
26+
Service string
27+
28+
// Partition of the service
29+
Partition string
30+
31+
// Namespace of the service
32+
Namespace string
33+
34+
// Consumers is a list of downstream consumers of the service.
35+
Consumers ResolvedConsumers
36+
}
37+
38+
type ResolvedConsumers struct {
39+
Peers []string
40+
Partitions []string
41+
SamenessGroups []string
42+
}
43+
44+
func fromConsulExportedService(svc capi.ExportedService) ExportedService {
45+
peers := make([]string, 0, len(svc.Consumers))
46+
partitions := make([]string, 0, len(svc.Consumers))
47+
samenessGroups := make([]string, 0, len(svc.Consumers))
48+
for _, consumer := range svc.Consumers {
49+
if consumer.Peer != "" {
50+
peers = append(peers, consumer.Peer)
51+
}
52+
if consumer.Partition != "" {
53+
partitions = append(partitions, consumer.Partition)
54+
}
55+
if consumer.SamenessGroup != "" {
56+
samenessGroups = append(samenessGroups, consumer.SamenessGroup)
57+
}
58+
}
59+
60+
return ExportedService{
61+
Service: svc.Name,
62+
Consumers: ResolvedConsumers{
63+
Peers: peers,
64+
Partitions: partitions,
65+
SamenessGroups: samenessGroups,
66+
},
67+
}
68+
}
69+
70+
// NewListExportedServicesQuery parses a string of the format @dc.
71+
func NewListExportedServicesQuery(s string) (*ListExportedServicesQuery, error) {
72+
return &ListExportedServicesQuery{
73+
stopCh: make(chan struct{}),
74+
partition: s,
75+
}, nil
76+
}
77+
78+
func (c *ListExportedServicesQuery) Fetch(clients *ClientSet, opts *QueryOptions) (interface{}, *ResponseMetadata, error) {
79+
select {
80+
case <-c.stopCh:
81+
return nil, nil, ErrStopped
82+
default:
83+
}
84+
85+
opts = opts.Merge(&QueryOptions{
86+
ConsulPartition: c.partition,
87+
})
88+
89+
log.Printf("[TRACE] %s: GET %s", c, &url.URL{
90+
Path: "/v1/config/exported-services",
91+
RawQuery: opts.String(),
92+
})
93+
94+
consulExportedServices, qm, err := clients.Consul().ConfigEntries().List(capi.ExportedServices, opts.ToConsulOpts())
95+
if err != nil {
96+
return nil, nil, fmt.Errorf("%s: %w", c.String(), err)
97+
}
98+
99+
exportedServices := make([]ExportedService, 0, len(consulExportedServices))
100+
for _, cfgEntry := range consulExportedServices {
101+
svc := cfgEntry.(*capi.ExportedServicesConfigEntry)
102+
for _, svc := range svc.Services {
103+
exportedServices = append(exportedServices, fromConsulExportedService(svc))
104+
}
105+
}
106+
107+
log.Printf("[TRACE] %s: returned %d results", c, len(exportedServices))
108+
109+
slices.SortStableFunc(exportedServices, func(i, j ExportedService) int {
110+
if i.Service < j.Service {
111+
return -1
112+
} else if i.Service > j.Service {
113+
return 1
114+
}
115+
return 0
116+
})
117+
118+
rm := &ResponseMetadata{
119+
LastContact: qm.LastContact,
120+
LastIndex: qm.LastIndex,
121+
}
122+
123+
return exportedServices, rm, nil
124+
}
125+
126+
// CanShare returns if this dependency is shareable when consul-template is running in de-duplication mode.
127+
func (c *ListExportedServicesQuery) CanShare() bool {
128+
return true
129+
}
130+
131+
func (c *ListExportedServicesQuery) String() string {
132+
return exportedServicesEndpointLabel
133+
}
134+
135+
func (c *ListExportedServicesQuery) Stop() {
136+
close(c.stopCh)
137+
}
138+
139+
func (c *ListExportedServicesQuery) Type() Type {
140+
return TypeConsul
141+
}

0 commit comments

Comments
 (0)