Allow for easy enterprise/oss coexistence

Uses struct/interface embedding with the embedded structs/interfaces being empty for oss. Also methods on the server/client types are defaulted to do nothing for OSS
This commit is contained in:
Matt Keeler 2018-05-24 10:36:42 -04:00
parent 971c38f537
commit 14661a417b
9 changed files with 124 additions and 5 deletions

View File

@ -73,6 +73,7 @@ type delegate interface {
SnapshotRPC(args *structs.SnapshotRequest, in io.Reader, out io.Writer, replyFn structs.SnapshotReplyFn) error
Shutdown() error
Stats() map[string]map[string]string
enterpriseDelegate
}
// notifier is called after a successful JoinLAN.

View File

@ -72,6 +72,9 @@ type Client struct {
shutdown bool
shutdownCh chan struct{}
shutdownLock sync.Mutex
// embedded struct to hold all the enterprise specific data
EnterpriseClient
}
// NewClient is used to construct a new Consul client from the
@ -131,6 +134,11 @@ func NewClientLogger(config *Config, logger *log.Logger) (*Client, error) {
shutdownCh: make(chan struct{}),
}
if err := c.initEnterprise(); err != nil {
c.Shutdown()
return nil, err
}
// Initialize the LAN Serf
c.serf, err = c.setupSerf(config.SerfLANConfig,
c.eventCh, serfLANSnapshot)
@ -147,6 +155,11 @@ func NewClientLogger(config *Config, logger *log.Logger) (*Client, error) {
// handlers depend on the router and the router depends on Serf.
go c.lanEventHandler()
if err := c.startEnterprise(); err != nil {
c.Shutdown()
return nil, err
}
return c, nil
}
@ -342,6 +355,17 @@ func (c *Client) Stats() map[string]map[string]string {
"serf_lan": c.serf.Stats(),
"runtime": runtimeStats(),
}
for outerKey, outerValue := range c.enterpriseStats() {
if _, ok := stats[outerKey]; ok {
for innerKey, innerValue := range outerValue {
stats[outerKey][innerKey] = innerValue
}
} else {
stats[outerKey] = outerValue
}
}
return stats
}

View File

@ -135,6 +135,8 @@ func (c *Client) localEvent(event serf.UserEvent) {
c.config.UserEventHandler(event)
}
default:
if !c.handleEnterpriseUserEvents(event) {
c.logger.Printf("[WARN] consul: Unhandled local event: %v", event)
}
}
}

View File

@ -0,0 +1,25 @@
// +build !ent
package consul
import (
"github.com/hashicorp/serf/serf"
)
type EnterpriseClient struct{}
func (c *Client) initEnterprise() error {
return nil
}
func (c *Client) startEnterprise() error {
return nil
}
func (c *Client) handleEnterpriseUserEvents(event serf.UserEvent) bool {
return false
}
func (c *Client) enterpriseStats() map[string]map[string]string {
return nil
}

View File

@ -0,0 +1,32 @@
// +build !ent
package consul
import (
"net"
"github.com/hashicorp/consul/agent/pool"
"github.com/hashicorp/serf/serf"
)
type EnterpriseServer struct{}
func (s *Server) initEnterprise() error {
return nil
}
func (s *Server) startEnterprise() error {
return nil
}
func (s *Server) handleEnterpriseUserEvents(event serf.UserEvent) bool {
return false
}
func (s *Server) handleEnterpriseRPCConn(rtype pool.RPCType, conn net.Conn, isTLS bool) bool {
return false
}
func (s *Server) enterpriseStats() map[string]map[string]string {
return nil
}

View File

@ -115,9 +115,10 @@ func (s *Server) handleConn(conn net.Conn, isTLS bool) {
s.handleSnapshotConn(conn)
default:
if !s.handleEnterpriseRPCConn(typ, conn, isTLS) {
s.logger.Printf("[ERR] consul.rpc: unrecognized RPC byte: %v %s", typ, logConn(conn))
conn.Close()
return
}
}
}

View File

@ -208,6 +208,9 @@ type Server struct {
shutdown bool
shutdownCh chan struct{}
shutdownLock sync.Mutex
// embedded struct to hold all the enterprise specific data
EnterpriseServer
}
func NewServer(config *Config) (*Server, error) {
@ -297,6 +300,12 @@ func NewServerLogger(config *Config, logger *log.Logger, tokens *token.Store) (*
shutdownCh: shutdownCh,
}
// Initialize enterprise specific server functionality
if err := s.initEnterprise(); err != nil {
s.Shutdown()
return nil, err
}
// Initialize the stats fetcher that autopilot will use.
s.statsFetcher = NewStatsFetcher(logger, s.connPool, s.config.Datacenter)
@ -338,6 +347,12 @@ func NewServerLogger(config *Config, logger *log.Logger, tokens *token.Store) (*
return nil, fmt.Errorf("Failed to start Raft: %v", err)
}
// Start enterprise specific functionality
if err := s.startEnterprise(); err != nil {
s.Shutdown()
return nil, err
}
// Serf and dynamic bind ports
//
// The LAN serf cluster announces the port of the WAN serf cluster
@ -1019,6 +1034,17 @@ func (s *Server) Stats() map[string]map[string]string {
if s.serfWAN != nil {
stats["serf_wan"] = s.serfWAN.Stats()
}
for outerKey, outerValue := range s.enterpriseStats() {
if _, ok := stats[outerKey]; ok {
for innerKey, innerValue := range outerValue {
stats[outerKey][innerKey] = innerValue
}
} else {
stats[outerKey] = outerValue
}
}
return stats
}

View File

@ -198,8 +198,10 @@ func (s *Server) localEvent(event serf.UserEvent) {
s.config.UserEventHandler(event)
}
default:
if !s.handleEnterpriseUserEvents(event) {
s.logger.Printf("[WARN] consul: Unhandled local event: %v", event)
}
}
}
// lanNodeJoin is used to handle join events on the LAN pool.

View File

@ -0,0 +1,6 @@
// +build !ent
package agent
// enterpriseDelegate has no functions in OSS
type enterpriseDelegate interface{}