server_others_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  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 app
  15. import (
  16. "fmt"
  17. "reflect"
  18. "testing"
  19. proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/config"
  20. "k8s.io/kubernetes/pkg/proxy/ipvs"
  21. proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables"
  22. utiliptables "k8s.io/kubernetes/pkg/util/iptables"
  23. utiliptablestest "k8s.io/kubernetes/pkg/util/iptables/testing"
  24. )
  25. type fakeIPSetVersioner struct {
  26. version string // what to return
  27. err error // what to return
  28. }
  29. func (fake *fakeIPSetVersioner) GetVersion() (string, error) {
  30. return fake.version, fake.err
  31. }
  32. type fakeKernelCompatTester struct {
  33. ok bool
  34. }
  35. func (fake *fakeKernelCompatTester) IsCompatible() error {
  36. if !fake.ok {
  37. return fmt.Errorf("error")
  38. }
  39. return nil
  40. }
  41. // fakeKernelHandler implements KernelHandler.
  42. type fakeKernelHandler struct {
  43. modules []string
  44. kernelVersion string
  45. }
  46. func (fake *fakeKernelHandler) GetModules() ([]string, error) {
  47. return fake.modules, nil
  48. }
  49. func (fake *fakeKernelHandler) GetKernelVersion() (string, error) {
  50. return fake.kernelVersion, nil
  51. }
  52. func Test_getProxyMode(t *testing.T) {
  53. var cases = []struct {
  54. flag string
  55. ipsetVersion string
  56. kmods []string
  57. kernelVersion string
  58. kernelCompat bool
  59. ipsetError error
  60. expected string
  61. }{
  62. { // flag says userspace
  63. flag: "userspace",
  64. expected: proxyModeUserspace,
  65. },
  66. { // flag says iptables, kernel not compatible
  67. flag: "iptables",
  68. kernelCompat: false,
  69. expected: proxyModeUserspace,
  70. },
  71. { // flag says iptables, kernel is compatible
  72. flag: "iptables",
  73. kernelCompat: true,
  74. expected: proxyModeIPTables,
  75. },
  76. { // detect, kernel not compatible
  77. flag: "",
  78. kernelCompat: false,
  79. expected: proxyModeUserspace,
  80. },
  81. { // detect, kernel is compatible
  82. flag: "",
  83. kernelCompat: true,
  84. expected: proxyModeIPTables,
  85. },
  86. { // flag says ipvs, ipset version ok, kernel modules installed for linux kernel before 4.19
  87. flag: "ipvs",
  88. kmods: []string{"ip_vs", "ip_vs_rr", "ip_vs_wrr", "ip_vs_sh", "nf_conntrack_ipv4"},
  89. kernelVersion: "4.18",
  90. ipsetVersion: ipvs.MinIPSetCheckVersion,
  91. expected: proxyModeIPVS,
  92. },
  93. { // flag says ipvs, ipset version ok, kernel modules installed for linux kernel 4.19
  94. flag: "ipvs",
  95. kmods: []string{"ip_vs", "ip_vs_rr", "ip_vs_wrr", "ip_vs_sh", "nf_conntrack"},
  96. kernelVersion: "4.19",
  97. ipsetVersion: ipvs.MinIPSetCheckVersion,
  98. expected: proxyModeIPVS,
  99. },
  100. { // flag says ipvs, ipset version too low, fallback on iptables mode
  101. flag: "ipvs",
  102. kmods: []string{"ip_vs", "ip_vs_rr", "ip_vs_wrr", "ip_vs_sh", "nf_conntrack"},
  103. kernelVersion: "4.19",
  104. ipsetVersion: "0.0",
  105. kernelCompat: true,
  106. expected: proxyModeIPTables,
  107. },
  108. { // flag says ipvs, bad ipset version, fallback on iptables mode
  109. flag: "ipvs",
  110. kmods: []string{"ip_vs", "ip_vs_rr", "ip_vs_wrr", "ip_vs_sh", "nf_conntrack"},
  111. kernelVersion: "4.19",
  112. ipsetVersion: "a.b.c",
  113. kernelCompat: true,
  114. expected: proxyModeIPTables,
  115. },
  116. { // flag says ipvs, required kernel modules are not installed, fallback on iptables mode
  117. flag: "ipvs",
  118. kmods: []string{"foo", "bar", "baz"},
  119. kernelVersion: "4.19",
  120. ipsetVersion: ipvs.MinIPSetCheckVersion,
  121. kernelCompat: true,
  122. expected: proxyModeIPTables,
  123. },
  124. }
  125. for i, c := range cases {
  126. kcompater := &fakeKernelCompatTester{c.kernelCompat}
  127. ipsetver := &fakeIPSetVersioner{c.ipsetVersion, c.ipsetError}
  128. khandler := &fakeKernelHandler{
  129. modules: c.kmods,
  130. kernelVersion: c.kernelVersion,
  131. }
  132. r := getProxyMode(c.flag, khandler, ipsetver, kcompater)
  133. if r != c.expected {
  134. t.Errorf("Case[%d] Expected %q, got %q", i, c.expected, r)
  135. }
  136. }
  137. }
  138. func Test_getDetectLocalMode(t *testing.T) {
  139. cases := []struct {
  140. detectLocal string
  141. expected proxyconfigapi.LocalMode
  142. errExpected bool
  143. }{
  144. {
  145. detectLocal: "",
  146. expected: proxyconfigapi.LocalModeClusterCIDR,
  147. errExpected: false,
  148. },
  149. {
  150. detectLocal: string(proxyconfigapi.LocalModeClusterCIDR),
  151. expected: proxyconfigapi.LocalModeClusterCIDR,
  152. errExpected: false,
  153. },
  154. {
  155. detectLocal: "abcd",
  156. expected: proxyconfigapi.LocalMode("abcd"),
  157. errExpected: true,
  158. },
  159. }
  160. for i, c := range cases {
  161. proxyConfig := &proxyconfigapi.KubeProxyConfiguration{DetectLocalMode: proxyconfigapi.LocalMode(c.detectLocal)}
  162. r, err := getDetectLocalMode(proxyConfig)
  163. if c.errExpected {
  164. if err == nil {
  165. t.Errorf("Expected error, but did not fail for mode %v", c.detectLocal)
  166. }
  167. continue
  168. }
  169. if err != nil {
  170. t.Errorf("Got error parsing mode: %v", err)
  171. continue
  172. }
  173. if r != c.expected {
  174. t.Errorf("Case[%d] Expected %q got %q", i, c.expected, r)
  175. }
  176. }
  177. }
  178. func Test_getLocalDetector(t *testing.T) {
  179. cases := []struct {
  180. mode proxyconfigapi.LocalMode
  181. config *proxyconfigapi.KubeProxyConfiguration
  182. ipt utiliptables.Interface
  183. expected proxyutiliptables.LocalTrafficDetector
  184. errExpected bool
  185. }{
  186. {
  187. mode: proxyconfigapi.LocalModeClusterCIDR,
  188. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
  189. ipt: utiliptablestest.NewFake(),
  190. expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/14", utiliptablestest.NewFake())),
  191. errExpected: false,
  192. },
  193. {
  194. mode: proxyconfigapi.LocalModeClusterCIDR,
  195. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002::1234:abcd:ffff:c0a8:101/64"},
  196. ipt: utiliptablestest.NewIpv6Fake(),
  197. expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("2002::1234:abcd:ffff:c0a8:101/64", utiliptablestest.NewIpv6Fake())),
  198. errExpected: false,
  199. },
  200. {
  201. mode: proxyconfigapi.LocalModeClusterCIDR,
  202. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0"},
  203. ipt: utiliptablestest.NewFake(),
  204. expected: nil,
  205. errExpected: true,
  206. },
  207. {
  208. mode: proxyconfigapi.LocalModeClusterCIDR,
  209. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002::1234:abcd:ffff:c0a8:101"},
  210. ipt: utiliptablestest.NewIpv6Fake(),
  211. expected: nil,
  212. errExpected: true,
  213. },
  214. {
  215. mode: proxyconfigapi.LocalModeClusterCIDR,
  216. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
  217. ipt: utiliptablestest.NewIpv6Fake(),
  218. expected: nil,
  219. errExpected: true,
  220. },
  221. {
  222. mode: proxyconfigapi.LocalModeClusterCIDR,
  223. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002::1234:abcd:ffff:c0a8:101/64"},
  224. ipt: utiliptablestest.NewFake(),
  225. expected: nil,
  226. errExpected: true,
  227. },
  228. {
  229. mode: proxyconfigapi.LocalMode("abcd"),
  230. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
  231. ipt: utiliptablestest.NewFake(),
  232. expected: proxyutiliptables.NewNoOpLocalDetector(),
  233. errExpected: false,
  234. },
  235. {
  236. mode: proxyconfigapi.LocalModeClusterCIDR,
  237. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""},
  238. ipt: utiliptablestest.NewFake(),
  239. expected: proxyutiliptables.NewNoOpLocalDetector(),
  240. errExpected: false,
  241. },
  242. }
  243. for i, c := range cases {
  244. r, err := getLocalDetector(c.mode, c.config, c.ipt)
  245. if c.errExpected {
  246. if err == nil {
  247. t.Errorf("Case[%d] Expected error, but succeeded with %v", i, r)
  248. }
  249. continue
  250. }
  251. if err != nil {
  252. t.Errorf("Case[%d] Error resolving detect-local: %v", i, err)
  253. continue
  254. }
  255. if !reflect.DeepEqual(r, c.expected) {
  256. t.Errorf("Case[%d] Unexpected detect-local implementation, expected: %q, got: %q", i, c.expected, r)
  257. }
  258. }
  259. }
  260. func Test_getDualStackLocalDetectorTuple(t *testing.T) {
  261. cases := []struct {
  262. mode proxyconfigapi.LocalMode
  263. config *proxyconfigapi.KubeProxyConfiguration
  264. ipt [2]utiliptables.Interface
  265. expected [2]proxyutiliptables.LocalTrafficDetector
  266. errExpected bool
  267. }{
  268. {
  269. mode: proxyconfigapi.LocalModeClusterCIDR,
  270. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14,2002::1234:abcd:ffff:c0a8:101/64"},
  271. ipt: [2]utiliptables.Interface{utiliptablestest.NewFake(), utiliptablestest.NewIpv6Fake()},
  272. expected: resolveDualStackLocalDetectors(t)(
  273. proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/14", utiliptablestest.NewFake()))(
  274. proxyutiliptables.NewDetectLocalByCIDR("2002::1234:abcd:ffff:c0a8:101/64", utiliptablestest.NewIpv6Fake())),
  275. errExpected: false,
  276. },
  277. {
  278. mode: proxyconfigapi.LocalModeClusterCIDR,
  279. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002::1234:abcd:ffff:c0a8:101/64,10.0.0.0/14"},
  280. ipt: [2]utiliptables.Interface{utiliptablestest.NewFake(), utiliptablestest.NewIpv6Fake()},
  281. expected: resolveDualStackLocalDetectors(t)(
  282. proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/14", utiliptablestest.NewFake()))(
  283. proxyutiliptables.NewDetectLocalByCIDR("2002::1234:abcd:ffff:c0a8:101/64", utiliptablestest.NewIpv6Fake())),
  284. errExpected: false,
  285. },
  286. {
  287. mode: proxyconfigapi.LocalModeClusterCIDR,
  288. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"},
  289. ipt: [2]utiliptables.Interface{utiliptablestest.NewFake(), utiliptablestest.NewIpv6Fake()},
  290. expected: [2]proxyutiliptables.LocalTrafficDetector{
  291. resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("10.0.0.0/14", utiliptablestest.NewFake())),
  292. proxyutiliptables.NewNoOpLocalDetector()},
  293. errExpected: false,
  294. },
  295. {
  296. mode: proxyconfigapi.LocalModeClusterCIDR,
  297. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002::1234:abcd:ffff:c0a8:101/64"},
  298. ipt: [2]utiliptables.Interface{utiliptablestest.NewFake(), utiliptablestest.NewIpv6Fake()},
  299. expected: [2]proxyutiliptables.LocalTrafficDetector{
  300. proxyutiliptables.NewNoOpLocalDetector(),
  301. resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("2002::1234:abcd:ffff:c0a8:101/64", utiliptablestest.NewIpv6Fake()))},
  302. errExpected: false,
  303. },
  304. {
  305. mode: proxyconfigapi.LocalModeClusterCIDR,
  306. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""},
  307. ipt: [2]utiliptables.Interface{utiliptablestest.NewFake(), utiliptablestest.NewIpv6Fake()},
  308. expected: [2]proxyutiliptables.LocalTrafficDetector{proxyutiliptables.NewNoOpLocalDetector(), proxyutiliptables.NewNoOpLocalDetector()},
  309. errExpected: false,
  310. },
  311. {
  312. mode: proxyconfigapi.LocalMode("abcd"),
  313. config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""},
  314. ipt: [2]utiliptables.Interface{utiliptablestest.NewFake(), utiliptablestest.NewIpv6Fake()},
  315. expected: [2]proxyutiliptables.LocalTrafficDetector{proxyutiliptables.NewNoOpLocalDetector(), proxyutiliptables.NewNoOpLocalDetector()},
  316. errExpected: false,
  317. },
  318. }
  319. for i, c := range cases {
  320. r, err := getDualStackLocalDetectorTuple(c.mode, c.config, c.ipt)
  321. if c.errExpected {
  322. if err == nil {
  323. t.Errorf("Case[%d] expected error, but succeeded with %q", i, r)
  324. }
  325. continue
  326. }
  327. if err != nil {
  328. t.Errorf("Case[%d] Error resolving detect-local: %v", i, err)
  329. continue
  330. }
  331. if !reflect.DeepEqual(r, c.expected) {
  332. t.Errorf("Case[%d] Unexpected detect-local implementation, expected: %q, got: %q", i, c.expected, r)
  333. }
  334. }
  335. }
  336. func resolveLocalDetector(t *testing.T) func(proxyutiliptables.LocalTrafficDetector, error) proxyutiliptables.LocalTrafficDetector {
  337. return func(localDetector proxyutiliptables.LocalTrafficDetector, err error) proxyutiliptables.LocalTrafficDetector {
  338. t.Helper()
  339. if err != nil {
  340. t.Fatalf("Error resolving detect-local: %v", err)
  341. }
  342. return localDetector
  343. }
  344. }
  345. func resolveDualStackLocalDetectors(t *testing.T) func(localDetector proxyutiliptables.LocalTrafficDetector, err1 error) func(proxyutiliptables.LocalTrafficDetector, error) [2]proxyutiliptables.LocalTrafficDetector {
  346. return func(localDetector proxyutiliptables.LocalTrafficDetector, err error) func(proxyutiliptables.LocalTrafficDetector, error) [2]proxyutiliptables.LocalTrafficDetector {
  347. t.Helper()
  348. if err != nil {
  349. t.Fatalf("Error resolving dual stack detect-local: %v", err)
  350. }
  351. return func(otherLocalDetector proxyutiliptables.LocalTrafficDetector, err1 error) [2]proxyutiliptables.LocalTrafficDetector {
  352. t.Helper()
  353. if err1 != nil {
  354. t.Fatalf("Error resolving dual stack detect-local: %v", err)
  355. }
  356. return [2]proxyutiliptables.LocalTrafficDetector{localDetector, otherLocalDetector}
  357. }
  358. }
  359. }