agent: initialize the cache and cache the CA roots

pull/4275/head
Mitchell Hashimoto 2018-04-11 09:52:51 +01:00
parent c329b4cb34
commit 6902d721d6
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
4 changed files with 55 additions and 11 deletions

View File

@ -21,6 +21,8 @@ import (
"github.com/armon/go-metrics"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/ae"
"github.com/hashicorp/consul/agent/cache"
"github.com/hashicorp/consul/agent/cache-types"
"github.com/hashicorp/consul/agent/checks"
"github.com/hashicorp/consul/agent/config"
"github.com/hashicorp/consul/agent/consul"
@ -118,6 +120,9 @@ type Agent struct {
// and the remote state.
sync *ae.StateSyncer
// cache is the in-memory cache for data the Agent requests.
cache *cache.Cache
// checkReapAfter maps the check ID to a timeout after which we should
// reap its associated service
checkReapAfter map[types.CheckID]time.Duration
@ -290,6 +295,9 @@ func (a *Agent) Start() error {
// regular and on-demand state synchronizations (anti-entropy).
a.sync = ae.NewStateSyncer(a.State, c.AEInterval, a.shutdownCh, a.logger)
// create the cache
a.cache = cache.New(nil)
// create the config for the rpc server/client
consulCfg, err := a.consulConfig()
if err != nil {
@ -326,6 +334,9 @@ func (a *Agent) Start() error {
a.State.Delegate = a.delegate
a.State.TriggerSyncChanges = a.sync.SyncChanges.Trigger
// Register the cache
a.registerCache()
// Load checks/services/metadata.
if err := a.loadServices(c); err != nil {
return err
@ -2624,3 +2635,18 @@ func (a *Agent) ReloadConfig(newCfg *config.RuntimeConfig) error {
return nil
}
// registerCache configures the cache and registers all the supported
// types onto the cache. This is NOT safe to call multiple times so
// care should be taken to call this exactly once after the cache
// field has been initialized.
func (a *Agent) registerCache() {
a.cache.RegisterType(cachetype.ConnectCARootName, &cachetype.ConnectCARoot{
RPC: a.delegate,
}, &cache.RegisterOptions{
// Maintain a blocking query, retry dropped connections quickly
Refresh: true,
RefreshTimer: 0,
RefreshTimeout: 10 * time.Minute,
})
}

View File

@ -13,6 +13,7 @@ import (
"github.com/mitchellh/hashstructure"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/cache-types"
"github.com/hashicorp/consul/agent/checks"
"github.com/hashicorp/consul/agent/config"
"github.com/hashicorp/consul/agent/connect"
@ -885,10 +886,24 @@ func (s *HTTPServer) AgentToken(resp http.ResponseWriter, req *http.Request) (in
// AgentConnectCARoots returns the trusted CA roots.
func (s *HTTPServer) AgentConnectCARoots(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
// NOTE(mitchellh): for now this is identical to /v1/connect/ca/roots.
// In the future, we're going to do some agent-local caching and the
// behavior will differ.
return s.ConnectCARoots(resp, req)
var args structs.DCSpecificRequest
if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
return nil, nil
}
raw, err := s.agent.cache.Get(cachetype.ConnectCARootName, &args)
if err != nil {
return nil, err
}
reply, ok := raw.(*structs.IndexedCARoots)
if !ok {
// This should never happen, but we want to protect against panics
return nil, fmt.Errorf("internal error: response type not correct")
}
defer setMeta(resp, &reply.QueryMeta)
return *reply, nil
}
// AgentConnectCALeafCert returns the certificate bundle for a service

View File

@ -7,12 +7,15 @@ import (
"github.com/hashicorp/consul/agent/structs"
)
// TypeCARoot supports fetching the Connect CA roots.
type TypeCARoot struct {
// Recommended name for registration for ConnectCARoot
const ConnectCARootName = "connect-ca"
// ConnectCARoot supports fetching the Connect CA roots.
type ConnectCARoot struct {
RPC RPC
}
func (c *TypeCARoot) Fetch(opts cache.FetchOptions, req cache.Request) (cache.FetchResult, error) {
func (c *ConnectCARoot) Fetch(opts cache.FetchOptions, req cache.Request) (cache.FetchResult, error) {
var result cache.FetchResult
// The request should be a DCSpecificRequest.

View File

@ -10,11 +10,11 @@ import (
"github.com/stretchr/testify/require"
)
func TestTypeCARoot(t *testing.T) {
func TestConnectCARoot(t *testing.T) {
require := require.New(t)
rpc := TestRPC(t)
defer rpc.AssertExpectations(t)
typ := &TypeCARoot{RPC: rpc}
typ := &ConnectCARoot{RPC: rpc}
// Expect the proper RPC call. This also sets the expected value
// since that is return-by-pointer in the arguments.
@ -42,11 +42,11 @@ func TestTypeCARoot(t *testing.T) {
}, result)
}
func TestTypeCARoot_badReqType(t *testing.T) {
func TestConnectCARoot_badReqType(t *testing.T) {
require := require.New(t)
rpc := TestRPC(t)
defer rpc.AssertExpectations(t)
typ := &TypeCARoot{RPC: rpc}
typ := &ConnectCARoot{RPC: rpc}
// Fetch
_, err := typ.Fetch(cache.FetchOptions{}, cache.TestRequest(