mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-11-26 19:35:10 +00:00
Merge pull request #51686 from choury/fix_dup_unbind
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Fix duplicate unbind action in kube-proxy **What this PR does / why we need it**: Fix duplicate unbind action in kube-proxy. It will generate unnecessary error info If unbind multi-ports on one service . **Which issue this PR fixes**: fixes #51694 **Release-note**: ```release-note NONE ```
This commit is contained in:
@@ -20,9 +20,6 @@ go_test(
|
||||
deps = select({
|
||||
"@io_bazel_rules_go//go/platform:linux_amd64": [
|
||||
"//vendor/github.com/docker/libnetwork/ipvs:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
|
||||
@@ -25,10 +25,6 @@ import (
|
||||
type Interface interface {
|
||||
// Flush clears all virtual servers in system. return occurred error immediately.
|
||||
Flush() error
|
||||
// EnsureVirtualServerAddressBind checks if virtual server's address is bound to dummy interface and, if not, binds it. If the address is already bound, return true.
|
||||
EnsureVirtualServerAddressBind(serv *VirtualServer, dev string) (exist bool, err error)
|
||||
// UnbindVirtualServerAddress checks if virtual server's address is bound to dummy interface and, if so, unbinds it.
|
||||
UnbindVirtualServerAddress(serv *VirtualServer, dev string) error
|
||||
// AddVirtualServer creates the specified virtual server.
|
||||
AddVirtualServer(*VirtualServer) error
|
||||
// UpdateVirtualServer updates an already existing virtual server. If the virtual server does not exist, return error.
|
||||
|
||||
@@ -30,8 +30,6 @@ import (
|
||||
utilexec "k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
const cmdIP = "ip"
|
||||
|
||||
// runner implements Interface.
|
||||
type runner struct {
|
||||
exec utilexec.Interface
|
||||
@@ -51,34 +49,6 @@ func New(exec utilexec.Interface) Interface {
|
||||
}
|
||||
}
|
||||
|
||||
// EnsureVirtualServerAddressBind is part of Interface.
|
||||
func (runner *runner) EnsureVirtualServerAddressBind(vs *VirtualServer, dummyDev string) (exist bool, err error) {
|
||||
addr := vs.Address.String()
|
||||
args := []string{"addr", "add", addr, "dev", dummyDev}
|
||||
out, err := runner.exec.Command(cmdIP, args...).CombinedOutput()
|
||||
if err != nil {
|
||||
// "exit status 2" will be returned if the address is already bound to dummy device
|
||||
if ee, ok := err.(utilexec.ExitError); ok {
|
||||
if ee.Exited() && ee.ExitStatus() == 2 {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, fmt.Errorf("error bind address: %s to dummy interface: %s, err: %v: %s", vs.Address.String(), dummyDev, err, out)
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// UnbindVirtualServerAddress is part of Interface.
|
||||
func (runner *runner) UnbindVirtualServerAddress(vs *VirtualServer, dummyDev string) error {
|
||||
addr := vs.Address.String()
|
||||
args := []string{"addr", "del", addr, "dev", dummyDev}
|
||||
out, err := runner.exec.Command(cmdIP, args...).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error unbind address: %s from dummy interface: %s, err: %v: %s", vs.Address.String(), dummyDev, err, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddVirtualServer is part of Interface.
|
||||
func (runner *runner) AddVirtualServer(vs *VirtualServer) error {
|
||||
eSvc, err := toBackendService(vs)
|
||||
|
||||
@@ -25,129 +25,9 @@ import (
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/utils/exec"
|
||||
fakeexec "k8s.io/utils/exec/testing"
|
||||
|
||||
"github.com/docker/libnetwork/ipvs"
|
||||
)
|
||||
|
||||
const dummyDevice = "kube-ipvs0"
|
||||
|
||||
func TestEnsureVirtualServerAddressBind(t *testing.T) {
|
||||
tests := []VirtualServer{
|
||||
{
|
||||
Address: net.ParseIP("10.20.30.40"),
|
||||
Port: uint16(1234),
|
||||
Protocol: string("TCP"),
|
||||
},
|
||||
{
|
||||
Address: net.ParseIP("2012::beef"),
|
||||
Port: uint16(5678),
|
||||
Protocol: string("UDP"),
|
||||
},
|
||||
}
|
||||
for i := range tests {
|
||||
vs := &tests[i]
|
||||
fcmd := fakeexec.FakeCmd{
|
||||
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{
|
||||
// Success.
|
||||
func() ([]byte, error) { return []byte{}, nil },
|
||||
// Exists.
|
||||
func() ([]byte, error) { return nil, &fakeexec.FakeExitError{Status: 2} },
|
||||
},
|
||||
}
|
||||
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...) },
|
||||
},
|
||||
}
|
||||
runner := New(&fexec)
|
||||
// Success.
|
||||
exists, err := runner.EnsureVirtualServerAddressBind(vs, dummyDevice)
|
||||
if err != nil {
|
||||
t.Errorf("expected success, got %v", err)
|
||||
}
|
||||
if exists {
|
||||
t.Errorf("expected exists = false")
|
||||
}
|
||||
if fcmd.CombinedOutputCalls != 1 {
|
||||
t.Errorf("expected 1 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
|
||||
}
|
||||
IP := tests[i].Address.String()
|
||||
if !sets.NewString(fcmd.CombinedOutputLog[0]...).HasAll("ip", "addr", "add", IP, "dev", dummyDevice) {
|
||||
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[0])
|
||||
}
|
||||
// Exists.
|
||||
exists, err = runner.EnsureVirtualServerAddressBind(vs, dummyDevice)
|
||||
if err != nil {
|
||||
t.Errorf("expected success, got %v", err)
|
||||
}
|
||||
if !exists {
|
||||
t.Errorf("expected exists = true")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnbindVirtualServerAddress(t *testing.T) {
|
||||
tests := []VirtualServer{
|
||||
{
|
||||
Address: net.ParseIP("2012::beef"),
|
||||
Port: uint16(5678),
|
||||
Protocol: string("UDP"),
|
||||
},
|
||||
{
|
||||
Address: net.ParseIP("10.20.30.40"),
|
||||
Port: uint16(1234),
|
||||
Protocol: string("TCP"),
|
||||
},
|
||||
}
|
||||
for i := range tests {
|
||||
vs := &tests[i]
|
||||
fcmd := fakeexec.FakeCmd{
|
||||
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{
|
||||
// Success.
|
||||
func() ([]byte, error) {
|
||||
return []byte{}, nil
|
||||
},
|
||||
// Failure.
|
||||
func() ([]byte, error) {
|
||||
return nil, &fakeexec.FakeExitError{Status: 2}
|
||||
},
|
||||
},
|
||||
}
|
||||
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...)
|
||||
},
|
||||
},
|
||||
}
|
||||
runner := New(&fexec)
|
||||
// Success.
|
||||
err := runner.UnbindVirtualServerAddress(vs, dummyDevice)
|
||||
if err != nil {
|
||||
t.Errorf("expected success, got %v", err)
|
||||
}
|
||||
if fcmd.CombinedOutputCalls != 1 {
|
||||
t.Errorf("expected 1 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
|
||||
}
|
||||
IP := tests[i].Address.String()
|
||||
if !sets.NewString(fcmd.CombinedOutputLog[0]...).HasAll("ip", "addr", "del", IP, "dev", dummyDevice) {
|
||||
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[0])
|
||||
}
|
||||
// Failure.
|
||||
err = runner.UnbindVirtualServerAddress(vs, dummyDevice)
|
||||
if err == nil {
|
||||
t.Errorf("expected failure")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_toVirtualServer(t *testing.T) {
|
||||
Tests := []struct {
|
||||
ipvsService ipvs.Service
|
||||
|
||||
@@ -36,14 +36,6 @@ func (runner *runner) Flush() error {
|
||||
return fmt.Errorf("IPVS not supported for this platform")
|
||||
}
|
||||
|
||||
func (runner *runner) EnsureVirtualServerAddressBind(*VirtualServer, string) (bool, error) {
|
||||
return false, fmt.Errorf("IPVS not supported for this platform")
|
||||
}
|
||||
|
||||
func (runner *runner) UnbindVirtualServerAddress(*VirtualServer, string) error {
|
||||
return fmt.Errorf("IPVS not supported for this platform")
|
||||
}
|
||||
|
||||
func (runner *runner) AddVirtualServer(*VirtualServer) error {
|
||||
return fmt.Errorf("IPVS not supported for this platform")
|
||||
}
|
||||
|
||||
@@ -55,16 +55,6 @@ func toServiceKey(serv *utilipvs.VirtualServer) serviceKey {
|
||||
}
|
||||
}
|
||||
|
||||
//EnsureVirtualServerAddressBind is an empty implementation
|
||||
func (*FakeIPVS) EnsureVirtualServerAddressBind(serv *utilipvs.VirtualServer, dev string) (exist bool, err error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
//UnbindVirtualServerAddress is an empty implementation
|
||||
func (*FakeIPVS) UnbindVirtualServerAddress(serv *utilipvs.VirtualServer, dev string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//AddVirtualServer is a fake implementation, it simply adds the VirtualServer into the cache store.
|
||||
func (f *FakeIPVS) AddVirtualServer(serv *utilipvs.VirtualServer) error {
|
||||
if serv == nil {
|
||||
|
||||
Reference in New Issue
Block a user