def __handle_set_config_all(self, cmd): old_data = copy.deepcopy(self.config.data) got_error = False err_list = [] # The format of the command is a dict with module->newconfig # sets, so we simply call set_config_module for each of those for module in cmd: if module != "version": answer = self.__handle_set_config_module(module, cmd[module]) if answer == None: got_error = True err_list.append("No answer message from " + module) else: rcode, val = ccsession.parse_answer(answer) if rcode != 0: got_error = True err_list.append(val) if not got_error: # if Logging config is in there, update our config as well self.check_logging_config(cmd); self.write_config() return ccsession.create_answer(0) else: # TODO rollback changes that did get through, should we re-send update? self.config.data = old_data return ccsession.create_answer(1, " ".join(err_list))
def __handle_set_config_module(self, module_name, cmd): # the answer comes (or does not come) from the relevant module # so we need a variable to see if we got it answer = None # todo: use api (and check the data against the definition?) old_data = copy.deepcopy(self.config.data) conf_part = data.find_no_exc(self.config.data, module_name) update_cmd = None use_part = None if conf_part: data.merge(conf_part, cmd) use_part = conf_part else: conf_part = data.set(self.config.data, module_name, {}) data.merge(conf_part[module_name], cmd) use_part = conf_part[module_name] # The command to send update_cmd = ccsession.create_command(ccsession.COMMAND_CONFIG_UPDATE, use_part) # TODO: This design might need some revisiting. We might want some # polymorphism instead of branching. But it just might turn out it # will get solved by itself when we move everything to virtual modules # (which is possible solution to the offline configuration problem) # or when we solve the incorect behaviour here when a config is # rejected (spying modules don't know it was rejected and some modules # might have been commited already). if module_name in self.virtual_modules: # The module is virtual, so call it to get the answer try: error = self.virtual_modules[module_name](use_part) if error is None: answer = ccsession.create_answer(0) # OK, it is successful, send the notify, but don't wait # for answer seq = self.cc.group_sendmsg(update_cmd, module_name) else: answer = ccsession.create_answer(1, error) # Make sure just a validating plugin don't kill the whole manager except Exception as excp: # Provide answer answer = ccsession.create_answer(1, "Exception: " + str(excp)) else: # Real module, send it over the wire to it # send out changed info and wait for answer seq = self.cc.group_sendmsg(update_cmd, module_name) try: # replace 'our' answer with that of the module answer, env = self.cc.group_recvmsg(False, seq) except isc.cc.SessionTimeout: answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name) except isc.cc.SessionError as se: logger.error(CFGMGR_BAD_UPDATE_RESPONSE_FROM_MODULE, module_name, se) answer = ccsession.create_answer(1, "Unable to parse response from " + module_name + ": " + str(se)) if answer: rcode, val = ccsession.parse_answer(answer) if rcode == 0: self.write_config() else: self.config.data = old_data return answer
def __handle_set_config_module(self, module_name, cmd): # the answer comes (or does not come) from the relevant module # so we need a variable to see if we got it answer = None # todo: use api (and check the data against the definition?) old_data = copy.deepcopy(self.config.data) conf_part = data.find_no_exc(self.config.data, module_name) update_cmd = None use_part = None if conf_part: data.merge(conf_part, cmd) use_part = conf_part else: conf_part = data.set(self.config.data, module_name, {}) data.merge(conf_part[module_name], cmd) use_part = conf_part[module_name] # The command to send update_cmd = ccsession.create_command(ccsession.COMMAND_CONFIG_UPDATE, use_part) # TODO: This design might need some revisiting. We might want some # polymorphism instead of branching. But it just might turn out it # will get solved by itself when we move everything to virtual modules # (which is possible solution to the offline configuration problem) # or when we solve the incorrect behaviour here when a config is # rejected (spying modules don't know it was rejected and some modules # might have been committed already). if module_name in self.virtual_modules: # The module is virtual, so call it to get the answer try: error = self.virtual_modules[module_name](use_part) if error is None: answer = ccsession.create_answer(0) # OK, it is successful, send the notify, but don't wait # for answer seq = self.cc.group_sendmsg(update_cmd, module_name) else: answer = ccsession.create_answer(1, error) # Make sure just a validating plugin don't kill the whole manager except Exception as excp: # Provide answer answer = ccsession.create_answer(1, "Exception: " + str(excp)) else: # Real module, send it over the wire to it # send out changed info and wait for answer seq = self.cc.group_sendmsg(update_cmd, module_name) try: # replace 'our' answer with that of the module answer, env = self.cc.group_recvmsg(False, seq) except isc.cc.SessionTimeout: answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name) except isc.cc.SessionError as se: logger.error(CFGMGR_BAD_UPDATE_RESPONSE_FROM_MODULE, module_name, se) answer = ccsession.create_answer(1, "Unable to parse response from " + module_name + ": " + str(se)) if answer: rcode, val = ccsession.parse_answer(answer) if rcode == 0: self.write_config() else: self.config.data = old_data return answer