Skip to content

Commit

Permalink
windows version works
Browse files Browse the repository at this point in the history
  • Loading branch information
balopat committed Aug 22, 2018
1 parent b766603 commit ecfa5d9
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 150 deletions.
5 changes: 2 additions & 3 deletions pkg/minikube/tunnel/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"fmt"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
"io/ioutil"
"os"
)
Expand Down Expand Up @@ -76,7 +75,7 @@ func (r *persistentRegistry) Register(tunnel *TunnelID) error {

logrus.Debugf("json marshalled: %v, %s\n", tunnels, bytes)

f, e := os.OpenFile(r.fileName, unix.O_RDWR|unix.O_TRUNC, 0666)
f, e := os.OpenFile(r.fileName, os.O_RDWR|os.O_TRUNC, 0666)
if e != nil {
if os.IsNotExist(e) {
f, e = os.Create(r.fileName)
Expand Down Expand Up @@ -115,7 +114,7 @@ func (r *persistentRegistry) Remove(route *Route) error {
}
tunnels = append(tunnels[:idx], tunnels[idx+1:]...)
logrus.Debugf("tunnels after remove: %s", tunnels)
f, e := os.OpenFile(r.fileName, unix.O_RDWR|unix.O_TRUNC, 0666)
f, e := os.OpenFile(r.fileName, os.O_RDWR | os.O_TRUNC, 0666)
if e != nil {
return fmt.Errorf("error removing tunnel %s", e)
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/minikube/tunnel/route_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ func (router *osRouter) EnsureRouteIsAdded(route *Route) error {
}

func (router *osRouter) Inspect(route *Route) (exists bool, conflict string, overlaps []string, err error) {
stdInAndOut, e := exec.Command("netstat", "-nr", "-f", "inet").CombinedOutput()
command := exec.Command("netstat", "-nr", "-f", "inet")
stdInAndOut, e := command.CombinedOutput()
if e != nil {
err = fmt.Errorf("error running netstat: %s", e)
err = fmt.Errorf("error running '%s': %s", command, e)
return
}
routeTableString := fmt.Sprintf("%s", stdInAndOut)
Expand Down Expand Up @@ -110,7 +111,7 @@ func (router *osRouter) parseTable(table string) routingTable {
return t
}

func (r *osRouter) padCIDR(origCIDR string) string {
func (router *osRouter) padCIDR(origCIDR string) string {
s := ""
dots := 0
slash := false
Expand Down
98 changes: 45 additions & 53 deletions pkg/minikube/tunnel/route_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,24 @@ import (
"github.com/sirupsen/logrus"
)

type OSRouter struct {
config Route
}

func (r *OSRouter) EnsureRouteIsAdded() error {
exists, e := checkRoute(r.config.RoutedCIDR, r.config.TargetGateway)
func (router *osRouter) EnsureRouteIsAdded(route *Route) error {
exists, e := isValidToAddOrDelete(router, route)
if e != nil {
return e
}
if exists {
return nil
}

serviceCIDR := r.config.RoutedCIDR.String()
destinationIP := r.config.RoutedCIDR.IP.String()
serviceCIDR := route.DestCIDR.String()
destinationIP := route.DestCIDR.IP.String()
destinationMask := fmt.Sprintf("%d.%d.%d.%d",
r.config.RoutedCIDR.Mask[0],
r.config.RoutedCIDR.Mask[1],
r.config.RoutedCIDR.Mask[2],
r.config.RoutedCIDR.Mask[3])
route.DestCIDR.Mask[0],
route.DestCIDR.Mask[1],
route.DestCIDR.Mask[2],
route.DestCIDR.Mask[3])

gatewayIP := r.config.TargetGateway.String()
gatewayIP := route.Gateway.String()

logrus.Infof("Adding Route for CIDR %s to gateway %s", serviceCIDR, gatewayIP)
command := exec.Command("Route", "ADD", destinationIP, "MASK", destinationMask, gatewayIP)
Expand All @@ -64,21 +60,10 @@ func (r *OSRouter) EnsureRouteIsAdded() error {
return nil
}

func checkRoute(cidr *net.IPNet, gateway net.IP) (bool, error) {
stdInAndOut, e := exec.Command("Route", "print", "-4").CombinedOutput()
if e != nil {
return false, e
}
routeTableString := fmt.Sprintf("%s", stdInAndOut)
return checkRouteTable(cidr, gateway, routeTableString)
}

func checkRouteTable(cidr *net.IPNet, gateway net.IP, routeTableString string) (bool, error) {
routeTable := strings.Split(routeTableString, "\n")
func (router *osRouter) parseTable(table string) routingTable {
t := routingTable{}
skip := true
exactMatch := false
collision := ""
for _, line := range routeTable {
for _, line := range strings.Split(table, "\n") {
//after first line of header we can start consuming
if strings.HasPrefix(line, "Network Destination") {
skip = false
Expand All @@ -94,48 +79,55 @@ func checkRouteTable(cidr *net.IPNet, gateway net.IP, routeTableString string) (
dstCIDRIP := net.ParseIP(fields[0])
dstCIDRMask := fields[1]
dstMaskIP := net.ParseIP(dstCIDRMask)
gatewayIP := fields[2]
dstCIDR := &net.IPNet{
IP: dstCIDRIP,
Mask: net.IPMask(dstMaskIP.To4()),
}
if dstCIDR.String() == cidr.String() {
if gatewayIP == gateway.String() {
exactMatch = true
} else {
collision = line
}
} else if dstCIDR != nil {
if dstCIDR.Contains(cidr.IP) || cidr.Contains(dstCIDRIP) {
logrus.Warningf("overlapping CIDR (%s) detected in routing table with minikube tunnel (%s). It is advisable to remove this rule. Run: sudo Route -n delete %s", dstCIDR.String(), cidr, dstCIDR.String())
}
gatewayIP := net.ParseIP(fields[2])
if dstCIDRIP == nil || dstMaskIP == nil || gatewayIP == nil {
logrus.Debugf("skipping line: can't parse all IPs from routing table: %s", line)
} else {
logrus.Errorf("can't parse CIDR from routing table: %s", dstCIDR)
tableLine := routingTableLine{
route: &Route{
DestCIDR: &net.IPNet{
IP: dstCIDRIP,
Mask: net.IPMask(dstMaskIP.To4()),
},
Gateway: gatewayIP,
},
line: line,
}
logrus.Debugf("adding line %s", tableLine)
t = append(t, tableLine)
}
}
}

if exactMatch {
return true, nil
}
return t
}

if len(collision) > 0 {
return false, fmt.Errorf("conflicting rule in routing table: %s", collision)
func (router *osRouter) Inspect(route *Route) (exists bool, conflict string, overlaps []string, err error) {
command := exec.Command("Route", "print", "-4")
stdInAndOut, e := command.CombinedOutput()
if e != nil {
err = fmt.Errorf("error running '%s': %s", command.Args, e)
return
}
routeTableString := fmt.Sprintf("%s", stdInAndOut)

rt := router.parseTable(routeTableString)

exists, conflict, overlaps = rt.Check(route)

return false, nil
return
}

func (r *OSRouter) Cleanup() error {
exists, e := checkRoute(r.config.RoutedCIDR, r.config.TargetGateway)
func (router *osRouter) Cleanup(route *Route) error {
exists, e := isValidToAddOrDelete(router, route)
if e != nil {
return e
}
if !exists {
return nil
}
serviceCIDR := r.config.RoutedCIDR.String()
gatewayIP := r.config.TargetGateway.String()
serviceCIDR := route.DestCIDR.String()
gatewayIP := route.Gateway.String()

fmt.Printf("Cleaning up Route for CIDR %s to gateway %s\n", serviceCIDR, gatewayIP)
command := exec.Command("Route", "delete", serviceCIDR)
Expand Down
117 changes: 30 additions & 87 deletions pkg/minikube/tunnel/route_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ import (
"os/exec"
"testing"

"fmt"

"strings"
"reflect"
)

func TestWindowsRouteFailsOnConflictIntegrationTest(t *testing.T) {
r := &OSRouter{types.Route{
route := &Route{
Gateway: net.IPv4(1, 2, 3, 4),
DestCIDR: &net.IPNet{
IP: net.IPv4(10, 96, 0, 0),
Mask: net.IPv4Mask(255, 240, 0, 0),
},
}}
}
r := &osRouter{}

cleanRoute(t, "10.96.0.0")
addRoute(t, "10.96.0.0", "255.240.0.0", "1.2.3.5")
err := r.EnsureRouteIsAdded()
err := r.EnsureRouteIsAdded(route)
if err == nil {
t.Errorf("add should have error, but it is nil")
t.Fail()
Expand All @@ -51,22 +51,23 @@ func TestWindowsRouteFailsOnConflictIntegrationTest(t *testing.T) {
}

func TestWindowsRouteIdempotentIntegrationTest(t *testing.T) {
r := &OSRouter{types.Route{
route := &Route{
Gateway: net.IPv4(1, 2, 3, 4),
DestCIDR: &net.IPNet{
IP: net.IPv4(10, 96, 0, 0),
Mask: net.IPv4Mask(255, 240, 0, 0),
},
}}
}
r := &osRouter{}

cleanRoute(t, "10.96.0.0")
err := r.EnsureRouteIsAdded()
err := r.EnsureRouteIsAdded(route)
if err != nil {
t.Errorf("add error: %s", err)
t.Fail()
}

err = r.EnsureRouteIsAdded()
err = r.EnsureRouteIsAdded(route)
if err != nil {
t.Errorf("add error: %s", err)
t.Fail()
Expand All @@ -76,23 +77,23 @@ func TestWindowsRouteIdempotentIntegrationTest(t *testing.T) {
}

func TestWindowsRouteCleanupIdempontentIntegrationTest(t *testing.T) {

r := &OSRouter{types.Route{
route := &Route{
Gateway: net.IPv4(1, 2, 3, 4),
DestCIDR: &net.IPNet{
IP: net.IPv4(10, 96, 0, 0),
Mask: net.IPv4Mask(255, 240, 0, 0),
},
}}
}
r := &osRouter{}

cleanRoute(t, "10.96.0.0")
addRoute(t, "10.96.0.0", "255.240.0.0", "1.2.3.4")
err := r.Cleanup()
err := r.Cleanup(route)
if err != nil {
t.Errorf("cleanup failed: %s", err)
t.Fail()
}
err = r.Cleanup()
err = r.Cleanup(route)
if err != nil {
t.Errorf("cleanup failed: %s", err)
t.Fail()
Expand All @@ -101,69 +102,6 @@ func TestWindowsRouteCleanupIdempontentIntegrationTest(t *testing.T) {
}

func TestRouteTable(t *testing.T) {
testCases := []struct {
name string
cidr *net.IPNet
gateway net.IP
expectedResult bool
expectedError error
}{
{
name: "Route already exists",
cidr: &net.IPNet{
IP: net.IPv4(10, 96, 0, 0),
Mask: net.IPv4Mask(255, 240, 0, 0),
},
gateway: net.IPv4(127, 0, 0, 1),
expectedError: nil,
expectedResult: true,
},

{
name: "destination exists but conflicting gateway",
cidr: &net.IPNet{
IP: net.IPv4(10, 96, 0, 0),
Mask: net.IPv4Mask(255, 240, 0, 0),
},
gateway: net.IPv4(127, 0, 0, 2),
expectedError: fmt.Errorf("conflicting rule in routing table: %s", " 10.96.0.0 255.240.0.0 127.0.0.1 127.0.0.1 281"),
expectedResult: false,
},

{
name: "Route doesn't exist yet",
cidr: &net.IPNet{
IP: net.IPv4(10, 112, 0, 0),
Mask: net.IPv4Mask(255, 240, 0, 0),
},
gateway: net.IPv4(127, 0, 0, 1),
expectedError: nil,
expectedResult: false,
},

{
name: "Route doesn't exist yet, but there is overlap (warning is only logged)",
cidr: &net.IPNet{
IP: net.IPv4(10, 0, 0, 0),
Mask: net.IPv4Mask(255, 0, 0, 0),
},
gateway: net.IPv4(127, 0, 0, 1),
expectedError: nil,
expectedResult: false,
},

{
name: "Route doesn't exist yet, but there is overlap (warning is only logged)",
cidr: &net.IPNet{
IP: net.IPv4(10, 96, 1, 0),
Mask: net.IPv4Mask(255, 255, 0, 0),
},
gateway: net.IPv4(127, 0, 0, 1),
expectedError: nil,
expectedResult: false,
},
}

const table = `===========================================================================
Interface List
14...00 1c 42 8f 70 58 ......Intel(R) 82574L Gigabit Network Connection
Expand All @@ -178,7 +116,6 @@ Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 10.211.55.1 10.211.55.3 25
10.96.0.0 255.240.0.0 127.0.0.1 127.0.0.1 281
10.211.55.0 255.255.255.0 On-link 10.211.55.3 281
10.211.55.3 255.255.255.255 On-link 10.211.55.3 281
10.211.55.255 255.255.255.255 On-link 10.211.55.3 281
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
Expand All @@ -189,6 +126,7 @@ Network Destination Netmask Gateway Interface Metric
192.168.56.255 255.255.255.255 On-link 192.168.56.1 281
192.168.99.0 255.255.255.0 On-link 192.168.99.1 281
192.168.99.1 255.255.255.255 On-link 192.168.99.1 281
10.211.55.0 255.255.255.0 192.168.1.2 10.211.55.3 281
192.168.99.255 255.255.255.255 On-link 192.168.99.1 281
224.0.0.0 240.0.0.0 On-link 127.0.0.1 331
224.0.0.0 240.0.0.0 On-link 10.211.55.3 281
Expand All @@ -202,15 +140,20 @@ Network Destination Netmask Gateway Interface Metric
Persistent Routes:
None`

for _, testCase := range testCases {
result, e := checkRouteTable(testCase.cidr, testCase.gateway, table)
errorsEqual := strings.Compare(fmt.Sprintf("%s", e), fmt.Sprintf("%s", testCase.expectedError)) == 0
if !errorsEqual || result != testCase.expectedResult {
t.Errorf(`[%s] failed.
expected "%v" | error: [%s]
got "%v" | error: [%s]`, testCase.name, testCase.expectedResult, testCase.expectedError, result, e)
t.Fail()
}
rt := (&osRouter{}).parseTable(table)

expectedRt := routingTable{
routingTableLine{
route: unsafeParseRoute("127.0.0.1", "10.96.0.0/12"),
line: " 10.96.0.0 255.240.0.0 127.0.0.1 127.0.0.1 281",
},
routingTableLine{
route: unsafeParseRoute("192.168.1.2", "10.211.55.0/24"),
line: " 10.211.55.0 255.255.255.0 192.168.1.2 10.211.55.3 281",
},
}
if !reflect.DeepEqual(rt.String(), expectedRt.String()) {
t.Errorf("expected:\n %s\ngot\n %s", expectedRt.String(), rt.String())
}

}
Expand Down
Loading

0 comments on commit ecfa5d9

Please sign in to comment.