Passed
Pull Request — master (#567)
by Murat
02:23
created

gossip.InitMemberList   A

Complexity

Conditions 3

Size

Total Lines 6
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nop 2
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
package gossip
2
3
import (
4
	"errors"
5
	"fmt"
6
	hash "github.com/Permify/permify/pkg/consistent"
7
	"net"
8
)
9
10
// IGossip is an interface that represents the basic operations
11
// of a gossip-based membership protocol. Implementations of this
12
// interface should provide mechanisms for synchronizing cluster
13
// membership and managing the lifecycle of the gossip protocol.
14
type IGossip interface {
15
	SyncNodes(consistent *hash.ConsistentHash, nodeName, port string)
16
	// Shutdown gracefully stops the gossip protocol and performs
17
	// any necessary cleanup. It returns an error if the shutdown
18
	// process encounters any issues.
19
	Shutdown() error
20
}
21
22
// InitMemberList initializes a memberlist instance with the given
23
func InitMemberList(nodes string, name string) (IGossip, error) {
24
	switch name {
25
	case "serf":
26
		return NewSerfGossip(nodes)
27
	default:
28
		return nil, fmt.Errorf("protocol not implamented: %s ", name)
29
	}
30
}
31
32
// ExternalIP returns the first non-loopback IPv4 address
33
func ExternalIP() (string, error) {
34
	// Get a list of network interfaces.
35
	interfaces, err := net.Interfaces()
36
	if err != nil {
37
		return "", err
38
	}
39
40
	// Iterate over the network interfaces.
41
	for _, iface := range interfaces {
42
		// Skip the interface if it's down or a loopback interface.
43
		if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
44
			continue
45
		}
46
47
		// Get a list of addresses associated with the interface.
48
		addresses, err := iface.Addrs()
49
		if err != nil {
50
			return "", err
51
		}
52
53
		// Iterate over the addresses.
54
		for _, addr := range addresses {
55
			// Extract the IP address from the address.
56
			var ip net.IP
57
			switch v := addr.(type) {
58
			case *net.IPNet:
59
				ip = v.IP
60
			case *net.IPAddr:
61
				ip = v.IP
62
			}
63
64
			// Skip the address if it's a loopback address or not IPv4.
65
			if ip == nil || ip.IsLoopback() || ip.To4() == nil {
66
				continue
67
			}
68
69
			// Return the IPv4 address as a string.
70
			return ip.String(), nil
71
		}
72
	}
73
74
	// Return an empty string if no external IPv4 address is found.
75
	return "", errors.New("network error")
76
}
77