fake.go 6.4 KB

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