iptables: add idempotent functions

Add the following idempotent functions to iptables utils:

DeleteRule: idempotently delete an iptables rule
DeleteChain: idempotently delete an iptables chain
ClearChain: idempotently flush an iptables chain

Signed-off-by: Antonio Ojea <antonio.ojea.garcia@gmail.com>
This commit is contained in:
Antonio Ojea
2019-12-12 14:03:33 +01:00
parent 3603738c6a
commit bf8f171041
3 changed files with 88 additions and 36 deletions

View File

@ -70,15 +70,8 @@ func (c *chain) teardown(ipt *iptables.IPTables) error {
// flush the chain
// This will succeed *and create the chain* if it does not exist.
// If the chain doesn't exist, the next checks will fail.
if err := ipt.ClearChain(c.table, c.name); err != nil {
eerr, eok := err.(*iptables.Error)
switch {
case eok && eerr.IsNotExist():
// swallow here, the chain was already deleted
return nil
default:
return err
}
if err := utils.ClearChain(ipt, c.table, c.name); err != nil {
return err
}
for _, entryChain := range c.entryChains {
@ -97,32 +90,15 @@ func (c *chain) teardown(ipt *iptables.IPTables) error {
}
chainParts = chainParts[2:] // List results always include an -A CHAINNAME
if err := ipt.Delete(c.table, entryChain, chainParts...); err != nil {
eerr, eok := err.(*iptables.Error)
switch {
case eok && eerr.IsNotExist():
// swallow here, the chain was already deleted
continue
case eok && eerr.ExitStatus() == 2:
// swallow here, invalid command line parameter because the referring rule is missing
continue
default:
return fmt.Errorf("Failed to delete referring rule %s %s: %v", c.table, entryChainRule, err)
}
if err := utils.DeleteRule(ipt, c.table, entryChain, chainParts...); err != nil {
return err
}
}
}
}
err := ipt.DeleteChain(c.table, c.name)
eerr, eok := err.(*iptables.Error)
switch {
case eok && eerr.IsNotExist():
// swallow here, the chain was already deleted
return nil
default:
return err
}
return utils.DeleteChain(ipt, c.table, c.name)
}
// insertUnique will add a rule to a chain if it does not already exist.