// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package serviceregistration /* ServiceRegistration is an interface that can be fulfilled to use varying applications for service discovery, regardless of the physical back-end used. Service registration implements notifications for changes in _dynamic_ properties regarding Vault's health. Vault's version is the only static property given in state for now, but if there's a need for more in the future, we could add them on. */ import ( "sync" log "github.com/hashicorp/go-hclog" ) type State struct { VaultVersion string IsInitialized, IsSealed, IsActive, IsPerformanceStandby bool } // Factory is the factory function to create a ServiceRegistration. // The config is the key/value pairs set _inside_ the service registration config stanza. // The state is the initial state. // The redirectAddr is Vault core's RedirectAddr. type Factory func(config map[string]string, logger log.Logger, state State) (ServiceRegistration, error) // ServiceRegistration is an interface that advertises the state of Vault to a // service discovery network. type ServiceRegistration interface { // Run provides a shutdownCh, wait WaitGroup, and redirectAddr. The // shutdownCh is for monitoring when a shutdown occurs and initiating any // actions needed to leave service registration in a final state. When // finished, signalling that with wait means that Vault will wait until // complete. The redirectAddr is an optional parameter for implementations // that might need to communicate with Vault's listener via this address. // // Run is called just after Factory instantiation so can be relied upon // for controlling shutdown behavior. // Here is an example of its intended use: // func Run(shutdownCh <-chan struct{}, wait sync.WaitGroup, redirectAddr string) error { // // // Since we are going to want Vault to wait to shutdown // // until after we do cleanup... // wait.Add(1) // // // Run shutdown code in a goroutine so Run doesn't block. // go func(){ // // Ensure that when this ends, no matter how it ends, // // we don't cause Vault to hang on shutdown. // defer wait.Done() // // // Now wait until we're actually receiving a shutdown. // <-shutdownCh // // // Now do whatever we need to clean up. // if err := someService.SetFinalState(); err != nil { // // Log it at error level. // } // }() // return nil // } Run(shutdownCh <-chan struct{}, wait *sync.WaitGroup, redirectAddr string) error // NotifyActiveStateChange is used by Core to notify that this Vault // instance has changed its status on whether it's active or is // a standby. // If errors are returned, Vault only logs a warning, so it is // the implementation's responsibility to retry updating state // in the face of errors. NotifyActiveStateChange(isActive bool) error // NotifySealedStateChange is used by Core to notify that Vault has changed // its Sealed status to sealed or unsealed. // If errors are returned, Vault only logs a warning, so it is // the implementation's responsibility to retry updating state // in the face of errors. NotifySealedStateChange(isSealed bool) error // NotifyPerformanceStandbyStateChange is used by Core to notify that this // Vault instance has changed its performance standby status. // If errors are returned, Vault only logs a warning, so it is // the implementation's responsibility to retry updating state // in the face of errors. NotifyPerformanceStandbyStateChange(isStandby bool) error // NotifyInitializedStateChange is used by Core to notify that storage // has been initialized. An unsealed core will always also be initialized. // If errors are returned, Vault only logs a warning, so it is // the implementation's responsibility to retry updating state // in the face of errors. NotifyInitializedStateChange(isInitialized bool) error }