github.com/nmstate/kubernetes-nmstate@v0.82.0/test/e2e/handler/default_bridged_network_with_nmpolicy_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  	"time"
    23  
    24  	. "github.com/onsi/ginkgo/v2"
    25  	. "github.com/onsi/gomega"
    26  
    27  	nmstate "github.com/nmstate/kubernetes-nmstate/api/shared"
    28  	"github.com/nmstate/kubernetes-nmstate/test/e2e/policy"
    29  )
    30  
    31  var _ = Describe("NodeNetworkConfigurationPolicy default bridged network with nmpolicy", func() {
    32  	var (
    33  		DefaultNetwork = "default-network"
    34  	)
    35  	Context("when there is a default interface with dynamic address", func() {
    36  		addressByNode := map[string]string{}
    37  
    38  		BeforeEach(func() {
    39  			Byf("Check %s is the default route interface and has dynamic address", primaryNic)
    40  			for _, node := range nodes {
    41  				defaultRouteNextHopInterface(node).Should(Equal(primaryNic))
    42  				Expect(dhcpFlag(node, primaryNic)).Should(BeTrue())
    43  			}
    44  
    45  			By("Fetching current IP address")
    46  			for _, node := range nodes {
    47  				address := ""
    48  				Eventually(func() string {
    49  					address = ipv4Address(node, primaryNic)
    50  					return address
    51  				}, 15*time.Second, 1*time.Second).ShouldNot(BeEmpty(), fmt.Sprintf("Interface %s has no ipv4 address", primaryNic))
    52  				addressByNode[node] = address
    53  			}
    54  		})
    55  
    56  		Context("and linux bridge is configured on top of the default interface", func() {
    57  			BeforeEach(func() {
    58  				By("Creating the policy")
    59  				bridgeOnTheDefaultInterfaceState := nmstate.NewState(`interfaces:
    60    - name: brext
    61      type: linux-bridge
    62      state: up
    63      mac-address: "{{ capture.base-iface.interfaces.0.mac-address }}"
    64      ipv4:
    65        dhcp: true
    66        enabled: true
    67      bridge:
    68        options:
    69          stp:
    70            enabled: false
    71        port:
    72        - name: "{{ capture.base-iface.interfaces.0.name }}"
    73  `)
    74  				capture := map[string]string{
    75  					"default-gw": `routes.running.destination=="0.0.0.0/0"`,
    76  					"base-iface": `interfaces.name==capture.default-gw.routes.running.0.next-hop-interface`,
    77  				}
    78  				setDesiredStateWithPolicyAndCapture(DefaultNetwork, bridgeOnTheDefaultInterfaceState, capture)
    79  
    80  				By("Waiting until the node becomes ready again")
    81  				waitForNodesReady()
    82  
    83  				By("Waiting for policy to be ready")
    84  				policy.WaitForAvailablePolicy(DefaultNetwork)
    85  			})
    86  
    87  			AfterEach(func() {
    88  				resetDefaultInterfaceState := nmstate.NewState(`interfaces:
    89    - name: "{{ capture.brext-bridge.interfaces.0.bridge.port.0.name }}"
    90      type: ethernet
    91      state: up
    92      ipv4:
    93        enabled: true
    94        dhcp: true
    95    - name: brext
    96      type: linux-bridge
    97      state: absent
    98  `)
    99  
   100  				capture := map[string]string{
   101  					"brext-bridge": `interfaces.name=="brext"`,
   102  				}
   103  
   104  				Byf("Removeing %s NNCP since capture cannot be modified", DefaultNetwork)
   105  				deletePolicy(DefaultNetwork)
   106  
   107  				Byf("Removing bridge and configuring %s with dhcp", primaryNic)
   108  				setDesiredStateWithPolicyAndCapture(DefaultNetwork, resetDefaultInterfaceState, capture)
   109  
   110  				By("Waiting until the node becomes ready again")
   111  				waitForNodesReady()
   112  
   113  				By("Wait for policy to be ready")
   114  				policy.WaitForAvailablePolicy(DefaultNetwork)
   115  
   116  				Byf("Check %s has the default ip address", primaryNic)
   117  				for _, node := range nodes {
   118  					Eventually(
   119  						func() string {
   120  							return ipv4Address(node, primaryNic)
   121  						},
   122  						30*time.Second,
   123  						1*time.Second,
   124  					).Should(Equal(addressByNode[node]), fmt.Sprintf("Interface %s address is not the original one", primaryNic))
   125  				}
   126  
   127  				Byf("Check %s is back as the default route interface", primaryNic)
   128  				for _, node := range nodes {
   129  					defaultRouteNextHopInterface(node).Should(Equal(primaryNic))
   130  				}
   131  
   132  				By("Remove the policy")
   133  				deletePolicy(DefaultNetwork)
   134  
   135  				By("Reset desired state at all nodes")
   136  				resetDesiredStateForNodes()
   137  			})
   138  
   139  			It("should successfully move default IP address on top of the bridge", func() {
   140  				checkThatBridgeTookOverTheDefaultIP(nodes, "brext", addressByNode)
   141  			})
   142  
   143  			It("should keep the default IP address after node reboot", func() {
   144  				nodeToReboot := nodes[0]
   145  
   146  				restartNodeWithoutWaiting(nodeToReboot)
   147  
   148  				By("Wait for policy re-reconciled after node reboot")
   149  				policy.WaitForPolicyTransitionUpdate(DefaultNetwork)
   150  				policy.WaitForAvailablePolicy(DefaultNetwork)
   151  
   152  				Byf("Node %s was rebooted, verifying that bridge took over the default IP", nodeToReboot)
   153  				checkThatBridgeTookOverTheDefaultIP([]string{nodeToReboot}, "brext", addressByNode)
   154  			})
   155  		})
   156  	})
   157  })