def delete(self): """ Deletes the ipsets. This is done on a best-effort basis. """ _log.debug("Delete ipsets %s and %s if they exist", self.set_name, self.temp_set_name) futils.call_silent(["ipset", "destroy", self.set_name]) futils.call_silent(["ipset", "destroy", self.temp_set_name])
def on_unreferenced(self): # Mark the object as stopped so that we don't accidentally recreate # the ipset in _finish_msg_batch. self.stopped = True try: # Destroy the ipsets - ignoring any errors. _log.debug("Delete ipsets %s and %s if they exist", self.name, self.tmpname) futils.call_silent(["ipset", "destroy", self.name]) futils.call_silent(["ipset", "destroy", self.tmpname]) finally: self._notify_cleanup_complete()
def create(name, typename, family): """ Create an ipset. If it already exists, do nothing. *name* is the name of the ipset. *typename* must be a valid type, such as "hash:net" or "hash:net,port" *family* must be *inet* or *inet6* """ if futils.call_silent(["ipset", "list", name]) != 0: # ipset list failed - either does not exist, or an error. Either way, # try creation, throwing an error if it does not work. futils.check_call( ["ipset", "create", name, typename, "family", family])
def replace_members(self, members): """ Atomically rewrites the ipset with the new members. Creates the set if it does not exist. """ # We use ipset restore, which processes a batch of ipset updates. # The only operation that we're sure is atomic is swapping two ipsets # so we build up the complete set of members in a temporary ipset, # swap it into place and then delete the old ipset. _log.info("Rewriting ipset %s with %d members", self, len(members)) assert isinstance(members, (set, frozenset)) assert len(members) <= self.max_elem # Try to destroy the temporary set so that we get to recreate it below, # possibly with new parameters. if futils.call_silent(["ipset", "destroy", self.temp_set_name]) != 0: if self.exists(temp_set=True): _log.error("Failed to delete temporary ipset %s. Subsequent " "commands may fail.", self.temp_set_name) if not self.exists(): # Ensure the main set exists so we can re-use the atomic swap # code below. _log.debug("Main set doesn't exist, creating it...") input_lines = [self._create_cmd(self.set_name)] else: # Avoid trying to create the main set in case we try to create it # with differing parameters (which fails even with the --exist # flag). _log.debug("Main set exists, skipping create.") input_lines = [] input_lines += [ # Ensure the temporary set exists. self._create_cmd(self.temp_set_name), # Flush the temporary set. This is a no-op unless we failed to # delete the set above. "flush %s" % self.temp_set_name, ] # Add all the members to the temporary set, input_lines += ["add %s %s" % (self.temp_set_name, m) for m in members] # Then, atomically swap the temporary set into place. input_lines.append("swap %s %s" % (self.set_name, self.temp_set_name)) # Finally, delete the temporary set (which was the old active set). input_lines.append("destroy %s" % self.temp_set_name) # COMMIT tells ipset restore to actually execute the changes. self._exec_and_commit(input_lines)
def replace_members(self, members): """ Atomically rewrites the ipset with the new members. Creates the set if it does not exist. """ # We use ipset restore, which processes a batch of ipset updates. # The only operation that we're sure is atomic is swapping two ipsets # so we build up the complete set of members in a temporary ipset, # swap it into place and then delete the old ipset. _log.info("Rewriting ipset %s with %d members", self, len(members)) assert isinstance(members, (set, frozenset)) assert len(members) <= self.max_elem # Try to destroy the temporary set so that we get to recreate it below, # possibly with new parameters. if futils.call_silent(["ipset", "destroy", self.temp_set_name]) != 0: if self.exists(temp_set=True): _log.error("Failed to delete temporary ipset %s. Subsequent " "commands may fail.", self.temp_set_name) if not self.exists(): # Ensure the main set exists so we can re-use the atomic swap # code below. _log.debug("Main set doesn't exist, creating it...") #uncovered input_lines = [self._create_cmd(self.set_name)] else: # Avoid trying to create the main set in case we try to create it # with differing parameters (which fails even with the --exist # flag). _log.debug("Main set exists, skipping create.") input_lines = [] input_lines += [ # Ensure the temporary set exists. self._create_cmd(self.temp_set_name), # Flush the temporary set. This is a no-op unless we failed to # delete the set above. "flush %s" % self.temp_set_name, ] # Add all the members to the temporary set, input_lines += ["add %s %s" % (self.temp_set_name, m) for m in members] # Then, atomically swap the temporary set into place. input_lines.append("swap %s %s" % (self.set_name, self.temp_set_name)) # Finally, delete the temporary set (which was the old active set). input_lines.append("destroy %s" % self.temp_set_name) # COMMIT tells ipset restore to actually execute the changes. self._exec_and_commit(input_lines)
def test_bad_call_silent(self): # Test an invalid command - must parse but not return anything. args = ["ls", "wibble_wobble"] retcode = futils.call_silent(args) self.assertNotEqual(retcode, 0)
def test_good_call_silent(self): # Test a command. Result must include "calico" given where it is run from. args = ["ls"] retcode = futils.call_silent(args) self.assertEqual(retcode, 0)
def ipset_exists(name): """ Check if a set of the correct name exists. """ return futils.call_silent(["ipset", "list", name]) == 0
def destroy(name): """ Destroy an ipset if it exists (and do nothing if not). """ if futils.call_silent(["ipset", "list", name]) == 0: futils.check_call(["ipset", "destroy", name])