add basic client; enable node level routing

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
Evan Hazlett 2019-10-04 22:56:46 -04:00
parent c0515d4802
commit ed73f97bd3
No known key found for this signature in database
GPG key ID: A519480096146526
16 changed files with 1292 additions and 143 deletions

View file

@ -8,6 +8,7 @@ import (
fmt "fmt"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
types "github.com/gogo/protobuf/types"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
@ -409,6 +410,272 @@ func (m *Peer) GetEndpoint() string {
return ""
}
type PeersRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PeersRequest) Reset() { *m = PeersRequest{} }
func (m *PeersRequest) String() string { return proto.CompactTextString(m) }
func (*PeersRequest) ProtoMessage() {}
func (*PeersRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_b6184fc395da86b1, []int{8}
}
func (m *PeersRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PeersRequest.Unmarshal(m, b)
}
func (m *PeersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PeersRequest.Marshal(b, m, deterministic)
}
func (m *PeersRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_PeersRequest.Merge(m, src)
}
func (m *PeersRequest) XXX_Size() int {
return xxx_messageInfo_PeersRequest.Size(m)
}
func (m *PeersRequest) XXX_DiscardUnknown() {
xxx_messageInfo_PeersRequest.DiscardUnknown(m)
}
var xxx_messageInfo_PeersRequest proto.InternalMessageInfo
type PeersResponse struct {
Peers []*Peer `protobuf:"bytes,1,rep,name=peers,proto3" json:"peers,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PeersResponse) Reset() { *m = PeersResponse{} }
func (m *PeersResponse) String() string { return proto.CompactTextString(m) }
func (*PeersResponse) ProtoMessage() {}
func (*PeersResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_b6184fc395da86b1, []int{9}
}
func (m *PeersResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PeersResponse.Unmarshal(m, b)
}
func (m *PeersResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PeersResponse.Marshal(b, m, deterministic)
}
func (m *PeersResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_PeersResponse.Merge(m, src)
}
func (m *PeersResponse) XXX_Size() int {
return xxx_messageInfo_PeersResponse.Size(m)
}
func (m *PeersResponse) XXX_DiscardUnknown() {
xxx_messageInfo_PeersResponse.DiscardUnknown(m)
}
var xxx_messageInfo_PeersResponse proto.InternalMessageInfo
func (m *PeersResponse) GetPeers() []*Peer {
if m != nil {
return m.Peers
}
return nil
}
type Route struct {
NodeID string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
Network string `protobuf:"bytes,2,opt,name=network,proto3" json:"network,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Route) Reset() { *m = Route{} }
func (m *Route) String() string { return proto.CompactTextString(m) }
func (*Route) ProtoMessage() {}
func (*Route) Descriptor() ([]byte, []int) {
return fileDescriptor_b6184fc395da86b1, []int{10}
}
func (m *Route) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Route.Unmarshal(m, b)
}
func (m *Route) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Route.Marshal(b, m, deterministic)
}
func (m *Route) XXX_Merge(src proto.Message) {
xxx_messageInfo_Route.Merge(m, src)
}
func (m *Route) XXX_Size() int {
return xxx_messageInfo_Route.Size(m)
}
func (m *Route) XXX_DiscardUnknown() {
xxx_messageInfo_Route.DiscardUnknown(m)
}
var xxx_messageInfo_Route proto.InternalMessageInfo
func (m *Route) GetNodeID() string {
if m != nil {
return m.NodeID
}
return ""
}
func (m *Route) GetNetwork() string {
if m != nil {
return m.Network
}
return ""
}
type CreateRouteRequest struct {
NodeID string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
Network string `protobuf:"bytes,2,opt,name=network,proto3" json:"network,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CreateRouteRequest) Reset() { *m = CreateRouteRequest{} }
func (m *CreateRouteRequest) String() string { return proto.CompactTextString(m) }
func (*CreateRouteRequest) ProtoMessage() {}
func (*CreateRouteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_b6184fc395da86b1, []int{11}
}
func (m *CreateRouteRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CreateRouteRequest.Unmarshal(m, b)
}
func (m *CreateRouteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CreateRouteRequest.Marshal(b, m, deterministic)
}
func (m *CreateRouteRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_CreateRouteRequest.Merge(m, src)
}
func (m *CreateRouteRequest) XXX_Size() int {
return xxx_messageInfo_CreateRouteRequest.Size(m)
}
func (m *CreateRouteRequest) XXX_DiscardUnknown() {
xxx_messageInfo_CreateRouteRequest.DiscardUnknown(m)
}
var xxx_messageInfo_CreateRouteRequest proto.InternalMessageInfo
func (m *CreateRouteRequest) GetNodeID() string {
if m != nil {
return m.NodeID
}
return ""
}
func (m *CreateRouteRequest) GetNetwork() string {
if m != nil {
return m.Network
}
return ""
}
type DeleteRouteRequest struct {
Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DeleteRouteRequest) Reset() { *m = DeleteRouteRequest{} }
func (m *DeleteRouteRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteRouteRequest) ProtoMessage() {}
func (*DeleteRouteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_b6184fc395da86b1, []int{12}
}
func (m *DeleteRouteRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteRouteRequest.Unmarshal(m, b)
}
func (m *DeleteRouteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DeleteRouteRequest.Marshal(b, m, deterministic)
}
func (m *DeleteRouteRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_DeleteRouteRequest.Merge(m, src)
}
func (m *DeleteRouteRequest) XXX_Size() int {
return xxx_messageInfo_DeleteRouteRequest.Size(m)
}
func (m *DeleteRouteRequest) XXX_DiscardUnknown() {
xxx_messageInfo_DeleteRouteRequest.DiscardUnknown(m)
}
var xxx_messageInfo_DeleteRouteRequest proto.InternalMessageInfo
func (m *DeleteRouteRequest) GetNetwork() string {
if m != nil {
return m.Network
}
return ""
}
type RoutesRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RoutesRequest) Reset() { *m = RoutesRequest{} }
func (m *RoutesRequest) String() string { return proto.CompactTextString(m) }
func (*RoutesRequest) ProtoMessage() {}
func (*RoutesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_b6184fc395da86b1, []int{13}
}
func (m *RoutesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RoutesRequest.Unmarshal(m, b)
}
func (m *RoutesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RoutesRequest.Marshal(b, m, deterministic)
}
func (m *RoutesRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_RoutesRequest.Merge(m, src)
}
func (m *RoutesRequest) XXX_Size() int {
return xxx_messageInfo_RoutesRequest.Size(m)
}
func (m *RoutesRequest) XXX_DiscardUnknown() {
xxx_messageInfo_RoutesRequest.DiscardUnknown(m)
}
var xxx_messageInfo_RoutesRequest proto.InternalMessageInfo
type RoutesResponse struct {
Routes []*Route `protobuf:"bytes,1,rep,name=routes,proto3" json:"routes,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RoutesResponse) Reset() { *m = RoutesResponse{} }
func (m *RoutesResponse) String() string { return proto.CompactTextString(m) }
func (*RoutesResponse) ProtoMessage() {}
func (*RoutesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_b6184fc395da86b1, []int{14}
}
func (m *RoutesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RoutesResponse.Unmarshal(m, b)
}
func (m *RoutesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RoutesResponse.Marshal(b, m, deterministic)
}
func (m *RoutesResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_RoutesResponse.Merge(m, src)
}
func (m *RoutesResponse) XXX_Size() int {
return xxx_messageInfo_RoutesResponse.Size(m)
}
func (m *RoutesResponse) XXX_DiscardUnknown() {
xxx_messageInfo_RoutesResponse.DiscardUnknown(m)
}
var xxx_messageInfo_RoutesResponse proto.InternalMessageInfo
func (m *RoutesResponse) GetRoutes() []*Route {
if m != nil {
return m.Routes
}
return nil
}
func init() {
proto.RegisterType((*Master)(nil), "io.stellarproject.heimdall.api.v1.Master")
proto.RegisterType((*ConnectRequest)(nil), "io.stellarproject.heimdall.api.v1.ConnectRequest")
@ -418,6 +685,13 @@ func init() {
proto.RegisterType((*NodesRequest)(nil), "io.stellarproject.heimdall.api.v1.NodesRequest")
proto.RegisterType((*NodesResponse)(nil), "io.stellarproject.heimdall.api.v1.NodesResponse")
proto.RegisterType((*Peer)(nil), "io.stellarproject.heimdall.api.v1.Peer")
proto.RegisterType((*PeersRequest)(nil), "io.stellarproject.heimdall.api.v1.PeersRequest")
proto.RegisterType((*PeersResponse)(nil), "io.stellarproject.heimdall.api.v1.PeersResponse")
proto.RegisterType((*Route)(nil), "io.stellarproject.heimdall.api.v1.Route")
proto.RegisterType((*CreateRouteRequest)(nil), "io.stellarproject.heimdall.api.v1.CreateRouteRequest")
proto.RegisterType((*DeleteRouteRequest)(nil), "io.stellarproject.heimdall.api.v1.DeleteRouteRequest")
proto.RegisterType((*RoutesRequest)(nil), "io.stellarproject.heimdall.api.v1.RoutesRequest")
proto.RegisterType((*RoutesResponse)(nil), "io.stellarproject.heimdall.api.v1.RoutesResponse")
}
func init() {
@ -425,42 +699,56 @@ func init() {
}
var fileDescriptor_b6184fc395da86b1 = []byte{
// 552 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcd, 0x6a, 0xdb, 0x4c,
0x14, 0x45, 0xb6, 0xe3, 0xd8, 0x57, 0x4e, 0x02, 0xc3, 0xc7, 0x87, 0x08, 0x14, 0x39, 0xda, 0xd4,
0x29, 0x41, 0xc2, 0xea, 0xa6, 0x50, 0xba, 0x88, 0x53, 0x48, 0x45, 0xda, 0xa0, 0x0e, 0xcd, 0xa6,
0x1b, 0x33, 0x91, 0x06, 0x67, 0x1a, 0x45, 0x33, 0x9d, 0x19, 0x3b, 0x08, 0x0a, 0x7d, 0xb3, 0x3e,
0x46, 0x97, 0x5a, 0xe8, 0x49, 0x8a, 0xa4, 0xb1, 0x49, 0x16, 0x69, 0x5d, 0xe8, 0x6e, 0xee, 0xd1,
0x39, 0x57, 0xe7, 0x9e, 0xf9, 0x81, 0x57, 0x0b, 0xa6, 0x6f, 0x96, 0xd7, 0x7e, 0xc2, 0xef, 0x02,
0xa5, 0x69, 0x96, 0x11, 0x29, 0x24, 0xff, 0x42, 0x13, 0x1d, 0xdc, 0x50, 0x76, 0x97, 0x92, 0x2c,
0x0b, 0x88, 0x60, 0xc1, 0x6a, 0xba, 0xa9, 0x7d, 0x21, 0xb9, 0xe6, 0xe8, 0x88, 0x71, 0xff, 0xb1,
0xc2, 0xdf, 0x30, 0x88, 0x60, 0xfe, 0x6a, 0x7a, 0xf8, 0xdf, 0x82, 0x2f, 0x78, 0xc3, 0x0e, 0xea,
0x55, 0x2b, 0xf4, 0xbe, 0x43, 0xff, 0x03, 0x51, 0x9a, 0x4a, 0xf4, 0x3f, 0x74, 0x58, 0xea, 0x58,
0x63, 0x6b, 0x32, 0x9c, 0xf5, 0xab, 0xd2, 0xed, 0x44, 0x6f, 0x71, 0x87, 0xa5, 0x28, 0x84, 0xd1,
0x42, 0x8a, 0x64, 0x4e, 0xd2, 0x54, 0x52, 0xa5, 0x9c, 0x4e, 0xc3, 0x38, 0xa8, 0x4a, 0xd7, 0x3e,
0xc7, 0xf1, 0xd9, 0x69, 0x0b, 0x63, 0xbb, 0x26, 0x99, 0x02, 0x1d, 0xc3, 0x50, 0xd2, 0x94, 0xa9,
0xf9, 0x52, 0x66, 0x4e, 0xb7, 0x11, 0x8c, 0xaa, 0xd2, 0x1d, 0xe0, 0x1a, 0xbc, 0xc2, 0xef, 0xf1,
0xa0, 0xf9, 0x7c, 0x25, 0x33, 0x2f, 0x82, 0xfd, 0x33, 0x9e, 0xe7, 0x34, 0xd1, 0x98, 0x7e, 0x5d,
0x52, 0xa5, 0x9f, 0x34, 0xe2, 0x82, 0x9d, 0x64, 0xcb, 0xda, 0xeb, 0xfc, 0x96, 0x16, 0xad, 0x0f,
0x0c, 0x06, 0xba, 0xa0, 0x85, 0xf7, 0x09, 0x0e, 0x36, 0xad, 0x94, 0xe0, 0xb9, 0xa2, 0xe8, 0x14,
0xfa, 0x77, 0xcd, 0x78, 0x4d, 0x3f, 0x3b, 0x3c, 0xf6, 0xff, 0x18, 0x94, 0xdf, 0xe6, 0x81, 0x8d,
0xd0, 0x8b, 0x60, 0xf7, 0x82, 0x16, 0x31, 0x61, 0xb2, 0x76, 0x20, 0x24, 0x5b, 0x11, 0x4d, 0x1b,
0x07, 0x56, 0xeb, 0xc0, 0x40, 0x17, 0xb4, 0x40, 0xcf, 0x00, 0xc4, 0xf2, 0x3a, 0x63, 0xc9, 0x03,
0x87, 0xc3, 0x16, 0xa9, 0x0d, 0xfe, 0xb4, 0xa0, 0x77, 0xc9, 0x53, 0xfa, 0xe4, 0x88, 0x08, 0x7a,
0x75, 0xcc, 0x46, 0xd9, 0xac, 0xd1, 0x47, 0xd8, 0xbd, 0xa5, 0x85, 0x20, 0x4c, 0x36, 0x49, 0xda,
0xe1, 0x8b, 0x2d, 0x66, 0x30, 0x8e, 0x67, 0x76, 0x55, 0xba, 0x6b, 0xfb, 0x78, 0xdd, 0x07, 0x9d,
0x00, 0x2c, 0x88, 0xa6, 0xf7, 0xa4, 0x98, 0x33, 0xe1, 0xf4, 0x1a, 0x1b, 0x7b, 0x55, 0xe9, 0x0e,
0xcf, 0x5b, 0x34, 0x8a, 0xf1, 0xd0, 0x10, 0x22, 0x81, 0x8e, 0x60, 0xb4, 0x66, 0x0b, 0x2e, 0xb5,
0xb3, 0x33, 0xb6, 0x26, 0x3d, 0x6c, 0x1b, 0x2c, 0xe6, 0x52, 0x7b, 0xfb, 0x30, 0xaa, 0xe7, 0x52,
0x66, 0x0b, 0xbd, 0x4b, 0xd8, 0x33, 0xb5, 0xd9, 0x87, 0x37, 0xb0, 0x93, 0xd7, 0x80, 0x63, 0x8d,
0xbb, 0x13, 0x3b, 0x7c, 0xbe, 0xc5, 0x08, 0x75, 0x03, 0xdc, 0xaa, 0xbc, 0x1f, 0x16, 0xf4, 0x62,
0xfa, 0x9b, 0x43, 0xfa, 0x20, 0xa4, 0xce, 0x3f, 0x0a, 0x29, 0x00, 0x9b, 0x64, 0x19, 0xbf, 0xa7,
0xe9, 0x9c, 0x09, 0xe5, 0x74, 0xc7, 0xdd, 0xc9, 0x70, 0xb6, 0x5f, 0x95, 0x2e, 0x9c, 0xb6, 0x70,
0x14, 0x2b, 0x0c, 0x86, 0x12, 0x09, 0x85, 0x0e, 0x61, 0x40, 0xf3, 0x54, 0x70, 0x96, 0xeb, 0x36,
0x53, 0xbc, 0xa9, 0xc3, 0x6f, 0x30, 0x78, 0x67, 0xfe, 0x8e, 0x04, 0xec, 0x9a, 0x63, 0x8a, 0xa6,
0x5b, 0xb8, 0x7c, 0x7c, 0x3b, 0x0e, 0xc3, 0xbf, 0x91, 0xb4, 0xe9, 0xcf, 0xfc, 0xcf, 0x27, 0x5b,
0xbf, 0x2c, 0xaf, 0x57, 0xd3, 0xeb, 0x7e, 0xf3, 0x36, 0xbc, 0xfc, 0x15, 0x00, 0x00, 0xff, 0xff,
0x5f, 0xf4, 0xa8, 0x6a, 0x90, 0x04, 0x00, 0x00,
// 770 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x5d, 0x6b, 0xe3, 0x46,
0x14, 0x45, 0xfe, 0x90, 0xed, 0x2b, 0xc7, 0x81, 0xa1, 0x04, 0xe1, 0x52, 0xe4, 0xa8, 0x0f, 0x75,
0x4a, 0x90, 0x62, 0x97, 0x42, 0xa1, 0x14, 0x1a, 0x27, 0x6d, 0x2a, 0xd2, 0x06, 0x77, 0xda, 0xbc,
0x94, 0x82, 0x91, 0xad, 0xa9, 0xa3, 0x44, 0xf6, 0x4c, 0x47, 0x63, 0x07, 0x3f, 0xf5, 0x9f, 0xf5,
0x67, 0xec, 0xa3, 0x1f, 0xfc, 0x47, 0x76, 0x99, 0xd1, 0xc8, 0x6b, 0x6f, 0xc8, 0xae, 0xc2, 0xee,
0x9b, 0xee, 0x99, 0x7b, 0xcf, 0x9c, 0x7b, 0xe6, 0x4b, 0xf0, 0xdd, 0x34, 0x16, 0x77, 0x8b, 0xb1,
0x37, 0xa1, 0x33, 0x3f, 0x15, 0x24, 0x49, 0x42, 0xce, 0x38, 0xbd, 0x27, 0x13, 0xe1, 0xdf, 0x91,
0x78, 0x16, 0x85, 0x49, 0xe2, 0x87, 0x2c, 0xf6, 0x97, 0xbd, 0x6d, 0xec, 0x31, 0x4e, 0x05, 0x45,
0xc7, 0x31, 0xf5, 0xf6, 0x2b, 0xbc, 0x6d, 0x46, 0xc8, 0x62, 0x6f, 0xd9, 0x6b, 0x7f, 0x36, 0xa5,
0x53, 0xaa, 0xb2, 0x7d, 0xf9, 0x95, 0x15, 0xb6, 0x3f, 0x9f, 0x52, 0x3a, 0x4d, 0x88, 0xaf, 0xa2,
0xf1, 0xe2, 0x1f, 0x9f, 0xcc, 0x98, 0x58, 0x65, 0x83, 0xee, 0x7f, 0x60, 0xfe, 0x16, 0xa6, 0x82,
0x70, 0x74, 0x04, 0xa5, 0x38, 0xb2, 0x8d, 0x8e, 0xd1, 0x6d, 0x0c, 0xcc, 0xcd, 0xda, 0x29, 0x05,
0x97, 0xb8, 0x14, 0x47, 0xa8, 0x0f, 0xcd, 0x29, 0x67, 0x93, 0x51, 0x18, 0x45, 0x9c, 0xa4, 0xa9,
0x5d, 0x52, 0x19, 0x87, 0x9b, 0xb5, 0x63, 0x5d, 0xe1, 0xe1, 0xc5, 0x79, 0x06, 0x63, 0x4b, 0x26,
0xe9, 0x00, 0x9d, 0x40, 0x83, 0x93, 0x28, 0x4e, 0x47, 0x0b, 0x9e, 0xd8, 0x65, 0x55, 0xd0, 0xdc,
0xac, 0x9d, 0x3a, 0x96, 0xe0, 0x2d, 0xfe, 0x15, 0xd7, 0xd5, 0xf0, 0x2d, 0x4f, 0xdc, 0x00, 0x5a,
0x17, 0x74, 0x3e, 0x27, 0x13, 0x81, 0xc9, 0xbf, 0x0b, 0x92, 0x8a, 0x67, 0x85, 0x38, 0x60, 0x4d,
0x92, 0x85, 0xd4, 0x3a, 0x7a, 0x20, 0xab, 0x4c, 0x07, 0x06, 0x0d, 0x5d, 0x93, 0x95, 0xfb, 0x27,
0x1c, 0x6e, 0xa9, 0x52, 0x46, 0xe7, 0x29, 0x41, 0xe7, 0x60, 0xce, 0x54, 0x7b, 0x8a, 0xcf, 0xea,
0x9f, 0x78, 0x1f, 0x74, 0xd1, 0xcb, 0xfc, 0xc0, 0xba, 0xd0, 0x0d, 0xa0, 0x76, 0x4d, 0x56, 0xc3,
0x30, 0xe6, 0x52, 0x01, 0xe3, 0xf1, 0x32, 0x14, 0x44, 0x29, 0x30, 0x32, 0x05, 0x1a, 0xba, 0x26,
0x2b, 0xf4, 0x05, 0x00, 0x5b, 0x8c, 0x93, 0x78, 0xb2, 0xa3, 0xb0, 0x91, 0x21, 0x52, 0xe0, 0x2b,
0x03, 0x2a, 0x37, 0x34, 0x22, 0xcf, 0xb6, 0x88, 0xa0, 0x22, 0x6d, 0xd6, 0x95, 0xea, 0x1b, 0xfd,
0x0e, 0xb5, 0x07, 0xb2, 0x62, 0x61, 0xcc, 0x95, 0x93, 0x56, 0xff, 0xeb, 0x02, 0x3d, 0x68, 0xc5,
0x03, 0x6b, 0xb3, 0x76, 0x72, 0xf9, 0x38, 0xe7, 0x41, 0xa7, 0x00, 0xd3, 0x50, 0x90, 0xc7, 0x70,
0x35, 0x8a, 0x99, 0x5d, 0x51, 0x32, 0x0e, 0x36, 0x6b, 0xa7, 0x71, 0x95, 0xa1, 0xc1, 0x10, 0x37,
0x74, 0x42, 0xc0, 0xd0, 0x31, 0x34, 0xf3, 0x6c, 0x46, 0xb9, 0xb0, 0xab, 0x1d, 0xa3, 0x5b, 0xc1,
0x96, 0xc6, 0x86, 0x94, 0x0b, 0xb7, 0x05, 0x4d, 0xd9, 0x57, 0xaa, 0x97, 0xd0, 0xbd, 0x81, 0x03,
0x1d, 0xeb, 0x75, 0xf8, 0x01, 0xaa, 0x73, 0x09, 0xd8, 0x46, 0xa7, 0xdc, 0xb5, 0xfa, 0x5f, 0x15,
0x68, 0x41, 0x12, 0xe0, 0xac, 0xca, 0xfd, 0xdf, 0x80, 0xca, 0x90, 0xbc, 0x67, 0x93, 0xee, 0x98,
0x54, 0xfa, 0x44, 0x26, 0xf9, 0x60, 0x85, 0x49, 0x42, 0x1f, 0x49, 0x34, 0x8a, 0x59, 0x6a, 0x97,
0x3b, 0xe5, 0x6e, 0x63, 0xd0, 0xda, 0xac, 0x1d, 0x38, 0xcf, 0xe0, 0x60, 0x98, 0x62, 0xd0, 0x29,
0x01, 0x4b, 0x51, 0x1b, 0xea, 0x64, 0x1e, 0x31, 0x1a, 0xcf, 0x45, 0xe6, 0x29, 0xde, 0xc6, 0xd2,
0x20, 0xa9, 0x7f, 0xd7, 0x20, 0x1d, 0xbf, 0x35, 0x88, 0x49, 0xe0, 0x05, 0x06, 0x49, 0x02, 0x9c,
0x55, 0xb9, 0x3f, 0x43, 0x15, 0xd3, 0x85, 0x20, 0xe8, 0x4b, 0xa8, 0x49, 0xcb, 0x46, 0x5b, 0x97,
0x60, 0xb3, 0x76, 0x4c, 0xe9, 0x65, 0x70, 0x89, 0x4d, 0x39, 0x14, 0x44, 0xc8, 0x86, 0xda, 0x9c,
0x88, 0x47, 0xca, 0x1f, 0xf4, 0x4e, 0xcb, 0x43, 0xf7, 0x0f, 0x40, 0x17, 0x9c, 0x84, 0x82, 0x28,
0xb6, 0xfc, 0x44, 0x7e, 0x24, 0xa9, 0x07, 0xe8, 0x92, 0x24, 0xe4, 0x1d, 0xd2, 0x9d, 0x7c, 0x63,
0x3f, 0xff, 0x10, 0x0e, 0x54, 0xe6, 0xd6, 0x2d, 0x0c, 0xad, 0x1c, 0xd0, 0x76, 0xfd, 0x08, 0x26,
0x57, 0x88, 0xf6, 0xab, 0x5b, 0xc0, 0xaf, 0x6c, 0x76, 0x5d, 0xd7, 0x7f, 0x5d, 0x81, 0xfa, 0x2f,
0x3a, 0x03, 0x31, 0xa8, 0xe9, 0x9b, 0x03, 0xf5, 0x0a, 0x30, 0xed, 0x5f, 0x58, 0xed, 0xfe, 0x4b,
0x4a, 0x74, 0x03, 0x33, 0x30, 0xb3, 0x96, 0xd0, 0x59, 0x51, 0xe9, 0xb9, 0x1d, 0xed, 0xde, 0x0b,
0x2a, 0xf4, 0x74, 0x7f, 0x83, 0xb5, 0xb3, 0xae, 0xe8, 0xdb, 0x22, 0x8a, 0x9f, 0xec, 0x83, 0xf6,
0x91, 0x97, 0x3d, 0x25, 0x5e, 0xfe, 0x94, 0x78, 0x3f, 0xc9, 0xa7, 0x44, 0xb2, 0xef, 0x2c, 0x70,
0x21, 0xf6, 0xa7, 0x1b, 0xe2, 0x59, 0xf6, 0x7b, 0xa8, 0xaa, 0xcb, 0x04, 0xf9, 0x05, 0x6f, 0x8d,
0xad, 0x51, 0x67, 0xc5, 0x0b, 0xb4, 0x4f, 0xf7, 0x50, 0x55, 0xe7, 0xb2, 0xd0, 0x5c, 0xbb, 0x27,
0xba, 0xd0, 0x5c, 0x7b, 0x47, 0x7e, 0xe0, 0xfd, 0x75, 0x5a, 0xf8, 0x67, 0xe0, 0xfb, 0x65, 0x6f,
0x6c, 0x2a, 0x5f, 0xbe, 0x79, 0x13, 0x00, 0x00, 0xff, 0xff, 0x30, 0x53, 0x36, 0x35, 0x43, 0x08,
0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -476,6 +764,11 @@ const _ = grpc.SupportPackageIsVersion4
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type HeimdallClient interface {
Connect(ctx context.Context, in *ConnectRequest, opts ...grpc.CallOption) (*ConnectResponse, error)
Routes(ctx context.Context, in *RoutesRequest, opts ...grpc.CallOption) (*RoutesResponse, error)
CreateRoute(ctx context.Context, in *CreateRouteRequest, opts ...grpc.CallOption) (*types.Empty, error)
DeleteRoute(ctx context.Context, in *DeleteRouteRequest, opts ...grpc.CallOption) (*types.Empty, error)
Nodes(ctx context.Context, in *NodesRequest, opts ...grpc.CallOption) (*NodesResponse, error)
Peers(ctx context.Context, in *PeersRequest, opts ...grpc.CallOption) (*PeersResponse, error)
}
type heimdallClient struct {
@ -495,9 +788,59 @@ func (c *heimdallClient) Connect(ctx context.Context, in *ConnectRequest, opts .
return out, nil
}
func (c *heimdallClient) Routes(ctx context.Context, in *RoutesRequest, opts ...grpc.CallOption) (*RoutesResponse, error) {
out := new(RoutesResponse)
err := c.cc.Invoke(ctx, "/io.stellarproject.heimdall.api.v1.Heimdall/Routes", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *heimdallClient) CreateRoute(ctx context.Context, in *CreateRouteRequest, opts ...grpc.CallOption) (*types.Empty, error) {
out := new(types.Empty)
err := c.cc.Invoke(ctx, "/io.stellarproject.heimdall.api.v1.Heimdall/CreateRoute", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *heimdallClient) DeleteRoute(ctx context.Context, in *DeleteRouteRequest, opts ...grpc.CallOption) (*types.Empty, error) {
out := new(types.Empty)
err := c.cc.Invoke(ctx, "/io.stellarproject.heimdall.api.v1.Heimdall/DeleteRoute", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *heimdallClient) Nodes(ctx context.Context, in *NodesRequest, opts ...grpc.CallOption) (*NodesResponse, error) {
out := new(NodesResponse)
err := c.cc.Invoke(ctx, "/io.stellarproject.heimdall.api.v1.Heimdall/Nodes", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *heimdallClient) Peers(ctx context.Context, in *PeersRequest, opts ...grpc.CallOption) (*PeersResponse, error) {
out := new(PeersResponse)
err := c.cc.Invoke(ctx, "/io.stellarproject.heimdall.api.v1.Heimdall/Peers", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// HeimdallServer is the server API for Heimdall service.
type HeimdallServer interface {
Connect(context.Context, *ConnectRequest) (*ConnectResponse, error)
Routes(context.Context, *RoutesRequest) (*RoutesResponse, error)
CreateRoute(context.Context, *CreateRouteRequest) (*types.Empty, error)
DeleteRoute(context.Context, *DeleteRouteRequest) (*types.Empty, error)
Nodes(context.Context, *NodesRequest) (*NodesResponse, error)
Peers(context.Context, *PeersRequest) (*PeersResponse, error)
}
// UnimplementedHeimdallServer can be embedded to have forward compatible implementations.
@ -507,6 +850,21 @@ type UnimplementedHeimdallServer struct {
func (*UnimplementedHeimdallServer) Connect(ctx context.Context, req *ConnectRequest) (*ConnectResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Connect not implemented")
}
func (*UnimplementedHeimdallServer) Routes(ctx context.Context, req *RoutesRequest) (*RoutesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Routes not implemented")
}
func (*UnimplementedHeimdallServer) CreateRoute(ctx context.Context, req *CreateRouteRequest) (*types.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateRoute not implemented")
}
func (*UnimplementedHeimdallServer) DeleteRoute(ctx context.Context, req *DeleteRouteRequest) (*types.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteRoute not implemented")
}
func (*UnimplementedHeimdallServer) Nodes(ctx context.Context, req *NodesRequest) (*NodesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Nodes not implemented")
}
func (*UnimplementedHeimdallServer) Peers(ctx context.Context, req *PeersRequest) (*PeersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Peers not implemented")
}
func RegisterHeimdallServer(s *grpc.Server, srv HeimdallServer) {
s.RegisterService(&_Heimdall_serviceDesc, srv)
@ -530,6 +888,96 @@ func _Heimdall_Connect_Handler(srv interface{}, ctx context.Context, dec func(in
return interceptor(ctx, in, info, handler)
}
func _Heimdall_Routes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RoutesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HeimdallServer).Routes(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/io.stellarproject.heimdall.api.v1.Heimdall/Routes",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeimdallServer).Routes(ctx, req.(*RoutesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Heimdall_CreateRoute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateRouteRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HeimdallServer).CreateRoute(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/io.stellarproject.heimdall.api.v1.Heimdall/CreateRoute",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeimdallServer).CreateRoute(ctx, req.(*CreateRouteRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Heimdall_DeleteRoute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteRouteRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HeimdallServer).DeleteRoute(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/io.stellarproject.heimdall.api.v1.Heimdall/DeleteRoute",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeimdallServer).DeleteRoute(ctx, req.(*DeleteRouteRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Heimdall_Nodes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NodesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HeimdallServer).Nodes(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/io.stellarproject.heimdall.api.v1.Heimdall/Nodes",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeimdallServer).Nodes(ctx, req.(*NodesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Heimdall_Peers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PeersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HeimdallServer).Peers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/io.stellarproject.heimdall.api.v1.Heimdall/Peers",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeimdallServer).Peers(ctx, req.(*PeersRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Heimdall_serviceDesc = grpc.ServiceDesc{
ServiceName: "io.stellarproject.heimdall.api.v1.Heimdall",
HandlerType: (*HeimdallServer)(nil),
@ -538,6 +986,26 @@ var _Heimdall_serviceDesc = grpc.ServiceDesc{
MethodName: "Connect",
Handler: _Heimdall_Connect_Handler,
},
{
MethodName: "Routes",
Handler: _Heimdall_Routes_Handler,
},
{
MethodName: "CreateRoute",
Handler: _Heimdall_CreateRoute_Handler,
},
{
MethodName: "DeleteRoute",
Handler: _Heimdall_DeleteRoute_Handler,
},
{
MethodName: "Nodes",
Handler: _Heimdall_Nodes_Handler,
},
{
MethodName: "Peers",
Handler: _Heimdall_Peers_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "github.com/stellarproject/heimdall/api/v1/heimdall.proto",

View file

@ -3,15 +3,17 @@ syntax = "proto3";
package io.stellarproject.heimdall.api.v1;
import "gogoproto/gogo.proto";
//import "google/protobuf/empty.proto";
//import "google/protobuf/any.proto";
import "google/protobuf/empty.proto";
option go_package = "github.com/stellarproject/heimdall/api/v1;v1";
service Heimdall {
rpc Connect(ConnectRequest) returns (ConnectResponse);
//rpc Nodes(NodesRequest) returns (NodesResponse);
//rpc Peers(PeersRequest) returns (PeersResponse);
rpc Routes(RoutesRequest) returns (RoutesResponse);
rpc CreateRoute(CreateRouteRequest) returns (google.protobuf.Empty);
rpc DeleteRoute(DeleteRouteRequest) returns (google.protobuf.Empty);
rpc Nodes(NodesRequest) returns (NodesResponse);
rpc Peers(PeersRequest) returns (PeersResponse);
}
message Master {
@ -54,3 +56,29 @@ message Peer {
repeated string allowed_ips = 3 [(gogoproto.customname) = "AllowedIPs"];
string endpoint = 4;
}
message PeersRequest {}
message PeersResponse {
repeated Peer peers = 1;
}
message Route {
string node_id = 1 [(gogoproto.customname) = "NodeID"];
string network = 2;
}
message CreateRouteRequest {
string node_id = 1 [(gogoproto.customname) = "NodeID"];
string network = 2;
}
message DeleteRouteRequest {
string network = 1;
}
message RoutesRequest {}
message RoutesResponse {
repeated Route routes = 1;
}

39
client/node.go Normal file
View file

@ -0,0 +1,39 @@
/*
Copyright 2019 Stellar Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package client
import (
"context"
v1 "github.com/stellarproject/heimdall/api/v1"
)
// Nodes returns the known nodes
func (c *Client) Nodes() ([]*v1.Node, error) {
ctx := context.Background()
resp, err := c.heimdallClient.Nodes(ctx, &v1.NodesRequest{})
if err != nil {
return nil, err
}
return resp.Nodes, nil
}

39
client/peer.go Normal file
View file

@ -0,0 +1,39 @@
/*
Copyright 2019 Stellar Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package client
import (
"context"
v1 "github.com/stellarproject/heimdall/api/v1"
)
// Peers returns the known peers
func (c *Client) Peers() ([]*v1.Peer, error) {
ctx := context.Background()
resp, err := c.heimdallClient.Peers(ctx, &v1.PeersRequest{})
if err != nil {
return nil, err
}
return resp.Peers, nil
}

64
client/route.go Normal file
View file

@ -0,0 +1,64 @@
/*
Copyright 2019 Stellar Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package client
import (
"context"
v1 "github.com/stellarproject/heimdall/api/v1"
)
// Routes returns the known routes
func (c *Client) Routes() ([]*v1.Route, error) {
ctx := context.Background()
resp, err := c.heimdallClient.Routes(ctx, &v1.RoutesRequest{})
if err != nil {
return nil, err
}
return resp.Routes, nil
}
// CreateRoute creates a new route via the specified node ID
func (c *Client) CreateRoute(nodeID, network string) error {
ctx := context.Background()
if _, err := c.heimdallClient.CreateRoute(ctx, &v1.CreateRouteRequest{
NodeID: nodeID,
Network: network,
}); err != nil {
return err
}
return nil
}
// DeleteRoute deletes a route
func (c *Client) DeleteRoute(network string) error {
ctx := context.Background()
if _, err := c.heimdallClient.DeleteRoute(ctx, &v1.DeleteRouteRequest{
Network: network,
}); err != nil {
return err
}
return nil
}

View file

@ -35,7 +35,7 @@ import (
func main() {
app := cli.NewApp()
app.Name = "actl"
app.Name = "hctl"
app.Version = version.BuildVersion()
app.Author = "@stellarproject"
app.Email = ""
@ -49,7 +49,7 @@ func main() {
Name: "addr, a",
Usage: "heimdall grpc address",
Value: "tcp://127.0.0.1:9000",
EnvVar: "ATLAS_ADDR",
EnvVar: "HEIMDALL_ADDR",
},
cli.StringFlag{
Name: "cert, c",
@ -72,7 +72,11 @@ func main() {
}
return nil
}
app.Commands = []cli.Command{}
app.Commands = []cli.Command{
nodesCommand,
peersCommand,
routesCommand,
}
if err := app.Run(os.Args); err != nil {
logrus.Fatal(err)

65
cmd/hctl/nodes.go Normal file
View file

@ -0,0 +1,65 @@
/*
Copyright 2019 Stellar Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package main
import (
"fmt"
"os"
"text/tabwriter"
"github.com/urfave/cli"
)
var nodesCommand = cli.Command{
Name: "nodes",
Usage: "node management",
Subcommands: []cli.Command{
listNodesCommand,
},
}
var listNodesCommand = cli.Command{
Name: "list",
Usage: "list nodes",
Action: func(cx *cli.Context) error {
c, err := getClient(cx)
if err != nil {
return err
}
defer c.Close()
nodes, err := c.Nodes()
if err != nil {
return err
}
w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
fmt.Fprintf(w, "ID\tADDR\tGATEWAY\tPUBLIC KEY\n")
for _, n := range nodes {
gw := fmt.Sprintf("%s:%d", n.GatewayIP, n.GatewayPort)
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", n.ID, n.Addr, gw, n.KeyPair.PublicKey)
}
w.Flush()
return nil
},
}

63
cmd/hctl/peers.go Normal file
View file

@ -0,0 +1,63 @@
/*
Copyright 2019 Stellar Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package main
import (
"fmt"
"os"
"text/tabwriter"
"github.com/urfave/cli"
)
var peersCommand = cli.Command{
Name: "peers",
Usage: "peer management",
Subcommands: []cli.Command{
listPeersCommand,
},
}
var listPeersCommand = cli.Command{
Name: "list",
Usage: "list peers",
Action: func(cx *cli.Context) error {
c, err := getClient(cx)
if err != nil {
return err
}
defer c.Close()
peers, err := c.Peers()
if err != nil {
return err
}
w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
fmt.Fprintf(w, "ID\tPUBLIC KEY\tENDPOINT\tALLOWED\n")
for _, p := range peers {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", p.ID, p.KeyPair.PublicKey, p.Endpoint, p.AllowedIPs)
}
w.Flush()
return nil
},
}

111
cmd/hctl/routes.go Normal file
View file

@ -0,0 +1,111 @@
/*
Copyright 2019 Stellar Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package main
import (
"fmt"
"os"
"text/tabwriter"
"github.com/urfave/cli"
)
var routesCommand = cli.Command{
Name: "routes",
Usage: "route management",
Subcommands: []cli.Command{
listRoutesCommand,
createRouteCommand,
deleteRouteCommand,
},
}
var listRoutesCommand = cli.Command{
Name: "list",
Usage: "list routes",
Action: func(cx *cli.Context) error {
c, err := getClient(cx)
if err != nil {
return err
}
defer c.Close()
routes, err := c.Routes()
if err != nil {
return err
}
w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
fmt.Fprintf(w, "NODE\tNETWORK\n")
for _, r := range routes {
fmt.Fprintf(w, "%s\t%s\n", r.NodeID, r.Network)
}
w.Flush()
return nil
},
}
var createRouteCommand = cli.Command{
Name: "create",
Usage: "create a new route",
Flags: []cli.Flag{
cli.StringFlag{
Name: "node-id",
Usage: "node id for route",
},
cli.StringFlag{
Name: "network",
Usage: "network for route (i.e. 10.100.0.0/24)",
},
},
Action: func(cx *cli.Context) error {
c, err := getClient(cx)
if err != nil {
return err
}
defer c.Close()
if err := c.CreateRoute(cx.String("node-id"), cx.String("network")); err != nil {
return err
}
return nil
},
}
var deleteRouteCommand = cli.Command{
Name: "delete",
Usage: "delete a route",
Action: func(cx *cli.Context) error {
c, err := getClient(cx)
if err != nil {
return err
}
defer c.Close()
network := cx.Args().First()
if err := c.DeleteRoute(network); err != nil {
return err
}
return nil
},
}

5
go.mod
View file

@ -4,6 +4,7 @@ go 1.12
require (
github.com/certifi/gocertifi v0.0.0-20190905060710-a5e0173ced67 // indirect
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd
github.com/crosbymichael/guard v0.0.0-20190716141324-5c2daadf8067 // indirect
github.com/getsentry/raven-go v0.2.0 // indirect
github.com/gogo/googleapis v1.3.0
@ -11,11 +12,9 @@ require (
github.com/gomodule/redigo v2.0.0+incompatible
github.com/google/uuid v1.1.1
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v1.1.0 // indirect
github.com/sirupsen/logrus v1.4.2
github.com/stellarproject/atlas v0.1.0
github.com/stellarproject/guard v0.0.0-20190716141324-5c2daadf8067
github.com/urfave/cli v1.22.1
google.golang.org/grpc v1.24.0

21
go.sum
View file

@ -9,21 +9,27 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/certifi/gocertifi v0.0.0-20190905060710-a5e0173ced67 h1:8k9FLYBLKT+9v2HQJ/a95ZemmTx+/ltJcAiRhVushG8=
github.com/certifi/gocertifi v0.0.0-20190905060710-a5e0173ced67/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/containerd/typeurl v0.0.0-20190515163108-7312978f2987/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd h1:bRLyitWw3PT/2YuVaCKTPg0cA5dOFKFwKtkfcP2dLsA=
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/crosbymichael/guard v0.0.0-20190716141324-5c2daadf8067 h1:jlV8Svz9lOwvxWBt2RN3uA1JUZ8AFj46boym2+Fx488=
github.com/crosbymichael/guard v0.0.0-20190716141324-5c2daadf8067/go.mod h1:+l2fIHwwiNb/sUw9RcsUH6wXnO07793PC4XjDWCuiHs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ehazlett/ttlcache v0.0.0-20190820213212-4400e3aef9f0/go.mod h1:D7IiYXsX2n2xixWvFTxGeZucCvvNtI14ikLj6L9Kp9E=
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
github.com/gogo/googleapis v1.3.0 h1:M695OaDJ5ipWvDPcoAg/YL9c3uORAegkEfBqTQF/fTQ=
github.com/gogo/googleapis v1.3.0/go.mod h1:d+q1s/xVJxZGKWwC/6UfPIF33J+G1Tq4GYv9Y+Tg/EU=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -44,18 +50,22 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/olebedev/emitter v0.0.0-20190110104742-e8d1457e6aee/go.mod h1:eT2/Pcsim3XBjbvldGiJBvvgiqZkAFyiOJJsDKXs/ts=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -81,14 +91,20 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stellarproject/atlas v0.1.0 h1:ZYRDbzERiu9hyBO1vTBaEro1ScZ8q874zVYdEASNNZQ=
github.com/stellarproject/atlas v0.1.0/go.mod h1:I6biE8fkkrchKwVASWzxyGVOson7ycZNjOGi2nWYUDA=
github.com/stellarproject/guard v0.0.0-20190716141324-5c2daadf8067 h1:rXVdzLEX//pCEeoLSu5p61PktACUZY1pFXQ9dCsnMA4=
github.com/stellarproject/guard v0.0.0-20190716141324-5c2daadf8067/go.mod h1:pJTo5Hd/Kb63HIoU6r3wfqWA7AMQWstyu7qvlOq+mqM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ=
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@ -108,18 +124,23 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/p
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View file

@ -34,6 +34,51 @@ import (
v1 "github.com/stellarproject/heimdall/api/v1"
)
// Nodes returns a list of known nodes
func (s *Server) Nodes(ctx context.Context, req *v1.NodesRequest) (*v1.NodesResponse, error) {
nodes, err := s.getNodes(ctx)
if err != nil {
return nil, err
}
return &v1.NodesResponse{
Nodes: nodes,
}, nil
}
func (s *Server) getNodes(ctx context.Context) ([]*v1.Node, error) {
nodeKeys, err := redis.Strings(s.local(ctx, "KEYS", s.getNodeKey("*")))
if err != nil {
return nil, err
}
var nodes []*v1.Node
for _, nodeKey := range nodeKeys {
data, err := redis.Bytes(s.local(ctx, "GET", nodeKey))
if err != nil {
return nil, err
}
var node v1.Node
if err := proto.Unmarshal(data, &node); err != nil {
return nil, err
}
nodes = append(nodes, &node)
}
return nodes, nil
}
func (s *Server) getNode(ctx context.Context, id string) (*v1.Node, error) {
data, err := redis.Bytes(s.local(ctx, "GET", s.getNodeKey(id)))
if err != nil {
return nil, err
}
var node v1.Node
if err := proto.Unmarshal(data, &node); err != nil {
return nil, err
}
return &node, nil
}
func (s *Server) configureNode() error {
ctx := context.Background()
nodeKeys, err := redis.Strings(s.local(ctx, "KEYS", s.getNodeKey("*")))

View file

@ -35,6 +35,60 @@ import (
v1 "github.com/stellarproject/heimdall/api/v1"
)
// Peers returns a list of known peers
func (s *Server) Peers(ctx context.Context, req *v1.PeersRequest) (*v1.PeersResponse, error) {
peers, err := s.getPeers(ctx)
if err != nil {
return nil, err
}
return &v1.PeersResponse{
Peers: peers,
}, nil
}
func (s *Server) getPeers(ctx context.Context) ([]*v1.Peer, error) {
peerKeys, err := redis.Strings(s.local(ctx, "KEYS", s.getPeerKey("*")))
if err != nil {
return nil, err
}
var peers []*v1.Peer
for _, peerKey := range peerKeys {
data, err := redis.Bytes(s.local(ctx, "GET", peerKey))
if err != nil {
return nil, err
}
var peer v1.Peer
if err := proto.Unmarshal(data, &peer); err != nil {
return nil, err
}
peers = append(peers, &peer)
}
return peers, nil
}
func (s *Server) peerUpdater(ctx context.Context) {
logrus.Debugf("starting peer config updater: ttl=%s", peerConfigUpdateInterval)
t := time.NewTicker(peerConfigUpdateInterval)
for range t.C {
uctx, cancel := context.WithTimeout(ctx, peerConfigUpdateInterval)
if err := s.updatePeerInfo(uctx); err != nil {
logrus.Errorf("updatePeerInfo: %s", err)
cancel()
continue
}
if err := s.updatePeerConfig(uctx); err != nil {
logrus.Errorf("updatePeerConfig: %s", err)
cancel()
continue
}
cancel()
}
}
func (s *Server) updatePeerInfo(ctx context.Context) error {
keypair, err := s.getOrCreateKeyPair(ctx, s.cfg.ID)
if err != nil {
@ -43,8 +97,23 @@ func (s *Server) updatePeerInfo(ctx context.Context) error {
endpoint := fmt.Sprintf("%s:%d", s.cfg.GatewayIP, s.cfg.GatewayPort)
// TODO: build allowedIPs from routes and peer network
// build allowedIPs from routes and peer network
allowedIPs := []string{s.cfg.PeerNetwork}
routes, err := s.getRoutes(ctx)
if err != nil {
return err
}
for _, route := range routes {
// only add the route if a peer to prevent route duplicate
if route.NodeID != s.cfg.ID {
continue
}
logrus.Debugf("adding route to allowed IPs: %s", route.Network)
allowedIPs = append(allowedIPs, route.Network)
}
n := &v1.Peer{
ID: s.cfg.ID,
@ -57,7 +126,23 @@ func (s *Server) updatePeerInfo(ctx context.Context) error {
if err != nil {
return err
}
pHash := hashData(data)
key := s.getPeerKey(s.cfg.ID)
peerData, err := redis.Bytes(s.local(ctx, "GET", key))
if err != nil {
if err != redis.ErrNil {
return err
}
}
eHash := hashData(peerData)
// skip update if same
if pHash == eHash {
return nil
}
if _, err := s.master(ctx, "SET", key, data); err != nil {
return err
}
@ -84,98 +169,86 @@ func (s *Server) getPeerInfo(ctx context.Context, id string) (*v1.Peer, error) {
return &peer, nil
}
func (s *Server) updatePeerConfig(ctx context.Context) {
logrus.Debugf("starting peer config updater: ttl=%s", peerConfigUpdateInterval)
t := time.NewTicker(peerConfigUpdateInterval)
configHash := ""
for range t.C {
uctx, cancel := context.WithTimeout(ctx, peerConfigUpdateInterval)
peerKeys, err := redis.Strings(s.local(uctx, "KEYS", s.getPeerKey("*")))
if err != nil {
logrus.Error(err)
cancel()
continue
}
var peers []*v1.Peer
for _, peerKey := range peerKeys {
peerData, err := redis.Bytes(s.local(uctx, "GET", peerKey))
if err != nil {
logrus.Error(err)
cancel()
continue
}
var p v1.Peer
if err := proto.Unmarshal(peerData, &p); err != nil {
logrus.Error(err)
cancel()
continue
}
// do not add self as a peer
if p.ID == s.cfg.ID {
continue
}
peers = append(peers, &p)
}
keyPair, err := s.getOrCreateKeyPair(ctx, s.cfg.ID)
if err != nil {
logrus.Error(err)
cancel()
continue
}
gatewayIP, _, err := s.getOrAllocateIP(ctx, s.cfg.ID)
if err != nil {
logrus.Error(err)
cancel()
continue
}
wireguardCfg := &wireguardConfig{
Iface: defaultWireguardInterface,
PrivateKey: keyPair.PrivateKey,
ListenPort: s.cfg.GatewayPort,
Address: gatewayIP.String() + "/32",
Peers: peers,
}
tmpCfg, err := generateNodeWireguardConfig(wireguardCfg)
if err != nil {
logrus.Error(err)
cancel()
continue
}
h, err := hashConfig(tmpCfg)
if err != nil {
logrus.Error(err)
cancel()
continue
}
// if config has not change skip update
if h == configHash {
continue
}
logrus.Debugf("updating peer config to version %s", h)
// update wireguard config
if err := os.Rename(tmpCfg, wireguardConfigPath); err != nil {
logrus.Error(err)
cancel()
continue
}
// reload wireguard
if err := restartWireguardTunnel(ctx); err != nil {
logrus.Error(err)
cancel()
continue
}
configHash = h
func (s *Server) updatePeerConfig(ctx context.Context) error {
peerKeys, err := redis.Strings(s.local(ctx, "KEYS", s.getPeerKey("*")))
if err != nil {
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
if p.ID == s.cfg.ID {
continue
}
peers = append(peers, &p)
}
keyPair, err := s.getOrCreateKeyPair(ctx, s.cfg.ID)
if err != nil {
return err
}
gatewayIP, _, err := s.getOrAllocateIP(ctx, s.cfg.ID)
if err != nil {
return err
}
wireguardCfg := &wireguardConfig{
Iface: defaultWireguardInterface,
PrivateKey: keyPair.PrivateKey,
ListenPort: s.cfg.GatewayPort,
Address: gatewayIP.String() + "/32",
Peers: peers,
}
tmpCfg, err := generateNodeWireguardConfig(wireguardCfg)
if err != nil {
return err
}
h, err := hashConfig(tmpCfg)
if err != nil {
return err
}
e, err := hashConfig(wireguardConfigPath)
if err != nil {
return err
}
// if config has not change skip update
if h == e {
logrus.Debugf("config not changed: hash=%s", e)
return nil
}
logrus.Debugf("updating peer config to version %s", h)
// update wireguard config
if err := os.Rename(tmpCfg, wireguardConfigPath); err != nil {
return err
}
// reload wireguard
if err := restartWireguardTunnel(ctx); err != nil {
return err
}
return nil
}
func hashData(data []byte) string {
h := sha256.New()
h.Write(data)
return fmt.Sprintf("%x", h.Sum(nil))
}
func hashConfig(cfgPath string) (string, error) {
@ -184,7 +257,5 @@ func hashConfig(cfgPath string) (string, error) {
return "", err
}
h := sha256.New()
h.Write(peerData)
return fmt.Sprintf("%x", h.Sum(nil)), nil
return hashData(peerData), nil
}

113
server/route.go Normal file
View file

@ -0,0 +1,113 @@
/*
Copyright 2019 Stellar Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package server
import (
"context"
"github.com/gogo/protobuf/proto"
ptypes "github.com/gogo/protobuf/types"
"github.com/gomodule/redigo/redis"
"github.com/pkg/errors"
v1 "github.com/stellarproject/heimdall/api/v1"
)
// CreateRoute reserves a new route
func (s *Server) CreateRoute(ctx context.Context, req *v1.CreateRouteRequest) (*ptypes.Empty, error) {
// check for existing route
routeKey := s.getRouteKey(req.Network)
routeData, err := redis.Bytes(s.local(ctx, "GET", routeKey))
if err != nil {
if err != redis.ErrNil {
return nil, err
}
}
if routeData != nil {
return nil, errors.Wrap(ErrRouteExists, req.Network)
}
// check for node id
if _, err := redis.Bytes(s.local(ctx, "GET", s.getNodeKey(req.NodeID))); err != nil {
if err == redis.ErrNil {
return nil, errors.Wrap(ErrNodeDoesNotExist, req.NodeID)
}
return nil, err
}
// save route
route := &v1.Route{
NodeID: req.NodeID,
Network: req.Network,
}
data, err := proto.Marshal(route)
if err != nil {
return nil, err
}
if _, err := s.master(ctx, "SET", routeKey, data); err != nil {
return nil, err
}
return empty, nil
}
// Delete deletes a new route
func (s *Server) DeleteRoute(ctx context.Context, req *v1.DeleteRouteRequest) (*ptypes.Empty, error) {
routeKey := s.getRouteKey(req.Network)
if _, err := s.master(ctx, "DEL", routeKey); err != nil {
return nil, err
}
return empty, nil
}
// Routes returns a list of known routes
func (s *Server) Routes(ctx context.Context, req *v1.RoutesRequest) (*v1.RoutesResponse, error) {
routes, err := s.getRoutes(ctx)
if err != nil {
return nil, err
}
return &v1.RoutesResponse{
Routes: routes,
}, nil
}
func (s *Server) getRoutes(ctx context.Context) ([]*v1.Route, error) {
routeKeys, err := redis.Strings(s.local(ctx, "KEYS", s.getRouteKey("*")))
if err != nil {
return nil, err
}
var routes []*v1.Route
for _, routeKey := range routeKeys {
data, err := redis.Bytes(s.local(ctx, "GET", routeKey))
if err != nil {
return nil, err
}
var route v1.Route
if err := proto.Unmarshal(data, &route); err != nil {
return nil, err
}
routes = append(routes, &route)
}
return routes, nil
}

View file

@ -47,6 +47,7 @@ const (
nodesKey = "heimdall:nodes"
nodeJoinKey = "heimdall:join"
peersKey = "heimdall:peers"
routesKey = "heimdall:routes"
ipsKey = "heimdall:ips"
wireguardConfigPath = "/etc/wireguard/darknet.conf"
@ -58,8 +59,14 @@ var (
nodeHeartbeatInterval = time.Second * 60
nodeHeartbeatExpiry = 86400
peerConfigUpdateInterval = time.Second * 10
// ErrRouteExists is returned when a requested route is already reserved
ErrRouteExists = errors.New("route already reserved")
// ErrNodeDoesNotExist is returned when an invalid node is requested
ErrNodeDoesNotExist = errors.New("node does not exist")
)
// Server represents the Heimdall server
type Server struct {
cfg *heimdall.Config
rpool *redis.Pool
@ -67,6 +74,7 @@ type Server struct {
replicaCh chan struct{}
}
// NewServer returns a new Heimdall server
func NewServer(cfg *heimdall.Config) (*Server, error) {
pool := getPool(cfg.RedisURL)
return &Server{
@ -130,6 +138,9 @@ func (s *Server) Run() error {
return err
}
// ensure wireguard is started
_, _ = wgquick(ctx, "up", getTunnelName())
if err := s.updatePeerInfo(ctx); err != nil {
return err
}
@ -138,7 +149,7 @@ func (s *Server) Run() error {
go s.nodeHeartbeat(ctx)
// start peer config updater to configure wireguard as peers join
go s.updatePeerConfig(ctx)
go s.peerUpdater(ctx)
// start listener for pub/sub
errCh := make(chan error, 1)
@ -219,6 +230,10 @@ func (s *Server) getNodeKey(id string) string {
return fmt.Sprintf("%s:%s", nodesKey, id)
}
func (s *Server) getRouteKey(network string) string {
return fmt.Sprintf("%s:%s", routesKey, network)
}
func (s *Server) getPeerKey(id string) string {
return fmt.Sprintf("%s:%s", peersKey, id)
}

View file

@ -107,8 +107,12 @@ func generateWireguardKeys(ctx context.Context) (string, string, error) {
return privateKey, publicKey, nil
}
func getTunnelName() string {
return strings.Replace(filepath.Base(wireguardConfigPath), filepath.Ext(filepath.Base(wireguardConfigPath)), "", 1)
}
func restartWireguardTunnel(ctx context.Context) error {
tunnelName := strings.Replace(filepath.Base(wireguardConfigPath), filepath.Ext(filepath.Base(wireguardConfigPath)), "", 1)
tunnelName := getTunnelName()
logrus.Infof("restarting tunnel %s", tunnelName)
d, err := wgquick(ctx, "down", tunnelName)
if err != nil {