dns_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  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 dns
  14. import (
  15. "context"
  16. "strings"
  17. "testing"
  18. apps "k8s.io/api/apps/v1"
  19. v1 "k8s.io/api/core/v1"
  20. apierrors "k8s.io/apimachinery/pkg/api/errors"
  21. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  22. "k8s.io/apimachinery/pkg/runtime"
  23. "k8s.io/apimachinery/pkg/runtime/schema"
  24. clientsetfake "k8s.io/client-go/kubernetes/fake"
  25. clientsetscheme "k8s.io/client-go/kubernetes/scheme"
  26. core "k8s.io/client-go/testing"
  27. kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
  28. kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
  29. )
  30. func TestCreateServiceAccount(t *testing.T) {
  31. tests := []struct {
  32. name string
  33. createErr error
  34. expectErr bool
  35. }{
  36. {
  37. "error-free case",
  38. nil,
  39. false,
  40. },
  41. {
  42. "duplication errors should be ignored",
  43. apierrors.NewAlreadyExists(schema.GroupResource{}, ""),
  44. false,
  45. },
  46. {
  47. "unexpected errors should be returned",
  48. apierrors.NewUnauthorized(""),
  49. true,
  50. },
  51. }
  52. for _, tc := range tests {
  53. t.Run(tc.name, func(t *testing.T) {
  54. client := clientsetfake.NewSimpleClientset()
  55. if tc.createErr != nil {
  56. client.PrependReactor("create", "serviceaccounts", func(action core.Action) (bool, runtime.Object, error) {
  57. return true, nil, tc.createErr
  58. })
  59. }
  60. err := CreateServiceAccount(client)
  61. if tc.expectErr {
  62. if err == nil {
  63. t.Errorf("CreateServiceAccounts(%s) wanted err, got nil", tc.name)
  64. }
  65. return
  66. } else if !tc.expectErr && err != nil {
  67. t.Errorf("CreateServiceAccounts(%s) returned unexpected err: %v", tc.name, err)
  68. }
  69. wantResourcesCreated := 1
  70. if len(client.Actions()) != wantResourcesCreated {
  71. t.Errorf("CreateServiceAccounts(%s) should have made %d actions, but made %d", tc.name, wantResourcesCreated, len(client.Actions()))
  72. }
  73. for _, action := range client.Actions() {
  74. if action.GetVerb() != "create" || action.GetResource().Resource != "serviceaccounts" {
  75. t.Errorf("CreateServiceAccounts(%s) called [%v %v], but wanted [create serviceaccounts]",
  76. tc.name, action.GetVerb(), action.GetResource().Resource)
  77. }
  78. }
  79. })
  80. }
  81. }
  82. func TestCompileManifests(t *testing.T) {
  83. replicas := int32(coreDNSReplicas)
  84. var tests = []struct {
  85. name string
  86. manifest string
  87. data interface{}
  88. }{
  89. {
  90. name: "KubeDNSDeployment manifest",
  91. manifest: KubeDNSDeployment,
  92. data: struct {
  93. DeploymentName, KubeDNSImage, DNSMasqImage, SidecarImage, DNSBindAddr, DNSProbeAddr, DNSDomain, ControlPlaneTaintKey string
  94. Replicas *int32
  95. }{
  96. DeploymentName: "foo",
  97. KubeDNSImage: "foo",
  98. DNSMasqImage: "foo",
  99. SidecarImage: "foo",
  100. DNSBindAddr: "foo",
  101. DNSProbeAddr: "foo",
  102. DNSDomain: "foo",
  103. ControlPlaneTaintKey: "foo",
  104. Replicas: &replicas,
  105. },
  106. },
  107. {
  108. name: "KubeDNSService manifest",
  109. manifest: KubeDNSService,
  110. data: struct{ DNSIP string }{
  111. DNSIP: "foo",
  112. },
  113. },
  114. {
  115. name: "CoreDNSDeployment manifest",
  116. manifest: CoreDNSDeployment,
  117. data: struct {
  118. DeploymentName, Image, ControlPlaneTaintKey string
  119. Replicas *int32
  120. }{
  121. DeploymentName: "foo",
  122. Image: "foo",
  123. ControlPlaneTaintKey: "foo",
  124. Replicas: &replicas,
  125. },
  126. },
  127. {
  128. name: "CoreDNSConfigMap manifest",
  129. manifest: CoreDNSConfigMap,
  130. data: struct{ DNSDomain, Federation, UpstreamNameserver, StubDomain string }{
  131. DNSDomain: "foo",
  132. Federation: "foo",
  133. UpstreamNameserver: "foo",
  134. StubDomain: "foo",
  135. },
  136. },
  137. }
  138. for _, rt := range tests {
  139. t.Run(rt.name, func(t *testing.T) {
  140. _, err := kubeadmutil.ParseTemplate(rt.manifest, rt.data)
  141. if err != nil {
  142. t.Errorf("unexpected ParseTemplate failure: %+v", err)
  143. }
  144. })
  145. }
  146. }
  147. func TestGetDNSIP(t *testing.T) {
  148. var tests = []struct {
  149. name, svcSubnet, expectedDNSIP string
  150. isDualStack bool
  151. }{
  152. {
  153. name: "subnet mask 12",
  154. svcSubnet: "10.96.0.0/12",
  155. expectedDNSIP: "10.96.0.10",
  156. isDualStack: false,
  157. },
  158. {
  159. name: "subnet mask 26",
  160. svcSubnet: "10.87.116.64/26",
  161. expectedDNSIP: "10.87.116.74",
  162. isDualStack: false,
  163. },
  164. {
  165. name: "dual-stack ipv4 primary, subnet mask 26",
  166. svcSubnet: "10.87.116.64/26,fd03::/112",
  167. expectedDNSIP: "10.87.116.74",
  168. isDualStack: true,
  169. },
  170. {
  171. name: "dual-stack ipv6 primary, subnet mask 112",
  172. svcSubnet: "fd03::/112,10.87.116.64/26",
  173. expectedDNSIP: "fd03::a",
  174. isDualStack: true,
  175. },
  176. }
  177. for _, rt := range tests {
  178. t.Run(rt.name, func(t *testing.T) {
  179. dnsIP, err := kubeadmconstants.GetDNSIP(rt.svcSubnet, rt.isDualStack)
  180. if err != nil {
  181. t.Fatalf("couldn't get dnsIP : %v", err)
  182. }
  183. actualDNSIP := dnsIP.String()
  184. if actualDNSIP != rt.expectedDNSIP {
  185. t.Errorf(
  186. "failed GetDNSIP\n\texpected: %s\n\t actual: %s",
  187. rt.expectedDNSIP,
  188. actualDNSIP,
  189. )
  190. }
  191. })
  192. }
  193. }
  194. func TestTranslateStubDomainKubeDNSToCoreDNS(t *testing.T) {
  195. testCases := []struct {
  196. name string
  197. configMap *v1.ConfigMap
  198. expectOne string
  199. expectTwo string
  200. }{
  201. {
  202. name: "valid call with multiple IPs",
  203. configMap: &v1.ConfigMap{
  204. ObjectMeta: metav1.ObjectMeta{
  205. Name: "kube-dns",
  206. Namespace: "kube-system",
  207. },
  208. Data: map[string]string{
  209. "stubDomains": `{"foo.com" : ["1.2.3.4:5300","3.3.3.3"], "my.cluster.local" : ["2.3.4.5"]}`,
  210. "upstreamNameservers": `["8.8.8.8", "8.8.4.4"]`,
  211. },
  212. },
  213. expectOne: `
  214. foo.com:53 {
  215. errors
  216. cache 30
  217. loop
  218. forward . 1.2.3.4:5300 3.3.3.3
  219. }
  220. my.cluster.local:53 {
  221. errors
  222. cache 30
  223. loop
  224. forward . 2.3.4.5
  225. }`,
  226. expectTwo: `
  227. my.cluster.local:53 {
  228. errors
  229. cache 30
  230. loop
  231. forward . 2.3.4.5
  232. }
  233. foo.com:53 {
  234. errors
  235. cache 30
  236. loop
  237. forward . 1.2.3.4:5300 3.3.3.3
  238. }`,
  239. },
  240. {
  241. name: "empty call",
  242. configMap: &v1.ConfigMap{
  243. ObjectMeta: metav1.ObjectMeta{
  244. Name: "kubedns",
  245. Namespace: "kube-system",
  246. },
  247. },
  248. expectOne: "",
  249. },
  250. {
  251. name: "valid call",
  252. configMap: &v1.ConfigMap{
  253. ObjectMeta: metav1.ObjectMeta{
  254. Name: "kube-dns",
  255. Namespace: "kube-system",
  256. },
  257. Data: map[string]string{
  258. "stubDomains": `{"foo.com" : ["1.2.3.4:5300"], "my.cluster.local" : ["2.3.4.5"]}`,
  259. "upstreamNameservers": `["8.8.8.8", "8.8.4.4"]`,
  260. },
  261. },
  262. expectOne: `
  263. foo.com:53 {
  264. errors
  265. cache 30
  266. loop
  267. forward . 1.2.3.4:5300
  268. }
  269. my.cluster.local:53 {
  270. errors
  271. cache 30
  272. loop
  273. forward . 2.3.4.5
  274. }`,
  275. expectTwo: `
  276. my.cluster.local:53 {
  277. errors
  278. cache 30
  279. loop
  280. forward . 2.3.4.5
  281. }
  282. foo.com:53 {
  283. errors
  284. cache 30
  285. loop
  286. forward . 1.2.3.4:5300
  287. }`,
  288. },
  289. {
  290. name: "If Hostname present: Omit Hostname",
  291. configMap: &v1.ConfigMap{
  292. ObjectMeta: metav1.ObjectMeta{
  293. Name: "kube-dns",
  294. Namespace: "kube-system",
  295. },
  296. Data: map[string]string{
  297. "stubDomains": `{"bar.com" : ["1.2.3.4:5300","service.consul"], "my.cluster.local" : ["2.3.4.5"], "foo.com" : ["service.consul"]}`,
  298. "upstreamNameservers": `["8.8.8.8", "8.8.4.4"]`,
  299. },
  300. },
  301. expectOne: `
  302. bar.com:53 {
  303. errors
  304. cache 30
  305. loop
  306. forward . 1.2.3.4:5300
  307. }
  308. my.cluster.local:53 {
  309. errors
  310. cache 30
  311. loop
  312. forward . 2.3.4.5
  313. }`,
  314. expectTwo: `
  315. my.cluster.local:53 {
  316. errors
  317. cache 30
  318. loop
  319. forward . 2.3.4.5
  320. }
  321. bar.com:53 {
  322. errors
  323. cache 30
  324. loop
  325. forward . 1.2.3.4:5300
  326. }`,
  327. },
  328. {
  329. name: "All hostname: return empty",
  330. configMap: &v1.ConfigMap{
  331. ObjectMeta: metav1.ObjectMeta{
  332. Name: "kube-dns",
  333. Namespace: "kube-system",
  334. },
  335. Data: map[string]string{
  336. "stubDomains": `{"foo.com" : ["service.consul"], "my.cluster.local" : ["ns.foo.com"]}`,
  337. "upstreamNameservers": `["8.8.8.8", "8.8.4.4"]`,
  338. },
  339. },
  340. expectOne: "",
  341. expectTwo: "",
  342. },
  343. {
  344. name: "missing stubDomains",
  345. configMap: &v1.ConfigMap{
  346. ObjectMeta: metav1.ObjectMeta{
  347. Name: "kube-dns",
  348. Namespace: "kube-system",
  349. },
  350. Data: map[string]string{
  351. "upstreamNameservers": `["8.8.8.8", "8.8.4.4"]`,
  352. },
  353. },
  354. expectOne: "",
  355. },
  356. }
  357. for _, testCase := range testCases {
  358. t.Run(testCase.name, func(t *testing.T) {
  359. out, err := translateStubDomainOfKubeDNSToForwardCoreDNS(kubeDNSStubDomain, testCase.configMap)
  360. if err != nil {
  361. t.Errorf("unexpected error: %v", err)
  362. }
  363. if !strings.EqualFold(out, testCase.expectOne) && !strings.EqualFold(out, testCase.expectTwo) {
  364. t.Errorf("expected to find %q or %q in output: %q", testCase.expectOne, testCase.expectTwo, out)
  365. }
  366. })
  367. }
  368. }
  369. func TestTranslateUpstreamKubeDNSToCoreDNS(t *testing.T) {
  370. testCases := []struct {
  371. name string
  372. configMap *v1.ConfigMap
  373. expect string
  374. }{
  375. {
  376. name: "expect resolv.conf",
  377. configMap: &v1.ConfigMap{
  378. ObjectMeta: metav1.ObjectMeta{
  379. Name: "kube-dns",
  380. Namespace: "kube-system",
  381. },
  382. },
  383. expect: "/etc/resolv.conf",
  384. },
  385. {
  386. name: "expect list of Name Server IP addresses",
  387. configMap: &v1.ConfigMap{
  388. ObjectMeta: metav1.ObjectMeta{
  389. Name: "kubedns",
  390. Namespace: "kube-system",
  391. },
  392. Data: map[string]string{
  393. "stubDomains": ` {"foo.com" : ["1.2.3.4:5300"], "my.cluster.local" : ["2.3.4.5"]}`,
  394. "upstreamNameservers": `["8.8.8.8", "8.8.4.4", "4.4.4.4"]`,
  395. },
  396. },
  397. expect: "8.8.8.8 8.8.4.4 4.4.4.4",
  398. },
  399. {
  400. name: "no stubDomains: expect list of Name Server IP addresses",
  401. configMap: &v1.ConfigMap{
  402. ObjectMeta: metav1.ObjectMeta{
  403. Name: "kubedns",
  404. Namespace: "kube-system",
  405. },
  406. Data: map[string]string{
  407. "upstreamNameservers": `["8.8.8.8", "8.8.4.4"]`,
  408. },
  409. },
  410. expect: "8.8.8.8 8.8.4.4",
  411. },
  412. {
  413. name: "Hostname present: expect NameServer to omit the hostname",
  414. configMap: &v1.ConfigMap{
  415. ObjectMeta: metav1.ObjectMeta{
  416. Name: "kubedns",
  417. Namespace: "kube-system",
  418. },
  419. Data: map[string]string{
  420. "upstreamNameservers": `["service.consul", "ns.foo.com", "8.8.4.4", "ns.moo.com", "ns.bar.com"]`,
  421. },
  422. },
  423. expect: "8.8.4.4",
  424. },
  425. {
  426. name: "All hostnames: return empty",
  427. configMap: &v1.ConfigMap{
  428. ObjectMeta: metav1.ObjectMeta{
  429. Name: "kube-dns",
  430. Namespace: "kube-system",
  431. },
  432. Data: map[string]string{
  433. "upstreamNameservers": `["service.consul", "ns.foo.com"]`,
  434. },
  435. },
  436. expect: "",
  437. },
  438. {
  439. name: "IPv6: expect list of Name Server IP addresses",
  440. configMap: &v1.ConfigMap{
  441. ObjectMeta: metav1.ObjectMeta{
  442. Name: "kubedns",
  443. Namespace: "kube-system",
  444. },
  445. Data: map[string]string{
  446. "upstreamNameservers": `["[2003::1]:53", "8.8.4.4"]`,
  447. },
  448. },
  449. expect: "[2003::1]:53 8.8.4.4",
  450. },
  451. }
  452. for _, testCase := range testCases {
  453. t.Run(testCase.name, func(t *testing.T) {
  454. out, err := translateUpstreamNameServerOfKubeDNSToUpstreamForwardCoreDNS(kubeDNSUpstreamNameservers, testCase.configMap)
  455. if err != nil {
  456. t.Errorf("unexpected error: %v", err)
  457. }
  458. if !strings.EqualFold(out, testCase.expect) {
  459. t.Errorf("expected to find %q in output: %q", testCase.expect, out)
  460. }
  461. })
  462. }
  463. }
  464. func TestTranslateFederationKubeDNSToCoreDNS(t *testing.T) {
  465. testCases := []struct {
  466. name string
  467. configMap *v1.ConfigMap
  468. expectOne string
  469. expectTwo string
  470. }{
  471. {
  472. name: "valid call",
  473. configMap: &v1.ConfigMap{
  474. ObjectMeta: metav1.ObjectMeta{
  475. Name: "kube-dns",
  476. Namespace: "kube-system",
  477. },
  478. Data: map[string]string{
  479. "federations": `{"foo" : "foo.feddomain.com", "bar" : "bar.feddomain.com"}`,
  480. "stubDomains": `{"foo.com" : ["1.2.3.4:5300","3.3.3.3"], "my.cluster.local" : ["2.3.4.5"]}`,
  481. "upstreamNameservers": `["8.8.8.8", "8.8.4.4"]`,
  482. },
  483. },
  484. expectOne: `
  485. federation cluster.local {
  486. foo foo.feddomain.com
  487. bar bar.feddomain.com
  488. }`,
  489. expectTwo: `
  490. federation cluster.local {
  491. bar bar.feddomain.com
  492. foo foo.feddomain.com
  493. }`,
  494. },
  495. {
  496. name: "empty data",
  497. configMap: &v1.ConfigMap{
  498. ObjectMeta: metav1.ObjectMeta{
  499. Name: "kubedns",
  500. Namespace: "kube-system",
  501. },
  502. },
  503. expectOne: "",
  504. expectTwo: "",
  505. },
  506. {
  507. name: "missing federations data",
  508. configMap: &v1.ConfigMap{
  509. ObjectMeta: metav1.ObjectMeta{
  510. Name: "kube-dns",
  511. Namespace: "kube-system",
  512. },
  513. Data: map[string]string{
  514. "stubDomains": `{"foo.com" : ["1.2.3.4:5300"], "my.cluster.local" : ["2.3.4.5"]}`,
  515. "upstreamNameservers": `["8.8.8.8", "8.8.4.4"]`,
  516. },
  517. },
  518. expectOne: "",
  519. expectTwo: "",
  520. },
  521. }
  522. for _, testCase := range testCases {
  523. t.Run(testCase.name, func(t *testing.T) {
  524. out, err := translateFederationsofKubeDNSToCoreDNS(kubeDNSFederation, "cluster.local", testCase.configMap)
  525. if err != nil {
  526. t.Errorf("unexpected error: %v", err)
  527. }
  528. if !strings.EqualFold(out, testCase.expectOne) && !strings.EqualFold(out, testCase.expectTwo) {
  529. t.Errorf("expected to find %q or %q in output: %q", testCase.expectOne, testCase.expectTwo, out)
  530. }
  531. })
  532. }
  533. }
  534. func TestDeploymentsHaveSystemClusterCriticalPriorityClassName(t *testing.T) {
  535. replicas := int32(coreDNSReplicas)
  536. testCases := []struct {
  537. name string
  538. manifest string
  539. data interface{}
  540. }{
  541. {
  542. name: "KubeDNSDeployment",
  543. manifest: KubeDNSDeployment,
  544. data: struct {
  545. DeploymentName, KubeDNSImage, DNSMasqImage, SidecarImage, DNSBindAddr, DNSProbeAddr, DNSDomain, ControlPlaneTaintKey string
  546. Replicas *int32
  547. }{
  548. DeploymentName: "foo",
  549. KubeDNSImage: "foo",
  550. DNSMasqImage: "foo",
  551. SidecarImage: "foo",
  552. DNSBindAddr: "foo",
  553. DNSProbeAddr: "foo",
  554. DNSDomain: "foo",
  555. ControlPlaneTaintKey: "foo",
  556. Replicas: &replicas,
  557. },
  558. },
  559. {
  560. name: "CoreDNSDeployment",
  561. manifest: CoreDNSDeployment,
  562. data: struct {
  563. DeploymentName, Image, ControlPlaneTaintKey, CoreDNSConfigMapName string
  564. Replicas *int32
  565. }{
  566. DeploymentName: "foo",
  567. Image: "foo",
  568. ControlPlaneTaintKey: "foo",
  569. CoreDNSConfigMapName: "foo",
  570. Replicas: &replicas,
  571. },
  572. },
  573. }
  574. for _, testCase := range testCases {
  575. t.Run(testCase.name, func(t *testing.T) {
  576. deploymentBytes, _ := kubeadmutil.ParseTemplate(testCase.manifest, testCase.data)
  577. deployment := &apps.Deployment{}
  578. if err := runtime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), deploymentBytes, deployment); err != nil {
  579. t.Errorf("unexpected error: %v", err)
  580. }
  581. if deployment.Spec.Template.Spec.PriorityClassName != "system-cluster-critical" {
  582. t.Errorf("expected to see system-cluster-critical priority class name. Got %q instead", deployment.Spec.Template.Spec.PriorityClassName)
  583. }
  584. })
  585. }
  586. }
  587. func TestCreateCoreDNSConfigMap(t *testing.T) {
  588. tests := []struct {
  589. name string
  590. initialCorefileData string
  591. expectedCorefileData string
  592. coreDNSVersion string
  593. }{
  594. {
  595. name: "Remove Deprecated options",
  596. initialCorefileData: `.:53 {
  597. errors
  598. health
  599. kubernetes cluster.local in-addr.arpa ip6.arpa {
  600. pods insecure
  601. upstream
  602. fallthrough in-addr.arpa ip6.arpa
  603. ttl 30
  604. }
  605. prometheus :9153
  606. forward . /etc/resolv.conf
  607. cache 30
  608. loop
  609. reload
  610. loadbalance
  611. }`,
  612. expectedCorefileData: `.:53 {
  613. errors
  614. health {
  615. lameduck 5s
  616. }
  617. kubernetes cluster.local in-addr.arpa ip6.arpa {
  618. pods insecure
  619. fallthrough in-addr.arpa ip6.arpa
  620. ttl 30
  621. }
  622. prometheus :9153
  623. forward . /etc/resolv.conf
  624. cache 30
  625. loop
  626. reload
  627. loadbalance
  628. ready
  629. }
  630. `,
  631. coreDNSVersion: "1.3.1",
  632. },
  633. {
  634. name: "Update proxy plugin to forward plugin",
  635. initialCorefileData: `.:53 {
  636. errors
  637. health
  638. kubernetes cluster.local in-addr.arpa ip6.arpa {
  639. pods insecure
  640. upstream
  641. fallthrough in-addr.arpa ip6.arpa
  642. }
  643. prometheus :9153
  644. proxy . /etc/resolv.conf
  645. k8s_external example.com
  646. cache 30
  647. loop
  648. reload
  649. loadbalance
  650. }`,
  651. expectedCorefileData: `.:53 {
  652. errors
  653. health {
  654. lameduck 5s
  655. }
  656. kubernetes cluster.local in-addr.arpa ip6.arpa {
  657. pods insecure
  658. fallthrough in-addr.arpa ip6.arpa
  659. }
  660. prometheus :9153
  661. forward . /etc/resolv.conf
  662. k8s_external example.com
  663. cache 30
  664. loop
  665. reload
  666. loadbalance
  667. ready
  668. }
  669. `,
  670. coreDNSVersion: "1.3.1",
  671. },
  672. }
  673. for _, tc := range tests {
  674. t.Run(tc.name, func(t *testing.T) {
  675. client := createClientAndCoreDNSManifest(t, tc.initialCorefileData, tc.coreDNSVersion)
  676. // Get the Corefile and installed CoreDNS version.
  677. cm, corefile, currentInstalledCoreDNSVersion, err := GetCoreDNSInfo(client)
  678. if err != nil {
  679. t.Fatalf("unable to fetch CoreDNS current installed version and ConfigMap.")
  680. }
  681. err = migrateCoreDNSCorefile(client, cm, corefile, currentInstalledCoreDNSVersion)
  682. if err != nil {
  683. t.Fatalf("error creating the CoreDNS ConfigMap: %v", err)
  684. }
  685. migratedConfigMap, _ := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(context.TODO(), kubeadmconstants.CoreDNSConfigMap, metav1.GetOptions{})
  686. if !strings.EqualFold(migratedConfigMap.Data["Corefile"], tc.expectedCorefileData) {
  687. t.Fatalf("expected to get %v, but got %v", tc.expectedCorefileData, migratedConfigMap.Data["Corefile"])
  688. }
  689. })
  690. }
  691. }
  692. func createClientAndCoreDNSManifest(t *testing.T, corefile, coreDNSVersion string) *clientsetfake.Clientset {
  693. client := clientsetfake.NewSimpleClientset()
  694. _, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Create(context.TODO(), &v1.ConfigMap{
  695. ObjectMeta: metav1.ObjectMeta{
  696. Name: kubeadmconstants.CoreDNSConfigMap,
  697. Namespace: metav1.NamespaceSystem,
  698. },
  699. Data: map[string]string{
  700. "Corefile": corefile,
  701. },
  702. }, metav1.CreateOptions{})
  703. if err != nil {
  704. t.Fatalf("error creating ConfigMap: %v", err)
  705. }
  706. _, err = client.AppsV1().Deployments(metav1.NamespaceSystem).Create(context.TODO(), &apps.Deployment{
  707. TypeMeta: metav1.TypeMeta{
  708. Kind: "Deployment",
  709. APIVersion: "apps/v1",
  710. },
  711. ObjectMeta: metav1.ObjectMeta{
  712. Name: kubeadmconstants.CoreDNSConfigMap,
  713. Namespace: metav1.NamespaceSystem,
  714. Labels: map[string]string{
  715. "k8s-app": "kube-dns",
  716. },
  717. },
  718. Spec: apps.DeploymentSpec{
  719. Template: v1.PodTemplateSpec{
  720. Spec: v1.PodSpec{
  721. Containers: []v1.Container{
  722. {
  723. Image: "test:" + coreDNSVersion,
  724. },
  725. },
  726. },
  727. },
  728. },
  729. }, metav1.CreateOptions{})
  730. if err != nil {
  731. t.Fatalf("error creating deployment: %v", err)
  732. }
  733. return client
  734. }