Replace godep with dep
This commit is contained in:
parent
1e7489927c
commit
bf5616c65b
14883 changed files with 3937406 additions and 361781 deletions
49
vendor/k8s.io/kubernetes/pkg/proxy/util/BUILD
generated
vendored
Normal file
49
vendor/k8s.io/kubernetes/pkg/proxy/util/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"conntrack.go",
|
||||
"port.go",
|
||||
"utils.go",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/helper:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"conntrack_test.go",
|
||||
"port_test.go",
|
||||
"utils_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
85
vendor/k8s.io/kubernetes/pkg/proxy/util/conntrack.go
generated
vendored
Normal file
85
vendor/k8s.io/kubernetes/pkg/proxy/util/conntrack.go
generated
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
// Utilities for dealing with conntrack
|
||||
|
||||
const noConnectionToDelete = "0 flow entries have been deleted"
|
||||
|
||||
// DeleteServiceConnections uses the conntrack tool to delete the conntrack entries
|
||||
// for the UDP connections specified by the given service IP
|
||||
func ClearUDPConntrackForIP(execer exec.Interface, ip string) error {
|
||||
err := ExecConntrackTool(execer, "-D", "--orig-dst", ip, "-p", "udp")
|
||||
if err != nil && !strings.Contains(err.Error(), noConnectionToDelete) {
|
||||
// TODO: Better handling for deletion failure. When failure occur, stale udp connection may not get flushed.
|
||||
// These stale udp connection will keep black hole traffic. Making this a best effort operation for now, since it
|
||||
// is expensive to baby-sit all udp connections to kubernetes services.
|
||||
return fmt.Errorf("error deleting connection tracking state for UDP service IP: %s, error: %v", ip, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExecConntrackTool executes the conntrack tool using the given parameters
|
||||
func ExecConntrackTool(execer exec.Interface, parameters ...string) error {
|
||||
conntrackPath, err := execer.LookPath("conntrack")
|
||||
if err != nil {
|
||||
return fmt.Errorf("error looking for path of conntrack: %v", err)
|
||||
}
|
||||
output, err := execer.Command(conntrackPath, parameters...).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("conntrack command returned: %q, error message: %s", string(output), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearUDPConntrackForPort uses the conntrack tool to delete the conntrack entries
|
||||
// for the UDP connections specified by the port.
|
||||
// When a packet arrives, it will not go through NAT table again, because it is not "the first" packet.
|
||||
// The solution is clearing the conntrack. Known issues:
|
||||
// https://github.com/docker/docker/issues/8795
|
||||
// https://github.com/kubernetes/kubernetes/issues/31983
|
||||
func ClearUDPConntrackForPort(execer exec.Interface, port int) error {
|
||||
if port <= 0 {
|
||||
return fmt.Errorf("Wrong port number. The port number must be greater than zero")
|
||||
}
|
||||
err := ExecConntrackTool(execer, "-D", "-p", "udp", "--dport", strconv.Itoa(port))
|
||||
if err != nil && !strings.Contains(err.Error(), noConnectionToDelete) {
|
||||
return fmt.Errorf("error deleting conntrack entries for UDP port: %d, error: %v", port, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearUDPConntrackForPeers uses the conntrack tool to delete the conntrack entries
|
||||
// for the UDP connections specified by the {origin, dest} IP pair.
|
||||
func ClearUDPConntrackForPeers(execer exec.Interface, origin, dest string) error {
|
||||
err := ExecConntrackTool(execer, "-D", "--orig-dst", origin, "--dst-nat", dest, "-p", "udp")
|
||||
if err != nil && !strings.Contains(err.Error(), noConnectionToDelete) {
|
||||
// TODO: Better handling for deletion failure. When failure occur, stale udp connection may not get flushed.
|
||||
// These stale udp connection will keep black hole traffic. Making this a best effort operation for now, since it
|
||||
// is expensive to baby sit all udp connections to kubernetes services.
|
||||
return fmt.Errorf("error deleting conntrack entries for UDP peer {%s, %s}, error: %v", origin, dest, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
214
vendor/k8s.io/kubernetes/pkg/proxy/util/conntrack_test.go
generated
vendored
Normal file
214
vendor/k8s.io/kubernetes/pkg/proxy/util/conntrack_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/utils/exec"
|
||||
fakeexec "k8s.io/utils/exec/testing"
|
||||
)
|
||||
|
||||
func TestExecConntrackTool(t *testing.T) {
|
||||
fcmd := fakeexec.FakeCmd{
|
||||
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{
|
||||
func() ([]byte, error) { return []byte("1 flow entries have been deleted"), nil },
|
||||
func() ([]byte, error) { return []byte("1 flow entries have been deleted"), nil },
|
||||
func() ([]byte, error) {
|
||||
return []byte(""), fmt.Errorf("conntrack v1.4.2 (conntrack-tools): 0 flow entries have been deleted.")
|
||||
},
|
||||
},
|
||||
}
|
||||
fexec := fakeexec.FakeExec{
|
||||
CommandScript: []fakeexec.FakeCommandAction{
|
||||
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||
},
|
||||
LookPathFunc: func(cmd string) (string, error) { return cmd, nil },
|
||||
}
|
||||
|
||||
testCases := [][]string{
|
||||
{"-L", "-p", "udp"},
|
||||
{"-D", "-p", "udp", "-d", "10.0.240.1"},
|
||||
{"-D", "-p", "udp", "--orig-dst", "10.240.0.2", "--dst-nat", "10.0.10.2"},
|
||||
}
|
||||
|
||||
expectErr := []bool{false, false, true}
|
||||
|
||||
for i := range testCases {
|
||||
err := ExecConntrackTool(&fexec, testCases[i]...)
|
||||
|
||||
if expectErr[i] {
|
||||
if err == nil {
|
||||
t.Errorf("expected err, got %v", err)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expected success, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
execCmd := strings.Join(fcmd.CombinedOutputLog[i], " ")
|
||||
expectCmd := fmt.Sprintf("%s %s", "conntrack", strings.Join(testCases[i], " "))
|
||||
|
||||
if execCmd != expectCmd {
|
||||
t.Errorf("expect execute command: %s, but got: %s", expectCmd, execCmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestClearUDPConntrackForIP(t *testing.T) {
|
||||
fcmd := fakeexec.FakeCmd{
|
||||
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{
|
||||
func() ([]byte, error) { return []byte("1 flow entries have been deleted"), nil },
|
||||
func() ([]byte, error) { return []byte("1 flow entries have been deleted"), nil },
|
||||
func() ([]byte, error) {
|
||||
return []byte(""), fmt.Errorf("conntrack v1.4.2 (conntrack-tools): 0 flow entries have been deleted.")
|
||||
},
|
||||
},
|
||||
}
|
||||
fexec := fakeexec.FakeExec{
|
||||
CommandScript: []fakeexec.FakeCommandAction{
|
||||
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||
},
|
||||
LookPathFunc: func(cmd string) (string, error) { return cmd, nil },
|
||||
}
|
||||
|
||||
testCases := [][]string{
|
||||
{
|
||||
"10.240.0.3",
|
||||
"10.240.0.5",
|
||||
},
|
||||
{
|
||||
"10.240.0.4",
|
||||
},
|
||||
}
|
||||
|
||||
svcCount := 0
|
||||
for i := range testCases {
|
||||
for _, ip := range testCases[i] {
|
||||
if err := ClearUDPConntrackForIP(&fexec, ip); err != nil {
|
||||
t.Errorf("Unexepected error: %v", err)
|
||||
}
|
||||
expectCommand := fmt.Sprintf("conntrack -D --orig-dst %s -p udp", ip)
|
||||
execCommand := strings.Join(fcmd.CombinedOutputLog[svcCount], " ")
|
||||
if expectCommand != execCommand {
|
||||
t.Errorf("Exepect comand: %s, but executed %s", expectCommand, execCommand)
|
||||
}
|
||||
svcCount += 1
|
||||
}
|
||||
if svcCount != fexec.CommandCalls {
|
||||
t.Errorf("Exepect comand executed %d times, but got %d", svcCount, fexec.CommandCalls)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestClearUDPConntrackForPort(t *testing.T) {
|
||||
fcmd := fakeexec.FakeCmd{
|
||||
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{
|
||||
func() ([]byte, error) { return []byte("1 flow entries have been deleted"), nil },
|
||||
func() ([]byte, error) {
|
||||
return []byte(""), fmt.Errorf("conntrack v1.4.2 (conntrack-tools): 0 flow entries have been deleted.")
|
||||
},
|
||||
},
|
||||
}
|
||||
fexec := fakeexec.FakeExec{
|
||||
CommandScript: []fakeexec.FakeCommandAction{
|
||||
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||
},
|
||||
LookPathFunc: func(cmd string) (string, error) { return cmd, nil },
|
||||
}
|
||||
|
||||
testCases := []string{
|
||||
"8080",
|
||||
"9090",
|
||||
}
|
||||
svcCount := 0
|
||||
for i := range testCases {
|
||||
portNum, _ := strconv.Atoi(testCases[i])
|
||||
err := ClearUDPConntrackForPort(&fexec, portNum)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
expectCommand := fmt.Sprintf("conntrack -D -p udp --dport %s", testCases[i])
|
||||
execCommand := strings.Join(fcmd.CombinedOutputLog[svcCount], " ")
|
||||
if expectCommand != execCommand {
|
||||
t.Errorf("Exepect comand: %s, but executed %s", expectCommand, execCommand)
|
||||
}
|
||||
svcCount += 1
|
||||
|
||||
if svcCount != fexec.CommandCalls {
|
||||
t.Errorf("Exepect comand executed %d times, but got %d", svcCount, fexec.CommandCalls)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteUDPConnections(t *testing.T) {
|
||||
fcmd := fakeexec.FakeCmd{
|
||||
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{
|
||||
func() ([]byte, error) { return []byte("1 flow entries have been deleted"), nil },
|
||||
func() ([]byte, error) {
|
||||
return []byte(""), fmt.Errorf("conntrack v1.4.2 (conntrack-tools): 0 flow entries have been deleted.")
|
||||
},
|
||||
},
|
||||
}
|
||||
fexec := fakeexec.FakeExec{
|
||||
CommandScript: []fakeexec.FakeCommandAction{
|
||||
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||
},
|
||||
LookPathFunc: func(cmd string) (string, error) { return cmd, nil },
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
origin string
|
||||
dest string
|
||||
}{
|
||||
{
|
||||
origin: "1.2.3.4",
|
||||
dest: "10.20.30.40",
|
||||
},
|
||||
{
|
||||
origin: "2.3.4.5",
|
||||
dest: "20.30.40.50",
|
||||
},
|
||||
}
|
||||
svcCount := 0
|
||||
for i := range testCases {
|
||||
err := ClearUDPConntrackForPeers(&fexec, testCases[i].origin, testCases[i].dest)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
expectCommand := fmt.Sprintf("conntrack -D --orig-dst %s --dst-nat %s -p udp", testCases[i].origin, testCases[i].dest)
|
||||
execCommand := strings.Join(fcmd.CombinedOutputLog[svcCount], " ")
|
||||
if expectCommand != execCommand {
|
||||
t.Errorf("Exepect comand: %s, but executed %s", expectCommand, execCommand)
|
||||
}
|
||||
svcCount += 1
|
||||
|
||||
if svcCount != fexec.CommandCalls {
|
||||
t.Errorf("Exepect comand executed %d times, but got %d", svcCount, fexec.CommandCalls)
|
||||
}
|
||||
}
|
||||
}
|
||||
64
vendor/k8s.io/kubernetes/pkg/proxy/util/port.go
generated
vendored
Normal file
64
vendor/k8s.io/kubernetes/pkg/proxy/util/port.go
generated
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// LocalPort describes a port on specific IP address and protocol
|
||||
type LocalPort struct {
|
||||
// Description is the identity message of a given local port.
|
||||
Description string
|
||||
// IP is the IP address part of a given local port.
|
||||
// If this string is empty, the port binds to all local IP addresses.
|
||||
IP string
|
||||
// Port is the port part of a given local port.
|
||||
Port int
|
||||
// Protocol is the protocol part of a given local port.
|
||||
// The value is assumed to be lower-case. For example, "udp" not "UDP", "tcp" not "TCP".
|
||||
Protocol string
|
||||
}
|
||||
|
||||
func (lp *LocalPort) String() string {
|
||||
return fmt.Sprintf("%q (%s:%d/%s)", lp.Description, lp.IP, lp.Port, lp.Protocol)
|
||||
}
|
||||
|
||||
// Closeable is an interface around closing an port.
|
||||
type Closeable interface {
|
||||
Close() error
|
||||
}
|
||||
|
||||
// PortOpener is an interface around port opening/closing.
|
||||
// Abstracted out for testing.
|
||||
type PortOpener interface {
|
||||
OpenLocalPort(lp *LocalPort) (Closeable, error)
|
||||
}
|
||||
|
||||
// RevertPorts is closing ports in replacementPortsMap but not in originalPortsMap. In other words, it only
|
||||
// closes the ports opened in this sync.
|
||||
func RevertPorts(replacementPortsMap, originalPortsMap map[LocalPort]Closeable) {
|
||||
for k, v := range replacementPortsMap {
|
||||
// Only close newly opened local ports - leave ones that were open before this update
|
||||
if originalPortsMap[k] == nil {
|
||||
glog.V(2).Infof("Closing local port %s", k.String())
|
||||
v.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
116
vendor/k8s.io/kubernetes/pkg/proxy/util/port_test.go
generated
vendored
Normal file
116
vendor/k8s.io/kubernetes/pkg/proxy/util/port_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import "testing"
|
||||
|
||||
type fakeClosable struct {
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (c *fakeClosable) Close() error {
|
||||
c.closed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestRevertPorts(t *testing.T) {
|
||||
testCases := []struct {
|
||||
replacementPorts []LocalPort
|
||||
existingPorts []LocalPort
|
||||
expectToBeClose []bool
|
||||
}{
|
||||
{
|
||||
replacementPorts: []LocalPort{
|
||||
{Port: 5001},
|
||||
{Port: 5002},
|
||||
{Port: 5003},
|
||||
},
|
||||
existingPorts: []LocalPort{},
|
||||
expectToBeClose: []bool{true, true, true},
|
||||
},
|
||||
{
|
||||
replacementPorts: []LocalPort{},
|
||||
existingPorts: []LocalPort{
|
||||
{Port: 5001},
|
||||
{Port: 5002},
|
||||
{Port: 5003},
|
||||
},
|
||||
expectToBeClose: []bool{},
|
||||
},
|
||||
{
|
||||
replacementPorts: []LocalPort{
|
||||
{Port: 5001},
|
||||
{Port: 5002},
|
||||
{Port: 5003},
|
||||
},
|
||||
existingPorts: []LocalPort{
|
||||
{Port: 5001},
|
||||
{Port: 5002},
|
||||
{Port: 5003},
|
||||
},
|
||||
expectToBeClose: []bool{false, false, false},
|
||||
},
|
||||
{
|
||||
replacementPorts: []LocalPort{
|
||||
{Port: 5001},
|
||||
{Port: 5002},
|
||||
{Port: 5003},
|
||||
},
|
||||
existingPorts: []LocalPort{
|
||||
{Port: 5001},
|
||||
{Port: 5003},
|
||||
},
|
||||
expectToBeClose: []bool{false, true, false},
|
||||
},
|
||||
{
|
||||
replacementPorts: []LocalPort{
|
||||
{Port: 5001},
|
||||
{Port: 5002},
|
||||
{Port: 5003},
|
||||
},
|
||||
existingPorts: []LocalPort{
|
||||
{Port: 5001},
|
||||
{Port: 5002},
|
||||
{Port: 5003},
|
||||
{Port: 5004},
|
||||
},
|
||||
expectToBeClose: []bool{false, false, false},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
replacementPortsMap := make(map[LocalPort]Closeable)
|
||||
for _, lp := range tc.replacementPorts {
|
||||
replacementPortsMap[lp] = &fakeClosable{}
|
||||
}
|
||||
existingPortsMap := make(map[LocalPort]Closeable)
|
||||
for _, lp := range tc.existingPorts {
|
||||
existingPortsMap[lp] = &fakeClosable{}
|
||||
}
|
||||
RevertPorts(replacementPortsMap, existingPortsMap)
|
||||
for j, expectation := range tc.expectToBeClose {
|
||||
if replacementPortsMap[tc.replacementPorts[j]].(*fakeClosable).closed != expectation {
|
||||
t.Errorf("Expect replacement localport %v to be %v in test case %v", tc.replacementPorts[j], expectation, i)
|
||||
}
|
||||
}
|
||||
for _, lp := range tc.existingPorts {
|
||||
if existingPortsMap[lp].(*fakeClosable).closed == true {
|
||||
t.Errorf("Expect existing localport %v to be false in test case %v", lp, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
vendor/k8s.io/kubernetes/pkg/proxy/util/utils.go
generated
vendored
Normal file
58
vendor/k8s.io/kubernetes/pkg/proxy/util/utils.go
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/helper"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
func IsLocalIP(ip string) (bool, error) {
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for i := range addrs {
|
||||
intf, _, err := net.ParseCIDR(addrs[i].String())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if net.ParseIP(ip).Equal(intf) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func ShouldSkipService(svcName types.NamespacedName, service *api.Service) bool {
|
||||
// if ClusterIP is "None" or empty, skip proxying
|
||||
if !helper.IsServiceIPSet(service) {
|
||||
glog.V(3).Infof("Skipping service %s due to clusterIP = %q", svcName, service.Spec.ClusterIP)
|
||||
return true
|
||||
}
|
||||
// Even if ClusterIP is set, ServiceTypeExternalName services don't get proxied
|
||||
if service.Spec.Type == api.ServiceTypeExternalName {
|
||||
glog.V(3).Infof("Skipping service %s due to Type=ExternalName", svcName)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
111
vendor/k8s.io/kubernetes/pkg/proxy/util/utils_test.go
generated
vendored
Normal file
111
vendor/k8s.io/kubernetes/pkg/proxy/util/utils_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func TestShouldSkipService(t *testing.T) {
|
||||
testCases := []struct {
|
||||
service *api.Service
|
||||
svcName types.NamespacedName
|
||||
shouldSkip bool
|
||||
}{
|
||||
{
|
||||
// Cluster IP is None
|
||||
service: &api.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
ClusterIP: api.ClusterIPNone,
|
||||
},
|
||||
},
|
||||
svcName: types.NamespacedName{Namespace: "foo", Name: "bar"},
|
||||
shouldSkip: true,
|
||||
},
|
||||
{
|
||||
// Cluster IP is empty
|
||||
service: &api.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
ClusterIP: "",
|
||||
},
|
||||
},
|
||||
svcName: types.NamespacedName{Namespace: "foo", Name: "bar"},
|
||||
shouldSkip: true,
|
||||
},
|
||||
{
|
||||
// ExternalName type service
|
||||
service: &api.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
ClusterIP: "1.2.3.4",
|
||||
Type: api.ServiceTypeExternalName,
|
||||
},
|
||||
},
|
||||
svcName: types.NamespacedName{Namespace: "foo", Name: "bar"},
|
||||
shouldSkip: true,
|
||||
},
|
||||
{
|
||||
// ClusterIP type service with ClusterIP set
|
||||
service: &api.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
ClusterIP: "1.2.3.4",
|
||||
Type: api.ServiceTypeClusterIP,
|
||||
},
|
||||
},
|
||||
svcName: types.NamespacedName{Namespace: "foo", Name: "bar"},
|
||||
shouldSkip: false,
|
||||
},
|
||||
{
|
||||
// NodePort type service with ClusterIP set
|
||||
service: &api.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
ClusterIP: "1.2.3.4",
|
||||
Type: api.ServiceTypeNodePort,
|
||||
},
|
||||
},
|
||||
svcName: types.NamespacedName{Namespace: "foo", Name: "bar"},
|
||||
shouldSkip: false,
|
||||
},
|
||||
{
|
||||
// LoadBalancer type service with ClusterIP set
|
||||
service: &api.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
ClusterIP: "1.2.3.4",
|
||||
Type: api.ServiceTypeLoadBalancer,
|
||||
},
|
||||
},
|
||||
svcName: types.NamespacedName{Namespace: "foo", Name: "bar"},
|
||||
shouldSkip: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i := range testCases {
|
||||
skip := ShouldSkipService(testCases[i].svcName, testCases[i].service)
|
||||
if skip != testCases[i].shouldSkip {
|
||||
t.Errorf("case %d: expect %v, got %v", i, testCases[i].shouldSkip, skip)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue