kubenetworks/kubevpn

View on GitHub
pkg/handler/sort.go

Summary

Maintainability
A
2 hrs
Test Coverage
package handler

import (
    "net"
    "sort"
)

type Connects []*ConnectOptions

func (s Connects) Len() int {
    return len(s)
}

func (s Connects) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}

func (s Connects) Append(options *ConnectOptions) Connects {
    if options != nil {
        return append(s, options)
    }
    return s
}

// Less ...
/**
assume: clusterA and clusterB in same VPC network, but only clusterA api-server have public ip,
we need access clusterB via clusterA network.
steps:
  - connect to clusterA with options --extra-cidr or --extra-domain (which container clusterB api-server address)
  - connect to clusterB
when we disconnect from all:
first, we need to disconnect clusterB
second, disconnect clusterA
*/
func (s Connects) Less(i, j int) bool {
    a := s[i]
    b := s[j]

    if a == nil {
        return true
    }

    var containsFunc = func(cidr *net.IPNet, ips []net.IP) bool {
        for _, ip := range ips {
            if !ip.IsLoopback() && cidr.Contains(ip) {
                return true
            }
        }
        return false
    }
    for _, extraCIDR := range b.ExtraRouteInfo.ExtraCIDR {
        ip, cidr, err := net.ParseCIDR(extraCIDR)
        if err != nil {
            continue
        }
        if containsFunc(cidr, a.apiServerIPs) {
            return true
        }
        for _, p := range a.apiServerIPs {
            if ip.Equal(p) {
                return true
            }
        }
    }
    for _, entry := range b.extraHost {
        ip := net.ParseIP(entry.IP)
        if ip == nil || ip.IsLoopback() {
            continue
        }
        for _, p := range a.apiServerIPs {
            if ip.Equal(p) {
                return true
            }
        }
    }
    return false
}

// Sort ...
// base order: first connect last disconnect
// sort by dependency
func (s Connects) Sort() Connects {
    for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
        s[i], s[j] = s[j], s[i]
    }
    sort.Stable(s)
    return s
}