def auth_loadzone_command(module_cc, zone_name, zone_class): '''Create a 'loadzone' command with a given zone for Auth server. This function generates an inter-module command for Auth to force it to reload the zone. Parameters: module_cc (CCSession): a CC session that can get access to auth module configuration as a remote configuration zone_name (bundy.dns.Name): the zone name to be possibly reloaded zone_class (bundy.dns.RRClass): the RR class of the zone to be possibly reloaded. Return: a CC command message for the reload. ''' # Note: this function was originally a dedicated subroutine of xfrin, # but was moved here so it can be shared by some other modules # (specifically, by ddns). It's expected that we'll soon fundamentally # revisit the whole data source related configuration, at which point # this function should be substantially modified if not completely # deprecated (which is a more likely scenario). For this reason, the # corresponding tests were still kept in xfrin. # Note: The function got very simplified by #1976. There's plan to move # to notification-driven approach, at which point the function would # be changed a lot. return create_command(AUTH_LOADZONE_COMMAND, auth_loadzone_params(zone_name, zone_class))
def _send_module_spec_to_cmdctl(self, module_name, spec): """Sends the given module spec for the given module name to Cmdctl. Parameters: module_name: A string with the name of the module spec: dict containing full module specification, as returned by ModuleSpec.get_full_spec(). This argument may also be None, in which case it signals Cmdctl to remove said module from its list. No response from Cmdctl is expected.""" spec_update = ccsession.create_command(ccsession.COMMAND_MODULE_SPECIFICATION_UPDATE, [ module_name, spec ]) self.cc.group_sendmsg(spec_update, "Cmdctl")
def _send_module_spec_to_cmdctl(self, module_name, spec): """Sends the given module spec for the given module name to Cmdctl. Parameters: module_name: A string with the name of the module spec: dict containing full module specification, as returned by ModuleSpec.get_full_spec(). This argument may also be None, in which case it signals Cmdctl to remove said module from its list. No response from Cmdctl is expected.""" spec_update = ccsession.create_command( ccsession.COMMAND_MODULE_SPECIFICATION_UPDATE, [module_name, spec]) self.cc.group_sendmsg(spec_update, "Cmdctl")
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 bundy.cc.SessionTimeout: answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name) except bundy.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, new_conf): # Reject attempts of overridding system reserved items. reserved_items = [ item for item in new_conf.keys() if item and item[0] == '_' ] if reserved_items: return ccsession.create_answer( 1, 'system reserved items cannot be set manually: ' + ' '.join(reserved_items)) # 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, new_conf) use_part = conf_part else: conf_part = data.set(self.config.data, module_name, {}) data.merge(conf_part[module_name], new_conf) use_part = conf_part[module_name] # set/increment the generation ID of the module config old_genid = use_part.get('_generation_id') use_part['_generation_id'] = 1 if old_genid is None else old_genid + 1 # 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 bundy.cc.SessionTimeout: answer = ccsession.create_answer( 1, "Timeout waiting for answer from " + module_name) except bundy.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