proxier_test.go 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. // +build windows
  2. /*
  3. Copyright 2018 The Kubernetes Authors.
  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. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. */
  14. package winkernel
  15. import (
  16. "k8s.io/api/core/v1"
  17. discovery "k8s.io/api/discovery/v1beta1"
  18. "k8s.io/apimachinery/pkg/types"
  19. "k8s.io/kubernetes/pkg/proxy"
  20. "k8s.io/kubernetes/pkg/proxy/healthcheck"
  21. "net"
  22. "strings"
  23. "testing"
  24. "time"
  25. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  26. )
  27. const testHostName = "test-hostname"
  28. const macAddress = "00-11-22-33-44-55"
  29. const clusterCIDR = "192.168.1.0/24"
  30. const destinationPrefix = "192.168.2.0/24"
  31. const providerAddress = "10.0.0.3"
  32. const guid = "123ABC"
  33. type fakeHNS struct{}
  34. func newFakeHNS() *fakeHNS {
  35. return &fakeHNS{}
  36. }
  37. func (hns fakeHNS) getNetworkByName(name string) (*hnsNetworkInfo, error) {
  38. var remoteSubnets []*remoteSubnetInfo
  39. rs := &remoteSubnetInfo{
  40. destinationPrefix: destinationPrefix,
  41. isolationID: 4096,
  42. providerAddress: providerAddress,
  43. drMacAddress: macAddress,
  44. }
  45. remoteSubnets = append(remoteSubnets, rs)
  46. return &hnsNetworkInfo{
  47. id: strings.ToUpper(guid),
  48. name: name,
  49. networkType: "Overlay",
  50. remoteSubnets: remoteSubnets,
  51. }, nil
  52. }
  53. func (hns fakeHNS) getEndpointByID(id string) (*endpointsInfo, error) {
  54. return nil, nil
  55. }
  56. func (hns fakeHNS) getEndpointByIpAddress(ip string, networkName string) (*endpointsInfo, error) {
  57. _, ipNet, _ := net.ParseCIDR(destinationPrefix)
  58. if ipNet.Contains(net.ParseIP(ip)) {
  59. return &endpointsInfo{
  60. ip: ip,
  61. isLocal: true,
  62. macAddress: macAddress,
  63. hnsID: guid,
  64. hns: hns,
  65. }, nil
  66. }
  67. return nil, nil
  68. }
  69. func (hns fakeHNS) createEndpoint(ep *endpointsInfo, networkName string) (*endpointsInfo, error) {
  70. return &endpointsInfo{
  71. ip: ep.ip,
  72. isLocal: ep.isLocal,
  73. macAddress: ep.macAddress,
  74. hnsID: guid,
  75. hns: hns,
  76. }, nil
  77. }
  78. func (hns fakeHNS) deleteEndpoint(hnsID string) error {
  79. return nil
  80. }
  81. func (hns fakeHNS) getLoadBalancer(endpoints []endpointsInfo, flags loadBalancerFlags, sourceVip string, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*loadBalancerInfo, error) {
  82. return &loadBalancerInfo{
  83. hnsID: guid,
  84. }, nil
  85. }
  86. func (hns fakeHNS) deleteLoadBalancer(hnsID string) error {
  87. return nil
  88. }
  89. func NewFakeProxier(syncPeriod time.Duration, minSyncPeriod time.Duration, clusterCIDR string, hostname string, nodeIP net.IP, networkType string) *Proxier {
  90. sourceVip := "192.168.1.2"
  91. hnsNetworkInfo := &hnsNetworkInfo{
  92. name: "TestNetwork",
  93. networkType: networkType,
  94. }
  95. proxier := &Proxier{
  96. portsMap: make(map[localPort]closeable),
  97. serviceMap: make(proxyServiceMap),
  98. serviceChanges: newServiceChangeMap(),
  99. endpointsMap: make(proxyEndpointsMap),
  100. endpointsChanges: newEndpointsChangeMap(hostname),
  101. clusterCIDR: clusterCIDR,
  102. hostname: testHostName,
  103. nodeIP: nodeIP,
  104. serviceHealthServer: healthcheck.NewFakeServiceHealthServer(),
  105. network: *hnsNetworkInfo,
  106. sourceVip: sourceVip,
  107. hostMac: macAddress,
  108. isDSR: false,
  109. hns: newFakeHNS(),
  110. }
  111. return proxier
  112. }
  113. func TestCreateServiceVip(t *testing.T) {
  114. syncPeriod := 30 * time.Second
  115. proxier := NewFakeProxier(syncPeriod, syncPeriod, clusterCIDR, "testhost", net.ParseIP("10.0.0.1"), "Overlay")
  116. if proxier == nil {
  117. t.Error()
  118. }
  119. svcIP := "10.20.30.41"
  120. svcPort := 80
  121. svcNodePort := 3001
  122. svcExternalIPs := "50.60.70.81"
  123. svcPortName := proxy.ServicePortName{
  124. NamespacedName: makeNSN("ns1", "svc1"),
  125. Port: "p80",
  126. }
  127. timeoutSeconds := v1.DefaultClientIPServiceAffinitySeconds
  128. makeServiceMap(proxier,
  129. makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *v1.Service) {
  130. svc.Spec.Type = "NodePort"
  131. svc.Spec.ClusterIP = svcIP
  132. svc.Spec.ExternalIPs = []string{svcExternalIPs}
  133. svc.Spec.SessionAffinity = v1.ServiceAffinityClientIP
  134. svc.Spec.SessionAffinityConfig = &v1.SessionAffinityConfig{
  135. ClientIP: &v1.ClientIPConfig{
  136. TimeoutSeconds: &timeoutSeconds,
  137. },
  138. }
  139. svc.Spec.Ports = []v1.ServicePort{{
  140. Name: svcPortName.Port,
  141. Port: int32(svcPort),
  142. Protocol: v1.ProtocolTCP,
  143. NodePort: int32(svcNodePort),
  144. }}
  145. }),
  146. )
  147. makeEndpointsMap(proxier)
  148. proxier.syncProxyRules()
  149. if proxier.serviceMap[svcPortName].remoteEndpoint == nil {
  150. t.Error()
  151. }
  152. if proxier.serviceMap[svcPortName].remoteEndpoint.ip != svcIP {
  153. t.Error()
  154. }
  155. }
  156. func TestCreateRemoteEndpointOverlay(t *testing.T) {
  157. syncPeriod := 30 * time.Second
  158. proxier := NewFakeProxier(syncPeriod, syncPeriod, clusterCIDR, "testhost", net.ParseIP("10.0.0.1"), "Overlay")
  159. if proxier == nil {
  160. t.Error()
  161. }
  162. svcIP := "10.20.30.41"
  163. svcPort := 80
  164. svcNodePort := 3001
  165. svcPortName := proxy.ServicePortName{
  166. NamespacedName: makeNSN("ns1", "svc1"),
  167. Port: "p80",
  168. }
  169. makeServiceMap(proxier,
  170. makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *v1.Service) {
  171. svc.Spec.Type = "NodePort"
  172. svc.Spec.ClusterIP = svcIP
  173. svc.Spec.Ports = []v1.ServicePort{{
  174. Name: svcPortName.Port,
  175. Port: int32(svcPort),
  176. Protocol: v1.ProtocolTCP,
  177. NodePort: int32(svcNodePort),
  178. }}
  179. }),
  180. )
  181. makeEndpointsMap(proxier,
  182. makeTestEndpoints(svcPortName.Namespace, svcPortName.Name, func(ept *v1.Endpoints) {
  183. ept.Subsets = []v1.EndpointSubset{{
  184. Addresses: []v1.EndpointAddress{{
  185. IP: epIpAddressRemote,
  186. }},
  187. Ports: []v1.EndpointPort{{
  188. Name: svcPortName.Port,
  189. Port: int32(svcPort),
  190. }},
  191. }}
  192. }),
  193. )
  194. proxier.syncProxyRules()
  195. if proxier.endpointsMap[svcPortName][0].hnsID != guid {
  196. t.Errorf("%v does not match %v", proxier.endpointsMap[svcPortName][0].hnsID, guid)
  197. }
  198. }
  199. func TestCreateRemoteEndpointL2Bridge(t *testing.T) {
  200. syncPeriod := 30 * time.Second
  201. proxier := NewFakeProxier(syncPeriod, syncPeriod, clusterCIDR, "testhost", net.ParseIP("10.0.0.1"), "L2Bridge")
  202. if proxier == nil {
  203. t.Error()
  204. }
  205. svcIP := "10.20.30.41"
  206. svcPort := 80
  207. svcNodePort := 3001
  208. svcPortName := proxy.ServicePortName{
  209. NamespacedName: makeNSN("ns1", "svc1"),
  210. Port: "p80",
  211. }
  212. makeServiceMap(proxier,
  213. makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *v1.Service) {
  214. svc.Spec.Type = "NodePort"
  215. svc.Spec.ClusterIP = svcIP
  216. svc.Spec.Ports = []v1.ServicePort{{
  217. Name: svcPortName.Port,
  218. Port: int32(svcPort),
  219. Protocol: v1.ProtocolTCP,
  220. NodePort: int32(svcNodePort),
  221. }}
  222. }),
  223. )
  224. makeEndpointsMap(proxier,
  225. makeTestEndpoints(svcPortName.Namespace, svcPortName.Name, func(ept *v1.Endpoints) {
  226. ept.Subsets = []v1.EndpointSubset{{
  227. Addresses: []v1.EndpointAddress{{
  228. IP: epIpAddressRemote,
  229. }},
  230. Ports: []v1.EndpointPort{{
  231. Name: svcPortName.Port,
  232. Port: int32(svcPort),
  233. }},
  234. }}
  235. }),
  236. )
  237. proxier.syncProxyRules()
  238. if proxier.endpointsMap[svcPortName][0].hnsID != guid {
  239. t.Errorf("%v does not match %v", proxier.endpointsMap[svcPortName][0].hnsID, guid)
  240. }
  241. }
  242. func TestCreateLoadBalancer(t *testing.T) {
  243. syncPeriod := 30 * time.Second
  244. proxier := NewFakeProxier(syncPeriod, syncPeriod, clusterCIDR, "testhost", net.ParseIP("10.0.0.1"), "Overlay")
  245. if proxier == nil {
  246. t.Error()
  247. }
  248. svcIP := "10.20.30.41"
  249. svcPort := 80
  250. svcNodePort := 3001
  251. svcPortName := proxy.ServicePortName{
  252. NamespacedName: makeNSN("ns1", "svc1"),
  253. Port: "p80",
  254. }
  255. makeServiceMap(proxier,
  256. makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *v1.Service) {
  257. svc.Spec.Type = "NodePort"
  258. svc.Spec.ClusterIP = svcIP
  259. svc.Spec.Ports = []v1.ServicePort{{
  260. Name: svcPortName.Port,
  261. Port: int32(svcPort),
  262. Protocol: v1.ProtocolTCP,
  263. NodePort: int32(svcNodePort),
  264. }}
  265. }),
  266. )
  267. makeEndpointsMap(proxier,
  268. makeTestEndpoints(svcPortName.Namespace, svcPortName.Name, func(ept *v1.Endpoints) {
  269. ept.Subsets = []v1.EndpointSubset{{
  270. Addresses: []v1.EndpointAddress{{
  271. IP: epIpAddressRemote,
  272. }},
  273. Ports: []v1.EndpointPort{{
  274. Name: svcPortName.Port,
  275. Port: int32(svcPort),
  276. }},
  277. }}
  278. }),
  279. )
  280. proxier.syncProxyRules()
  281. if proxier.serviceMap[svcPortName].hnsID != guid {
  282. t.Errorf("%v does not match %v", proxier.serviceMap[svcPortName].hnsID, guid)
  283. }
  284. }
  285. func TestNoopEndpointSlice(t *testing.T) {
  286. p := Proxier{}
  287. p.OnEndpointSliceAdd(&discovery.EndpointSlice{})
  288. p.OnEndpointSliceUpdate(&discovery.EndpointSlice{}, &discovery.EndpointSlice{})
  289. p.OnEndpointSliceDelete(&discovery.EndpointSlice{})
  290. p.OnEndpointSlicesSynced()
  291. }
  292. func makeNSN(namespace, name string) types.NamespacedName {
  293. return types.NamespacedName{Namespace: namespace, Name: name}
  294. }
  295. func makeServiceMap(proxier *Proxier, allServices ...*v1.Service) {
  296. for i := range allServices {
  297. proxier.OnServiceAdd(allServices[i])
  298. }
  299. proxier.mu.Lock()
  300. defer proxier.mu.Unlock()
  301. proxier.servicesSynced = true
  302. }
  303. func makeTestService(namespace, name string, svcFunc func(*v1.Service)) *v1.Service {
  304. svc := &v1.Service{
  305. ObjectMeta: metav1.ObjectMeta{
  306. Name: name,
  307. Namespace: namespace,
  308. Annotations: map[string]string{},
  309. },
  310. Spec: v1.ServiceSpec{},
  311. Status: v1.ServiceStatus{},
  312. }
  313. svcFunc(svc)
  314. return svc
  315. }
  316. func makeEndpointsMap(proxier *Proxier, allEndpoints ...*v1.Endpoints) {
  317. for i := range allEndpoints {
  318. proxier.OnEndpointsAdd(allEndpoints[i])
  319. }
  320. proxier.mu.Lock()
  321. defer proxier.mu.Unlock()
  322. proxier.endpointsSynced = true
  323. }
  324. func makeTestEndpoints(namespace, name string, eptFunc func(*v1.Endpoints)) *v1.Endpoints {
  325. ept := &v1.Endpoints{
  326. ObjectMeta: metav1.ObjectMeta{
  327. Name: name,
  328. Namespace: namespace,
  329. },
  330. }
  331. eptFunc(ept)
  332. return ept
  333. }