From dc2925263c5920dd501ad73e57a2512185bc1009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Austerm=C3=BChle?= Date: Thu, 23 Feb 2017 17:37:31 +0100 Subject: [PATCH] Destroy ipsets prefixed `weave-` only (issue #2751) --- npc/constants.go | 2 ++ npc/ipset/ipset.go | 55 +++++++++++++++++++++++++++++++++--------- npc/selector.go | 2 +- prog/weave-npc/main.go | 16 +++++++++--- 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/npc/constants.go b/npc/constants.go index 64565484..7ab01f7b 100644 --- a/npc/constants.go +++ b/npc/constants.go @@ -6,4 +6,6 @@ const ( MainChain = "WEAVE-NPC" DefaultChain = "WEAVE-NPC-DEFAULT" IngressChain = "WEAVE-NPC-INGRESS" + + IpsetNamePrefix = "weave-" ) diff --git a/npc/ipset/ipset.go b/npc/ipset/ipset.go index 3a27327b..1a197bb1 100644 --- a/npc/ipset/ipset.go +++ b/npc/ipset/ipset.go @@ -1,7 +1,9 @@ package ipset import ( + "bytes" "os/exec" + "strings" "github.com/pkg/errors" ) @@ -22,6 +24,8 @@ type Interface interface { Flush(ipsetName Name) error Destroy(ipsetName Name) error + List(prefix string) ([]Name, error) + FlushAll() error DestroyAll() error } @@ -35,48 +39,77 @@ func New() Interface { } func (i *ipset) Create(ipsetName Name, ipsetType Type) error { - return doExec("create", string(ipsetName), string(ipsetType)) + err, _ := doExec("create", string(ipsetName), string(ipsetType)) + return err } func (i *ipset) AddEntry(ipsetName Name, entry string) error { if i.inc(ipsetName, entry) > 1 { // already in the set return nil } - return doExec("add", string(ipsetName), entry) + err, _ := doExec("add", string(ipsetName), entry) + return err } func (i *ipset) DelEntry(ipsetName Name, entry string) error { if i.dec(ipsetName, entry) > 0 { // still needed return nil } - return doExec("del", string(ipsetName), entry) + err, _ := doExec("del", string(ipsetName), entry) + return err } func (i *ipset) Flush(ipsetName Name) error { i.removeSet(ipsetName) - return doExec("flush", string(ipsetName)) + err, _ := doExec("flush", string(ipsetName)) + return err } func (i *ipset) FlushAll() error { i.refCount = newRefCount() - return doExec("flush") + err, _ := doExec("flush") + return err } func (i *ipset) Destroy(ipsetName Name) error { i.removeSet(ipsetName) - return doExec("destroy", string(ipsetName)) + err, _ := doExec("destroy", string(ipsetName)) + return err } func (i *ipset) DestroyAll() error { i.refCount = newRefCount() - return doExec("destroy") + err, _ := doExec("destroy") + return err } -func doExec(args ...string) error { - if output, err := exec.Command("ipset", args...).CombinedOutput(); err != nil { - return errors.Wrapf(err, "ipset %v failed: %s", args, output) +// Fetch a list of all existing sets +func (i *ipset) List(prefix string) ([]Name, error) { + err, output := doExec("list","-name","-output","plain") + + var selected []Name + if err == nil && len(output) > 0 { + output = bytes.TrimRight(output, "\n") + sets := strings.Split(string(output[:]), "\n") + + plen := len(prefix) + for _, v := range sets { + if (plen <= len(v)) && (prefix == v[:len(prefix)]) { + selected = append(selected, Name(v)) + } + } + } - return nil + + return selected, err +} + +func doExec(args ...string) (error, []byte) { + output, err := exec.Command("ipset", args...).CombinedOutput() + if err != nil { + return errors.Wrapf(err, "ipset %v failed: %s", args, output), output + } + return nil, output } // Reference-counting diff --git a/npc/selector.go b/npc/selector.go index b03c97b1..1f34fa3b 100644 --- a/npc/selector.go +++ b/npc/selector.go @@ -29,7 +29,7 @@ func newSelectorSpec(json *unversioned.LabelSelector, nsName string, ipsetType i // We prefix the selector string with the namespace name when generating // the shortname because you can specify the same selector in multiple // namespaces - we need those to map to distinct ipsets - ipsetName: ipset.Name("weave-" + shortName(nsName+":"+key)), + ipsetName: ipset.Name(IpsetNamePrefix + shortName(nsName+":"+key)), ipsetType: ipsetType}, nil } diff --git a/prog/weave-npc/main.go b/prog/weave-npc/main.go index 2c0623a2..9908ac22 100644 --- a/prog/weave-npc/main.go +++ b/prog/weave-npc/main.go @@ -80,14 +80,22 @@ func resetIPTables(ipt *iptables.IPTables) error { } func resetIPSets(ips ipset.Interface) error { - // TODO should restrict ipset operations to the `weave-` prefix: + // Remove ipsets prefixed `weave-` only - if err := ips.FlushAll(); err != nil { + sets, err := ips.List(npc.IpsetNamePrefix) + if (err != nil) { + common.Log.Errorf("Failed to retrieve list of ipsets") return err } - if err := ips.DestroyAll(); err != nil { - return err + common.Log.Debugf("Got list of ipsets: %v", sets) + + for _, s := range sets { + common.Log.Debugf("Destroying ipsets '%s'", string(s)) + if err := ips.Destroy(s); err != nil { + common.Log.Errorf("Failed to destroy ipset '%s'", string(s)) + return err + } } return nil