Commit 1ad4549f authored by Justin Santa Barbara's avatar Justin Santa Barbara

Proxy infrastructure for NodePorts

A service with a NodePort set will listen on that port, on every node. This is both handy for some load balancers (AWS ELB) and for people that want to expose a service without using a load balancer.
parent 295d0564
...@@ -92,7 +92,7 @@ func (fake *fakeIptables) FlushChain(table iptables.Table, chain iptables.Chain) ...@@ -92,7 +92,7 @@ func (fake *fakeIptables) FlushChain(table iptables.Table, chain iptables.Chain)
return nil return nil
} }
func (fake *fakeIptables) EnsureRule(table iptables.Table, chain iptables.Chain, args ...string) (bool, error) { func (fake *fakeIptables) EnsureRule(position iptables.RulePosition, table iptables.Table, chain iptables.Chain, args ...string) (bool, error) {
return false, nil return false, nil
} }
...@@ -810,3 +810,5 @@ func TestProxyUpdatePortal(t *testing.T) { ...@@ -810,3 +810,5 @@ func TestProxyUpdatePortal(t *testing.T) {
} }
// TODO: Test UDP timeouts. // TODO: Test UDP timeouts.
// TODO(justinsb): Add test for nodePort conflict detection, once we have nodePort wired in
...@@ -28,6 +28,13 @@ import ( ...@@ -28,6 +28,13 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
) )
type RulePosition string
const (
Prepend RulePosition = "-I"
Append RulePosition = "-A"
)
// An injectable interface for running iptables commands. Implementations must be goroutine-safe. // An injectable interface for running iptables commands. Implementations must be goroutine-safe.
type Interface interface { type Interface interface {
// EnsureChain checks if the specified chain exists and, if not, creates it. If the chain existed, return true. // EnsureChain checks if the specified chain exists and, if not, creates it. If the chain existed, return true.
...@@ -37,7 +44,7 @@ type Interface interface { ...@@ -37,7 +44,7 @@ type Interface interface {
// DeleteChain deletes the specified chain. If the chain did not exist, return error. // DeleteChain deletes the specified chain. If the chain did not exist, return error.
DeleteChain(table Table, chain Chain) error DeleteChain(table Table, chain Chain) error
// EnsureRule checks if the specified rule is present and, if not, creates it. If the rule existed, return true. // EnsureRule checks if the specified rule is present and, if not, creates it. If the rule existed, return true.
EnsureRule(table Table, chain Chain, args ...string) (bool, error) EnsureRule(position RulePosition, table Table, chain Chain, args ...string) (bool, error)
// DeleteRule checks if the specified rule is present and, if so, deletes it. // DeleteRule checks if the specified rule is present and, if so, deletes it.
DeleteRule(table Table, chain Chain, args ...string) error DeleteRule(table Table, chain Chain, args ...string) error
// IsIpv6 returns true if this is managing ipv6 tables // IsIpv6 returns true if this is managing ipv6 tables
...@@ -126,7 +133,7 @@ func (runner *runner) DeleteChain(table Table, chain Chain) error { ...@@ -126,7 +133,7 @@ func (runner *runner) DeleteChain(table Table, chain Chain) error {
} }
// EnsureRule is part of Interface. // EnsureRule is part of Interface.
func (runner *runner) EnsureRule(table Table, chain Chain, args ...string) (bool, error) { func (runner *runner) EnsureRule(position RulePosition, table Table, chain Chain, args ...string) (bool, error) {
fullArgs := makeFullArgs(table, chain, args...) fullArgs := makeFullArgs(table, chain, args...)
runner.mu.Lock() runner.mu.Lock()
...@@ -139,7 +146,7 @@ func (runner *runner) EnsureRule(table Table, chain Chain, args ...string) (bool ...@@ -139,7 +146,7 @@ func (runner *runner) EnsureRule(table Table, chain Chain, args ...string) (bool
if exists { if exists {
return true, nil return true, nil
} }
out, err := runner.run(opAppendRule, fullArgs) out, err := runner.run(operation(position), fullArgs)
if err != nil { if err != nil {
return false, fmt.Errorf("error appending rule: %v: %s", err, out) return false, fmt.Errorf("error appending rule: %v: %s", err, out)
} }
......
...@@ -176,7 +176,7 @@ func TestEnsureRuleAlreadyExists(t *testing.T) { ...@@ -176,7 +176,7 @@ func TestEnsureRuleAlreadyExists(t *testing.T) {
}, },
} }
runner := New(&fexec, ProtocolIpv4) runner := New(&fexec, ProtocolIpv4)
exists, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123") exists, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123")
if err != nil { if err != nil {
t.Errorf("expected success, got %v", err) t.Errorf("expected success, got %v", err)
} }
...@@ -212,7 +212,7 @@ func TestEnsureRuleNew(t *testing.T) { ...@@ -212,7 +212,7 @@ func TestEnsureRuleNew(t *testing.T) {
}, },
} }
runner := New(&fexec, ProtocolIpv4) runner := New(&fexec, ProtocolIpv4)
exists, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123") exists, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123")
if err != nil { if err != nil {
t.Errorf("expected success, got %v", err) t.Errorf("expected success, got %v", err)
} }
...@@ -245,7 +245,7 @@ func TestEnsureRuleErrorChecking(t *testing.T) { ...@@ -245,7 +245,7 @@ func TestEnsureRuleErrorChecking(t *testing.T) {
}, },
} }
runner := New(&fexec, ProtocolIpv4) runner := New(&fexec, ProtocolIpv4)
_, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123") _, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123")
if err == nil { if err == nil {
t.Errorf("expected failure") t.Errorf("expected failure")
} }
...@@ -275,7 +275,7 @@ func TestEnsureRuleErrorCreating(t *testing.T) { ...@@ -275,7 +275,7 @@ func TestEnsureRuleErrorCreating(t *testing.T) {
}, },
} }
runner := New(&fexec, ProtocolIpv4) runner := New(&fexec, ProtocolIpv4)
_, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123") _, err := runner.EnsureRule(Append, TableNAT, ChainOutput, "abc", "123")
if err == nil { if err == nil {
t.Errorf("expected failure") t.Errorf("expected failure")
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment