From 7b5b170a0d8252f7b7b1383529fa62c8c278b8d2 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Mon, 10 Aug 2020 20:20:06 -0400 Subject: [PATCH] agent: Move setupKeyring functions to keyring.go There are a couple reasons for this change: 1. agent.go is way too big. Smaller files makes code eaasier to read because tools that show usage also include filename which can give a lot more context to someone trying to understand which functions call other functions. 2. these two functions call into a large number of functions already in keyring.go. --- agent/agent.go | 121 +---------------------------------------------- agent/keyring.go | 116 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 119 deletions(-) diff --git a/agent/agent.go b/agent/agent.go index 7aca04c35a..75afef97e1 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -51,7 +51,6 @@ import ( "github.com/hashicorp/consul/tlsutil" "github.com/hashicorp/consul/types" "github.com/hashicorp/go-multierror" - "github.com/hashicorp/memberlist" "github.com/hashicorp/raft" "github.com/hashicorp/serf/serf" "golang.org/x/net/http2" @@ -1269,7 +1268,7 @@ func (a *Agent) reloadWatches(cfg *config.RuntimeConfig) error { } // newConsulConfig translates a RuntimeConfig into a consul.Config. -// FIXME: move this function to a different file, maybe config.go +// TODO: move this function to a different file, maybe config.go func newConsulConfig(config *config.RuntimeConfig, logger hclog.Logger) (*consul.Config, error) { // Start with the provided config or default config base := consul.DefaultConfig() @@ -1508,7 +1507,7 @@ func newConsulConfig(config *config.RuntimeConfig, logger hclog.Logger) (*consul // This will set up the LAN keyring, as well as the WAN and any segments // for servers. - // FIXME: move this to remove the need to pass in logger. + // TODO: move this closer to where the keyrings will be used. if err := setupKeyrings(base, config, logger); err != nil { return nil, fmt.Errorf("Failed to configure keyring: %v", err) } @@ -1562,122 +1561,6 @@ func segmentConfig(config *config.RuntimeConfig) ([]consul.NetworkSegment, error return segments, nil } -// setupBaseKeyrings configures the LAN and WAN keyrings. -// FIXME: move this function to a different file. maybe keyring.go, or config.go -func setupBaseKeyrings(config *consul.Config, rtConfig *config.RuntimeConfig, logger hclog.Logger) error { - // If the keyring file is disabled then just poke the provided key - // into the in-memory keyring. - federationEnabled := config.SerfWANConfig != nil - if rtConfig.DisableKeyringFile { - if rtConfig.EncryptKey == "" { - return nil - } - - keys := []string{rtConfig.EncryptKey} - if err := loadKeyring(config.SerfLANConfig, keys); err != nil { - return err - } - if rtConfig.ServerMode && federationEnabled { - if err := loadKeyring(config.SerfWANConfig, keys); err != nil { - return err - } - } - return nil - } - - // Otherwise, we need to deal with the keyring files. - fileLAN := filepath.Join(rtConfig.DataDir, SerfLANKeyring) - fileWAN := filepath.Join(rtConfig.DataDir, SerfWANKeyring) - - var existingLANKeyring, existingWANKeyring bool - if rtConfig.EncryptKey == "" { - goto LOAD - } - if _, err := os.Stat(fileLAN); err != nil { - if err := initKeyring(fileLAN, rtConfig.EncryptKey); err != nil { - return err - } - } else { - existingLANKeyring = true - } - if rtConfig.ServerMode && federationEnabled { - if _, err := os.Stat(fileWAN); err != nil { - if err := initKeyring(fileWAN, rtConfig.EncryptKey); err != nil { - return err - } - } else { - existingWANKeyring = true - } - } - -LOAD: - if _, err := os.Stat(fileLAN); err == nil { - config.SerfLANConfig.KeyringFile = fileLAN - } - if err := loadKeyringFile(config.SerfLANConfig); err != nil { - return err - } - if rtConfig.ServerMode && federationEnabled { - if _, err := os.Stat(fileWAN); err == nil { - config.SerfWANConfig.KeyringFile = fileWAN - } - if err := loadKeyringFile(config.SerfWANConfig); err != nil { - return err - } - } - - // Only perform the following checks if there was an encrypt_key - // provided in the configuration. - if rtConfig.EncryptKey != "" { - msg := " keyring doesn't include key provided with -encrypt, using keyring" - if existingLANKeyring && - keyringIsMissingKey( - config.SerfLANConfig.MemberlistConfig.Keyring, - rtConfig.EncryptKey, - ) { - logger.Warn(msg, "keyring", "LAN") - } - if existingWANKeyring && - keyringIsMissingKey( - config.SerfWANConfig.MemberlistConfig.Keyring, - rtConfig.EncryptKey, - ) { - logger.Warn(msg, "keyring", "WAN") - } - } - - return nil -} - -// setupKeyrings is used to initialize and load keyrings during agent startup. -// FIXME: move this function to a different file. maybe keyring.go, or config.go -func setupKeyrings(config *consul.Config, rtConfig *config.RuntimeConfig, logger hclog.Logger) error { - // First set up the LAN and WAN keyrings. - if err := setupBaseKeyrings(config, rtConfig, logger); err != nil { - return err - } - - // If there's no LAN keyring then there's nothing else to set up for - // any segments. - lanKeyring := config.SerfLANConfig.MemberlistConfig.Keyring - if lanKeyring == nil { - return nil - } - - // Copy the initial state of the LAN keyring into each segment config. - // Segments don't have their own keyring file, they rely on the LAN - // holding the state so things can't get out of sync. - k, pk := lanKeyring.GetKeys(), lanKeyring.GetPrimaryKey() - for _, segment := range config.Segments { - keyring, err := memberlist.NewKeyring(k, pk) - if err != nil { - return err - } - segment.SerfConfig.MemberlistConfig.Keyring = keyring - } - return nil -} - // registerEndpoint registers a handler for the consul RPC server // under a unique name while making it accessible under the provided // name. This allows overwriting handlers for the golang net/rpc diff --git a/agent/keyring.go b/agent/keyring.go index 48c1ebc0ba..c6a91e2b74 100644 --- a/agent/keyring.go +++ b/agent/keyring.go @@ -9,8 +9,10 @@ import ( "os" "path/filepath" + "github.com/hashicorp/consul/agent/config" "github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/go-hclog" "github.com/hashicorp/memberlist" "github.com/hashicorp/serf/serf" ) @@ -20,6 +22,120 @@ const ( SerfWANKeyring = "serf/remote.keyring" ) +// setupKeyrings in config.SerfLANConfig and config.SerfWANConfig. +func setupKeyrings(config *consul.Config, rtConfig *config.RuntimeConfig, logger hclog.Logger) error { + // First set up the LAN and WAN keyrings. + if err := setupBaseKeyrings(config, rtConfig, logger); err != nil { + return err + } + + // If there's no LAN keyring then there's nothing else to set up for + // any segments. + lanKeyring := config.SerfLANConfig.MemberlistConfig.Keyring + if lanKeyring == nil { + return nil + } + + // Copy the initial state of the LAN keyring into each segment config. + // Segments don't have their own keyring file, they rely on the LAN + // holding the state so things can't get out of sync. + k, pk := lanKeyring.GetKeys(), lanKeyring.GetPrimaryKey() + for _, segment := range config.Segments { + keyring, err := memberlist.NewKeyring(k, pk) + if err != nil { + return err + } + segment.SerfConfig.MemberlistConfig.Keyring = keyring + } + return nil +} + +// setupBaseKeyrings configures the LAN and WAN keyrings. +func setupBaseKeyrings(config *consul.Config, rtConfig *config.RuntimeConfig, logger hclog.Logger) error { + // If the keyring file is disabled then just poke the provided key + // into the in-memory keyring. + federationEnabled := config.SerfWANConfig != nil + if rtConfig.DisableKeyringFile { + if rtConfig.EncryptKey == "" { + return nil + } + + keys := []string{rtConfig.EncryptKey} + if err := loadKeyring(config.SerfLANConfig, keys); err != nil { + return err + } + if rtConfig.ServerMode && federationEnabled { + if err := loadKeyring(config.SerfWANConfig, keys); err != nil { + return err + } + } + return nil + } + + // Otherwise, we need to deal with the keyring files. + fileLAN := filepath.Join(rtConfig.DataDir, SerfLANKeyring) + fileWAN := filepath.Join(rtConfig.DataDir, SerfWANKeyring) + + var existingLANKeyring, existingWANKeyring bool + if rtConfig.EncryptKey == "" { + goto LOAD + } + if _, err := os.Stat(fileLAN); err != nil { + if err := initKeyring(fileLAN, rtConfig.EncryptKey); err != nil { + return err + } + } else { + existingLANKeyring = true + } + if rtConfig.ServerMode && federationEnabled { + if _, err := os.Stat(fileWAN); err != nil { + if err := initKeyring(fileWAN, rtConfig.EncryptKey); err != nil { + return err + } + } else { + existingWANKeyring = true + } + } + +LOAD: + if _, err := os.Stat(fileLAN); err == nil { + config.SerfLANConfig.KeyringFile = fileLAN + } + if err := loadKeyringFile(config.SerfLANConfig); err != nil { + return err + } + if rtConfig.ServerMode && federationEnabled { + if _, err := os.Stat(fileWAN); err == nil { + config.SerfWANConfig.KeyringFile = fileWAN + } + if err := loadKeyringFile(config.SerfWANConfig); err != nil { + return err + } + } + + // Only perform the following checks if there was an encrypt_key + // provided in the configuration. + if rtConfig.EncryptKey != "" { + msg := " keyring doesn't include key provided with -encrypt, using keyring" + if existingLANKeyring && + keyringIsMissingKey( + config.SerfLANConfig.MemberlistConfig.Keyring, + rtConfig.EncryptKey, + ) { + logger.Warn(msg, "keyring", "LAN") + } + if existingWANKeyring && + keyringIsMissingKey( + config.SerfWANConfig.MemberlistConfig.Keyring, + rtConfig.EncryptKey, + ) { + logger.Warn(msg, "keyring", "WAN") + } + } + + return nil +} + // initKeyring will create a keyring file at a given path. func initKeyring(path, key string) error { var keys []string