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