Commit 0adcc4ff authored by Likun Zhang's avatar Likun Zhang
Browse files

1. Check if module name and command name exist according module's...

1. Check if module name and command name exist according module's specification file before send it to the specified module. Parameter check need to be added later.
2. Let cmdctl return the command result to bindctl.

git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@992 e5f2f494-b856-4b98-b285-d166d9295462
parent 7a848289
......@@ -191,12 +191,18 @@ class SecureHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
except:
pass
reply = self.server.send_command_to_module(mod, cmd, param)
rcode, reply = self.server.send_command_to_module(mod, cmd, param)
print('b10-cmdctl finish send message \'%s\' to module %s' % (cmd, mod))
# TODO, need set proper rcode
return http.client.OK, reply
ret = http.client.OK
if rcode != 0:
ret = http.client.BAD_REQUEST
return ret, reply
def log_request(self, code='-', size='-'):
'''Rewrite the log request function, log nothing.'''
pass
class CommandControl():
'''Get all modules' config data/specification from configmanager.
receive command from client and resend it to proper module.
......@@ -210,12 +216,20 @@ class CommandControl():
self.config_spec = self.get_data_specification()
self.config_data = self.get_config_data()
def _parse_command_result(self, rcode, reply):
'''Ignore the error reason when command rcode isn't 0, '''
if rcode != 0:
return {}
return reply
def get_cmd_specification(self):
return self.send_command('ConfigManager', isc.config.ccsession.COMMAND_GET_COMMANDS_SPEC)
rcode, reply = self.send_command('ConfigManager', isc.config.ccsession.COMMAND_GET_COMMANDS_SPEC)
return self._parse_command_result(rcode, reply)
def get_config_data(self):
'''Get config data for all modules from configmanager '''
return self.send_command('ConfigManager', isc.config.ccsession.COMMAND_GET_CONFIG)
rcode, reply = self.send_command('ConfigManager', isc.config.ccsession.COMMAND_GET_CONFIG)
return self._parse_command_result(rcode, reply)
def update_config_data(self, module_name, command_name):
'''Get lastest config data for all modules from configmanager '''
......@@ -223,7 +237,8 @@ class CommandControl():
self.config_data = self.get_config_data()
def get_data_specification(self):
return self.send_command('ConfigManager', isc.config.ccsession.COMMAND_GET_MODULE_SPEC)
rcode, reply = self.send_command('ConfigManager', isc.config.ccsession.COMMAND_GET_MODULE_SPEC)
return self._parse_command_result(rcode, reply)
def handle_recv_msg(self):
'''Handle received message, if 'shutdown' is received, return False'''
......@@ -241,9 +256,35 @@ class CommandControl():
return True
def send_command_with_check(self, module_name, command_name, params = None):
'''Before send the command to modules, check if module_name, command_name
parameters are legal according the spec file of the module.
Return rcode, dict.
rcode = 0: dict is the correct returned value.
rcode > 0: dict is : { 'error' : 'error reason' }
TODO. add check for parameters.
'''
if module_name not in self.command_spec.keys():
return 1, {'error' : 'unknown module'}
cmd_valid = False
commands = self.command_spec[module_name]
for cmd in commands:
if cmd['command_name'] == command_name:
cmd_valid = True
break
if not cmd_valid:
return 1, {'error' : 'unknown command'}
return self.send_command(module_name, command_name, params)
def send_command(self, module_name, command_name, params = None):
'''Send the command from bindctl to proper module. '''
reply = {}
errstr = 'no error'
print('b10-cmdctl send command \'%s\' to %s' %(command_name, module_name))
try:
msg = isc.config.ccsession.create_command(command_name, params)
......@@ -256,18 +297,20 @@ class CommandControl():
if rcode == 0:
self.update_config_data(module_name, command_name)
if arg != None:
return arg
return rcode, arg
else:
return rcode, {}
else:
# todo: exception
print("Error: " + str(answer['result'][1]))
return {}
errstr = str(answer['result'][1])
except isc.config.ccsession.ModuleCCSessionError as mcse:
print("Error in ccsession answer: %s" % str(mcse))
errstr = str("Error in ccsession answer:") + str(mcse)
print(answer)
except Exception as e:
errstr = str(e)
print(e, ':b10-cmdctl fail send command \'%s\' to %s' % (command_name, module_name))
return reply
return 1, {'error': errstr}
class SecureHTTPServer(http.server.HTTPServer):
......@@ -354,7 +397,7 @@ class SecureHTTPServer(http.server.HTTPServer):
def send_command_to_module(self, module_name, command_name, params):
return self.cmdctrl.send_command(module_name, command_name, params)
return self.cmdctrl.send_command_with_check(module_name, command_name, params)
httpd = None
......
......@@ -48,14 +48,14 @@ class MySecureHTTPServer(SecureHTTPServer):
self.idle_timeout = 1200
self.cmdctrl = MyCommandControl()
class MyCommandControl():
class MyCommandControl(CommandControl):
def __init__(self):
self.command_spec = []
self.config_spec = []
self.config_data = []
self.command_spec = {}
self.config_spec = {}
self.config_data = {}
def send_command(self, mod, cmd, param):
pass
return 0, {}
class TestSecureHTTPRequestHandler(unittest.TestCase):
......@@ -226,7 +226,7 @@ class TestSecureHTTPRequestHandler(unittest.TestCase):
self.handler.path = '/cfgmgr/revert'
self.handler.headers = {}
rcode, reply = self.handler._handle_post_request()
self.assertEqual(http.client.OK, rcode)
self.assertEqual(http.client.BAD_REQUEST, rcode)
def test_handle_post_request_1(self):
self.handler.path = '/*d/revert'
......@@ -243,7 +243,9 @@ class TestSecureHTTPRequestHandler(unittest.TestCase):
self.handler.rfile.close()
os.remove('check.tmp')
self.handler.path = '/d/revert'
self.handler.path = '/module/command'
self.handler.server.cmdctrl.command_spec = {}
self.handler.server.cmdctrl.command_spec['module'] = [{'command_name':'command'}, {'command_name': ['data1']} ]
rcode, reply = self.handler._handle_post_request()
self.assertEqual(http.client.OK, rcode)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment