[svn] commit: r1205 - in /trunk/src/lib/python/isc/config: ccsession.py cfgmgr.py unittests/ccsession_test.py

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Mar 8 16:09:44 UTC 2010


Author: jelte
Date: Mon Mar  8 16:09:43 2010
New Revision: 1205

Log:
added support for access to the configuration settings of other modules
(on the python side)

ModuleCCSession.add_remote_config(specfile) sets this up; you provide it the spec file of the module you want a setting from. Config updates will be caught so the get function below should always give you the latest error.
(there is no rollback yet, so if the other module does not accept the new value for any reason this is currently missed here)

ModuleCCSession.get_remote_config_value(module name, identifier) returns the same value,default tuple as ConfigData::get_value(identifier), but obviously for the remote module

ModuleCCSession.remove_remote_config(module_name) removes the remote config settings again.

Modified:
    trunk/src/lib/python/isc/config/ccsession.py
    trunk/src/lib/python/isc/config/cfgmgr.py
    trunk/src/lib/python/isc/config/unittests/ccsession_test.py

Modified: trunk/src/lib/python/isc/config/ccsession.py
==============================================================================
--- trunk/src/lib/python/isc/config/ccsession.py (original)
+++ trunk/src/lib/python/isc/config/ccsession.py Mon Mar  8 16:09:43 2010
@@ -148,6 +148,8 @@
             self._session = cc_session
         self._session.group_subscribe(self._module_name, "*")
 
+        self._remote_module_configs = {}
+
     def start(self):
         """Send the specification for this module to the configuration
            manager, and request the current non-default configuration.
@@ -183,6 +185,21 @@
                 cmd, arg = isc.config.ccsession.parse_command(msg)
                 if cmd == COMMAND_CONFIG_UPDATE:
                     new_config = arg
+                    module_name = env['group']
+                    # If the target channel was not this module
+                    # it might be in the remote_module_configs
+                    if module_name != self._module_name:
+                        if module_name in self._remote_module_configs:
+                            # no checking for validity, that's up to the
+                            # module itself.
+                            newc = self._remote_module_configs[module_name].get_local_config()
+                            isc.cc.data.merge(newc, new_config)
+                            self._remote_module_configs[module_name].set_local_config(newc)
+                            print("[XX] updated remote config value: ")
+                            print(newc)
+                            return
+
+                    # ok, so apparently this update is for us.
                     errors = []
                     if not self._config_handler:
                         answer = create_answer(2, self._module_name + " has no config handler")
@@ -202,7 +219,6 @@
                     else:
                         answer = create_answer(2, self._module_name + " has no command handler")
             except Exception as exc:
-                print("error! " + str(exc))
                 answer = create_answer(1, str(exc))
                 raise exc
             if answer:
@@ -220,6 +236,47 @@
            function that takes a command as defined in the .spec file
            and return an answer created with create_answer()"""
         self._command_handler = command_handler
+
+    def add_remote_config(self, spec_file_name):
+        """Gives access to the configuration of a different module.
+           These remote module options can at this moment only be
+           accessed through get_remote_config_value(). This function
+           also subscribes to the channel of the remote module name
+           to receive the relevant updates. It is not possible to
+           specify your own handler for this right now.
+           Returns the name of the module."""
+        module_spec = isc.config.module_spec_from_file(spec_file_name)
+        module_cfg = ConfigData(module_spec)
+        module_name = module_spec.get_module_name()
+        self._session.group_subscribe(module_name);
+
+        # Get the current config for that module now
+        self._session.group_sendmsg({ "command": [ "get_config", { "module_name": module_name } ] }, "ConfigManager")
+        answer, env = self._session.group_recvmsg(False)
+        if answer:
+            rcode, value = parse_answer(answer)
+            if rcode == 0:
+                if value != None and self.get_module_spec().validate_config(False, value):
+                    module_cfg.set_local_config(value);
+
+        # all done, add it
+        self._remote_module_configs[module_name] = module_cfg
+        return module_name
+        
+    def remove_remote_config(self, module_name):
+        """Removes the remote configuration access for this module"""
+        if module_name in self._remote_module_configs:
+            del self._remote_module_configs[module_name]
+
+    def get_remote_config_value(self, module_name, identifier):
+        """Returns the current setting for the given identifier at the
+           given module. If the module has not been added with
+           add_remote_config, a ModuleCCSessionError is raised"""
+        if module_name in self._remote_module_configs:
+            return self._remote_module_configs[module_name].get_value(identifier)
+        else:
+            raise ModuleCCSessionError("Remote module " + module_name +
+                                       " not found")
 
     def __send_spec(self):
         """Sends the data specification to the configuration manager"""
@@ -245,6 +302,7 @@
         else:
             raise ModuleCCSessionError("No answer from configuration manager")
 
+
 class UIModuleCCSession(MultiConfigData):
     """This class is used in a configuration user interface. It contains
        specific functions for getting, displaying, and sending

Modified: trunk/src/lib/python/isc/config/cfgmgr.py
==============================================================================
--- trunk/src/lib/python/isc/config/cfgmgr.py (original)
+++ trunk/src/lib/python/isc/config/cfgmgr.py Mon Mar  8 16:09:43 2010
@@ -316,7 +316,6 @@
         """Handle a command from the cc channel to the configuration manager"""
         answer = {}
         cmd, arg = isc.config.ccsession.parse_command(msg)
-        print("[b10-cfgmgr] got message: " + str(msg))
         if cmd:
             if cmd == isc.config.ccsession.COMMAND_GET_COMMANDS_SPEC:
                 answer = isc.config.ccsession.create_answer(0, self.get_commands_spec())

Modified: trunk/src/lib/python/isc/config/unittests/ccsession_test.py
==============================================================================
--- trunk/src/lib/python/isc/config/unittests/ccsession_test.py (original)
+++ trunk/src/lib/python/isc/config/unittests/ccsession_test.py Mon Mar  8 16:09:43 2010
@@ -343,6 +343,23 @@
         mccs.check_command()
         self.assertEqual(len(fake_session.message_queue), 0)
 
+    def test_remote_module(self):
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec1.spec", None, None, fake_session)
+        mccs.remove_remote_config("Spec2")
+
+        self.assertRaises(ModuleCCSessionError, mccs.get_remote_config_value, "Spec2", "item1")
+
+        rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
+        self.assertEqual("Spec2", rmodname)
+        self.assertRaises(isc.cc.data.DataNotFoundError, mccs.get_remote_config_value, rmodname, "asdf")
+        value, default = mccs.get_remote_config_value(rmodname, "item1")
+        self.assertEqual(1, value)
+        self.assertEqual(True, default)
+
+        mccs.remove_remote_config(rmodname)
+        self.assertRaises(ModuleCCSessionError, mccs.get_remote_config_value, "Spec2", "item1")
+    
 class fakeUIConn():
     def __init__(self):
         self.get_answers = {}




More information about the bind10-changes mailing list