Skip to content

Commit

Permalink
Merge pull request #1899 from hashicorp/jm/NET-5879
Browse files Browse the repository at this point in the history
NET-5879 - consul-template support for sameness groups
  • Loading branch information
jmurret authored Jun 18, 2024
2 parents 53a5f43 + b725045 commit 93de881
Show file tree
Hide file tree
Showing 10 changed files with 324 additions and 107 deletions.
6 changes: 3 additions & 3 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ issues:
exclude-rules:
- text: 'shadow: declaration of "(err|ctx)" shadows declaration at'
linters: [ govet ]
exclude-dirs-use-default: false

linters-settings:
govet:
Expand Down Expand Up @@ -78,7 +79,7 @@ linters-settings:
- github.com/hashicorp/logutils
- github.com/hashicorp/nomad/api
- github.com/hashicorp/vault/api
- github.com/imdario/mergo
- dario.cat/mergo
- github.com/mitchellh/go-homedir
- github.com/mitchellh/hashstructure
- github.com/mitchellh/mapstructure
Expand All @@ -88,5 +89,4 @@ linters-settings:

run:
timeout: 10m
concurrency: 4
skip-dirs-use-default: false
concurrency: 4
35 changes: 21 additions & 14 deletions dependency/dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,19 @@ type ServiceTags []string
// client-agnostic, and the dependency determines which, if any, of the options
// to use.
type QueryOptions struct {
AllowStale bool
Datacenter string
Region string
Near string
Choose string
RequireConsistent bool
VaultGrace time.Duration
WaitIndex uint64
WaitTime time.Duration
ConsulPeer string
ConsulPartition string
ConsulNamespace string
AllowStale bool
Datacenter string
Region string
Near string
Choose string
RequireConsistent bool
VaultGrace time.Duration
WaitIndex uint64
WaitTime time.Duration
ConsulPeer string
ConsulPartition string
ConsulNamespace string
ConsulSamenessGroup string
}

func (q *QueryOptions) Merge(o *QueryOptions) *QueryOptions {
Expand Down Expand Up @@ -150,6 +151,10 @@ func (q *QueryOptions) Merge(o *QueryOptions) *QueryOptions {
r.ConsulPeer = o.ConsulPeer
}

if o.ConsulSamenessGroup != "" {
r.ConsulSamenessGroup = o.ConsulSamenessGroup
}

return &r
}

Expand All @@ -159,6 +164,7 @@ func (q *QueryOptions) ToConsulOpts() *consulapi.QueryOptions {
Datacenter: q.Datacenter,
Namespace: q.ConsulNamespace,
Partition: q.ConsulPartition,
SamenessGroup: q.ConsulSamenessGroup,
Peer: q.ConsulPeer,
Near: q.Near,
RequireConsistent: q.RequireConsistent,
Expand All @@ -184,10 +190,11 @@ func GetConsulQueryOpts(queryMap map[string]string, endpointLabel string) (url.V
switch key {
case QueryNamespace,
QueryPeer,
QueryPartition:
QueryPartition,
QuerySamenessGroup:
default:
return nil,
fmt.Errorf("%s: invalid query parameter key %q in query %q: supported keys: %s,%s,%s", endpointLabel, key, queryRaw, QueryNamespace, QueryPeer, QueryPartition)
fmt.Errorf("%s: invalid query parameter key %q in query %q: supported keys: %s,%s,%s,%s", endpointLabel, key, queryRaw, QueryNamespace, QueryPeer, QueryPartition, QuerySamenessGroup)
}
}
}
Expand Down
65 changes: 42 additions & 23 deletions dependency/dependency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,11 @@ func TestMain(m *testing.M) {
Address: testConsul.HTTPAddr,
}); err != nil {
testConsul.Stop()
testVault.Stop()
testNomad.Stop()
Fatalf("failed to create consul client: %v\n", err)
}

if t, err := test.NewTenancyHelper(clients.Consul()); err != nil {
testConsul.Stop()
testVault.Stop()
testNomad.Stop()
stopTestClients()
Fatalf("failed to create tenancy helper: %v\n", err)
} else {
tenancyHelper = t
Expand All @@ -86,52 +82,46 @@ func TestMain(m *testing.M) {
if err := clients.CreateNomadClient(&CreateNomadClientInput{
Address: "http://127.0.0.1:4646",
}); err != nil {
testConsul.Stop()
testVault.Stop()
testNomad.Stop()
stopTestClients()
Fatalf("failed to create nomad client: %v\n", err)
}

testClients = clients

if err := testClients.createConsulPartitions(); err != nil {
testConsul.Stop()
testVault.Stop()
testNomad.Stop()
stopTestClients()
Fatalf("failed to create consul partitions: %v\n", err)
}

if err := testClients.createConsulNs(); err != nil {
testConsul.Stop()
testVault.Stop()
testNomad.Stop()
stopTestClients()
Fatalf("failed to create consul namespaces: %v\n", err)
}

setupVaultPKI(clients)

if err := testClients.createConsulTestResources(); err != nil {
testConsul.Stop()
testVault.Stop()
testNomad.Stop()
stopTestClients()
Fatalf("failed to create consul test resources: %v\n", err)
}

// Wait for Nomad initialization to finish
if err := <-nomadFuture; err != nil {
testConsul.Stop()
testNomad.Stop()
testVault.Stop()
stopTestClients()
Fatalf("failed to start Nomad: %v\n", err)
}

exit := m.Run()

tb.DoCleanup()
stopTestClients()
os.Exit(exit)
}

func stopTestClients() {
testConsul.Stop()
testVault.Stop()
testNomad.Stop()
os.Exit(exit)
}

func (c *ClientSet) createConsulTestResources() error {
Expand Down Expand Up @@ -239,6 +229,27 @@ func (c *ClientSet) createConsulTestResources() error {
return nil
}

func (c *ClientSet) createConsulSamenessGroups(name, partition, failoverPartition string) error {
members := append([]api.SamenessGroupMember{}, api.SamenessGroupMember{
Partition: partition,
}, api.SamenessGroupMember{
Partition: failoverPartition,
})
sg := &api.SamenessGroupConfigEntry{
Kind: api.SamenessGroup,
Name: name,
Partition: partition,
DefaultForFailover: true,
Members: members,
}
_, _, err := c.consul.client.ConfigEntries().Set(sg, &api.WriteOptions{})
if err != nil {
return err
}

return nil
}

func (c *ClientSet) createConsulPeerings(tenancy *test.Tenancy) error {
generateReq := api.PeeringGenerateTokenRequest{PeerName: "foo", Partition: tenancy.Partition}
_, _, err := c.consul.client.Peerings().GenerateToken(context.Background(), generateReq, &api.WriteOptions{})
Expand Down Expand Up @@ -545,8 +556,7 @@ func (v *nomadServer) DeleteVariable(path string, opts *nomadapi.WriteOptions) e
func (c *ClientSet) createConsulPartitions() error {
for p := range tenancyHelper.GetUniquePartitions() {
if p.Name != "" && p.Name != "default" {
partition := &api.Partition{Name: p.Name}
_, _, err := c.Consul().Partitions().Create(context.Background(), partition, nil)
err := c.createConsulPartition(p.Name)
if err != nil {
return err
}
Expand All @@ -556,6 +566,15 @@ func (c *ClientSet) createConsulPartitions() error {
return nil
}

func (c *ClientSet) createConsulPartition(name string) error {
partition := &api.Partition{Name: name}
_, _, err := c.Consul().Partitions().Create(context.Background(), partition, nil)
if err != nil {
return err
}
return nil
}

func (c *ClientSet) createConsulNs() error {
for _, tenancy := range tenancyHelper.TestTenancies() {
if tenancy.Namespace != "" && tenancy.Namespace != "default" {
Expand Down
71 changes: 42 additions & 29 deletions dependency/health_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ const (
HealthCritical = "critical"
HealthMaint = "maintenance"

QueryNamespace = "ns"
QueryPartition = "partition"
QueryPeer = "peer"
QueryNamespace = "ns"
QueryPartition = "partition"
QueryPeer = "peer"
QuerySamenessGroup = "sameness-group"

NodeMaint = "_node_maintenance"
ServiceMaint = "_service_maintenance:"
Expand Down Expand Up @@ -66,15 +67,16 @@ type HealthService struct {
type HealthServiceQuery struct {
stopCh chan struct{}

dc string
filters []string
name string
near string
tag string
connect bool
partition string
peer string
namespace string
dc string
filters []string
name string
near string
tag string
connect bool
partition string
peer string
namespace string
samenessGroup string
}

// NewHealthServiceQuery processes the strings to build a service dependency.
Expand Down Expand Up @@ -122,18 +124,25 @@ func healthServiceQuery(s string, connect bool) (*HealthServiceQuery, error) {
return nil, err
}

return &HealthServiceQuery{
stopCh: make(chan struct{}, 1),
dc: m["dc"],
filters: filters,
name: m["name"],
near: m["near"],
tag: m["tag"],
connect: connect,
namespace: queryParams.Get(QueryNamespace),
peer: queryParams.Get(QueryPeer),
partition: queryParams.Get(QueryPartition),
}, nil
if queryParams.Get(QuerySamenessGroup) != "" && queryParams.Get(QueryPeer) != "" {
return nil, fmt.Errorf("health.service: cannot specify both %s and %s", QueryPeer, QuerySamenessGroup)
}

qry := &HealthServiceQuery{
stopCh: make(chan struct{}, 1),
dc: m["dc"],
filters: filters,
name: m["name"],
near: m["near"],
tag: m["tag"],
connect: connect,
namespace: queryParams.Get(QueryNamespace),
peer: queryParams.Get(QueryPeer),
partition: queryParams.Get(QueryPartition),
samenessGroup: queryParams.Get(QuerySamenessGroup),
}

return qry, nil
}

// Fetch queries the Consul API defined by the given client and returns a slice
Expand All @@ -146,11 +155,12 @@ func (d *HealthServiceQuery) Fetch(clients *ClientSet, opts *QueryOptions) (inte
}

opts = opts.Merge(&QueryOptions{
Datacenter: d.dc,
Near: d.near,
ConsulNamespace: d.namespace,
ConsulPartition: d.partition,
ConsulPeer: d.peer,
Datacenter: d.dc,
Near: d.near,
ConsulNamespace: d.namespace,
ConsulPartition: d.partition,
ConsulPeer: d.peer,
ConsulSamenessGroup: d.samenessGroup,
})

u := &url.URL{
Expand Down Expand Up @@ -261,6 +271,9 @@ func (d *HealthServiceQuery) String() string {
if d.peer != "" {
name = name + "@peer=" + d.peer
}
if d.samenessGroup != "" {
name = name + "@sameness-group=" + d.samenessGroup
}
if d.near != "" {
name = name + "~" + d.near
}
Expand Down
Loading

0 comments on commit 93de881

Please sign in to comment.