...

Source file src/k8s.io/kubernetes/pkg/proxy/ipvs/testing/fake.go

Documentation: k8s.io/kubernetes/pkg/proxy/ipvs/testing

     1  //go:build linux
     2  // +build linux
     3  
     4  /*
     5  Copyright 2017 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package testing
    21  
    22  import (
    23  	"fmt"
    24  	"k8s.io/utils/net"
    25  
    26  	"k8s.io/apimachinery/pkg/util/sets"
    27  )
    28  
    29  // FakeNetlinkHandle mock implementation of proxy NetlinkHandle
    30  type FakeNetlinkHandle struct {
    31  	// localAddresses is a network interface name to all of its IP addresses map, e.g.
    32  	// eth0 -> [1.2.3.4, 10.20.30.40]
    33  	localAddresses map[string][]string
    34  
    35  	IsIPv6 bool
    36  }
    37  
    38  // NewFakeNetlinkHandle will create a new FakeNetlinkHandle
    39  func NewFakeNetlinkHandle(isIPv6 bool) *FakeNetlinkHandle {
    40  	fake := &FakeNetlinkHandle{
    41  		localAddresses: make(map[string][]string),
    42  		IsIPv6:         isIPv6,
    43  	}
    44  	return fake
    45  }
    46  
    47  // EnsureAddressBind is a mock implementation
    48  func (h *FakeNetlinkHandle) EnsureAddressBind(address, devName string) (exist bool, err error) {
    49  	if len(devName) == 0 {
    50  		return false, fmt.Errorf("device name can't be empty")
    51  	}
    52  	if _, ok := h.localAddresses[devName]; !ok {
    53  		return false, fmt.Errorf("error bind address: %s to a non-exist interface: %s", address, devName)
    54  	}
    55  	for _, addr := range h.localAddresses[devName] {
    56  		if addr == address {
    57  			// return true if the address is already bound to device
    58  			return true, nil
    59  		}
    60  	}
    61  	h.localAddresses[devName] = append(h.localAddresses[devName], address)
    62  	return false, nil
    63  }
    64  
    65  // UnbindAddress is a mock implementation
    66  func (h *FakeNetlinkHandle) UnbindAddress(address, devName string) error {
    67  	if len(devName) == 0 {
    68  		return fmt.Errorf("device name can't be empty")
    69  	}
    70  	if _, ok := h.localAddresses[devName]; !ok {
    71  		return fmt.Errorf("error unbind address: %s from a non-exist interface: %s", address, devName)
    72  	}
    73  	for i, addr := range h.localAddresses[devName] {
    74  		if addr == address {
    75  			// delete address from slice h.localAddresses[devName]
    76  			h.localAddresses[devName] = append(h.localAddresses[devName][:i], h.localAddresses[devName][i+1:]...)
    77  			return nil
    78  		}
    79  	}
    80  	// return error message if address is not found in slice h.localAddresses[devName]
    81  	return fmt.Errorf("address: %s is not found in interface: %s", address, devName)
    82  }
    83  
    84  // EnsureDummyDevice is a mock implementation
    85  func (h *FakeNetlinkHandle) EnsureDummyDevice(devName string) (bool, error) {
    86  	if len(devName) == 0 {
    87  		return false, fmt.Errorf("device name can't be empty")
    88  	}
    89  	if _, ok := h.localAddresses[devName]; !ok {
    90  		// create dummy interface if devName is not found in localAddress map
    91  		h.localAddresses[devName] = make([]string, 0)
    92  		return false, nil
    93  	}
    94  	// return true if devName is already created in localAddress map
    95  	return true, nil
    96  }
    97  
    98  // DeleteDummyDevice is a mock implementation
    99  func (h *FakeNetlinkHandle) DeleteDummyDevice(devName string) error {
   100  	if len(devName) == 0 {
   101  		return fmt.Errorf("device name can't be empty")
   102  	}
   103  	if _, ok := h.localAddresses[devName]; !ok {
   104  		return fmt.Errorf("error deleting a non-exist interface: %s", devName)
   105  	}
   106  	delete(h.localAddresses, devName)
   107  	return nil
   108  }
   109  
   110  // ListBindAddress is a mock implementation
   111  func (h *FakeNetlinkHandle) ListBindAddress(devName string) ([]string, error) {
   112  	if len(devName) == 0 {
   113  		return nil, fmt.Errorf("device name can't be empty")
   114  	}
   115  	if _, ok := h.localAddresses[devName]; !ok {
   116  		return nil, fmt.Errorf("error list addresses from a non-exist interface: %s", devName)
   117  	}
   118  	return h.localAddresses[devName], nil
   119  }
   120  
   121  // GetLocalAddresses is a mock implementation
   122  func (h *FakeNetlinkHandle) GetLocalAddresses(dev string) (sets.Set[string], error) {
   123  	res := sets.New[string]()
   124  	// list all addresses from a given network interface.
   125  	for _, addr := range h.localAddresses[dev] {
   126  		if h.isValidForSet(addr) {
   127  			res.Insert(addr)
   128  		}
   129  	}
   130  	return res, nil
   131  }
   132  func (h *FakeNetlinkHandle) GetAllLocalAddresses() (sets.Set[string], error) {
   133  	res := sets.New[string]()
   134  	// List all addresses from all available network interfaces.
   135  	for linkName := range h.localAddresses {
   136  		// list all addresses from a given network interface.
   137  		for _, addr := range h.localAddresses[linkName] {
   138  			if h.isValidForSet(addr) {
   139  				res.Insert(addr)
   140  			}
   141  		}
   142  	}
   143  	return res, nil
   144  }
   145  
   146  func (h *FakeNetlinkHandle) GetAllLocalAddressesExcept(dev string) (sets.Set[string], error) {
   147  	res := sets.New[string]()
   148  	for linkName := range h.localAddresses {
   149  		if linkName == dev {
   150  			continue
   151  		}
   152  		for _, addr := range h.localAddresses[linkName] {
   153  			if h.isValidForSet(addr) {
   154  				res.Insert(addr)
   155  			}
   156  		}
   157  	}
   158  	return res, nil
   159  }
   160  
   161  // SetLocalAddresses set IP addresses to the given interface device.  It's not part of interface.
   162  func (h *FakeNetlinkHandle) SetLocalAddresses(dev string, ips ...string) error {
   163  	if h.localAddresses == nil {
   164  		h.localAddresses = make(map[string][]string)
   165  	}
   166  	if len(dev) == 0 {
   167  		return fmt.Errorf("device name can't be empty")
   168  	}
   169  	h.localAddresses[dev] = make([]string, 0)
   170  	h.localAddresses[dev] = append(h.localAddresses[dev], ips...)
   171  	return nil
   172  }
   173  
   174  func (h *FakeNetlinkHandle) isValidForSet(ipString string) bool {
   175  	ip := net.ParseIPSloppy(ipString)
   176  	if h.IsIPv6 != (ip.To4() == nil) {
   177  		return false
   178  	}
   179  	if h.IsIPv6 && ip.IsLinkLocalUnicast() {
   180  		return false
   181  	}
   182  	if ip.IsLoopback() {
   183  		return false
   184  	}
   185  	return true
   186  }
   187  

View as plain text