github.imxd.top/hashicorp/consul@v1.4.5/agent/consul/autopilot.go (about) 1 package consul 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 "strconv" 8 9 "github.com/armon/go-metrics" 10 "github.com/hashicorp/consul/agent/consul/autopilot" 11 "github.com/hashicorp/consul/agent/metadata" 12 "github.com/hashicorp/raft" 13 "github.com/hashicorp/serf/serf" 14 ) 15 16 // AutopilotDelegate is a Consul delegate for autopilot operations. 17 type AutopilotDelegate struct { 18 server *Server 19 } 20 21 func (d *AutopilotDelegate) AutopilotConfig() *autopilot.Config { 22 return d.server.getOrCreateAutopilotConfig() 23 } 24 25 func (d *AutopilotDelegate) FetchStats(ctx context.Context, servers []serf.Member) map[string]*autopilot.ServerStats { 26 return d.server.statsFetcher.Fetch(ctx, servers) 27 } 28 29 func (d *AutopilotDelegate) IsServer(m serf.Member) (*autopilot.ServerInfo, error) { 30 if m.Tags["role"] != "consul" { 31 return nil, nil 32 } 33 34 portStr := m.Tags["port"] 35 port, err := strconv.Atoi(portStr) 36 if err != nil { 37 return nil, err 38 } 39 40 buildVersion, err := metadata.Build(&m) 41 if err != nil { 42 return nil, err 43 } 44 45 server := &autopilot.ServerInfo{ 46 Name: m.Name, 47 ID: m.Tags["id"], 48 Addr: &net.TCPAddr{IP: m.Addr, Port: port}, 49 Build: *buildVersion, 50 Status: m.Status, 51 } 52 return server, nil 53 } 54 55 // Heartbeat a metric for monitoring if we're the leader 56 func (d *AutopilotDelegate) NotifyHealth(health autopilot.OperatorHealthReply) { 57 if d.server.raft.State() == raft.Leader { 58 metrics.SetGauge([]string{"autopilot", "failure_tolerance"}, float32(health.FailureTolerance)) 59 if health.Healthy { 60 metrics.SetGauge([]string{"autopilot", "healthy"}, 1) 61 } else { 62 metrics.SetGauge([]string{"autopilot", "healthy"}, 0) 63 } 64 } 65 } 66 67 func (d *AutopilotDelegate) PromoteNonVoters(conf *autopilot.Config, health autopilot.OperatorHealthReply) ([]raft.Server, error) { 68 future := d.server.raft.GetConfiguration() 69 if err := future.Error(); err != nil { 70 return nil, fmt.Errorf("failed to get raft configuration: %v", err) 71 } 72 73 return autopilot.PromoteStableServers(conf, health, future.Configuration().Servers), nil 74 } 75 76 func (d *AutopilotDelegate) Raft() *raft.Raft { 77 return d.server.raft 78 } 79 80 func (d *AutopilotDelegate) Serf() *serf.Serf { 81 return d.server.serfLAN 82 }