Allow setting of Consul ServiceMeta tags from config file (#11084)

* Allow setting of Consul ServiceMeta tags from config file

probably a bad idea, let's see how it works
scaffold tests

* kick circleci

* Add links to consul docs

Co-authored-by: Violet Hynes <a.xenasis@gmail.com>

* add changelog note

* use relative developer docs links

* address feedback

* please linter

---------

Co-authored-by: Violet Hynes <violet.hynes@hashicorp.com>
This commit is contained in:
Roberto Hidalgo
2024-05-27 14:28:10 -06:00
committed by GitHub
parent 4975e699e0
commit 6e72397a86
5 changed files with 85 additions and 3 deletions

3
changelog/11084.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:improvement
serviceregistration: Added support for Consul ServiceMeta tags from config file from the new `service_meta` config field.
```

View File

@@ -5,6 +5,7 @@ package consul
import (
"context"
"encoding/json"
"errors"
"fmt"
"math/rand"
@@ -73,6 +74,7 @@ type serviceRegistration struct {
redirectPort int64
serviceName string
serviceTags []string
serviceMeta map[string]string
serviceAddress *string
disableRegistration bool
checkTimeout time.Duration
@@ -229,6 +231,18 @@ func (c *serviceRegistration) merge(conf map[string]string) error {
c.logger.Debug("config service_tags set", "service_tags", tags)
}
// Get user-defined meta tags to attach to the registered service name
metaTags := map[string]string{}
if metaTagsJSON, ok := conf["service_meta"]; ok {
if err := json.Unmarshal([]byte(metaTagsJSON), &metaTags); err != nil {
return errors.New("service tags must be a dictionary of string keys and values")
}
}
metaTags["external-source"] = metaExternalSource
if c.logger.IsDebug() {
c.logger.Debug("config service_meta set", "service_meta", metaTags)
}
// Get the service-specific address to override the use of the HA redirect address
var serviceAddr *string
serviceAddrStr, ok := conf["service_address"]
@@ -294,6 +308,7 @@ func (c *serviceRegistration) merge(conf map[string]string) error {
c.config = consulConf
c.serviceName = service
c.serviceTags = strutil.ParseDedupAndSortStrings(tags, ",")
c.serviceMeta = metaTags
c.serviceAddress = serviceAddr
c.checkTimeout = checkTimeout
c.disableRegistration = disableRegistration
@@ -586,12 +601,10 @@ func (c *serviceRegistration) reconcileConsul() (serviceID string, err error) {
ID: serviceID,
Name: c.serviceName,
Tags: tags,
Meta: c.serviceMeta,
Port: int(c.redirectPort),
Address: serviceAddress,
EnableTagOverride: false,
Meta: map[string]string{
"external-source": metaExternalSource,
},
}
checkStatus := api.HealthCritical

View File

@@ -492,6 +492,66 @@ func TestConsul_serviceTags(t *testing.T) {
}
}
// TestConsul_ServiceMeta tests whether consul service meta registration works
func TestConsul_ServiceMeta(t *testing.T) {
tests := []struct {
conf map[string]string
pass bool
expect map[string]string
}{
{
conf: map[string]string{},
pass: true,
expect: map[string]string{"external-source": "vault"},
},
{
conf: map[string]string{"service_meta": "true"},
pass: false,
expect: map[string]string{"external-source": "vault"},
},
{
conf: map[string]string{"service_meta": "{\"key\":\"value\"}"},
pass: true,
expect: map[string]string{"key": "value", "external-source": "vault"},
},
{
conf: map[string]string{"service_meta": "{\"external-source\":\"something-else\"}"},
pass: true,
expect: map[string]string{"external-source": "vault"},
},
}
for _, test := range tests {
logger := logging.NewVaultLogger(log.Debug)
shutdownCh := make(chan struct{})
defer func() {
close(shutdownCh)
}()
sr, err := NewServiceRegistration(test.conf, logger, sr.State{})
if !test.pass {
if err == nil {
t.Fatal("Expected Consul to fail with error")
}
continue
}
if err != nil && test.pass {
t.Fatalf("Expected Consul to initialize: %v", err)
}
c, ok := sr.(*serviceRegistration)
if !ok {
t.Fatalf("Expected serviceRegistration")
}
if !reflect.DeepEqual(c.serviceMeta, test.expect) {
t.Fatalf("Did not produce expected meta: wanted: %v, got %v", test.expect, c.serviceMeta)
}
}
}
func TestConsul_setRedirectAddr(t *testing.T) {
tests := []struct {
addr string

View File

@@ -85,6 +85,9 @@ at Consul's service discovery layer.
- `service_tags` `(string: "")` Specifies a comma-separated list of case-sensitive
tags to attach to the service registration in Consul.
- `service_meta` `(map[string]string: {})` Specifies a key-value list of meta tags to
attach to the service registration in Consul. See [ServiceMeta](/consul/api-docs/catalog#servicemeta) in the Consul docs for more information.
- `service_address` `(string: nil)` Specifies a service-specific address to
set on the service registration in Consul. If unset, Vault will use what it
knows to be the HA redirect address - which is usually desirable. Setting

View File

@@ -92,6 +92,9 @@ and [`cluster_addr`][cluster-addr] ([example][listener-example]).
- `service_tags` `(string: "")` Specifies a comma-separated list of tags to
attach to the service registration in Consul.
- `service_meta` `(map[string]string: {})` Specifies a key-value list of meta tags to
attach to the service registration in Consul. See [ServiceMeta](/consul/api-docs/catalog#servicemeta) in the Consul docs for more information.
- `service_address` `(string: nil)` Specifies a service-specific address to
set on the service registration in Consul. If unset, Vault will use what it
knows to be the HA redirect address - which is usually desirable. Setting