mirror of https://github.com/kubernetes/kops.git
				
				
				
			
		
			
				
	
	
		
			224 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
| package mesh
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"net"
 | |
| )
 | |
| 
 | |
| // Status is our current state as a peer, as taken from a router.
 | |
| // This is designed to be used as diagnostic information.
 | |
| type Status struct {
 | |
| 	Protocol           string
 | |
| 	ProtocolMinVersion int
 | |
| 	ProtocolMaxVersion int
 | |
| 	Encryption         bool
 | |
| 	PeerDiscovery      bool
 | |
| 	Name               string
 | |
| 	NickName           string
 | |
| 	Port               int
 | |
| 	Peers              []PeerStatus
 | |
| 	UnicastRoutes      []unicastRouteStatus
 | |
| 	BroadcastRoutes    []broadcastRouteStatus
 | |
| 	Connections        []LocalConnectionStatus
 | |
| 	TerminationCount   int
 | |
| 	Targets            []string
 | |
| 	OverlayDiagnostics interface{}
 | |
| 	TrustedSubnets     []string
 | |
| }
 | |
| 
 | |
| // NewStatus returns a Status object, taken as a snapshot from the router.
 | |
| func NewStatus(router *Router) *Status {
 | |
| 	return &Status{
 | |
| 		Protocol:           Protocol,
 | |
| 		ProtocolMinVersion: ProtocolMinVersion,
 | |
| 		ProtocolMaxVersion: ProtocolMaxVersion,
 | |
| 		Encryption:         router.usingPassword(),
 | |
| 		PeerDiscovery:      router.PeerDiscovery,
 | |
| 		Name:               router.Ourself.Name.String(),
 | |
| 		NickName:           router.Ourself.NickName,
 | |
| 		Port:               router.Port,
 | |
| 		Peers:              makePeerStatusSlice(router.Peers),
 | |
| 		UnicastRoutes:      makeUnicastRouteStatusSlice(router.Routes),
 | |
| 		BroadcastRoutes:    makeBroadcastRouteStatusSlice(router.Routes),
 | |
| 		Connections:        makeLocalConnectionStatusSlice(router.ConnectionMaker),
 | |
| 		TerminationCount:   router.ConnectionMaker.terminationCount,
 | |
| 		Targets:            router.ConnectionMaker.Targets(false),
 | |
| 		OverlayDiagnostics: router.Overlay.Diagnostics(),
 | |
| 		TrustedSubnets:     makeTrustedSubnetsSlice(router.TrustedSubnets),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // PeerStatus is the current state of a peer in the mesh.
 | |
| type PeerStatus struct {
 | |
| 	Name        string
 | |
| 	NickName    string
 | |
| 	UID         PeerUID
 | |
| 	ShortID     PeerShortID
 | |
| 	Version     uint64
 | |
| 	Connections []connectionStatus
 | |
| }
 | |
| 
 | |
| // makePeerStatusSlice takes a snapshot of the state of peers.
 | |
| func makePeerStatusSlice(peers *Peers) []PeerStatus {
 | |
| 	var slice []PeerStatus
 | |
| 
 | |
| 	peers.forEach(func(peer *Peer) {
 | |
| 		var connections []connectionStatus
 | |
| 		if peer == peers.ourself.Peer {
 | |
| 			for conn := range peers.ourself.getConnections() {
 | |
| 				connections = append(connections, makeConnectionStatus(conn))
 | |
| 			}
 | |
| 		} else {
 | |
| 			// Modifying peer.connections requires a write lock on
 | |
| 			// Peers, and since we are holding a read lock (due to the
 | |
| 			// ForEach), access without locking the peer is safe.
 | |
| 			for _, conn := range peer.connections {
 | |
| 				connections = append(connections, makeConnectionStatus(conn))
 | |
| 			}
 | |
| 		}
 | |
| 		slice = append(slice, PeerStatus{
 | |
| 			peer.Name.String(),
 | |
| 			peer.NickName,
 | |
| 			peer.UID,
 | |
| 			peer.ShortID,
 | |
| 			peer.Version,
 | |
| 			connections,
 | |
| 		})
 | |
| 	})
 | |
| 
 | |
| 	return slice
 | |
| }
 | |
| 
 | |
| type connectionStatus struct {
 | |
| 	Name        string
 | |
| 	NickName    string
 | |
| 	Address     string
 | |
| 	Outbound    bool
 | |
| 	Established bool
 | |
| }
 | |
| 
 | |
| func makeConnectionStatus(c Connection) connectionStatus {
 | |
| 	return connectionStatus{
 | |
| 		Name:        c.Remote().Name.String(),
 | |
| 		NickName:    c.Remote().NickName,
 | |
| 		Address:     c.remoteTCPAddress(),
 | |
| 		Outbound:    c.isOutbound(),
 | |
| 		Established: c.isEstablished(),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // unicastRouteStatus is the current state of an established unicast route.
 | |
| type unicastRouteStatus struct {
 | |
| 	Dest, Via string
 | |
| }
 | |
| 
 | |
| // makeUnicastRouteStatusSlice takes a snapshot of the unicast routes in routes.
 | |
| func makeUnicastRouteStatusSlice(r *routes) []unicastRouteStatus {
 | |
| 	r.RLock()
 | |
| 	defer r.RUnlock()
 | |
| 
 | |
| 	var slice []unicastRouteStatus
 | |
| 	for dest, via := range r.unicast {
 | |
| 		slice = append(slice, unicastRouteStatus{dest.String(), via.String()})
 | |
| 	}
 | |
| 	return slice
 | |
| }
 | |
| 
 | |
| // BroadcastRouteStatus is the current state of an established broadcast route.
 | |
| type broadcastRouteStatus struct {
 | |
| 	Source string
 | |
| 	Via    []string
 | |
| }
 | |
| 
 | |
| // makeBroadcastRouteStatusSlice takes a snapshot of the broadcast routes in routes.
 | |
| func makeBroadcastRouteStatusSlice(r *routes) []broadcastRouteStatus {
 | |
| 	r.RLock()
 | |
| 	defer r.RUnlock()
 | |
| 
 | |
| 	var slice []broadcastRouteStatus
 | |
| 	for source, via := range r.broadcast {
 | |
| 		var hops []string
 | |
| 		for _, hop := range via {
 | |
| 			hops = append(hops, hop.String())
 | |
| 		}
 | |
| 		slice = append(slice, broadcastRouteStatus{source.String(), hops})
 | |
| 	}
 | |
| 	return slice
 | |
| }
 | |
| 
 | |
| // LocalConnectionStatus is the current state of a physical connection to a peer.
 | |
| type LocalConnectionStatus struct {
 | |
| 	Address  string
 | |
| 	Outbound bool
 | |
| 	State    string
 | |
| 	Info     string
 | |
| 	Attrs    map[string]interface{}
 | |
| }
 | |
| 
 | |
| // makeLocalConnectionStatusSlice takes a snapshot of the active local
 | |
| // connections in the ConnectionMaker.
 | |
| func makeLocalConnectionStatusSlice(cm *connectionMaker) []LocalConnectionStatus {
 | |
| 	resultChan := make(chan []LocalConnectionStatus, 0)
 | |
| 	cm.actionChan <- func() bool {
 | |
| 		var slice []LocalConnectionStatus
 | |
| 		for conn := range cm.connections {
 | |
| 			state := "pending"
 | |
| 			if conn.isEstablished() {
 | |
| 				state = "established"
 | |
| 			}
 | |
| 			lc, _ := conn.(*LocalConnection)
 | |
| 			attrs := lc.OverlayConn.Attrs()
 | |
| 			name, ok := attrs["name"]
 | |
| 			if !ok {
 | |
| 				name = "none"
 | |
| 			}
 | |
| 			info := fmt.Sprintf("%-6v %v", name, conn.Remote())
 | |
| 			if lc.router.usingPassword() {
 | |
| 				if lc.untrusted() {
 | |
| 					info = fmt.Sprintf("%-11v %v", "encrypted", info)
 | |
| 				} else {
 | |
| 					info = fmt.Sprintf("%-11v %v", "unencrypted", info)
 | |
| 				}
 | |
| 			}
 | |
| 			slice = append(slice, LocalConnectionStatus{conn.remoteTCPAddress(), conn.isOutbound(), state, info, attrs})
 | |
| 		}
 | |
| 		for address, target := range cm.targets {
 | |
| 			add := func(state, info string) {
 | |
| 				slice = append(slice, LocalConnectionStatus{address, true, state, info, nil})
 | |
| 			}
 | |
| 			switch target.state {
 | |
| 			case targetWaiting:
 | |
| 				until := "never"
 | |
| 				if !target.tryAfter.IsZero() {
 | |
| 					until = target.tryAfter.String()
 | |
| 				}
 | |
| 				if target.lastError == nil { // shouldn't happen
 | |
| 					add("waiting", "until: "+until)
 | |
| 				} else {
 | |
| 					add("failed", target.lastError.Error()+", retry: "+until)
 | |
| 				}
 | |
| 			case targetAttempting:
 | |
| 				if target.lastError == nil {
 | |
| 					add("connecting", "")
 | |
| 				} else {
 | |
| 					add("retrying", target.lastError.Error())
 | |
| 				}
 | |
| 			case targetConnected:
 | |
| 			case targetSuspended:
 | |
| 			}
 | |
| 		}
 | |
| 		resultChan <- slice
 | |
| 		return false
 | |
| 	}
 | |
| 	return <-resultChan
 | |
| }
 | |
| 
 | |
| // makeTrustedSubnetsSlice makes a human-readable copy of the trustedSubnets.
 | |
| func makeTrustedSubnetsSlice(trustedSubnets []*net.IPNet) []string {
 | |
| 	trustedSubnetStrs := []string{}
 | |
| 	for _, trustedSubnet := range trustedSubnets {
 | |
| 		trustedSubnetStrs = append(trustedSubnetStrs, trustedSubnet.String())
 | |
| 	}
 | |
| 	return trustedSubnetStrs
 | |
| }
 |