github.com/Iqoqo/consul@v1.4.5/agent/metadata/server.go (about)

     1  package metadata
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"regexp"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/hashicorp/consul/agent/structs"
    11  	"github.com/hashicorp/go-version"
    12  	"github.com/hashicorp/serf/serf"
    13  )
    14  
    15  // Key is used in maps and for equality tests.  A key is based on endpoints.
    16  type Key struct {
    17  	name string
    18  }
    19  
    20  // Equal compares two Key objects
    21  func (k *Key) Equal(x *Key) bool {
    22  	return k.name == x.name
    23  }
    24  
    25  // Server is used to return details of a consul server
    26  type Server struct {
    27  	Name         string
    28  	ID           string
    29  	Datacenter   string
    30  	Segment      string
    31  	Port         int
    32  	SegmentAddrs map[string]string
    33  	SegmentPorts map[string]int
    34  	WanJoinPort  int
    35  	Bootstrap    bool
    36  	Expect       int
    37  	Build        version.Version
    38  	Version      int
    39  	RaftVersion  int
    40  	Addr         net.Addr
    41  	Status       serf.MemberStatus
    42  	NonVoter     bool
    43  	ACLs         structs.ACLMode
    44  
    45  	// If true, use TLS when connecting to this server
    46  	UseTLS bool
    47  }
    48  
    49  // Key returns the corresponding Key
    50  func (s *Server) Key() *Key {
    51  	return &Key{
    52  		name: s.Name,
    53  	}
    54  }
    55  
    56  // String returns a string representation of Server
    57  func (s *Server) String() string {
    58  	var addrStr, networkStr string
    59  	if s.Addr != nil {
    60  		addrStr = s.Addr.String()
    61  		networkStr = s.Addr.Network()
    62  	}
    63  
    64  	return fmt.Sprintf("%s (Addr: %s/%s) (DC: %s)", s.Name, networkStr, addrStr, s.Datacenter)
    65  }
    66  
    67  var versionFormat = regexp.MustCompile(`\d+\.\d+\.\d+`)
    68  
    69  // IsConsulServer returns true if a serf member is a consul server
    70  // agent. Returns a bool and a pointer to the Server.
    71  func IsConsulServer(m serf.Member) (bool, *Server) {
    72  	if m.Tags["role"] != "consul" {
    73  		return false, nil
    74  	}
    75  
    76  	datacenter := m.Tags["dc"]
    77  	segment := m.Tags["segment"]
    78  	_, bootstrap := m.Tags["bootstrap"]
    79  	_, useTLS := m.Tags["use_tls"]
    80  
    81  	expect := 0
    82  	expectStr, ok := m.Tags["expect"]
    83  	var err error
    84  	if ok {
    85  		expect, err = strconv.Atoi(expectStr)
    86  		if err != nil {
    87  			return false, nil
    88  		}
    89  	}
    90  
    91  	portStr := m.Tags["port"]
    92  	port, err := strconv.Atoi(portStr)
    93  	if err != nil {
    94  		return false, nil
    95  	}
    96  
    97  	var acls structs.ACLMode
    98  	if aclMode, ok := m.Tags["acls"]; ok {
    99  		acls = structs.ACLMode(aclMode)
   100  	} else {
   101  		acls = structs.ACLModeUnknown
   102  	}
   103  
   104  	segmentAddrs := make(map[string]string)
   105  	segmentPorts := make(map[string]int)
   106  	for name, value := range m.Tags {
   107  		if strings.HasPrefix(name, "sl_") {
   108  			addr, port, err := net.SplitHostPort(value)
   109  			if err != nil {
   110  				return false, nil
   111  			}
   112  			segmentPort, err := strconv.Atoi(port)
   113  			if err != nil {
   114  				return false, nil
   115  			}
   116  
   117  			segmentName := strings.TrimPrefix(name, "sl_")
   118  			segmentAddrs[segmentName] = addr
   119  			segmentPorts[segmentName] = segmentPort
   120  		}
   121  	}
   122  
   123  	buildVersion, err := Build(&m)
   124  	if err != nil {
   125  		return false, nil
   126  	}
   127  
   128  	wanJoinPort := 0
   129  	wanJoinPortStr, ok := m.Tags["wan_join_port"]
   130  	if ok {
   131  		wanJoinPort, err = strconv.Atoi(wanJoinPortStr)
   132  		if err != nil {
   133  			return false, nil
   134  		}
   135  	}
   136  
   137  	vsnStr := m.Tags["vsn"]
   138  	vsn, err := strconv.Atoi(vsnStr)
   139  	if err != nil {
   140  		return false, nil
   141  	}
   142  
   143  	raftVsn := 0
   144  	raftVsnStr, ok := m.Tags["raft_vsn"]
   145  	if ok {
   146  		raftVsn, err = strconv.Atoi(raftVsnStr)
   147  		if err != nil {
   148  			return false, nil
   149  		}
   150  	}
   151  
   152  	// Check if the server is a non voter
   153  	_, nonVoter := m.Tags["nonvoter"]
   154  
   155  	addr := &net.TCPAddr{IP: m.Addr, Port: port}
   156  
   157  	parts := &Server{
   158  		Name:         m.Name,
   159  		ID:           m.Tags["id"],
   160  		Datacenter:   datacenter,
   161  		Segment:      segment,
   162  		Port:         port,
   163  		SegmentAddrs: segmentAddrs,
   164  		SegmentPorts: segmentPorts,
   165  		WanJoinPort:  wanJoinPort,
   166  		Bootstrap:    bootstrap,
   167  		Expect:       expect,
   168  		Addr:         addr,
   169  		Build:        *buildVersion,
   170  		Version:      vsn,
   171  		RaftVersion:  raftVsn,
   172  		Status:       m.Status,
   173  		UseTLS:       useTLS,
   174  		NonVoter:     nonVoter,
   175  		ACLs:         acls,
   176  	}
   177  	return true, parts
   178  }