fake.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package testing
  14. import (
  15. "fmt"
  16. "net"
  17. "strconv"
  18. "time"
  19. utilipvs "k8s.io/kubernetes/pkg/util/ipvs"
  20. )
  21. //FakeIPVS no-op implementation of ipvs Interface
  22. type FakeIPVS struct {
  23. Scheduler string
  24. Services map[ServiceKey]*utilipvs.VirtualServer
  25. Destinations map[ServiceKey][]*utilipvs.RealServer
  26. }
  27. // ServiceKey uniquely identifies a Service for an IPVS virtual server
  28. type ServiceKey struct {
  29. IP string
  30. Port uint16
  31. Protocol string
  32. }
  33. func (s *ServiceKey) String() string {
  34. return fmt.Sprintf("%s:%d/%s", s.IP, s.Port, s.Protocol)
  35. }
  36. // RealServerKey uniquely identifies an Endpoint for an IPVS real server
  37. type RealServerKey struct {
  38. Address net.IP
  39. Port uint16
  40. }
  41. func (r *RealServerKey) String() string {
  42. return net.JoinHostPort(r.Address.String(), strconv.Itoa(int(r.Port)))
  43. }
  44. //NewFake creates a fake ipvs implementation - a cache store.
  45. func NewFake() *FakeIPVS {
  46. return &FakeIPVS{
  47. Services: make(map[ServiceKey]*utilipvs.VirtualServer),
  48. Destinations: make(map[ServiceKey][]*utilipvs.RealServer),
  49. }
  50. }
  51. func toServiceKey(serv *utilipvs.VirtualServer) ServiceKey {
  52. return ServiceKey{
  53. IP: serv.Address.String(),
  54. Port: serv.Port,
  55. Protocol: serv.Protocol,
  56. }
  57. }
  58. func toRealServerKey(rs *utilipvs.RealServer) *RealServerKey {
  59. return &RealServerKey{
  60. Address: rs.Address,
  61. Port: rs.Port,
  62. }
  63. }
  64. //AddVirtualServer is a fake implementation, it simply adds the VirtualServer into the cache store.
  65. func (f *FakeIPVS) AddVirtualServer(serv *utilipvs.VirtualServer) error {
  66. if serv == nil {
  67. return fmt.Errorf("Failed to add virtual server, error: virtual server can't be nil")
  68. }
  69. key := toServiceKey(serv)
  70. f.Services[key] = serv
  71. // make sure no destination present when creating new service
  72. f.Destinations[key] = make([]*utilipvs.RealServer, 0)
  73. return nil
  74. }
  75. //UpdateVirtualServer is a fake implementation, it updates the VirtualServer in the cache store.
  76. func (f *FakeIPVS) UpdateVirtualServer(serv *utilipvs.VirtualServer) error {
  77. if serv == nil {
  78. return fmt.Errorf("Failed to update service, service can't be nil")
  79. }
  80. key := toServiceKey(serv)
  81. f.Services[key] = serv
  82. return nil
  83. }
  84. //DeleteVirtualServer is a fake implementation, it simply deletes the VirtualServer from the cache store.
  85. func (f *FakeIPVS) DeleteVirtualServer(serv *utilipvs.VirtualServer) error {
  86. if serv == nil {
  87. return fmt.Errorf("Failed to delete service: service can't be nil")
  88. }
  89. key := toServiceKey(serv)
  90. delete(f.Services, key)
  91. // clear specific destinations as well
  92. f.Destinations[key] = nil
  93. return nil
  94. }
  95. //GetVirtualServer is a fake implementation, it tries to find a specific VirtualServer from the cache store.
  96. func (f *FakeIPVS) GetVirtualServer(serv *utilipvs.VirtualServer) (*utilipvs.VirtualServer, error) {
  97. if serv == nil {
  98. return nil, fmt.Errorf("Failed to get service: service can't be nil")
  99. }
  100. key := toServiceKey(serv)
  101. svc, found := f.Services[key]
  102. if found {
  103. return svc, nil
  104. }
  105. return nil, fmt.Errorf("Not found serv: %v", key.String())
  106. }
  107. //GetVirtualServers is a fake implementation, it simply returns all VirtualServers in the cache store.
  108. func (f *FakeIPVS) GetVirtualServers() ([]*utilipvs.VirtualServer, error) {
  109. res := make([]*utilipvs.VirtualServer, 0)
  110. for _, svc := range f.Services {
  111. res = append(res, svc)
  112. }
  113. return res, nil
  114. }
  115. //Flush is a fake implementation, it simply clears the cache store.
  116. func (f *FakeIPVS) Flush() error {
  117. // directly drop old data
  118. f.Services = nil
  119. f.Destinations = nil
  120. return nil
  121. }
  122. //AddRealServer is a fake implementation, it simply creates a RealServer for a VirtualServer in the cache store.
  123. func (f *FakeIPVS) AddRealServer(serv *utilipvs.VirtualServer, dest *utilipvs.RealServer) error {
  124. if serv == nil || dest == nil {
  125. return fmt.Errorf("Failed to add destination for service, neither service nor destination shouldn't be nil")
  126. }
  127. key := toServiceKey(serv)
  128. if _, ok := f.Services[key]; !ok {
  129. return fmt.Errorf("Failed to add destination for service %v, service not found", key.String())
  130. }
  131. dests := f.Destinations[key]
  132. if dests == nil {
  133. dests = make([]*utilipvs.RealServer, 0)
  134. f.Destinations[key] = dests
  135. }
  136. f.Destinations[key] = append(f.Destinations[key], dest)
  137. return nil
  138. }
  139. //GetRealServers is a fake implementation, it simply returns all RealServers in the cache store.
  140. func (f *FakeIPVS) GetRealServers(serv *utilipvs.VirtualServer) ([]*utilipvs.RealServer, error) {
  141. if serv == nil {
  142. return nil, fmt.Errorf("Failed to get destination for nil service")
  143. }
  144. key := toServiceKey(serv)
  145. if _, ok := f.Services[key]; !ok {
  146. return nil, fmt.Errorf("Failed to get destinations for service %v, service not found", key.String())
  147. }
  148. return f.Destinations[key], nil
  149. }
  150. //DeleteRealServer is a fake implementation, it deletes the real server in the cache store.
  151. func (f *FakeIPVS) DeleteRealServer(serv *utilipvs.VirtualServer, dest *utilipvs.RealServer) error {
  152. if serv == nil || dest == nil {
  153. return fmt.Errorf("Failed to delete destination, neither service nor destination can't be nil")
  154. }
  155. key := toServiceKey(serv)
  156. if _, ok := f.Services[key]; !ok {
  157. return fmt.Errorf("Failed to delete destination for service %v, service not found", key.String())
  158. }
  159. dests := f.Destinations[key]
  160. exist := false
  161. for i := range dests {
  162. if toRealServerKey(dests[i]).String() == toRealServerKey(dest).String() {
  163. // Delete one element
  164. f.Destinations[key] = append(f.Destinations[key][:i], f.Destinations[key][i+1:]...)
  165. exist = true
  166. break
  167. }
  168. }
  169. // Not Found
  170. if !exist {
  171. return fmt.Errorf("Failed to delete real server for service %v, real server not found", key.String())
  172. }
  173. return nil
  174. }
  175. // UpdateRealServer is a fake implementation, it deletes the old real server then add new real server
  176. func (f *FakeIPVS) UpdateRealServer(serv *utilipvs.VirtualServer, dest *utilipvs.RealServer) error {
  177. err := f.DeleteRealServer(serv, dest)
  178. if err != nil {
  179. return err
  180. }
  181. return f.AddRealServer(serv, dest)
  182. }
  183. // ConfigureTimeouts is not supported for fake IPVS
  184. func (f *FakeIPVS) ConfigureTimeouts(time.Duration, time.Duration, time.Duration) error {
  185. return fmt.Errorf("not supported in fake IPVS")
  186. }
  187. var _ = utilipvs.Interface(&FakeIPVS{})