github.com/nmstate/kubernetes-nmstate@v0.82.0/test/e2e/handler/dns_test.go (about)

     1  /*
     2  Copyright The Kubernetes NMState Authors.
     3  
     4  
     5  Licensed under the Apache License, Version 2.0 (the "License");
     6  you may not use this file except in compliance with the License.
     7  You may obtain a copy of the License at
     8  
     9      http://www.apache.org/licenses/LICENSE-2.0
    10  
    11  Unless required by applicable law or agreed to in writing, software
    12  distributed under the License is distributed on an "AS IS" BASIS,
    13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  See the License for the specific language governing permissions and
    15  limitations under the License.
    16  */
    17  
    18  package handler
    19  
    20  import (
    21  	"fmt"
    22  	"strings"
    23  
    24  	. "github.com/onsi/ginkgo/v2"
    25  	. "github.com/onsi/gomega"
    26  
    27  	nmstate "github.com/nmstate/kubernetes-nmstate/api/shared"
    28  )
    29  
    30  func dhcpAwareDNSConfig(searchDomain1, searchDomain2, server1, server2, dnsTestNic string) nmstate.State {
    31  	return nmstate.NewState(fmt.Sprintf(`dns-resolver:
    32    config:
    33     search:
    34     - %s
    35     - %s
    36     server:
    37     - %s
    38     - %s
    39  interfaces:
    40  - name: %s
    41    type: ethernet
    42    state: up
    43    ipv4:
    44      auto-dns: false
    45      enabled: true
    46      dhcp: true
    47    ipv6:
    48      enabled: true
    49      dhcp: true
    50      auto-dns: false
    51  `, searchDomain1, searchDomain2, server1, server2, dnsTestNic))
    52  }
    53  
    54  func staticIPAndGwConfig(searchDomain1, searchDomain2, server1, server2, dnsTestNic, dnsTestNicIP string) nmstate.State {
    55  	return nmstate.NewState(fmt.Sprintf(`
    56  dns-resolver:
    57    config:
    58     search:
    59     - %s
    60     - %s
    61     server:
    62     - %s
    63     - %s
    64  routes:
    65    config:
    66    - destination: 0.0.0.0/0
    67      metric: 100
    68      next-hop-address: %s
    69      next-hop-interface: %s
    70      table-id: 253
    71    - destination: 0::/0
    72      metric: 100
    73      next-hop-address: fd80:0:0:0::1
    74      next-hop-interface: eth1
    75      table-id: 253
    76  interfaces:
    77  - name: %s
    78    type: ethernet
    79    state: up
    80    ipv4:
    81      address:
    82      - ip: %s
    83        prefix-length: 24
    84      enabled: true
    85      dhcp: false
    86      auto-dns: false
    87  - name: eth1
    88    type: ethernet
    89    state: up
    90    ipv6:
    91      enabled: true
    92      dhcp: false
    93      auto-dns: false
    94      address:
    95      - ip: 2001:db8::1:1
    96        prefix-length: 64
    97  `, searchDomain1, searchDomain2, server1, server2, dnsTestNicIP, dnsTestNic, dnsTestNic, dnsTestNicIP))
    98  }
    99  
   100  func staticIPAbsentAndRoutesAbsent(dnsTestNic, dnsTestNicIP string) nmstate.State {
   101  	return nmstate.NewState(fmt.Sprintf(`dns-resolver:
   102    config:
   103      server: []
   104      search: []
   105  routes:
   106    config:
   107    - destination: 0.0.0.0/0
   108      metric: 100
   109      state: absent
   110      next-hop-address: %s
   111      next-hop-interface: %s
   112      table-id: 253
   113    - destination: 0::/0
   114      state: absent
   115      metric: 100
   116      next-hop-address: fd80:0:0:0::1
   117      next-hop-interface: eth1
   118      table-id: 253
   119  interfaces:
   120  - name: %s
   121    type: ethernet
   122    state: up
   123    ipv4:
   124      auto-dns: true
   125      enabled: true
   126      dhcp: true
   127    ipv6:
   128      auto-dns: true
   129      enabled: true
   130      dhcp: true
   131  - name: eth1
   132    type: ethernet
   133    state: up
   134    ipv4:
   135      enabled: false
   136    ipv6:
   137      enabled: false
   138  `, dnsTestNicIP, dnsTestNic, dnsTestNic))
   139  }
   140  
   141  func dhcpAwareDNSAbsent(dnsTestNic string) nmstate.State {
   142  	return nmstate.NewState(fmt.Sprintf(`dns-resolver:
   143    config:
   144      server: []
   145      search: []
   146  interfaces:
   147  - name: %s
   148    type: ethernet
   149    state: up
   150    ipv4:
   151      auto-dns: true
   152      enabled: true
   153      dhcp: true
   154    ipv6:
   155      auto-dns: true
   156      enabled: true
   157      dhcp: true
   158  `, dnsTestNic))
   159  }
   160  
   161  var _ = Describe("Dns configuration", func() {
   162  	Context("when desiredState is configured", func() {
   163  		var (
   164  			searchDomain1 = "fufu.ostest.test.metalkube.org"
   165  			searchDomain2 = "sometest.com"
   166  			server1V4     = "8.8.9.9"
   167  			server1V6     = "2001:db8::1:2"
   168  		)
   169  		extractDNSServerAddress := func(dnsServer string) string {
   170  			return strings.Split(dnsServer, "%")[0]
   171  		}
   172  
   173  		Context("with DHCP aware interface", func() {
   174  			Context("with V4 upstream servers", func() {
   175  				BeforeEach(func() {
   176  					// read primary DNS server from one of the nodes
   177  					serverList := dnsResolverForNode(nodes[0], "dns-resolver.running.server")
   178  					updateDesiredStateAndWait(
   179  						dhcpAwareDNSConfig(
   180  							searchDomain1,
   181  							searchDomain2,
   182  							extractDNSServerAddress(serverList[0]),
   183  							server1V4,
   184  							dnsTestNic,
   185  						),
   186  					)
   187  				})
   188  				AfterEach(func() {
   189  					updateDesiredStateAndWait(dhcpAwareDNSAbsent(dnsTestNic))
   190  					for _, node := range nodes {
   191  						dnsResolverServerForNodeEventually(node).ShouldNot(ContainElement(server1V4))
   192  						dnsResolverSearchForNodeEventually(node).ShouldNot(ContainElement(searchDomain1))
   193  						dnsResolverSearchForNodeEventually(node).ShouldNot(ContainElement(searchDomain2))
   194  					}
   195  					resetDesiredStateForNodes()
   196  				})
   197  				It("should have the static V4 address", func() {
   198  					for _, node := range nodes {
   199  						dnsResolverServerForNodeEventually(node).Should(ContainElement(server1V4))
   200  						dnsResolverSearchForNodeEventually(node).Should(ContainElement(searchDomain1))
   201  						dnsResolverSearchForNodeEventually(node).Should(ContainElement(searchDomain2))
   202  					}
   203  				})
   204  			})
   205  			Context("with V6 upstream servers", func() {
   206  				BeforeEach(func() {
   207  					// read primary DNS server from one of the nodes
   208  					serverList := dnsResolverForNode(nodes[0], "dns-resolver.running.server")
   209  					updateDesiredStateAndWait(
   210  						dhcpAwareDNSConfig(
   211  							searchDomain1,
   212  							searchDomain2,
   213  							extractDNSServerAddress(serverList[0]),
   214  							server1V6,
   215  							dnsTestNic,
   216  						),
   217  					)
   218  				})
   219  				AfterEach(func() {
   220  					updateDesiredStateAndWait(dhcpAwareDNSAbsent(dnsTestNic))
   221  					for _, node := range nodes {
   222  						dnsResolverServerForNodeEventually(node).ShouldNot(ContainElement(server1V6))
   223  						dnsResolverSearchForNodeEventually(node).ShouldNot(ContainElement(searchDomain1))
   224  						dnsResolverSearchForNodeEventually(node).ShouldNot(ContainElement(searchDomain2))
   225  					}
   226  					resetDesiredStateForNodes()
   227  				})
   228  				It("should have the static V6 address", func() {
   229  					for _, node := range nodes {
   230  						dnsResolverServerForNodeEventually(node).Should(ContainElement(server1V6))
   231  						dnsResolverSearchForNodeEventually(node).Should(ContainElement(searchDomain1))
   232  						dnsResolverSearchForNodeEventually(node).Should(ContainElement(searchDomain2))
   233  					}
   234  				})
   235  			})
   236  		})
   237  		XContext("with DHCP unaware interface, Skip Reason: https://bugzilla.redhat.com/show_bug.cgi?id=2054726", func() {
   238  			var (
   239  				designatedNode   string
   240  				designatedNodeIP string
   241  			)
   242  			BeforeEach(func() {
   243  				designatedNode = nodes[0]
   244  				designatedNodeIP = ipv4Address(designatedNode, dnsTestNic)
   245  			})
   246  			Context("with V4 upstream servers", func() {
   247  				BeforeEach(func() {
   248  					// read primary DNS server from one of the nodes
   249  					serverList := dnsResolverForNode(designatedNode, "dns-resolver.running.server")
   250  					updateDesiredStateAtNodeAndWait(
   251  						designatedNode,
   252  						staticIPAndGwConfig(
   253  							searchDomain1,
   254  							searchDomain2,
   255  							extractDNSServerAddress(serverList[0]),
   256  							server1V4,
   257  							dnsTestNic,
   258  							designatedNodeIP,
   259  						),
   260  					)
   261  				})
   262  				AfterEach(func() {
   263  					updateDesiredStateAtNodeAndWait(designatedNode, staticIPAbsentAndRoutesAbsent(dnsTestNic, designatedNodeIP))
   264  					dnsResolverServerForNodeEventually(designatedNode).ShouldNot(ContainElement(server1V4))
   265  					dnsResolverSearchForNodeEventually(designatedNode).ShouldNot(ContainElement(searchDomain1))
   266  					dnsResolverSearchForNodeEventually(designatedNode).ShouldNot(ContainElement(searchDomain2))
   267  					resetDesiredStateForNodes()
   268  				})
   269  				It("should have the static V4 address", func() {
   270  					dnsResolverServerForNodeEventually(designatedNode).Should(ContainElement(server1V4))
   271  					dnsResolverSearchForNodeEventually(designatedNode).Should(ContainElement(searchDomain1))
   272  					dnsResolverSearchForNodeEventually(designatedNode).Should(ContainElement(searchDomain2))
   273  				})
   274  			})
   275  			Context("with V6 upstream servers", func() {
   276  				BeforeEach(func() {
   277  					// read primary DNS server from one of the nodes
   278  					serverList := dnsResolverForNode(designatedNode, "dns-resolver.running.server")
   279  					updateDesiredStateAtNodeAndWait(
   280  						designatedNode,
   281  						staticIPAndGwConfig(
   282  							searchDomain1,
   283  							searchDomain2,
   284  							extractDNSServerAddress(serverList[0]),
   285  							server1V6,
   286  							dnsTestNic,
   287  							designatedNodeIP,
   288  						),
   289  					)
   290  				})
   291  				AfterEach(func() {
   292  					updateDesiredStateAtNodeAndWait(designatedNode, staticIPAbsentAndRoutesAbsent(dnsTestNic, designatedNodeIP))
   293  					dnsResolverServerForNodeEventually(designatedNode).ShouldNot(ContainElement(server1V6))
   294  					dnsResolverSearchForNodeEventually(designatedNode).ShouldNot(ContainElement(searchDomain1))
   295  					dnsResolverSearchForNodeEventually(designatedNode).ShouldNot(ContainElement(searchDomain2))
   296  					resetDesiredStateForNodes()
   297  				})
   298  				It("should have the static V6 address", func() {
   299  					dnsResolverServerForNodeEventually(designatedNode).Should(ContainElement(server1V6))
   300  					dnsResolverSearchForNodeEventually(designatedNode).Should(ContainElement(searchDomain1))
   301  					dnsResolverSearchForNodeEventually(designatedNode).Should(ContainElement(searchDomain2))
   302  				})
   303  			})
   304  		})
   305  	})
   306  })