mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-10-09 13:46:20 +00:00
1. Change bindctl's code according the suggestion in trac220.
Command parser only do minimal check. now parameter value can be a sequence of non-space characters, or a string surrounded by quotation marks(these marks can be a part of the value string in escaped form) Make error message be more friendly.(if there is some error in parameter's value, the parameter name will be provided) 2. Refactor function login_to_cmdctl() in class BindCmdInterpreter. Avoid using Exception to catch all exceptions. git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac220@2108 e5f2f494-b856-4b98-b285-d166d9295462
This commit is contained in:
@@ -49,6 +49,12 @@ try:
|
||||
except ImportError:
|
||||
my_readline = sys.stdin.readline
|
||||
|
||||
CSV_FILE_DIR = None
|
||||
if ('HOME' in os.environ):
|
||||
CSV_FILE_DIR = os.environ['HOME']
|
||||
CSV_FILE_DIR += os.sep + '.bind10' + os.sep
|
||||
CSV_FILE_NAME = 'default_user.csv'
|
||||
FAIL_TO_CONNEC_WITH_CMDCTL = "Fail to connect with b10-cmdctl module, is it running?"
|
||||
CONFIG_MODULE_NAME = 'config'
|
||||
CONST_BINDCTL_HELP = """
|
||||
usage: <module name> <command name> [param1 = value1 [, param2 = value2]]
|
||||
@@ -96,14 +102,64 @@ class BindCmdInterpreter(Cmd):
|
||||
'''Parse commands inputted from user and send them to cmdctl. '''
|
||||
try:
|
||||
if not self.login_to_cmdctl():
|
||||
return False
|
||||
return
|
||||
|
||||
# Get all module information from cmd-ctrld
|
||||
self.config_data = isc.config.UIModuleCCSession(self)
|
||||
self._update_commands()
|
||||
self.cmdloop()
|
||||
except FailToLogin as err:
|
||||
print(err)
|
||||
print(FAIL_TO_CONNEC_WITH_CMDCTL)
|
||||
except KeyboardInterrupt:
|
||||
return True
|
||||
print('\nExit from bindctl')
|
||||
|
||||
def _get_saved_user_info(self, dir, file_name):
|
||||
''' Read all the available username and password pairs saved in
|
||||
file(path is "dir + file_name"), Return value is one list of elements
|
||||
['name', 'password'], If get information failed, empty list will be
|
||||
returned.'''
|
||||
csvfile = None
|
||||
try:
|
||||
if (not dir) or (not os.path.exists(dir)):
|
||||
return []
|
||||
|
||||
csvfile = open(dir + file_name)
|
||||
users_info = csv.reader(csvfile)
|
||||
users = []
|
||||
for row in users_info:
|
||||
users.append([row[0], row[1]])
|
||||
|
||||
return users
|
||||
except (IOError, IndexError) as e:
|
||||
pass
|
||||
finally:
|
||||
if csvfile:
|
||||
csvfile.close()
|
||||
return []
|
||||
|
||||
def _save_user_info(self, username, passwd, dir, file_name):
|
||||
''' Save username and password in file "dir + file_name"
|
||||
If it's saved properly, return True, or else return False. '''
|
||||
try:
|
||||
if dir:
|
||||
if not os.path.exists(dir):
|
||||
os.mkdir(dir, 0o700)
|
||||
else:
|
||||
print("Cannot determine location of $HOME. Not storing default user")
|
||||
return False
|
||||
csvfilepath = dir + file_name
|
||||
csvfile = open(csvfilepath, 'w')
|
||||
os.chmod(csvfilepath, 0o600)
|
||||
writer = csv.writer(csvfile)
|
||||
writer.writerow([username, passwd])
|
||||
csvfile.close()
|
||||
except Exception as e:
|
||||
# just not store it
|
||||
print(e, "\nCannot write ~/.bind10/default_user.csv; default user is not stored")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def login_to_cmdctl(self):
|
||||
'''Login to cmdctl with the username and password inputted
|
||||
@@ -112,33 +168,18 @@ class BindCmdInterpreter(Cmd):
|
||||
time, username and password saved in 'default_user.csv' will be
|
||||
used first.
|
||||
'''
|
||||
csvfile = None
|
||||
bsuccess = False
|
||||
try:
|
||||
cvsfilepath = ""
|
||||
if ('HOME' in os.environ):
|
||||
cvsfilepath = os.environ['HOME']
|
||||
cvsfilepath += os.sep + '.bind10' + os.sep
|
||||
cvsfilepath += 'default_user.csv'
|
||||
csvfile = open(cvsfilepath)
|
||||
users = csv.reader(csvfile)
|
||||
for row in users:
|
||||
param = {'username': row[0], 'password' : row[1]}
|
||||
users = self._get_saved_user_info(CSV_FILE_DIR, CSV_FILE_NAME)
|
||||
for row in users:
|
||||
param = {'username': row[0], 'password' : row[1]}
|
||||
try:
|
||||
response = self.send_POST('/login', param)
|
||||
data = response.read().decode()
|
||||
if response.status == http.client.OK:
|
||||
print(data + ' login as ' + row[0] )
|
||||
bsuccess = True
|
||||
break
|
||||
except IOError as e:
|
||||
pass
|
||||
except Exception as e:
|
||||
print(e)
|
||||
finally:
|
||||
if csvfile:
|
||||
csvfile.close()
|
||||
if bsuccess:
|
||||
return True
|
||||
except socket.error:
|
||||
raise FailToLogin()
|
||||
|
||||
if response.status == http.client.OK:
|
||||
print(data + ' login as ' + row[0] )
|
||||
return True
|
||||
|
||||
count = 0
|
||||
print("[TEMP MESSAGE]: username :root password :bind10")
|
||||
@@ -151,33 +192,16 @@ class BindCmdInterpreter(Cmd):
|
||||
username = input("Username:")
|
||||
passwd = getpass.getpass()
|
||||
param = {'username': username, 'password' : passwd}
|
||||
response = self.send_POST('/login', param)
|
||||
data = response.read().decode()
|
||||
print(data)
|
||||
|
||||
if response.status == http.client.OK:
|
||||
cvsfilepath = ""
|
||||
try:
|
||||
if ('HOME' in os.environ):
|
||||
cvsfilepath = os.environ['HOME']
|
||||
cvsfilepath += os.sep + '.bind10' + os.sep
|
||||
if not os.path.exists(cvsfilepath):
|
||||
os.mkdir(cvsfilepath, 0o700)
|
||||
else:
|
||||
print("Cannot determine location of $HOME. Not storing default user")
|
||||
return True
|
||||
cvsfilepath += 'default_user.csv'
|
||||
csvfile = open(cvsfilepath, 'w')
|
||||
os.chmod(cvsfilepath, 0o600)
|
||||
writer = csv.writer(csvfile)
|
||||
writer.writerow([username, passwd])
|
||||
csvfile.close()
|
||||
except Exception as e:
|
||||
# just not store it
|
||||
print("Cannot write ~/.bind10/default_user.csv; default user is not stored")
|
||||
print(e)
|
||||
return True
|
||||
try:
|
||||
response = self.send_POST('/login', param)
|
||||
data = response.read().decode()
|
||||
print(data)
|
||||
except socket.error as e:
|
||||
raise FailToLogin()
|
||||
|
||||
if response.status == http.client.OK:
|
||||
self._save_user_info(username, passwd, CSV_FILE_DIR, CSV_FILE_NAME)
|
||||
return True
|
||||
|
||||
def _update_commands(self):
|
||||
'''Update the commands of all modules. '''
|
||||
@@ -308,8 +332,11 @@ class BindCmdInterpreter(Cmd):
|
||||
if cmd.module != CONFIG_MODULE_NAME:
|
||||
for param_name in cmd.params:
|
||||
param_spec = command_info.get_param_with_name(param_name).param_spec
|
||||
cmd.params[param_name] = isc.config.config_data.convert_type(param_spec, cmd.params[param_name])
|
||||
|
||||
try:
|
||||
cmd.params[param_name] = isc.config.config_data.convert_type(param_spec, cmd.params[param_name])
|
||||
except isc.cc.data.DataTypeError as e:
|
||||
raise isc.cc.data.DataTypeError('Invalid parameter value for \"%s\", the type should be \"%s\" \n'
|
||||
% (param_name, param_spec['item_type']) + str(e))
|
||||
|
||||
def _handle_cmd(self, cmd):
|
||||
'''Handle a command entered by the user'''
|
||||
@@ -441,13 +468,14 @@ class BindCmdInterpreter(Cmd):
|
||||
cmd = BindCmdParse(line)
|
||||
self._validate_cmd(cmd)
|
||||
self._handle_cmd(cmd)
|
||||
except BindCtlException as e:
|
||||
print("Error! ", e)
|
||||
self._print_correct_usage(e)
|
||||
except isc.cc.data.DataTypeError as e:
|
||||
print("Error! ", e)
|
||||
self._print_correct_usage(e)
|
||||
|
||||
except (IOError, http.client.HTTPException) as err:
|
||||
print('Error!', err)
|
||||
print(FAIL_TO_CONNEC_WITH_CMDCTL)
|
||||
except BindCtlException as err:
|
||||
print("Error! ", err)
|
||||
self._print_correct_usage(err)
|
||||
except isc.cc.data.DataTypeError as err:
|
||||
print("Error! ", err)
|
||||
|
||||
def _print_correct_usage(self, ept):
|
||||
if isinstance(ept, CmdUnknownModuleSyntaxError):
|
||||
@@ -556,7 +584,7 @@ class BindCmdInterpreter(Cmd):
|
||||
if (len(cmd.params) != 0):
|
||||
cmd_params = json.dumps(cmd.params)
|
||||
|
||||
print("send the message to cmd-ctrld")
|
||||
print("send the command to cmd-ctrld")
|
||||
reply = self.send_POST(url, cmd.params)
|
||||
data = reply.read().decode()
|
||||
print("received reply:", data)
|
||||
|
Reference in New Issue
Block a user