github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/common/networking.go (about)

     1  package common
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"strings"
     7  	"sync"
     8  )
     9  
    10  type Networking struct {
    11  	mux        sync.Mutex `yaml:"-"`
    12  	Interfaces map[string]*NetworkingInterface
    13  }
    14  
    15  type NetworkingInterface struct {
    16  	Type string
    17  	IPs  MarshallableSlice
    18  }
    19  
    20  type NetworkingCurrent []*NetworkingInterfaceCurrent
    21  
    22  type NetworkingInterfaceCurrent struct {
    23  	Name string
    24  	IPs  MarshallableSlice
    25  }
    26  
    27  func (n *Networking) Merge(nw Networking) {
    28  	n.mux.Lock()
    29  	defer n.mux.Unlock()
    30  	if n.Interfaces == nil {
    31  		n.Interfaces = make(map[string]*NetworkingInterface, 0)
    32  	}
    33  
    34  	if nw.Interfaces == nil {
    35  		return
    36  	}
    37  
    38  	for name, iface := range nw.Interfaces {
    39  		if iface == nil {
    40  			continue
    41  		}
    42  		current, ok := n.Interfaces[name]
    43  		if !ok || current == nil {
    44  			current = &NetworkingInterface{}
    45  		}
    46  
    47  		current.Type = iface.Type
    48  
    49  		if iface.IPs != nil {
    50  			if current.IPs == nil {
    51  				current.IPs = make(MarshallableSlice, 0)
    52  			}
    53  
    54  			for _, value := range iface.IPs {
    55  				found := false
    56  				for _, currentValue := range current.IPs {
    57  					if currentValue == value {
    58  						found = true
    59  					}
    60  				}
    61  				if !found {
    62  					current.IPs = append(current.IPs, value)
    63  				}
    64  			}
    65  		}
    66  		n.Interfaces[name] = current
    67  	}
    68  }
    69  
    70  func (n *Networking) ToCurrent() NetworkingCurrent {
    71  	current := make(NetworkingCurrent, 0)
    72  	if n.Interfaces == nil {
    73  		return current
    74  	}
    75  
    76  	for name, iface := range n.Interfaces {
    77  		if iface != nil {
    78  			current = append(current, &NetworkingInterfaceCurrent{
    79  				Name: name,
    80  				IPs:  iface.IPs,
    81  			})
    82  		}
    83  	}
    84  	current.Sort()
    85  	return current
    86  }
    87  
    88  func (c NetworkingCurrent) Sort() {
    89  	sort.Slice(c, func(i, j int) bool {
    90  		return c[i].Name < c[j].Name
    91  	})
    92  
    93  	for _, currentEntry := range c {
    94  		sort.Slice(currentEntry.IPs, func(i, j int) bool {
    95  			return currentEntry.IPs[i] < currentEntry.IPs[j]
    96  		})
    97  	}
    98  }
    99  
   100  func (n Networking) IsContainedIn(interfaces NetworkingCurrent) bool {
   101  	if n.Interfaces == nil || len(n.Interfaces) == 0 {
   102  		return true
   103  	}
   104  	if interfaces == nil || len(interfaces) == 0 {
   105  		return false
   106  	}
   107  
   108  	for name, iface := range n.Interfaces {
   109  		if iface.IPs == nil || len(iface.IPs) == 0 {
   110  			continue
   111  		}
   112  
   113  		foundIface := false
   114  		for _, currentInterface := range interfaces {
   115  			if currentInterface == nil {
   116  				continue
   117  			}
   118  
   119  			if foundIface {
   120  				break
   121  			}
   122  
   123  			if currentInterface.Name == name {
   124  				foundIface = true
   125  
   126  				if currentInterface.IPs == nil || len(currentInterface.IPs) == 0 {
   127  					return false
   128  				}
   129  
   130  				if iface.IPs != nil {
   131  					for _, ip := range iface.IPs {
   132  						foundIP := false
   133  						if currentInterface.IPs != nil {
   134  							for _, currentIP := range currentInterface.IPs {
   135  								if ip == currentIP {
   136  									foundIP = true
   137  									break
   138  								}
   139  							}
   140  						}
   141  
   142  						if !foundIP {
   143  							return false
   144  						}
   145  					}
   146  				}
   147  			}
   148  		}
   149  		if !foundIface {
   150  			return false
   151  		}
   152  	}
   153  	return true
   154  }
   155  
   156  var _ fmt.Stringer = (*NetworkingCurrent)(nil)
   157  
   158  func (c NetworkingCurrent) String() string {
   159  	nw := ""
   160  	for _, iface := range c {
   161  
   162  		ips := ""
   163  		for idx := range iface.IPs {
   164  			ips = ips + iface.IPs[idx] + " "
   165  		}
   166  		nw = nw + iface.Name + "(" + strings.TrimSpace(ips) + ") "
   167  	}
   168  	return strings.TrimSpace(nw)
   169  }