Пример #1
0
 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))
Пример #2
0
 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))
Пример #3
0
 def __handle_get_config(self, cmd):
     """Private function that handles the 'get_config' command"""
     if cmd != None:
         if type(cmd) == dict:
             return self.__handle_get_config_dict(cmd)
         else:
             return ccsession.create_answer(1, "Bad get_config command, argument not a dict")
     else:
         return ccsession.create_answer(0, self.config.data)
Пример #4
0
 def __handle_get_config(self, cmd):
     """Private function that handles the 'get_config' command"""
     if cmd != None:
         if type(cmd) == dict:
             return self.__handle_get_config_dict(cmd)
         else:
             return ccsession.create_answer(1, "Bad get_config command, argument not a dict")
     else:
         return ccsession.create_answer(0, self.config.data)
Пример #5
0
 def __handle_get_config_dict(self, cmd):
     """Private function that handles the 'get_config' command
        where the command has been checked to be a dict"""
     if 'module_name' in cmd and cmd['module_name'] != '':
         module_name = cmd['module_name']
         try:
             return ccsession.create_answer(0, data.find(self.config.data, module_name))
         except data.DataNotFoundError as dnfe:
             # no data is ok, that means we have nothing that
             # deviates from default values
             return ccsession.create_answer(0, { 'version': config_data.BIND10_CONFIG_DATA_VERSION })
     else:
         return ccsession.create_answer(1, "Bad module_name in get_config command")
Пример #6
0
 def __handle_get_config_dict(self, cmd):
     """Private function that handles the 'get_config' command
        where the command has been checked to be a dict"""
     if 'module_name' in cmd and cmd['module_name'] != '':
         module_name = cmd['module_name']
         try:
             return ccsession.create_answer(0, data.find(self.config.data, module_name))
         except data.DataNotFoundError as dnfe:
             # no data is ok, that means we have nothing that
             # deviates from default values
             return ccsession.create_answer(0, { 'version': config_data.BIND10_CONFIG_DATA_VERSION })
     else:
         return ccsession.create_answer(1, "Bad module_name in get_config command")
Пример #7
0
    def __handle_set_config(self, cmd):
        """Private function that handles the 'set_config' command"""
        answer = None

        if cmd == None:
            return ccsession.create_answer(1, "Wrong number of arguments")
        if len(cmd) == 2:
            answer = self.__handle_set_config_module(cmd[0], cmd[1])
        elif len(cmd) == 1:
            answer = self.__handle_set_config_all(cmd[0])
        else:
            answer = ccsession.create_answer(1, "Wrong number of arguments")
        if not answer:
            answer = ccsession.create_answer(1, "No answer message from " + cmd[0])

        return answer
Пример #8
0
    def __handle_set_config(self, cmd):
        """Private function that handles the 'set_config' command"""
        answer = None

        if cmd == None:
            return ccsession.create_answer(1, "Wrong number of arguments")
        if len(cmd) == 2:
            answer = self.__handle_set_config_module(cmd[0], cmd[1])
        elif len(cmd) == 1:
            answer = self.__handle_set_config_all(cmd[0])
        else:
            answer = ccsession.create_answer(1, "Wrong number of arguments")
        if not answer:
            answer = ccsession.create_answer(1, "No answer message from " + cmd[0])

        return answer
Пример #9
0
 def __handle_module_spec(self, spec):
     """Private function that handles the 'module_spec' command"""
     # todo: validate? (no direct access to spec as
     # todo: use ModuleSpec class
     # todo: error checking (like keyerrors)
     answer = {}
     self.set_module_spec(spec)
     self._send_module_spec_to_cmdctl(spec.get_module_name(),
                                      spec.get_full_spec())
     return ccsession.create_answer(0)
Пример #10
0
 def __handle_module_spec(self, spec):
     """Private function that handles the 'module_spec' command"""
     # todo: validate? (no direct access to spec as
     # todo: use ModuleSpec class
     # todo: error checking (like keyerrors)
     answer = {}
     self.set_module_spec(spec)
     self._send_module_spec_to_cmdctl(spec.get_module_name(),
                                      spec.get_full_spec())
     return ccsession.create_answer(0)
Пример #11
0
 def __handle_get_module_spec(self, cmd):
     """Private function that handles the 'get_module_spec' command"""
     answer = {}
     if cmd != None:
         if type(cmd) == dict:
             if 'module_name' in cmd and cmd['module_name'] != '':
                 module_name = cmd['module_name']
                 spec = self.get_module_spec(cmd['module_name'])
                 if type(spec) != type({}):
                     # this is a ModuleSpec object.  Extract the
                     # internal spec.
                     spec = spec.get_full_spec()
                 answer = ccsession.create_answer(0, spec)
             else:
                 answer = ccsession.create_answer(1, "Bad module_name in get_module_spec command")
         else:
             answer = ccsession.create_answer(1, "Bad get_module_spec command, argument not a dict")
     else:
         answer = ccsession.create_answer(0, self.get_module_spec())
     return answer
Пример #12
0
 def __handle_get_module_spec(self, cmd):
     """Private function that handles the 'get_module_spec' command"""
     answer = {}
     if cmd != None:
         if type(cmd) == dict:
             if 'module_name' in cmd and cmd['module_name'] != '':
                 module_name = cmd['module_name']
                 spec = self.get_module_spec(cmd['module_name'])
                 if type(spec) != type({}):
                     # this is a ModuleSpec object.  Extract the
                     # internal spec.
                     spec = spec.get_full_spec()
                 answer = ccsession.create_answer(0, spec)
             else:
                 answer = ccsession.create_answer(1, "Bad module_name in get_module_spec command")
         else:
             answer = ccsession.create_answer(1, "Bad get_module_spec command, argument not a dict")
     else:
         answer = ccsession.create_answer(0, self.get_module_spec())
     return answer
Пример #13
0
 def handle_msg(self, msg):
     """Handle a command from the cc channel to the configuration manager"""
     answer = {}
     cmd, arg = ccsession.parse_command(msg)
     if cmd:
         if cmd == ccsession.COMMAND_GET_COMMANDS_SPEC:
             answer = ccsession.create_answer(0, self.get_commands_spec())
         elif cmd == ccsession.COMMAND_GET_STATISTICS_SPEC:
             answer = ccsession.create_answer(0, self.get_statistics_spec())
         elif cmd == ccsession.COMMAND_GET_MODULE_SPEC:
             answer = self.__handle_get_module_spec(arg)
         elif cmd == ccsession.COMMAND_GET_CONFIG:
             answer = self.__handle_get_config(arg)
         elif cmd == ccsession.COMMAND_SET_CONFIG:
             answer = self.__handle_set_config(arg)
         elif cmd == ccsession.COMMAND_MODULE_STOPPING:
             answer = self.__handle_module_stopping(arg)
         elif cmd == ccsession.COMMAND_SHUTDOWN:
             self.running = False
             answer = ccsession.create_answer(0)
         elif cmd == ccsession.COMMAND_MODULE_SPEC:
             try:
                 answer = self.__handle_module_spec(isc.config.ModuleSpec(arg))
             except isc.config.ModuleSpecError as dde:
                 answer = ccsession.create_answer(1, "Error in data definition: " + str(dde))
         else:
             answer = ccsession.create_answer(1, "Unknown command: " + str(cmd))
     else:
         answer = ccsession.create_answer(1, "Unknown message format: " + str(msg))
     return answer
Пример #14
0
 def handle_msg(self, msg):
     """Handle a command from the cc channel to the configuration manager"""
     answer = {}
     cmd, arg = ccsession.parse_command(msg)
     if cmd:
         if cmd == ccsession.COMMAND_GET_COMMANDS_SPEC:
             answer = ccsession.create_answer(0, self.get_commands_spec())
         elif cmd == ccsession.COMMAND_GET_STATISTICS_SPEC:
             answer = ccsession.create_answer(0, self.get_statistics_spec())
         elif cmd == ccsession.COMMAND_GET_MODULE_SPEC:
             answer = self.__handle_get_module_spec(arg)
         elif cmd == ccsession.COMMAND_GET_CONFIG:
             answer = self.__handle_get_config(arg)
         elif cmd == ccsession.COMMAND_SET_CONFIG:
             answer = self.__handle_set_config(arg)
         elif cmd == ccsession.COMMAND_MODULE_STOPPING:
             answer = self.__handle_module_stopping(arg)
         elif cmd == ccsession.COMMAND_SHUTDOWN:
             self.running = False
             answer = ccsession.create_answer(0)
         elif cmd == ccsession.COMMAND_MODULE_SPEC:
             try:
                 answer = self.__handle_module_spec(isc.config.ModuleSpec(arg))
             except isc.config.ModuleSpecError as dde:
                 answer = ccsession.create_answer(1, "Error in data definition: " + str(dde))
         else:
             answer = ccsession.create_answer(1, "Unknown command: " + str(cmd))
     else:
         answer = ccsession.create_answer(1, "Unknown message format: " + str(msg))
     return answer
Пример #15
0
    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
Пример #16
0
    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