Skip to content

Commit

Permalink
Introduce optional service_registration stanza (#7887)
Browse files Browse the repository at this point in the history
* move ServiceDiscovery into methods

* add ServiceDiscoveryFactory

* add serviceDiscovery field to vault.Core

* refactor ConsulServiceDiscovery into separate struct

* cleanup

* revert accidental change to go.mod

* cleanup

* get rid of un-needed struct tags in vault.CoreConfig

* add service_discovery parser

* add ServiceDiscovery to config

* cleanup

* cleanup

* add test for ConfigServiceDiscovery to Core

* unit testing for config service_discovery stanza

* cleanup

* get rid of un-needed redirect_addr stuff in service_discovery stanza

* improve test suite

* cleanup

* clean up test a bit

* create docs for service_discovery

* check if service_discovery is configured, but storage does not support HA

* tinker with test

* tinker with test

* tweak docs

* move ServiceDiscovery into its own package

* tweak a variable name

* fix comment

* rename service_discovery to service_registration

* tweak service_registration config

* Revert "tweak service_registration config"

This reverts commit 5509920.

* simplify naming

* refactor into ./serviceregistration/consul
  • Loading branch information
mjarmy authored Dec 6, 2019
1 parent 47cffd0 commit df01a43
Show file tree
Hide file tree
Showing 21 changed files with 1,991 additions and 968 deletions.
16 changes: 13 additions & 3 deletions command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ import (
physZooKeeper "github.com/hashicorp/vault/physical/zookeeper"
physFile "github.com/hashicorp/vault/sdk/physical/file"
physInmem "github.com/hashicorp/vault/sdk/physical/inmem"

sr "github.com/hashicorp/vault/serviceregistration"
csr "github.com/hashicorp/vault/serviceregistration/consul"
)

const (
Expand Down Expand Up @@ -155,6 +158,10 @@ var (
"raft": physRaft.NewRaftBackend,
"zookeeper": physZooKeeper.NewZooKeeperBackend,
}

serviceRegistrations = map[string]sr.Factory{
"consul": csr.NewConsulServiceRegistration,
}
)

// Commands is the mapping of all the available commands.
Expand Down Expand Up @@ -517,9 +524,12 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) {
CredentialBackends: credentialBackends,
LogicalBackends: logicalBackends,
PhysicalBackends: physicalBackends,
ShutdownCh: MakeShutdownCh(),
SighupCh: MakeSighupCh(),
SigUSR2Ch: MakeSigUSR2Ch(),

ServiceRegistrations: serviceRegistrations,

ShutdownCh: MakeShutdownCh(),
SighupCh: MakeSighupCh(),
SigUSR2Ch: MakeSigUSR2Ch(),
}, nil
},
"ssh": func() (cli.Command, error) {
Expand Down
53 changes: 39 additions & 14 deletions command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import (
"github.com/hashicorp/vault/sdk/logical"
"github.com/hashicorp/vault/sdk/physical"
"github.com/hashicorp/vault/sdk/version"
sr "github.com/hashicorp/vault/serviceregistration"
"github.com/hashicorp/vault/vault"
vaultseal "github.com/hashicorp/vault/vault/seal"
shamirseal "github.com/hashicorp/vault/vault/seal/shamir"
Expand Down Expand Up @@ -79,6 +80,8 @@ type ServerCommand struct {
LogicalBackends map[string]logical.Factory
PhysicalBackends map[string]physical.Factory

ServiceRegistrations map[string]sr.Factory

ShutdownCh chan struct{}
SighupCh chan struct{}
SigUSR2Ch chan struct{}
Expand Down Expand Up @@ -935,6 +938,24 @@ func (c *ServerCommand) Run(args []string) int {
return 1
}

// Initialize the Service Discovery, if there is one
var configSR sr.ServiceRegistration
if config.ServiceRegistration != nil {
sdFactory, ok := c.ServiceRegistrations[config.ServiceRegistration.Type]
if !ok {
c.UI.Error(fmt.Sprintf("Unknown service_registration type %s", config.ServiceRegistration.Type))
return 1
}

namedSDLogger := c.logger.Named("service_registration." + config.ServiceRegistration.Type)
allLoggers = append(allLoggers, namedSDLogger)
configSR, err = sdFactory(config.ServiceRegistration.Config, namedSDLogger)
if err != nil {
c.UI.Error(fmt.Sprintf("Error initializing service_registration of type %s: %s", config.ServiceRegistration.Type, err))
return 1
}
}

infoKeys := make([]string, 0, 10)
info := make(map[string]string)
info["log level"] = logLevelString
Expand Down Expand Up @@ -1019,6 +1040,7 @@ func (c *ServerCommand) Run(args []string) int {
RedirectAddr: config.Storage.RedirectAddr,
StorageType: config.Storage.Type,
HAPhysical: nil,
ServiceRegistration: configSR,
Seal: barrierSeal,
AuditBackends: c.AuditBackends,
CredentialBackends: c.CredentialBackends,
Expand Down Expand Up @@ -1218,6 +1240,13 @@ CLUSTER_SYNTHESIS_COMPLETE:
}
}

// If ServiceRegistration is configured, then the backend must support HA
isBackendHA := coreConfig.HAPhysical != nil && coreConfig.HAPhysical.HAEnabled()
if (coreConfig.ServiceRegistration != nil) && !isBackendHA {
c.UI.Output("service_registration is configured, but storage does not support HA")
return 1
}

// Initialize the core
core, newCoreError := vault.NewCore(coreConfig)
if newCoreError != nil {
Expand Down Expand Up @@ -1473,21 +1502,17 @@ CLUSTER_SYNTHESIS_COMPLETE:
// Instantiate the wait group
c.WaitGroup = &sync.WaitGroup{}

// If the backend supports service discovery, run service discovery
if coreConfig.HAPhysical != nil && coreConfig.HAPhysical.HAEnabled() {
sd, ok := coreConfig.HAPhysical.(physical.ServiceDiscovery)
if ok {
activeFunc := func() bool {
if isLeader, _, _, err := core.Leader(); err == nil {
return isLeader
}
return false
}

if err := sd.RunServiceDiscovery(c.WaitGroup, c.ShutdownCh, coreConfig.RedirectAddr, activeFunc, core.Sealed, core.PerfStandby); err != nil {
c.UI.Error(fmt.Sprintf("Error initializing service discovery: %v", err))
return 1
// If service discovery is available, run service discovery
if disc := coreConfig.GetServiceRegistration(); disc != nil {
activeFunc := func() bool {
if isLeader, _, _, err := core.Leader(); err == nil {
return isLeader
}
return false
}
if err := disc.RunServiceRegistration(c.WaitGroup, c.ShutdownCh, coreConfig.RedirectAddr, activeFunc, core.Sealed, core.PerfStandby); err != nil {
c.UI.Error(fmt.Sprintf("Error initializing service discovery: %v", err))
return 1
}
}

Expand Down
56 changes: 56 additions & 0 deletions command/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ type Config struct {
Storage *Storage `hcl:"-"`
HAStorage *Storage `hcl:"-"`

ServiceRegistration *ServiceRegistration `hcl:"-"`

Seals []*Seal `hcl:"-"`
Entropy *Entropy `hcl:"-"`

Expand Down Expand Up @@ -150,6 +152,16 @@ func (b *Storage) GoString() string {
return fmt.Sprintf("*%#v", *b)
}

// ServiceRegistration is the optional service discovery for the server.
type ServiceRegistration struct {
Type string
Config map[string]string
}

func (b *ServiceRegistration) GoString() string {
return fmt.Sprintf("*%#v", *b)
}

// Seal contains Seal configuration for the server
type Seal struct {
Type string
Expand Down Expand Up @@ -292,6 +304,11 @@ func (c *Config) Merge(c2 *Config) *Config {
result.HAStorage = c2.HAStorage
}

result.ServiceRegistration = c.ServiceRegistration
if c2.ServiceRegistration != nil {
result.ServiceRegistration = c2.ServiceRegistration
}

result.Entropy = c.Entropy
if c2.Entropy != nil {
result.Entropy = c2.Entropy
Expand Down Expand Up @@ -585,6 +602,13 @@ func ParseConfig(d string) (*Config, error) {
}
}

// Parse service discovery
if o := list.Filter("service_registration"); len(o.Items) > 0 {
if err := parseServiceRegistration(&result, o, "service_registration"); err != nil {
return nil, errwrap.Wrapf("error parsing 'service_registration': {{err}}", err)
}
}

if o := list.Filter("hsm"); len(o.Items) > 0 {
if err := parseSeals(&result, o, "hsm"); err != nil {
return nil, errwrap.Wrapf("error parsing 'hsm': {{err}}", err)
Expand Down Expand Up @@ -829,6 +853,30 @@ func parseHAStorage(result *Config, list *ast.ObjectList, name string) error {
return nil
}

func parseServiceRegistration(result *Config, list *ast.ObjectList, name string) error {
if len(list.Items) > 1 {
return fmt.Errorf("only one %q block is permitted", name)
}

// Get our item
item := list.Items[0]
key := name
if len(item.Keys) > 0 {
key = item.Keys[0].Token.Value().(string)
}

var m map[string]string
if err := hcl.DecodeObject(&m, item.Val); err != nil {
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", name, key))
}

result.ServiceRegistration = &ServiceRegistration{
Type: strings.ToLower(key),
Config: m,
}
return nil
}

func parseSeals(result *Config, list *ast.ObjectList, blockName string) error {
if len(list.Items) > 2 {
return fmt.Errorf("only two or less %q blocks are permitted", blockName)
Expand Down Expand Up @@ -1009,6 +1057,14 @@ func (c *Config) Sanitized() map[string]interface{} {
result["ha_storage"] = sanitizedHAStorage
}

// Sanitize service_registration stanza
if c.ServiceRegistration != nil {
sanitizedServiceRegistration := map[string]interface{}{
"type": c.ServiceRegistration.Type,
}
result["service_registration"] = sanitizedServiceRegistration
}

// Sanitize seals stanza
if len(c.Seals) != 0 {
var sanitizedSeals []interface{}
Expand Down
31 changes: 31 additions & 0 deletions command/server/config_test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ func testLoadConfigFile_topLevel(t *testing.T, entropy *Entropy) {
DisableClustering: true,
},

ServiceRegistration: &ServiceRegistration{
Type: "consul",
Config: map[string]string{
"foo": "bar",
},
},

Telemetry: &Telemetry{
StatsdAddr: "bar",
StatsiteAddr: "foo",
Expand Down Expand Up @@ -126,6 +133,13 @@ func testLoadConfigFile_json2(t *testing.T, entropy *Entropy) {
DisableClustering: true,
},

ServiceRegistration: &ServiceRegistration{
Type: "consul",
Config: map[string]string{
"foo": "bar",
},
},

CacheSize: 45678,

EnableUI: true,
Expand Down Expand Up @@ -261,6 +275,13 @@ func testLoadConfigFile(t *testing.T) {
DisableClustering: true,
},

ServiceRegistration: &ServiceRegistration{
Type: "consul",
Config: map[string]string{
"foo": "bar",
},
},

Telemetry: &Telemetry{
StatsdAddr: "bar",
StatsiteAddr: "foo",
Expand Down Expand Up @@ -324,6 +345,13 @@ func testLoadConfigFile_json(t *testing.T) {
DisableClustering: true,
},

ServiceRegistration: &ServiceRegistration{
Type: "consul",
Config: map[string]string{
"foo": "bar",
},
},

ClusterCipherSuites: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",

Telemetry: &Telemetry{
Expand Down Expand Up @@ -476,6 +504,9 @@ func testConfig_Sanitized(t *testing.T) {
"redirect_addr": "top_level_api_addr",
"type": "consul",
},
"service_registration": map[string]interface{}{
"type": "consul",
},
"telemetry": map[string]interface{}{
"circonus_api_app": "",
"circonus_api_token": "",
Expand Down
4 changes: 4 additions & 0 deletions command/server/test-fixtures/config.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ ha_backend "consul" {
disable_clustering = "true"
}

service_registration "consul" {
foo = "bar"
}

telemetry {
statsd_address = "bar"
statsite_address = "foo"
Expand Down
5 changes: 5 additions & 0 deletions command/server/test-fixtures/config.hcl.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
"disable_clustering": "true"
}
},
"service_registration": {
"consul": {
"foo": "bar",
}
},
"telemetry": {
"statsite_address": "baz"
},
Expand Down
4 changes: 4 additions & 0 deletions command/server/test-fixtures/config2.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ ha_storage "consul" {
disable_clustering = "true"
}

service_registration "consul" {
foo = "bar"
}

telemetry {
statsd_address = "bar"
statsite_address = "foo"
Expand Down
5 changes: 5 additions & 0 deletions command/server/test-fixtures/config2.hcl.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
"disable_clustering": "true"
}
},
"service_registration":{
"consul":{
"foo":"bar"
}
},
"cache_size": 45678,
"telemetry":{
"statsd_address":"bar",
Expand Down
6 changes: 5 additions & 1 deletion command/server/test-fixtures/config3.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ ha_backend "consul" {
token = "foo"
}

service_registration "consul" {
token = "foo"
}

telemetry {
statsd_address = "bar"
circonus_api_token = "baz"
Expand All @@ -38,4 +42,4 @@ default_lease_ttl = "10h"
cluster_name = "testcluster"
pid_file = "./pidfile"
raw_storage_endpoint = true
disable_sealwrap = true
disable_sealwrap = true
Loading

0 comments on commit df01a43

Please sign in to comment.