add advertise grpc address option

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
Evan Hazlett 2019-10-07 13:52:47 -04:00
parent 4bc08c92c2
commit 190ec3130d
12 changed files with 415 additions and 204 deletions

View file

@ -5,5 +5,3 @@ auto-elects in the event of a current master failure. Non-node peers are also s
can only access the network but do not provide routing capabilities. can only access the network but do not provide routing capabilities.
![Heimdall](docs/overview.png) ![Heimdall](docs/overview.png)
#

View file

@ -32,6 +32,7 @@ type Master struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
GRPCAddress string `protobuf:"bytes,2,opt,name=grpc_address,json=grpcAddress,proto3" json:"grpc_address,omitempty"` GRPCAddress string `protobuf:"bytes,2,opt,name=grpc_address,json=grpcAddress,proto3" json:"grpc_address,omitempty"`
RedisURL string `protobuf:"bytes,3,opt,name=redis_url,json=redisUrl,proto3" json:"redis_url,omitempty"` RedisURL string `protobuf:"bytes,3,opt,name=redis_url,json=redisUrl,proto3" json:"redis_url,omitempty"`
Peers []*Peer `protobuf:"bytes,5,rep,name=peers,proto3" json:"peers,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -82,9 +83,20 @@ func (m *Master) GetRedisURL() string {
return "" return ""
} }
func (m *Master) GetPeers() []*Peer {
if m != nil {
return m.Peers
}
return nil
}
type JoinRequest struct { type JoinRequest struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
ClusterKey string `protobuf:"bytes,2,opt,name=cluster_key,json=clusterKey,proto3" json:"cluster_key,omitempty"` ClusterKey string `protobuf:"bytes,2,opt,name=cluster_key,json=clusterKey,proto3" json:"cluster_key,omitempty"`
GRPCAddress string `protobuf:"bytes,3,opt,name=grpc_address,json=grpcAddress,proto3" json:"grpc_address,omitempty"`
EndpointIP string `protobuf:"bytes,4,opt,name=endpoint_ip,json=endpointIp,proto3" json:"endpoint_ip,omitempty"`
EndpointPort uint64 `protobuf:"varint,5,opt,name=endpoint_port,json=endpointPort,proto3" json:"endpoint_port,omitempty"`
InterfaceName string `protobuf:"bytes,6,opt,name=interface_name,json=interfaceName,proto3" json:"interface_name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -128,8 +140,38 @@ func (m *JoinRequest) GetClusterKey() string {
return "" return ""
} }
func (m *JoinRequest) GetGRPCAddress() string {
if m != nil {
return m.GRPCAddress
}
return ""
}
func (m *JoinRequest) GetEndpointIP() string {
if m != nil {
return m.EndpointIP
}
return ""
}
func (m *JoinRequest) GetEndpointPort() uint64 {
if m != nil {
return m.EndpointPort
}
return 0
}
func (m *JoinRequest) GetInterfaceName() string {
if m != nil {
return m.InterfaceName
}
return ""
}
type JoinResponse struct { type JoinResponse struct {
Master *Master `protobuf:"bytes,1,opt,name=master,proto3" json:"master,omitempty"` Master *Master `protobuf:"bytes,1,opt,name=master,proto3" json:"master,omitempty"`
Node *Node `protobuf:"bytes,2,opt,name=node,proto3" json:"node,omitempty"`
Peers []*Peer `protobuf:"bytes,3,rep,name=peers,proto3" json:"peers,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -166,6 +208,20 @@ func (m *JoinResponse) GetMaster() *Master {
return nil return nil
} }
func (m *JoinResponse) GetNode() *Node {
if m != nil {
return m.Node
}
return nil
}
func (m *JoinResponse) GetPeers() []*Peer {
if m != nil {
return m.Peers
}
return nil
}
type ConnectRequest struct { type ConnectRequest struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -464,6 +520,7 @@ type Node struct {
EndpointPort uint64 `protobuf:"varint,5,opt,name=endpoint_port,json=endpointPort,proto3" json:"endpoint_port,omitempty"` EndpointPort uint64 `protobuf:"varint,5,opt,name=endpoint_port,json=endpointPort,proto3" json:"endpoint_port,omitempty"`
GatewayIP string `protobuf:"bytes,6,opt,name=gateway_ip,json=gatewayIp,proto3" json:"gateway_ip,omitempty"` GatewayIP string `protobuf:"bytes,6,opt,name=gateway_ip,json=gatewayIp,proto3" json:"gateway_ip,omitempty"`
Updated time.Time `protobuf:"bytes,7,opt,name=updated,proto3,stdtime" json:"updated"` Updated time.Time `protobuf:"bytes,7,opt,name=updated,proto3,stdtime" json:"updated"`
InterfaceName string `protobuf:"bytes,8,opt,name=interface_name,json=interfaceName,proto3" json:"interface_name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -542,6 +599,13 @@ func (m *Node) GetUpdated() time.Time {
return time.Time{} return time.Time{}
} }
func (m *Node) GetInterfaceName() string {
if m != nil {
return m.InterfaceName
}
return ""
}
type NodesRequest struct { type NodesRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
@ -967,71 +1031,75 @@ func init() {
} }
var fileDescriptor_b6184fc395da86b1 = []byte{ var fileDescriptor_b6184fc395da86b1 = []byte{
// 1014 bytes of a gzipped FileDescriptorProto // 1076 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x5d, 0x6f, 0xe3, 0x44, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x5f, 0x6f, 0xe3, 0x44,
0x17, 0x7e, 0x9d, 0xef, 0x1c, 0x27, 0x8d, 0x34, 0x5a, 0xf5, 0xf5, 0x06, 0x21, 0x17, 0xef, 0x05, 0x10, 0xc7, 0xf9, 0x9f, 0x49, 0xd3, 0x4a, 0xab, 0x53, 0xf1, 0x05, 0x21, 0x97, 0x9c, 0x10, 0x39,
0x59, 0xb4, 0xb2, 0x9b, 0x00, 0xe2, 0x4b, 0x8b, 0x68, 0x9a, 0xdd, 0xc5, 0x14, 0xaa, 0xec, 0x2c, 0x74, 0xb2, 0xdb, 0x02, 0xe2, 0xcf, 0xe9, 0x10, 0x4d, 0x73, 0x1c, 0xa6, 0x50, 0x85, 0x3d, 0xee,
0x7b, 0x83, 0x56, 0x0a, 0x6e, 0x3c, 0xa4, 0x6e, 0x9d, 0xcc, 0x60, 0x4f, 0x5a, 0x85, 0x1b, 0x6e, 0x05, 0x9d, 0x14, 0xdc, 0x78, 0x2e, 0x75, 0xeb, 0xd8, 0x8b, 0xbd, 0x69, 0x15, 0x3e, 0x01, 0x8f,
0xb9, 0xe4, 0xff, 0x20, 0x71, 0x0d, 0xff, 0x80, 0xab, 0x20, 0xe5, 0x97, 0xa0, 0x19, 0x8f, 0x4d, 0x7c, 0x1f, 0x24, 0x9e, 0x79, 0xe1, 0x9d, 0xa7, 0x20, 0xe5, 0x13, 0xf0, 0xc6, 0x2b, 0xda, 0xf5,
0xd2, 0x36, 0xaa, 0xbb, 0xec, 0x5d, 0xe6, 0xcc, 0x79, 0xce, 0x39, 0x7e, 0xce, 0x73, 0x8e, 0x1d, 0xda, 0x97, 0xb4, 0x8d, 0xea, 0xf6, 0x8e, 0xb7, 0xee, 0xec, 0xfc, 0x66, 0x32, 0xbf, 0xdf, 0xcc,
0xf8, 0x78, 0x12, 0xf0, 0xd3, 0xf9, 0x89, 0x3d, 0xa6, 0x53, 0x27, 0xe6, 0x24, 0x0c, 0xbd, 0x88, 0xac, 0x0b, 0x9f, 0x8c, 0x3c, 0x7e, 0x3c, 0x39, 0x32, 0x87, 0xe1, 0xd8, 0x8a, 0x39, 0xfa, 0xbe,
0x45, 0xf4, 0x8c, 0x8c, 0xb9, 0x73, 0x4a, 0x82, 0xa9, 0xef, 0x85, 0xa1, 0xe3, 0xb1, 0xc0, 0xb9, 0x13, 0xb1, 0x28, 0x3c, 0xc1, 0x21, 0xb7, 0x8e, 0xd1, 0x1b, 0xbb, 0x8e, 0xef, 0x5b, 0x0e, 0xf3,
0xe8, 0x66, 0x67, 0x9b, 0x45, 0x94, 0x53, 0xf4, 0x4e, 0x40, 0xed, 0x4d, 0x84, 0x9d, 0x79, 0x78, 0xac, 0xb3, 0x9d, 0xec, 0x6c, 0xb2, 0x28, 0xe4, 0x21, 0x79, 0xc7, 0x0b, 0xcd, 0x65, 0x84, 0x99,
0x2c, 0xb0, 0x2f, 0xba, 0xed, 0x7b, 0x13, 0x3a, 0xa1, 0xd2, 0xdb, 0x11, 0xbf, 0x12, 0x60, 0xfb, 0x79, 0x38, 0xcc, 0x33, 0xcf, 0x76, 0x5a, 0x77, 0x46, 0xe1, 0x28, 0x94, 0xde, 0x96, 0xf8, 0x2b,
0xad, 0x09, 0xa5, 0x93, 0x90, 0x38, 0xf2, 0x74, 0x32, 0xff, 0xc1, 0x21, 0x53, 0xc6, 0x17, 0xea, 0x01, 0xb6, 0xde, 0x1a, 0x85, 0xe1, 0xc8, 0x47, 0x4b, 0x9e, 0x8e, 0x26, 0x2f, 0x2c, 0x1c, 0x33,
0xd2, 0xbc, 0x7a, 0xc9, 0x83, 0x29, 0x89, 0xb9, 0x37, 0x65, 0x89, 0x83, 0xf5, 0x33, 0x54, 0xbe, 0x3e, 0x55, 0x97, 0xc6, 0xc5, 0x4b, 0xee, 0x8d, 0x31, 0xe6, 0xce, 0x98, 0x25, 0x0e, 0xed, 0xdf,
0xf1, 0x62, 0x4e, 0x22, 0xb4, 0x0b, 0x85, 0xc0, 0x37, 0xb4, 0x3d, 0xad, 0x53, 0xef, 0x57, 0x56, 0x35, 0xa8, 0x7c, 0xeb, 0xc4, 0x1c, 0x23, 0xb2, 0x09, 0x05, 0xcf, 0xd5, 0xb5, 0x2d, 0xad, 0x53,
0x4b, 0xb3, 0xe0, 0x0e, 0x70, 0x21, 0xf0, 0x51, 0x0f, 0x1a, 0x93, 0x88, 0x8d, 0x47, 0x9e, 0xef, 0xef, 0x56, 0xe6, 0x33, 0xa3, 0x60, 0xf7, 0x68, 0xc1, 0x73, 0xc9, 0x2e, 0xac, 0x8d, 0x22, 0x36,
0x47, 0x24, 0x8e, 0x8d, 0x82, 0xf4, 0x68, 0xad, 0x96, 0xa6, 0xfe, 0x0c, 0x0f, 0x0f, 0x0f, 0x12, 0x1c, 0x38, 0xae, 0x1b, 0x61, 0x1c, 0xeb, 0x05, 0xe9, 0xb1, 0x31, 0x9f, 0x19, 0x8d, 0x27, 0xb4,
0x33, 0xd6, 0x85, 0x93, 0x3a, 0xa0, 0x87, 0x50, 0x8f, 0x88, 0x1f, 0xc4, 0xa3, 0x79, 0x14, 0x1a, 0xbf, 0xbf, 0x97, 0x98, 0x69, 0x43, 0x38, 0xa9, 0x03, 0xb9, 0x0f, 0xf5, 0x08, 0x5d, 0x2f, 0x1e,
0x45, 0x09, 0x68, 0xac, 0x96, 0x66, 0x0d, 0x0b, 0xe3, 0x4b, 0xfc, 0x35, 0xae, 0xc9, 0xeb, 0x97, 0x4c, 0x22, 0x5f, 0x2f, 0x4a, 0xc0, 0xda, 0x7c, 0x66, 0xd4, 0xa8, 0x30, 0x3e, 0xa3, 0xdf, 0xd0,
0x51, 0x68, 0x3d, 0x05, 0xfd, 0x2b, 0x1a, 0xcc, 0x30, 0xf9, 0x71, 0x4e, 0x62, 0xbe, 0xb5, 0x0a, 0x9a, 0xbc, 0x7e, 0x16, 0xf9, 0xe4, 0x11, 0x94, 0x19, 0x62, 0x14, 0xeb, 0xe5, 0xad, 0x62, 0xa7,
0x13, 0xf4, 0x71, 0x38, 0x17, 0x85, 0x8e, 0xce, 0xc9, 0x22, 0x29, 0x02, 0x83, 0x32, 0x1d, 0x91, 0xb1, 0xfb, 0x9e, 0x79, 0x2d, 0x11, 0x66, 0x1f, 0x31, 0xa2, 0x09, 0xaa, 0xfd, 0xaf, 0x06, 0x8d,
0x85, 0xf5, 0x1c, 0x1a, 0x49, 0x9c, 0x98, 0xd1, 0x59, 0x4c, 0xd0, 0x01, 0x54, 0xa6, 0xf2, 0xc1, 0xaf, 0x43, 0x2f, 0xa0, 0xf8, 0xd3, 0x04, 0x63, 0xbe, 0xb2, 0x0a, 0x03, 0x1a, 0x43, 0x7f, 0x22,
0x64, 0x30, 0xbd, 0xf7, 0xd0, 0xbe, 0x95, 0x60, 0x3b, 0x61, 0x02, 0x2b, 0xa0, 0xd5, 0x81, 0x9d, 0x0a, 0x1d, 0x9c, 0xe2, 0x34, 0x29, 0x82, 0x82, 0x32, 0x1d, 0xe0, 0xf4, 0x52, 0x99, 0xc5, 0x1c,
0x43, 0x3a, 0x9b, 0x91, 0x31, 0xbf, 0xa5, 0x3a, 0xeb, 0x2f, 0x0d, 0x5a, 0x99, 0xab, 0x2a, 0xe0, 0x65, 0x5a, 0xd0, 0xc0, 0xc0, 0x65, 0xa1, 0x17, 0xf0, 0x81, 0xc7, 0xf4, 0x92, 0x84, 0xac, 0xcf,
0x39, 0x54, 0xcf, 0xc9, 0x82, 0x79, 0x41, 0x5a, 0xc1, 0x7b, 0x39, 0x2a, 0x38, 0x22, 0x8b, 0xa1, 0x67, 0x06, 0x3c, 0x56, 0x66, 0xbb, 0x4f, 0x21, 0x75, 0xb1, 0x19, 0xb9, 0x07, 0xcd, 0x0c, 0xc0,
0x17, 0x44, 0x7d, 0x7d, 0xb5, 0x34, 0xab, 0xea, 0x80, 0xd3, 0x38, 0xc8, 0x80, 0xea, 0x46, 0x17, 0xc2, 0x88, 0xeb, 0xe5, 0x2d, 0xad, 0x53, 0xa2, 0x6b, 0xa9, 0xb1, 0x1f, 0x46, 0x9c, 0xbc, 0x0b,
0x70, 0x7a, 0x44, 0x8f, 0xa1, 0xcc, 0x08, 0x89, 0x62, 0xa3, 0xb8, 0x57, 0xec, 0xe8, 0xbd, 0x77, 0xeb, 0x5e, 0xc0, 0x31, 0x7a, 0xe1, 0x0c, 0x71, 0x10, 0x38, 0x63, 0xd4, 0x2b, 0xf2, 0xd7, 0x36,
0x73, 0xa4, 0x1a, 0x12, 0x12, 0xe1, 0x04, 0x85, 0xee, 0x43, 0xd1, 0x9f, 0xc5, 0x46, 0x69, 0xaf, 0x33, 0xeb, 0xa1, 0x33, 0xc6, 0xf6, 0x9f, 0x1a, 0xac, 0x25, 0x95, 0xc7, 0x2c, 0x0c, 0x62, 0x24,
0xd8, 0xa9, 0xf7, 0xab, 0xab, 0xa5, 0x59, 0x1c, 0x1c, 0xbf, 0xc0, 0xc2, 0x66, 0xd9, 0x70, 0xef, 0x7b, 0x50, 0x19, 0x4b, 0x29, 0x65, 0xf9, 0x8d, 0xdd, 0xfb, 0x39, 0xa8, 0x4c, 0xb4, 0xa7, 0x0a,
0x60, 0xce, 0x4f, 0x69, 0x14, 0xfc, 0x44, 0x24, 0xe4, 0x16, 0x2a, 0xf6, 0x61, 0x77, 0x40, 0xbc, 0x48, 0x1e, 0x42, 0x29, 0x08, 0x5d, 0x94, 0xf4, 0xe4, 0xd3, 0xe2, 0x30, 0x74, 0x91, 0x4a, 0xd0,
0xbb, 0x20, 0x0c, 0xd8, 0xcd, 0x32, 0xf8, 0x02, 0x10, 0x2b, 0x84, 0xf5, 0x01, 0xfc, 0xff, 0xda, 0x4b, 0x25, 0x8b, 0xb7, 0x52, 0xb2, 0x03, 0xeb, 0xfb, 0x61, 0x10, 0xe0, 0x90, 0x5f, 0xa3, 0x65,
0x8d, 0x62, 0xf7, 0x3e, 0x14, 0x03, 0x3f, 0x36, 0xb4, 0x7f, 0x2b, 0x76, 0x07, 0x31, 0x16, 0x36, 0xfb, 0x2f, 0x0d, 0x36, 0x32, 0x57, 0x55, 0xfc, 0x77, 0x50, 0x3d, 0xc5, 0x29, 0x73, 0xbc, 0xb4,
0xcb, 0x85, 0x94, 0x39, 0xa1, 0x1a, 0x16, 0x05, 0x17, 0x1e, 0x27, 0x52, 0x35, 0x5a, 0xa2, 0x1a, 0xfa, 0xf7, 0x73, 0xa4, 0x3f, 0xc0, 0x69, 0xdf, 0xf1, 0xa2, 0x6e, 0x63, 0x3e, 0x33, 0xaa, 0xea,
0x65, 0x3a, 0x22, 0x0b, 0xf4, 0x36, 0x00, 0x9b, 0x9f, 0x84, 0xc1, 0x78, 0x4d, 0x55, 0xf5, 0xc4, 0x40, 0xd3, 0x38, 0x44, 0x87, 0xea, 0x52, 0xcf, 0xd3, 0xf4, 0xf8, 0x8a, 0x95, 0x92, 0xbb, 0x50,
0x22, 0x44, 0xf5, 0x67, 0x01, 0x4a, 0xc7, 0xd4, 0x27, 0x5b, 0x65, 0x89, 0xa0, 0x24, 0x5a, 0xa0, 0x74, 0x83, 0x58, 0x2f, 0x6d, 0x15, 0x3b, 0xf5, 0x6e, 0x75, 0x3e, 0x33, 0x8a, 0xbd, 0xc3, 0xa7,
0x90, 0xf2, 0xf7, 0x7a, 0xe3, 0x8b, 0x6f, 0xa8, 0xf1, 0x0e, 0xe8, 0x64, 0xe6, 0x33, 0x1a, 0xcc, 0x54, 0xd8, 0xda, 0x26, 0xdc, 0xd9, 0x9b, 0xf0, 0xe3, 0x30, 0xf2, 0x7e, 0x46, 0x09, 0xb9, 0x86,
0xf8, 0x28, 0x60, 0x46, 0x49, 0xd6, 0xb1, 0xb3, 0x5a, 0x9a, 0xf0, 0x44, 0x99, 0xdd, 0x21, 0x86, 0x8a, 0x6d, 0xd8, 0xec, 0xa1, 0x73, 0x13, 0x84, 0x0e, 0x9b, 0x59, 0x06, 0x57, 0x00, 0x62, 0x85,
0xd4, 0xc5, 0x65, 0xe8, 0x01, 0x34, 0x33, 0x00, 0xa3, 0x11, 0x37, 0xca, 0x7b, 0x5a, 0xa7, 0x84, 0x68, 0x7f, 0x08, 0x6f, 0x5e, 0xba, 0x51, 0xec, 0xde, 0x85, 0xa2, 0xe7, 0xc6, 0xba, 0xf6, 0xf2,
0x1b, 0xa9, 0x71, 0x48, 0x23, 0x8e, 0x1e, 0x01, 0x4c, 0x3c, 0x4e, 0x2e, 0xbd, 0x85, 0x08, 0x5a, 0x17, 0xdb, 0xbd, 0x98, 0x0a, 0x5b, 0xdb, 0x86, 0x94, 0x39, 0x31, 0x63, 0x2c, 0xf2, 0xce, 0x1c,
0x91, 0x41, 0x9b, 0xab, 0xa5, 0x59, 0x7f, 0x96, 0x58, 0xdd, 0x21, 0xae, 0x2b, 0x07, 0x97, 0xa1, 0x8e, 0x72, 0xc6, 0xb4, 0x64, 0xc6, 0x94, 0x49, 0xcc, 0xd8, 0xdb, 0x00, 0x6c, 0x72, 0xe4, 0x7b,
0xcf, 0xa1, 0x3a, 0x67, 0xbe, 0xc7, 0x89, 0x6f, 0x54, 0xe5, 0x63, 0xb5, 0xed, 0x64, 0xb9, 0xd8, 0xc3, 0x85, 0x19, 0xac, 0x27, 0x96, 0x03, 0x9c, 0xb6, 0xff, 0x29, 0x40, 0x49, 0xf4, 0xd3, 0xca,
0xe9, 0x72, 0xb1, 0xbf, 0x4d, 0x97, 0x4b, 0xbf, 0xf6, 0xc7, 0xd2, 0xfc, 0xdf, 0xaf, 0x7f, 0x9b, 0x21, 0x26, 0x50, 0x12, 0x12, 0x28, 0xa4, 0xfc, 0x7b, 0x51, 0xf8, 0xe2, 0x6b, 0x12, 0xfe, 0xff,
0x1a, 0x4e, 0x41, 0xd6, 0x0e, 0x34, 0x04, 0x95, 0x59, 0x73, 0x8f, 0xa1, 0xa9, 0xce, 0xaa, 0xa5, 0x19, 0xeb, 0x07, 0x00, 0x23, 0x87, 0xe3, 0xb9, 0x33, 0x15, 0x41, 0xe5, 0x48, 0x77, 0x9b, 0xf3,
0x8f, 0xa1, 0x3c, 0x13, 0x06, 0xd9, 0xd4, 0x7c, 0x1a, 0x16, 0x01, 0x70, 0x82, 0xb2, 0x7e, 0xd7, 0x99, 0x51, 0x7f, 0x92, 0x58, 0xed, 0x3e, 0xad, 0x2b, 0x07, 0x9b, 0x91, 0xcf, 0xa1, 0x3a, 0x61,
0xa0, 0x24, 0x34, 0xb2, 0xb5, 0x57, 0x6b, 0x7d, 0x29, 0xbc, 0xb9, 0xbe, 0x78, 0x61, 0x48, 0x2f, 0xae, 0xc3, 0xd1, 0xd5, 0xab, 0xb2, 0xac, 0x96, 0x99, 0xec, 0x72, 0x33, 0xdd, 0xe5, 0xe6, 0xf7,
0x89, 0x3f, 0x0a, 0x58, 0x32, 0x7c, 0xaa, 0x2f, 0x07, 0x89, 0xd9, 0x1d, 0xc6, 0x18, 0x94, 0x8b, 0xe9, 0x2e, 0xef, 0xd6, 0xfe, 0x98, 0x19, 0x6f, 0xfc, 0xfa, 0xb7, 0xa1, 0xd1, 0x14, 0x74, 0xc5,
0xcb, 0x62, 0xd4, 0x86, 0x5a, 0xda, 0x82, 0xa4, 0x8b, 0x38, 0x3b, 0x0b, 0x82, 0x36, 0xd4, 0x7f, 0x12, 0xa9, 0x5d, 0xb5, 0x44, 0xd6, 0x61, 0x4d, 0x30, 0x9e, 0xf5, 0xc0, 0x21, 0x34, 0xd5, 0x59,
0x0c, 0xcd, 0x4d, 0xcd, 0x67, 0x43, 0xae, 0xbd, 0xce, 0x90, 0x5b, 0x4f, 0xa1, 0x8c, 0xe9, 0x9c, 0x29, 0xff, 0x08, 0xca, 0x62, 0xb8, 0x13, 0xed, 0x6f, 0xb0, 0x12, 0x12, 0x94, 0x78, 0x5f, 0x4a,
0x13, 0xf4, 0x00, 0xaa, 0x82, 0xb2, 0x51, 0xc6, 0x12, 0xac, 0x96, 0x66, 0x45, 0x70, 0xe9, 0x0e, 0xa2, 0x95, 0x56, 0x4a, 0xba, 0x20, 0x5f, 0xe1, 0xf5, 0xc9, 0xe7, 0xf8, 0x7e, 0x78, 0x8e, 0xee,
0x70, 0x45, 0x5c, 0xb9, 0xbe, 0xd8, 0x35, 0x33, 0xc2, 0x2f, 0x69, 0x74, 0x9e, 0xee, 0x1a, 0x75, 0xc0, 0x63, 0xc9, 0x8c, 0x2a, 0xf9, 0xf6, 0x12, 0xb3, 0xdd, 0x8f, 0x29, 0x28, 0x17, 0x9b, 0xc5,
0xb4, 0x5e, 0x00, 0x3a, 0x8c, 0x88, 0xc7, 0x89, 0x8c, 0x96, 0x4e, 0xf7, 0x7f, 0x0c, 0x6a, 0x03, 0xa4, 0x05, 0xb5, 0x54, 0xa9, 0x44, 0x6c, 0x9a, 0x9d, 0x05, 0x41, 0x4b, 0x43, 0x72, 0x08, 0xcd,
0x1a, 0x90, 0x90, 0x5c, 0x09, 0xba, 0xe6, 0xaf, 0x6d, 0xfa, 0xb7, 0xa0, 0x29, 0x3d, 0x33, 0xb6, 0xe5, 0xd1, 0xc8, 0x76, 0x81, 0x76, 0xab, 0xad, 0xf7, 0x25, 0x94, 0x69, 0x38, 0xe1, 0x48, 0xee,
0x30, 0xec, 0xa4, 0x06, 0x45, 0xd7, 0x17, 0x50, 0x89, 0xa4, 0x45, 0xf1, 0xd5, 0xc9, 0xc1, 0x57, 0x41, 0x55, 0x50, 0x36, 0xc8, 0x58, 0x82, 0xf9, 0xcc, 0xa8, 0x08, 0x2e, 0xed, 0x1e, 0xad, 0x88,
0x92, 0x5d, 0xe1, 0x7a, 0xbf, 0xd5, 0xa0, 0xf6, 0xa5, 0xf2, 0x40, 0x0c, 0xaa, 0x6a, 0xc5, 0xa3, 0x2b, 0xdb, 0x15, 0x2b, 0x29, 0x40, 0x7e, 0x1e, 0x46, 0xa7, 0xe9, 0x4a, 0x52, 0xc7, 0xf6, 0x53,
0x6e, 0x8e, 0x48, 0x9b, 0x6f, 0x8e, 0x76, 0xef, 0x2e, 0x10, 0xf5, 0x00, 0xdf, 0x43, 0x73, 0x63, 0x20, 0xfb, 0x11, 0x3a, 0x1c, 0x65, 0xb4, 0x74, 0x09, 0xbc, 0x62, 0x50, 0x13, 0x48, 0x0f, 0x7d,
0xf5, 0xa2, 0x8f, 0x72, 0x04, 0xb9, 0x69, 0x59, 0xb7, 0x77, 0xaf, 0x8d, 0xea, 0x13, 0xf1, 0x91, 0xbc, 0x10, 0x74, 0xc1, 0x5f, 0x5b, 0xf6, 0xdf, 0x80, 0xa6, 0xf4, 0xcc, 0xd8, 0xa2, 0xb0, 0x9e,
0x80, 0x7c, 0x68, 0x5d, 0x59, 0xd6, 0xe8, 0x93, 0x1c, 0x39, 0x6e, 0x5e, 0xf0, 0x5b, 0xb3, 0xfc, 0x1a, 0x14, 0x5d, 0x5f, 0x40, 0x25, 0x92, 0x16, 0xc5, 0x57, 0x27, 0x07, 0x5f, 0x49, 0x76, 0x85,
0xa2, 0x41, 0xeb, 0xca, 0x1e, 0xcf, 0x95, 0xe6, 0xe6, 0xb7, 0x42, 0xfb, 0xd3, 0xd7, 0x81, 0x2a, 0xdb, 0xfd, 0xad, 0x06, 0xb5, 0xaf, 0x94, 0x07, 0x61, 0x50, 0x55, 0x2f, 0x01, 0xd9, 0xc9, 0x11,
0x4a, 0x27, 0x50, 0x12, 0x5f, 0x09, 0xc8, 0xce, 0x11, 0x63, 0xed, 0xb3, 0xa4, 0xed, 0xe4, 0xf6, 0x69, 0xf9, 0x81, 0x69, 0xed, 0xde, 0x04, 0xa2, 0x0a, 0xf8, 0x11, 0x9a, 0x4b, 0x1b, 0x9a, 0x7c,
0x57, 0x89, 0xa6, 0x50, 0x49, 0xe4, 0x88, 0xf6, 0xf3, 0xca, 0x2e, 0x7b, 0xc0, 0xee, 0x1d, 0x10, 0x9c, 0x23, 0xc8, 0x55, 0x3b, 0xbd, 0xb5, 0x79, 0x69, 0xa2, 0x1f, 0x8b, 0x4f, 0x37, 0xe2, 0xc2,
0x2a, 0xdd, 0x2b, 0xd0, 0xd7, 0x66, 0x12, 0x7d, 0x98, 0x47, 0x6d, 0xd7, 0x66, 0x78, 0x6b, 0x03, 0xc6, 0x85, 0x9d, 0x4e, 0x3e, 0xcd, 0x91, 0xe3, 0xea, 0x77, 0x60, 0x65, 0x96, 0x5f, 0x34, 0xd8,
0x5f, 0x81, 0xbe, 0x36, 0x9c, 0xb9, 0xa2, 0x5f, 0x1f, 0xe6, 0xad, 0xd1, 0xcf, 0xa0, 0x2c, 0x5f, 0xb8, 0xb0, 0xee, 0x73, 0xa5, 0xb9, 0xfa, 0xf1, 0x68, 0x7d, 0x76, 0x1b, 0xa8, 0xa2, 0x74, 0x04,
0x04, 0xc8, 0xc9, 0xb9, 0xf1, 0x33, 0xa2, 0xf6, 0xf3, 0x03, 0x14, 0x4f, 0x67, 0x50, 0x4e, 0xf4, 0x25, 0xf1, 0x21, 0x43, 0xcc, 0x1c, 0x31, 0x16, 0xbe, 0xf5, 0x5a, 0x56, 0x6e, 0x7f, 0x95, 0x68,
0xe7, 0xe4, 0x5c, 0x9e, 0x77, 0xca, 0xb5, 0xa1, 0xb5, 0xbe, 0xfd, 0xdd, 0xa3, 0xdc, 0xff, 0x06, 0x0c, 0x95, 0xa4, 0x1d, 0xc9, 0x76, 0xde, 0xb6, 0xcb, 0x0a, 0xdc, 0xb9, 0x01, 0x42, 0xa5, 0x7b,
0x3e, 0xbb, 0xe8, 0x9e, 0x54, 0x24, 0x2f, 0xef, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xcd, 0x85, 0x0e, 0x8d, 0x85, 0x99, 0x24, 0x1f, 0xe5, 0xe9, 0xb6, 0x4b, 0x33, 0xbc, 0x52, 0xc0, 0xe7, 0xd0,
0x12, 0x11, 0x44, 0x0c, 0x00, 0x00, 0x58, 0x18, 0xce, 0x5c, 0xd1, 0x2f, 0x0f, 0xf3, 0xca, 0xe8, 0x27, 0x50, 0x96, 0x0f, 0x01, 0xb1,
0x72, 0x6e, 0xfc, 0x8c, 0xa8, 0xed, 0xfc, 0x00, 0xc5, 0xd3, 0x09, 0x94, 0x93, 0xfe, 0xb3, 0x72,
0x2e, 0xcf, 0x1b, 0xe5, 0x5a, 0xea, 0xb5, 0xae, 0xf9, 0xc3, 0x83, 0xdc, 0xff, 0xa3, 0x3d, 0x3c,
0xdb, 0x39, 0xaa, 0x48, 0x5e, 0x3e, 0xf8, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x58, 0x29, 0xda, 0xfa,
0xda, 0x0d, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.

View file

@ -25,15 +25,22 @@ message Master {
string id = 1 [(gogoproto.customname) = "ID"]; string id = 1 [(gogoproto.customname) = "ID"];
string grpc_address = 2 [(gogoproto.customname) = "GRPCAddress"]; string grpc_address = 2 [(gogoproto.customname) = "GRPCAddress"];
string redis_url = 3 [(gogoproto.customname) = "RedisURL"]; string redis_url = 3 [(gogoproto.customname) = "RedisURL"];
repeated Peer peers = 5;
} }
message JoinRequest { message JoinRequest {
string id = 1 [(gogoproto.customname) = "ID"]; string id = 1 [(gogoproto.customname) = "ID"];
string cluster_key = 2; string cluster_key = 2;
string grpc_address = 3 [(gogoproto.customname) = "GRPCAddress"];
string endpoint_ip = 4 [(gogoproto.customname) = "EndpointIP"];
uint64 endpoint_port = 5;
string interface_name = 6;
} }
message JoinResponse { message JoinResponse {
Master master = 1; Master master = 1;
Node node = 2;
repeated Peer peers = 3;
} }
message ConnectRequest { message ConnectRequest {
@ -74,6 +81,7 @@ message Node {
uint64 endpoint_port = 5; uint64 endpoint_port = 5;
string gateway_ip = 6 [(gogoproto.customname) = "GatewayIP"]; string gateway_ip = 6 [(gogoproto.customname) = "GatewayIP"];
google.protobuf.Timestamp updated = 7 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; google.protobuf.Timestamp updated = 7 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
string interface_name = 8;
} }
message NodesRequest {} message NodesRequest {}

View file

@ -28,15 +28,7 @@ import (
) )
// Join attempts to connect to the peer and returns the master info // Join attempts to connect to the peer and returns the master info
func (c *Client) Join(key string) (*v1.Master, error) { func (c *Client) Join(req *v1.JoinRequest) (*v1.JoinResponse, error) {
ctx := context.Background() ctx := context.Background()
resp, err := c.heimdallClient.Join(ctx, &v1.JoinRequest{ return c.heimdallClient.Join(ctx, req)
ID: c.id,
ClusterKey: key,
})
if err != nil {
return nil, err
}
return resp.Master, nil
} }

View file

@ -60,6 +60,12 @@ func main() {
Value: fmt.Sprintf("tcp://%s:%d", heimdall.GetIP(), defaultGRPCPort), Value: fmt.Sprintf("tcp://%s:%d", heimdall.GetIP(), defaultGRPCPort),
EnvVar: "HEIMDALL_GRPC_ADDR", EnvVar: "HEIMDALL_GRPC_ADDR",
}, },
cli.StringFlag{
Name: "advertise-grpc-address",
Usage: "public advertise grpc address",
Value: fmt.Sprintf("tcp://%s:%d", heimdall.GetIP(), defaultGRPCPort),
EnvVar: "HEIMDALL_ADVERTISE_GRPC_ADDR",
},
cli.StringFlag{ cli.StringFlag{
Name: "redis-url, r", Name: "redis-url, r",
Usage: "uri for datastore backend", Usage: "uri for datastore backend",

View file

@ -41,17 +41,18 @@ import (
func runServer(cx *cli.Context) error { func runServer(cx *cli.Context) error {
cfg := &heimdall.Config{ cfg := &heimdall.Config{
ID: cx.String("id"), ID: cx.String("id"),
GRPCAddress: cx.String("addr"), GRPCAddress: cx.String("addr"),
GRPCPeerAddress: cx.String("peer"), AdvertiseGRPCAddress: cx.String("advertise-grpc-address"),
ClusterKey: cx.String("cluster-key"), GRPCPeerAddress: cx.String("peer"),
NodeNetwork: cx.String("node-network"), ClusterKey: cx.String("cluster-key"),
PeerNetwork: cx.String("peer-network"), NodeNetwork: cx.String("node-network"),
EndpointIP: cx.String("endpoint-ip"), PeerNetwork: cx.String("peer-network"),
EndpointPort: cx.Int("endpoint-port"), EndpointIP: cx.String("endpoint-ip"),
InterfaceName: cx.String("interface-name"), EndpointPort: cx.Int("endpoint-port"),
RedisURL: cx.String("redis-url"), InterfaceName: cx.String("interface-name"),
AdvertiseRedisURL: cx.String("advertise-redis-url"), RedisURL: cx.String("redis-url"),
AdvertiseRedisURL: cx.String("advertise-redis-url"),
} }
errCh := make(chan error, 1) errCh := make(chan error, 1)

View file

@ -29,6 +29,8 @@ type Config struct {
ID string ID string
// GRPCAddress is the address for the grpc server // GRPCAddress is the address for the grpc server
GRPCAddress string GRPCAddress string
// AdvertiseGRPCAddress is the public address for the grpc server
AdvertiseGRPCAddress string
// GRPCPeerAddress is the peer address to join // GRPCPeerAddress is the peer address to join
GRPCPeerAddress string GRPCPeerAddress string
// ClusterKey is a preshared key for cluster peers // ClusterKey is a preshared key for cluster peers

View file

@ -60,7 +60,35 @@ func (s *Server) Join(ctx context.Context, req *v1.JoinRequest) (*v1.JoinRespons
return nil, err return nil, err
} }
peers, err := s.getPeers(ctx)
if err != nil {
return nil, err
}
if err := s.ensureNetworkSubnet(ctx, req.ID); err != nil {
return nil, err
}
node, err := s.getNode(ctx, req.ID)
if err != nil {
if err != redis.ErrNil {
return nil, err
}
n, err := s.createNode(ctx, req)
if err != nil {
return nil, err
}
if err := s.updatePeerInfo(ctx, req.ID); err != nil {
return nil, err
}
node = n
}
return &v1.JoinResponse{ return &v1.JoinResponse{
Master: &master, Master: &master,
Node: node,
Peers: peers,
}, nil }, nil
} }

View file

@ -29,6 +29,7 @@ import (
"strings" "strings"
"github.com/gomodule/redigo/redis" "github.com/gomodule/redigo/redis"
"github.com/pkg/errors"
) )
type subnetRange struct { type subnetRange struct {
@ -37,8 +38,8 @@ type subnetRange struct {
Subnet *net.IPNet Subnet *net.IPNet
} }
func (s *Server) updateNodeNetwork(ctx context.Context, subnet string) error { func (s *Server) updateNodeNetwork(ctx context.Context, id string, subnet string) error {
if _, err := s.master(ctx, "SET", s.getNodeNetworkKey(s.cfg.ID), subnet); err != nil { if _, err := s.master(ctx, "SET", s.getNodeNetworkKey(id), subnet); err != nil {
return err return err
} }
return nil return nil
@ -70,7 +71,7 @@ func (s *Server) getOrAllocatePeerIP(ctx context.Context, id string) (net.IP, *n
func (s *Server) getNodeIP(ctx context.Context, id string) (net.IP, *net.IPNet, error) { func (s *Server) getNodeIP(ctx context.Context, id string) (net.IP, *net.IPNet, error) {
subnet, err := redis.String(s.local(ctx, "GET", s.getNodeNetworkKey(id))) subnet, err := redis.String(s.local(ctx, "GET", s.getNodeNetworkKey(id)))
if err != nil { if err != nil {
return nil, nil, err return nil, nil, errors.Wrap(err, "error getting node ip")
} }
r, err := parseSubnetRange(subnet) r, err := parseSubnetRange(subnet)
if err != nil { if err != nil {

View file

@ -23,6 +23,7 @@ package server
import ( import (
"context" "context"
"fmt"
"net/url" "net/url"
"sort" "sort"
"strings" "strings"
@ -82,24 +83,15 @@ func (s *Server) getNode(ctx context.Context, id string) (*v1.Node, error) {
func (s *Server) configureNode() error { func (s *Server) configureNode() error {
ctx := context.Background() ctx := context.Background()
nodeKeys, err := redis.Strings(s.local(ctx, "KEYS", s.getNodeKey("*"))) nodes, err := s.getNodes(ctx)
if err != nil { if err != nil {
return err return err
} }
// attempt to connect to existing // attempt to connect to existing
if len(nodeKeys) > 0 { if len(nodes) > 0 {
for _, nodeKey := range nodeKeys { for _, node := range nodes {
nodeData, err := redis.Bytes(s.local(ctx, "GET", nodeKey))
if err != nil {
logrus.Warn(err)
continue
}
var node v1.Node
if err := proto.Unmarshal(nodeData, &node); err != nil {
return err
}
// ignore self // ignore self
if node.Addr == s.cfg.GRPCAddress { if node.ID == s.cfg.ID {
continue continue
} }
@ -109,14 +101,28 @@ func (s *Server) configureNode() error {
logrus.Warn(err) logrus.Warn(err)
continue continue
} }
m, err := c.Join(s.cfg.ClusterKey) r, err := c.Join(&v1.JoinRequest{
ID: s.cfg.ID,
ClusterKey: s.cfg.ClusterKey,
GRPCAddress: s.cfg.GRPCAddress,
EndpointIP: s.cfg.EndpointIP,
EndpointPort: uint64(s.cfg.EndpointPort),
InterfaceName: s.cfg.InterfaceName,
})
if err != nil { if err != nil {
c.Close() c.Close()
logrus.Warn(err) logrus.Warn(err)
continue continue
} }
if err := s.joinMaster(m); err != nil { // TODO: start tunnel
if err := s.updatePeerConfig(ctx, r.Node, r.Peers); err != nil {
return err
}
// TODO: wait for tunnel to come up
time.Sleep(time.Second * 20)
if err := s.joinMaster(r.Master); err != nil {
c.Close() c.Close()
logrus.Warn(err) logrus.Warn(err)
continue continue
@ -154,6 +160,8 @@ func (s *Server) configureNode() error {
return err return err
} }
// TODO: start tunnel
if err := s.joinMaster(&master); err != nil { if err := s.joinMaster(&master); err != nil {
return err return err
} }
@ -163,14 +171,19 @@ func (s *Server) configureNode() error {
return nil return nil
} }
func (s *Server) disableReplica() { func (s *Server) disableReplica() error {
s.wpool = getPool(s.cfg.RedisURL) p, err := getPool(s.cfg.RedisURL)
if err != nil {
return err
}
s.wpool = p
// signal replica monitor to stop if started as a peer // signal replica monitor to stop if started as a peer
close(s.replicaCh) close(s.replicaCh)
// unset peer // unset peer
s.cfg.GRPCPeerAddress = "" s.cfg.GRPCPeerAddress = ""
return nil
} }
func (s *Server) replicaMonitor() { func (s *Server) replicaMonitor() {
@ -187,7 +200,7 @@ func (s *Server) replicaMonitor() {
logrus.Error(err) logrus.Error(err)
continue continue
} }
if n.ID != s.cfg.ID { if n == nil || n.ID != s.cfg.ID {
logrus.Debugf("waiting for new master to initialize: %s", n.ID) logrus.Debugf("waiting for new master to initialize: %s", n.ID)
continue continue
} }
@ -242,12 +255,15 @@ func (s *Server) masterHeartbeat() {
func (s *Server) joinMaster(m *v1.Master) error { func (s *Server) joinMaster(m *v1.Master) error {
// configure replica // configure replica
logrus.Infof("configuring node as replica of %+v", m.ID) logrus.Infof("configuring node as replica of %+v", m.ID)
conn, err := redis.DialURL(s.cfg.RedisURL) pool, err := getPool(s.cfg.RedisURL)
if err != nil { if err != nil {
return errors.Wrap(err, "unable to connect to redis") return err
} }
conn := pool.Get()
defer conn.Close() defer conn.Close()
logrus.Debugf("configuring redis as slave of %s", m.RedisURL)
u, err := url.Parse(m.RedisURL) u, err := url.Parse(m.RedisURL)
if err != nil { if err != nil {
return errors.Wrap(err, "error parsing master redis url") return errors.Wrap(err, "error parsing master redis url")
@ -258,15 +274,11 @@ func (s *Server) joinMaster(m *v1.Master) error {
if _, err := conn.Do("REPLICAOF", host, port); err != nil { if _, err := conn.Do("REPLICAOF", host, port); err != nil {
return err return err
} }
// auth
auth, ok := u.User.Password()
if ok {
if _, err := conn.Do("CONFIG", "SET", "MASTERAUTH", auth); err != nil {
return errors.Wrap(err, "error authenticating to redis")
}
}
s.wpool = getPool(m.RedisURL) s.wpool, err = getPool(m.RedisURL)
if err != nil {
return err
}
return nil return nil
} }
@ -275,10 +287,21 @@ func (s *Server) updateMasterInfo(ctx context.Context) error {
if _, err := s.master(ctx, "SET", clusterKey, s.cfg.ClusterKey); err != nil { if _, err := s.master(ctx, "SET", clusterKey, s.cfg.ClusterKey); err != nil {
return err return err
} }
// build redis url with gateway ip
gatewayIP, _, err := s.getNodeIP(ctx, s.cfg.ID)
if err != nil {
return err
}
u, err := url.Parse(s.cfg.RedisURL)
if err != nil {
return err
}
// update master redis url to gateway to serve over wireguard
u.Host = fmt.Sprintf("%s:%s", gatewayIP.String(), u.Port())
m := &v1.Master{ m := &v1.Master{
ID: s.cfg.ID, ID: s.cfg.ID,
GRPCAddress: s.cfg.GRPCAddress, GRPCAddress: s.cfg.AdvertiseGRPCAddress,
RedisURL: s.cfg.AdvertiseRedisURL, RedisURL: u.String(),
} }
data, err := proto.Marshal(m) data, err := proto.Marshal(m)
if err != nil { if err != nil {
@ -292,48 +315,91 @@ func (s *Server) updateMasterInfo(ctx context.Context) error {
if _, err := s.master(ctx, "EXPIRE", masterKey, int(masterHeartbeatInterval.Seconds())); err != nil { if _, err := s.master(ctx, "EXPIRE", masterKey, int(masterHeartbeatInterval.Seconds())); err != nil {
return errors.Wrap(err, "error setting expire for master info") return errors.Wrap(err, "error setting expire for master info")
} }
return nil return nil
} }
func (s *Server) nodeHeartbeat(ctx context.Context) { func (s *Server) updateNodeInfo(ctx context.Context) {
logrus.Debugf("starting node heartbeat: ttl=%s", nodeHeartbeatInterval) logrus.Debugf("starting node heartbeat: ttl=%s", nodeHeartbeatInterval)
t := time.NewTicker(nodeHeartbeatInterval) t := time.NewTicker(nodeHeartbeatInterval)
key := s.getNodeKey(s.cfg.ID)
for range t.C { for range t.C {
keyPair, err := s.getOrCreateKeyPair(ctx, s.cfg.ID) if err := s.updateLocalNodeInfo(ctx); err != nil {
if err != nil {
logrus.Error(err)
continue
}
nodeIP, _, err := s.getNodeIP(ctx, s.cfg.ID)
if err != nil {
logrus.Error(err)
continue
}
node := &v1.Node{
Updated: time.Now(),
ID: s.cfg.ID,
Addr: s.cfg.GRPCAddress,
KeyPair: keyPair,
EndpointIP: s.cfg.EndpointIP,
EndpointPort: uint64(s.cfg.EndpointPort),
GatewayIP: nodeIP.String(),
}
data, err := proto.Marshal(node)
if err != nil {
logrus.Error(err)
continue
}
if _, err := s.master(ctx, "SET", key, data); err != nil {
logrus.Error(err)
continue
}
if _, err := s.master(ctx, "EXPIRE", key, nodeHeartbeatExpiry); err != nil {
logrus.Error(err) logrus.Error(err)
continue continue
} }
} }
} }
func (s *Server) updateLocalNodeInfo(ctx context.Context) error {
key := s.getNodeKey(s.cfg.ID)
keyPair, err := s.getOrCreateKeyPair(ctx, s.cfg.ID)
if err != nil {
return err
}
nodeIP, _, err := s.getNodeIP(ctx, s.cfg.ID)
if err != nil {
return err
}
node := &v1.Node{
Updated: time.Now(),
ID: s.cfg.ID,
Addr: s.cfg.GRPCAddress,
KeyPair: keyPair,
EndpointIP: s.cfg.EndpointIP,
EndpointPort: uint64(s.cfg.EndpointPort),
GatewayIP: nodeIP.String(),
InterfaceName: s.cfg.InterfaceName,
}
data, err := proto.Marshal(node)
if err != nil {
return err
}
if _, err := s.master(ctx, "SET", key, data); err != nil {
return err
}
if _, err := s.master(ctx, "EXPIRE", key, nodeHeartbeatExpiry); err != nil {
return err
}
return nil
}
func (s *Server) createNode(ctx context.Context, req *v1.JoinRequest) (*v1.Node, error) {
key := s.getNodeKey(req.ID)
keyPair, err := s.getOrCreateKeyPair(ctx, req.ID)
if err != nil {
return nil, errors.Wrapf(err, "error getting/creating keypair for %s", req.ID)
}
nodeIP, _, err := s.getNodeIP(ctx, req.ID)
if err != nil {
return nil, errors.Wrapf(err, "error getting node ip for %s", req.ID)
}
node := &v1.Node{
Updated: time.Now(),
ID: req.ID,
Addr: req.GRPCAddress,
KeyPair: keyPair,
EndpointIP: req.EndpointIP,
EndpointPort: uint64(req.EndpointPort),
GatewayIP: nodeIP.String(),
InterfaceName: req.InterfaceName,
}
data, err := proto.Marshal(node)
if err != nil {
return nil, err
}
if _, err := s.master(ctx, "SET", key, data); err != nil {
return nil, err
}
if _, err := s.master(ctx, "EXPIRE", key, nodeHeartbeatExpiry); err != nil {
return nil, err
}
return node, nil
}

View file

@ -69,10 +69,9 @@ func (s *Server) getPeers(ctx context.Context) ([]*v1.Peer, error) {
func (s *Server) peerUpdater(ctx context.Context) { func (s *Server) peerUpdater(ctx context.Context) {
logrus.Debugf("starting peer config updater: ttl=%s", peerConfigUpdateInterval) logrus.Debugf("starting peer config updater: ttl=%s", peerConfigUpdateInterval)
t := time.NewTicker(peerConfigUpdateInterval) t := time.NewTicker(peerConfigUpdateInterval)
for range t.C { for range t.C {
logrus.Debug("peer config update")
uctx, cancel := context.WithTimeout(ctx, peerConfigUpdateInterval) uctx, cancel := context.WithTimeout(ctx, peerConfigUpdateInterval)
if err := s.updatePeerInfo(uctx, s.cfg.ID); err != nil { if err := s.updatePeerInfo(uctx, s.cfg.ID); err != nil {
logrus.Errorf("updateLocalPeerInfo: %s", err) logrus.Errorf("updateLocalPeerInfo: %s", err)
@ -80,7 +79,23 @@ func (s *Server) peerUpdater(ctx context.Context) {
continue continue
} }
if err := s.updatePeerConfig(uctx); err != nil { peers, err := s.getPeers(ctx)
if err != nil {
logrus.Error(err)
cancel()
continue
}
logrus.Debugf("peer update: peers %+v", peers)
node, err := s.getNode(ctx, s.cfg.ID)
if err != nil {
logrus.Error(err)
cancel()
continue
}
if err := s.updatePeerConfig(uctx, node, peers); err != nil {
logrus.Errorf("updatePeerConfig: %s", err) logrus.Errorf("updatePeerConfig: %s", err)
cancel() cancel()
continue continue
@ -208,47 +223,29 @@ func (s *Server) getPeerInfo(ctx context.Context, id string) (*v1.Peer, error) {
return &peer, nil return &peer, nil
} }
func (s *Server) updatePeerConfig(ctx context.Context) error { func (s *Server) updatePeerConfig(ctx context.Context, node *v1.Node, peers []*v1.Peer) error {
peerKeys, err := redis.Strings(s.local(ctx, "KEYS", s.getPeerKey("*"))) var nodePeers []*v1.Peer
if err != nil { for _, peer := range peers {
return err
}
var peers []*v1.Peer
for _, peerKey := range peerKeys {
peerData, err := redis.Bytes(s.local(ctx, "GET", peerKey))
if err != nil {
return err
}
var p v1.Peer
if err := proto.Unmarshal(peerData, &p); err != nil {
return err
}
// do not add self as a peer // do not add self as a peer
if p.ID == s.cfg.ID { if peer.ID == node.ID {
continue continue
} }
peers = append(peers, &p) nodePeers = append(nodePeers, peer)
} }
keyPair, err := s.getOrCreateKeyPair(ctx, s.cfg.ID) keyPair, err := s.getOrCreateKeyPair(ctx, node.ID)
if err != nil { if err != nil {
return err return err
} }
gatewayIP, gatewayNet, err := s.getNodeIP(ctx, s.cfg.ID) //size, _ := gatewayNet.Mask.Size()
if err != nil {
return err
}
size, _ := gatewayNet.Mask.Size()
wireguardCfg := &wg.Config{ wireguardCfg := &wg.Config{
Iface: s.cfg.InterfaceName, Iface: node.InterfaceName,
PrivateKey: keyPair.PrivateKey, PrivateKey: keyPair.PrivateKey,
ListenPort: s.cfg.EndpointPort, ListenPort: int(node.EndpointPort),
Address: fmt.Sprintf("%s/%d", gatewayIP.To4().String(), size), Address: fmt.Sprintf("%s/%d", node.GatewayIP, 16),
Peers: peers, Peers: nodePeers,
} }
wireguardConfigPath := s.getWireguardConfigPath() wireguardConfigPath := s.getWireguardConfigPath()

View file

@ -25,6 +25,7 @@ import (
"context" "context"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/url"
"path/filepath" "path/filepath"
"runtime" "runtime"
"runtime/pprof" "runtime/pprof"
@ -81,7 +82,10 @@ type Server struct {
// NewServer returns a new Heimdall server // NewServer returns a new Heimdall server
func NewServer(cfg *heimdall.Config) (*Server, error) { func NewServer(cfg *heimdall.Config) (*Server, error) {
pool := getPool(cfg.RedisURL) pool, err := getPool(cfg.RedisURL)
if err != nil {
return nil, err
}
return &Server{ return &Server{
cfg: cfg, cfg: cfg,
rpool: pool, rpool: pool,
@ -121,13 +125,28 @@ func (s *Server) Run() error {
} }
defer c.Close() defer c.Close()
master, err := c.Join(s.cfg.ClusterKey) r, err := c.Join(&v1.JoinRequest{
ID: s.cfg.ID,
ClusterKey: s.cfg.ClusterKey,
GRPCAddress: s.cfg.GRPCAddress,
EndpointIP: s.cfg.EndpointIP,
EndpointPort: uint64(s.cfg.EndpointPort),
InterfaceName: s.cfg.InterfaceName,
})
if err != nil { if err != nil {
return err return err
} }
logrus.Debugf("master info received: %+v", master) logrus.Debugf("response: %+v", r)
if err := s.joinMaster(master); err != nil { // start tunnel
if err := s.updatePeerConfig(ctx, r.Node, r.Peers); err != nil {
return errors.Wrap(err, "error updating peer config")
}
// TODO: wait for tunnel to come up
time.Sleep(time.Second * 20)
logrus.Debugf("master info received: %+v", r)
if err := s.joinMaster(r.Master); err != nil {
return err return err
} }
@ -144,12 +163,17 @@ func (s *Server) Run() error {
} }
// ensure node network subnet // ensure node network subnet
if err := s.ensureNetworkSubnet(ctx); err != nil { if err := s.ensureNetworkSubnet(ctx, s.cfg.ID); err != nil {
return err
}
// initial node update
if err := s.updateLocalNodeInfo(ctx); err != nil {
return err return err
} }
// start node heartbeat to update in redis // start node heartbeat to update in redis
go s.nodeHeartbeat(ctx) go s.updateNodeInfo(ctx)
// initial peer info update // initial peer info update
if err := s.updatePeerInfo(ctx, s.cfg.ID); err != nil { if err := s.updatePeerInfo(ctx, s.cfg.ID); err != nil {
@ -157,7 +181,15 @@ func (s *Server) Run() error {
} }
// initial config update // initial config update
if err := s.updatePeerConfig(ctx); err != nil { node, err := s.getNode(ctx, s.cfg.ID)
if err != nil {
return err
}
peers, err := s.getPeers(ctx)
if err != nil {
return err
}
if err := s.updatePeerConfig(ctx, node, peers); err != nil {
return err return err
} }
@ -184,7 +216,7 @@ func (s *Server) Run() error {
} }
}() }()
err := <-errCh err = <-errCh
return err return err
} }
@ -194,20 +226,33 @@ func (s *Server) Stop() error {
return nil return nil
} }
func getPool(u string) *redis.Pool { func getPool(redisUrl string) (*redis.Pool, error) {
pool := redis.NewPool(func() (redis.Conn, error) { pool := redis.NewPool(func() (redis.Conn, error) {
conn, err := redis.DialURL(u) conn, err := redis.DialURL(redisUrl)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "unable to connect to redis") return nil, errors.Wrap(err, "unable to connect to redis")
} }
u, err := url.Parse(redisUrl)
if err != nil {
return nil, err
}
auth, ok := u.User.Password()
if ok {
logrus.Debug("setting masterauth for redis")
if _, err := conn.Do("CONFIG", "SET", "MASTERAUTH", auth); err != nil {
return nil, errors.Wrap(err, "error authenticating to redis")
}
}
return conn, nil return conn, nil
}, 10) }, 10)
return pool return pool, nil
} }
func (s *Server) ensureNetworkSubnet(ctx context.Context) error { func (s *Server) ensureNetworkSubnet(ctx context.Context, id string) error {
network, err := redis.String(s.local(ctx, "GET", s.getNodeNetworkKey(s.cfg.ID))) network, err := redis.String(s.local(ctx, "GET", s.getNodeNetworkKey(id)))
if err != nil { if err != nil {
if err != redis.ErrNil { if err != redis.ErrNil {
return err return err
@ -222,7 +267,6 @@ func (s *Server) ensureNetworkSubnet(ctx context.Context) error {
if err != nil { if err != nil {
return err return err
} }
logrus.Debug(nodeNetworkKeys)
lookup := map[string]struct{}{} lookup := map[string]struct{}{}
for _, netKey := range nodeNetworkKeys { for _, netKey := range nodeNetworkKeys {
n, err := redis.String(s.local(ctx, "GET", netKey)) n, err := redis.String(s.local(ctx, "GET", netKey))
@ -244,8 +288,8 @@ func (s *Server) ensureNetworkSubnet(ctx context.Context) error {
subnet = n subnet = n
continue continue
} }
logrus.Debugf("allocated network %s for %s", n.String(), s.cfg.ID) logrus.Debugf("allocated network %s for %s", n.String(), id)
if err := s.updateNodeNetwork(ctx, n.String()); err != nil { if err := s.updateNodeNetwork(ctx, id, n.String()); err != nil {
return err return err
} }
break break
@ -253,7 +297,7 @@ func (s *Server) ensureNetworkSubnet(ctx context.Context) error {
return nil return nil
} }
logrus.Debugf("node network: %s", network) logrus.Debugf("node network for %s: %s", id, network)
return nil return nil
} }