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 ( import (
"context" "context"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"math/rand" "math/rand"
@@ -73,6 +74,7 @@ type serviceRegistration struct {
redirectPort int64 redirectPort int64
serviceName string serviceName string
serviceTags []string serviceTags []string
serviceMeta map[string]string
serviceAddress *string serviceAddress *string
disableRegistration bool disableRegistration bool
checkTimeout time.Duration 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) 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 // Get the service-specific address to override the use of the HA redirect address
var serviceAddr *string var serviceAddr *string
serviceAddrStr, ok := conf["service_address"] serviceAddrStr, ok := conf["service_address"]
@@ -294,6 +308,7 @@ func (c *serviceRegistration) merge(conf map[string]string) error {
c.config = consulConf c.config = consulConf
c.serviceName = service c.serviceName = service
c.serviceTags = strutil.ParseDedupAndSortStrings(tags, ",") c.serviceTags = strutil.ParseDedupAndSortStrings(tags, ",")
c.serviceMeta = metaTags
c.serviceAddress = serviceAddr c.serviceAddress = serviceAddr
c.checkTimeout = checkTimeout c.checkTimeout = checkTimeout
c.disableRegistration = disableRegistration c.disableRegistration = disableRegistration
@@ -586,12 +601,10 @@ func (c *serviceRegistration) reconcileConsul() (serviceID string, err error) {
ID: serviceID, ID: serviceID,
Name: c.serviceName, Name: c.serviceName,
Tags: tags, Tags: tags,
Meta: c.serviceMeta,
Port: int(c.redirectPort), Port: int(c.redirectPort),
Address: serviceAddress, Address: serviceAddress,
EnableTagOverride: false, EnableTagOverride: false,
Meta: map[string]string{
"external-source": metaExternalSource,
},
} }
checkStatus := api.HealthCritical 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) { func TestConsul_setRedirectAddr(t *testing.T) {
tests := []struct { tests := []struct {
addr string 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 - `service_tags` `(string: "")` Specifies a comma-separated list of case-sensitive
tags to attach to the service registration in Consul. 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 - `service_address` `(string: nil)` Specifies a service-specific address to
set on the service registration in Consul. If unset, Vault will use what it 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 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 - `service_tags` `(string: "")` Specifies a comma-separated list of tags to
attach to the service registration in Consul. 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 - `service_address` `(string: nil)` Specifies a service-specific address to
set on the service registration in Consul. If unset, Vault will use what it 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 knows to be the HA redirect address - which is usually desirable. Setting