backend.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright 2019 the Kilo authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package mesh
  15. import (
  16. "net"
  17. "time"
  18. "github.com/squat/kilo/pkg/wireguard"
  19. )
  20. const (
  21. // resyncPeriod is how often the mesh checks state if no events have been received.
  22. resyncPeriod = 30 * time.Second
  23. // DefaultKiloInterface is the default iterface created and used by Kilo.
  24. DefaultKiloInterface = "kilo0"
  25. // DefaultKiloPort is the default UDP port Kilo uses.
  26. DefaultKiloPort = 51820
  27. // DefaultCNIPath is the default path to the CNI config file.
  28. DefaultCNIPath = "/etc/cni/net.d/10-kilo.conflist"
  29. )
  30. // DefaultKiloSubnet is the default CIDR for Kilo.
  31. var DefaultKiloSubnet = &net.IPNet{IP: []byte{10, 4, 0, 0}, Mask: []byte{255, 255, 0, 0}}
  32. // Granularity represents the abstraction level at which the network
  33. // should be meshed.
  34. type Granularity string
  35. const (
  36. // LogicalGranularity indicates that the network should create
  37. // a mesh between logical locations, e.g. data-centers, but not between
  38. // all nodes within a single location.
  39. LogicalGranularity Granularity = "location"
  40. // FullGranularity indicates that the network should create
  41. // a mesh between every node.
  42. FullGranularity Granularity = "full"
  43. )
  44. // Node represents a node in the network.
  45. type Node struct {
  46. Endpoint *wireguard.Endpoint
  47. Key []byte
  48. InternalIP *net.IPNet
  49. // LastSeen is a Unix time for the last time
  50. // the node confirmed it was live.
  51. LastSeen int64
  52. // Leader is a suggestion to Kilo that
  53. // the node wants to lead its segment.
  54. Leader bool
  55. Location string
  56. Name string
  57. PersistentKeepalive int
  58. Subnet *net.IPNet
  59. WireGuardIP *net.IPNet
  60. }
  61. // Ready indicates whether or not the node is ready.
  62. func (n *Node) Ready() bool {
  63. // Nodes that are not leaders will not have WireGuardIPs, so it is not required.
  64. return n != nil && n.Endpoint != nil && !(n.Endpoint.IP == nil && n.Endpoint.DNS == "") && n.Endpoint.Port != 0 && n.Key != nil && n.InternalIP != nil && n.Subnet != nil && time.Now().Unix()-n.LastSeen < int64(resyncPeriod)*2/int64(time.Second)
  65. }
  66. // Peer represents a peer in the network.
  67. type Peer struct {
  68. wireguard.Peer
  69. Name string
  70. }
  71. // Ready indicates whether or not the peer is ready.
  72. // Peers can have empty endpoints because they may not have an
  73. // IP, for example if they are behind a NAT, and thus
  74. // will not declare their endpoint and instead allow it to be
  75. // discovered.
  76. func (p *Peer) Ready() bool {
  77. return p != nil && p.AllowedIPs != nil && len(p.AllowedIPs) != 0 && p.PublicKey != nil
  78. }
  79. // EventType describes what kind of an action an event represents.
  80. type EventType string
  81. const (
  82. // AddEvent represents an action where an item was added.
  83. AddEvent EventType = "add"
  84. // DeleteEvent represents an action where an item was removed.
  85. DeleteEvent EventType = "delete"
  86. // UpdateEvent represents an action where an item was updated.
  87. UpdateEvent EventType = "update"
  88. )
  89. // NodeEvent represents an event concerning a node in the cluster.
  90. type NodeEvent struct {
  91. Type EventType
  92. Node *Node
  93. Old *Node
  94. }
  95. // PeerEvent represents an event concerning a peer in the cluster.
  96. type PeerEvent struct {
  97. Type EventType
  98. Peer *Peer
  99. Old *Peer
  100. }
  101. // Backend can create clients for all of the
  102. // primitive types that Kilo deals with, namely:
  103. // * nodes; and
  104. // * peers.
  105. type Backend interface {
  106. Nodes() NodeBackend
  107. Peers() PeerBackend
  108. }
  109. // NodeBackend can get nodes by name, init itself,
  110. // list the nodes that should be meshed,
  111. // set Kilo properties for a node,
  112. // clean up any changes applied to the backend,
  113. // and watch for changes to nodes.
  114. type NodeBackend interface {
  115. CleanUp(string) error
  116. Get(string) (*Node, error)
  117. Init(<-chan struct{}) error
  118. List() ([]*Node, error)
  119. Set(string, *Node) error
  120. Watch() <-chan *NodeEvent
  121. }
  122. // PeerBackend can get peers by name, init itself,
  123. // list the peers that should be in the mesh,
  124. // set fields for a peer,
  125. // clean up any changes applied to the backend,
  126. // and watch for changes to peers.
  127. type PeerBackend interface {
  128. CleanUp(string) error
  129. Get(string) (*Peer, error)
  130. Init(<-chan struct{}) error
  131. List() ([]*Peer, error)
  132. Set(string, *Peer) error
  133. Watch() <-chan *PeerEvent
  134. }