[svn] commit: r494 - in /branches/parkinglot: configure.ac src/lib/bind-cfgd/python/bind-cfgd.py src/lib/bindctl/bindctl.py src/lib/bindctl/command.py src/lib/cc/python/ISC/CC/data.py
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Jan 21 09:08:33 UTC 2010
Author: zhanglikun
Date: Thu Jan 21 09:08:32 2010
New Revision: 494
Log:
Change the code to support new module 'cmd-ctrld'.
When bindctl starts up, it needs login into cmd-ctrld. The communication between bindctl and cmd-ctrld is protected by SSL.
Modified:
branches/parkinglot/configure.ac
branches/parkinglot/src/lib/bind-cfgd/python/bind-cfgd.py
branches/parkinglot/src/lib/bindctl/bindctl.py
branches/parkinglot/src/lib/bindctl/command.py
branches/parkinglot/src/lib/cc/python/ISC/CC/data.py
Modified: branches/parkinglot/configure.ac
==============================================================================
--- branches/parkinglot/configure.ac (original)
+++ branches/parkinglot/configure.ac Thu Jan 21 09:08:32 2010
@@ -114,6 +114,7 @@
src/Makefile
src/bin/Makefile
src/bin/bind10/Makefile
+ src/bin/cmd-ctrld/Makefile
src/bin/bindctl/Makefile
src/bin/host/Makefile
src/bin/msgq/Makefile
@@ -124,6 +125,7 @@
src/lib/dns/Makefile
])
AC_OUTPUT([src/bin/bind-cfgd/bind-cfgd
+ src/bin/cmd-ctrld/cmd-ctrld
src/bin/bind10/bind10
src/bin/bind10/bind10_test
src/bin/bindctl/run_bindctl
@@ -132,6 +134,7 @@
src/bin/parkinglot/config.h
], [
chmod +x src/bin/bind-cfgd/bind-cfgd
+ chmod +x src/bin/cmd-ctrld/cmd-ctrld
chmod +x src/bin/bind10/bind10
chmod +x src/bin/bindctl/run_bindctl
chmod +x src/bin/msgq/msgq
Modified: branches/parkinglot/src/lib/bind-cfgd/python/bind-cfgd.py
==============================================================================
--- branches/parkinglot/src/lib/bind-cfgd/python/bind-cfgd.py (original)
+++ branches/parkinglot/src/lib/bind-cfgd/python/bind-cfgd.py Thu Jan 21 09:08:32 2010
@@ -93,11 +93,12 @@
if cmd[0] == "get_commands":
answer["result"] = [ 0, self.commands ]
elif cmd[0] == "get_data_spec":
- if len(cmd) > 1 and cmd[1] != "":
+ if len(cmd) > 1 and cmd[1]['module_name'] != '':
+ module_name = cmd[1]['module_name']
try:
- answer["result"] = [0, self.data_definitions[cmd[1]]]
+ answer["result"] = [0, self.data_definitions[module_name]]
except KeyError as ke:
- answer["result"] = [1, "No specification for module " + cmd[1]]
+ answer["result"] = [1, "No specification for module " + module_name]
else:
answer["result"] = [0, self.data_definitions]
elif cmd[0] == "get_config":
@@ -105,7 +106,7 @@
conf_part = None
if len(cmd) > 1:
try:
- conf_part = data.find(self.config.data, cmd[1])
+ conf_part = data.find(self.config.data, cmd[1]['module_name'])
except data.DataNotFoundError as dnfe:
pass
else:
@@ -114,6 +115,7 @@
answer["result"] = [ 0, conf_part ]
else:
answer["result"] = [ 0 ]
+
elif cmd[0] == "set_config":
if len(cmd) == 3:
# todo: use api (and check types?)
@@ -143,20 +145,8 @@
answer["result"] = [ 0 ]
else:
answer["result"] = [ 1, "Wrong number of arguments" ]
- elif cmd[0] == "zone" and cmd[1] == "add":
- self.add_zone(cmd[2])
- answer["result"] = [ 0 ]
- elif cmd[0] == "zone" and cmd[1] == "remove":
- try:
- self.remove_zone(cmd[2])
- answer["result"] = [ 0 ]
- except KeyError:
- # zone wasn't there, should we make
- # a separate exception for that?
- answer["result"] = [ 1, "Unknown zone" ]
- elif cmd[0] == "zone" and cmd[1] == "list":
- answer["result"] = []#list(self.config.zones.keys())
- elif cmd == "shutdown":
+
+ elif cmd[0] == "shutdown":
print("[bind-cfgd] Received shutdown command")
self.running = False
else:
@@ -171,11 +161,13 @@
spec = msg["data_specification"]
if "config_data" in spec:
self.set_config(spec["module_name"], spec["config_data"])
- self.cc.group_sendmsg({ "specification_update": [ spec["module_name"], spec["config_data"] ] }, "BindCtl")
+ self.cc.group_sendmsg({ "specification_update": [ spec["module_name"], spec["config_data"] ] }, "Cmd-Ctrld")
if "commands" in spec:
self.set_commands(spec["module_name"], spec["commands"])
- self.cc.group_sendmsg({ "commands_update": [ spec["module_name"], spec["commands"] ] }, "BindCtl")
+ self.cc.group_sendmsg({ "commands_update": [ spec["module_name"], spec["commands"] ] }, "Cmd-Ctrld")
answer["result"] = [ 0 ]
+ elif 'result' in msg:
+ answer['result'] = [0]
else:
print("[bind-cfgd] unknown message: " + str(msg))
answer["result"] = [ 1, "Unknown module: " + str(msg) ]
Modified: branches/parkinglot/src/lib/bindctl/bindctl.py
==============================================================================
--- branches/parkinglot/src/lib/bindctl/bindctl.py (original)
+++ branches/parkinglot/src/lib/bindctl/bindctl.py Thu Jan 21 09:08:32 2010
@@ -7,6 +7,13 @@
from xml.dom import minidom
import ISC
import ISC.CC.data
+import http.client
+import json
+import inspect
+import pprint
+import ssl, socket
+import os, time, random, re
+from hashlib import sha1
try:
from collections import OrderedDict
@@ -27,7 +34,7 @@
class BindCtl(Cmd):
"""simple bindctl example."""
- def __init__(self, session = None):
+ def __init__(self, server_port = 'localhost:8080'):
Cmd.__init__(self)
self.location = ""
self.prompt_end = '> '
@@ -35,12 +42,104 @@
self.ruler = '-'
self.modules = OrderedDict()
self.add_module_info(ModuleInfo("help", desc = "Get help for bindctl"))
- self.cc = session
- self.config_data = ISC.CC.data.UIConfigData("", session)
+ self.server_port = server_port
+ self.connect_to_cmd_ctrld()
+ self.session_id = self._get_session_id()
+
+ def connect_to_cmd_ctrld(self):
+ try:
+ self.conn = http.client.HTTPSConnection(self.server_port, cert_file='create_your_cert.pem')
+ except Exception as e:
+ print(e)
+ print("can't connect to %s, please make sure cmd-ctrld is running" % self.server_port)
+
+ def _get_session_id(self):
+ rand = os.urandom(16)
+ now = time.time()
+ ip = socket.gethostbyname(socket.gethostname())
+ session_id = sha1(("%s%s%s" %(rand, now, ip)).encode())
+ session_id = session_id.hexdigest()
+ return session_id
+
+ def run(self):
+ count = 0
+ print("[TEMP MESSAGE]: username :root password :bind10")
+ try:
+ while count < 3:
+ count = count + 1
+ username = input("username:")
+ passwd = input("password:")
+ param = {'username': username, 'password' : passwd}
+ response = self.send_POST('/', param)
+ data = response.read().decode()
+ print(data)
+
+ if response.status == http.client.OK:
+ break
+ if count == 3:
+ print("Too many authentication failures")
+ return True
+
+ # Get all module information from cmd-ctrld
+ self.config_data = ISC.CC.data.UIConfigData(self)
+ self.update_commands()
+ self.cmdloop()
+ except KeyboardInterrupt:
+ return True
+
+
+ def update_commands(self):
+ cmd_spec = self.send_GET('/command_spec')
+ if (len(cmd_spec) == 0):
+ print('can\'t get any command specification')
+ for module_name in cmd_spec.keys():
+ self.prepare_module_commands(module_name, cmd_spec[module_name])
+
+ def send_GET(self, url, body = None):
+ headers = {"cookie" : self.session_id}
+ self.conn.request('GET', url, body, headers)
+ res = self.conn.getresponse()
+ reply_msg = res.read()
+ if reply_msg:
+ return json.loads(reply_msg.decode())
+ else:
+ return None
+
+
+ def send_POST(self, url, post_param = None):
+ '''
+ Format: /module_name/command_name
+ parameters of command is encoded as a map
+ '''
+ param = None
+ if (len(post_param) != 0):
+ param = json.dumps(post_param)
+
+ headers = {"cookie" : self.session_id}
+ self.conn.request('POST', url, param, headers)
+ return self.conn.getresponse()
+
def postcmd(self, stop, line):
self.prompt = self.location + self.prompt_end
return stop
+
+ def prepare_module_commands(self, module_name, module_commands):
+ module = ModuleInfo(name = module_name,
+ desc = "same here")
+ for command in module_commands:
+ cmd = CommandInfo(name = command["command_name"],
+ desc = command["command_description"],
+ need_inst_param = False)
+ for arg in command["command_args"]:
+ param = ParamInfo(name = arg["item_name"],
+ type = arg["item_type"],
+ optional = bool(arg["item_optional"]))
+ if ("item_default" in arg):
+ param.default = arg["item_default"]
+ cmd.add_param(param)
+ module.add_command(cmd)
+ self.add_module_info(module)
def validate_cmd(self, cmd):
if not cmd.module in self.modules:
@@ -127,13 +226,7 @@
def emptyline(self):
pass
-
- def cmdloop(self):
- try:
- Cmd.cmdloop(self)
- except KeyboardInterrupt:
- return True
-
+
def do_help(self, name):
print(CONST_BINDCTL_HELP)
for k in self.modules.keys():
@@ -141,9 +234,8 @@
def onecmd(self, line):
- # check if there's anything on the cc first
- self.check_cc_messages()
if line == 'EOF' or line.lower() == "quit":
+ self.conn.close()
return True
if line == 'h':
@@ -170,8 +262,8 @@
hints.extend([val for val in list if val.startswith(text)])
except CmdModuleNameFormatError:
if not text:
- hints = list(self.modules.keys())
-
+ hints = self.get_module_names()
+
except CmdMissCommandNameFormatError as e:
if not text.strip(): # command name is empty
hints = self.modules[e.module].get_command_names()
@@ -230,36 +322,8 @@
return hint
return []
-
- def prepare_module_commands(self, module_name, module_commands):
- module = ModuleInfo(name = module_name,
- desc = "same here")
- for command in module_commands:
- cmd = CommandInfo(name = command["command_name"],
- desc = command["command_description"],
- need_inst_param = False)
- for arg in command["command_args"]:
- param = ParamInfo(name = arg["item_name"],
- type = arg["item_type"],
- optional = bool(arg["item_optional"]))
- if ("item_default" in arg):
- param.default = arg["item_default"]
- cmd.add_param(param)
- module.add_command(cmd)
- self.add_module_info(module)
-
- def check_cc_messages(self):
- (message, env) = self.cc.group_recvmsg(True)
- while message:
- if 'commands_update' in message:
- self.prepare_module_commands(message['commands_update'][0], message['commands_update'][1])
- elif 'specification_update' in message:
- self.config_data.config.specification[message['specification_update'][0]] = message['specification_update'][1]
- (message, env) = self.cc.group_recvmsg(True)
def _parse_cmd(self, line):
- # check if there's anything on the cc first
- self.check_cc_messages()
try:
cmd = BindCtlCmd(line)
self.validate_cmd(cmd)
@@ -283,7 +347,6 @@
def _append_space_to_hint(self):
"""Append one space at the end of complete hint."""
-
self.hint = [(val + " ") for val in self.hint]
@@ -330,7 +393,7 @@
elif cmd.command == "revert":
self.config_data.revert()
elif cmd.command == "commit":
- self.config_data.commit(self.cc)
+ self.config_data.commit(self)
elif cmd.command == "go":
self.go(identifier)
except ISC.CC.data.DataTypeError as dte:
@@ -353,30 +416,16 @@
self.location = identifier
def apply_cmd(self, cmd):
- if not self.cc:
- return
-
- groupName = cmd.module
- content = [cmd.module, cmd.command]
- values = cmd.params.values()
- if len(values) > 0:
- content.append(list(values)[0])
-
- msg = {"command":content}
- print("begin to send the message...")
-
- # XXTODO: remove this with new msgq
- #self.cc.group_subscribe(groupName)
-
- try:
- self.cc.group_sendmsg(msg, groupName)
- print("waiting for %s reply..." % groupName)
-
- reply, env = self.cc.group_recvmsg(False)
- print("received reply:", reply)
- except:
- print("Error communication with %s" % groupName)
-
-
-
-
+ url = '/' + cmd.module + '/' + cmd.command
+ cmd_params = None
+ if (len(cmd.params) != 0):
+ cmd_params = json.dumps(cmd.params)
+
+ print("send the message to cmd-ctrld")
+ reply = self.send_POST(url, cmd.params)
+ data = reply.read().decode()
+ print("received reply:", data)
+
+
+
+
Modified: branches/parkinglot/src/lib/bindctl/command.py
==============================================================================
--- branches/parkinglot/src/lib/bindctl/command.py (original)
+++ branches/parkinglot/src/lib/bindctl/command.py Thu Jan 21 09:08:32 2010
@@ -6,8 +6,8 @@
from mycollections import OrderedDict
param_name_str = "^\s*(?P<param_name>[\w]+)\s*=\s*"
-param_value_str = "(?P<param_value>[\w\./]+)"
-param_value_with_quota_str = "[\"\'](?P<param_value>[\w\., /]+)[\"\']"
+param_value_str = "(?P<param_value>[\w\./-]+)"
+param_value_with_quota_str = "[\"\'](?P<param_value>[\w\., /-]+)[\"\']"
next_params_str = "(?P<blank>\s*)(?P<comma>,?)(?P<next_params>.*)$"
PARAM_WITH_QUOTA_PATTERN = re.compile(param_name_str +
Modified: branches/parkinglot/src/lib/cc/python/ISC/CC/data.py
==============================================================================
--- branches/parkinglot/src/lib/cc/python/ISC/CC/data.py (original)
+++ branches/parkinglot/src/lib/cc/python/ISC/CC/data.py Thu Jan 21 09:08:32 2010
@@ -17,7 +17,7 @@
else:
orig[kn] = new[kn]
else:
- orig.remove(kn)
+ del orig[kn]
else:
orig[kn] = new[kn]
@@ -180,63 +180,24 @@
return None, False
class UIConfigData():
- def __init__(self, name, cc):
+ def __init__(self, conn, name = ''):
self.module_name = name
- data_spec = self.get_data_specification(cc)
+ data_spec = self.get_data_specification(conn)
self.config = ConfigData(data_spec)
- self.get_config_data(cc)
+ self.get_config_data(conn)
self.config_changes = {}
- def get_config_data(self, cc):
- cc.group_sendmsg({ "command": ["get_config", self.module_name] }, "ConfigManager")
- answer, env = cc.group_recvmsg(False)
- if 'result' in answer.keys() and type(answer['result']) == list:
- # TODO: with the new cc implementation, replace "1" by 1
- if answer['result'][0] == "1":
- # todo: exception
- print("Error: " + str(answer['result'][1]))
- else:
- self.config.data = answer['result'][1]
- else:
- # XX todo: raise exc
- print("Error: unexpected answer from config manager:")
- print(answer)
-
- def send_changes(self, cc):
- """Sends the changes configuration values to the config manager.
- If the command succeeds, the changes are re-requested and
- the changed list is reset"""
- if self.module_name and self.module_name != "":
- cc.group_sendmsg({ "command": [ "set_config", self.module_name, self.config_changes ]}, "ConfigManager")
- else:
- cc.group_sendmsg({ "command": [ "set_config", self.config_changes ]}, "ConfigManager")
- answer, env = cc.group_recvmsg(False)
- if 'result' in answer and type(answer['result']) == list:
- if answer['result'][0] == 0:
- # ok
- self.get_config_data(cc)
- self.config_changes = {}
- else:
- print("Error committing changes: " + answer['result'][1])
- else:
- print("Error: unexpected answer: " + str(answer))
+ def get_config_data(self, conn):
+ self.config.data = conn.send_GET('/config_data')
+
+ def send_changes(self, conn):
+ conn.send_POST('/ConfigManager/set_config', self.config_changes)
+ # Get latest config data
+ self.get_config_data(conn)
+ self.config_changes = {}
- def get_data_specification(self, cc):
- cc.group_sendmsg({ "command": ["get_data_spec", self.module_name] }, "ConfigManager")
- answer, env = cc.group_recvmsg(False)
- if 'result' in answer.keys() and type(answer['result']) == list:
- # TODO: with the new cc implementation, replace "1" by 1
- if answer['result'][0] == "1":
- # todo: exception
- print("Error: " + str(answer['result'][1]))
- return None
- else:
- return answer['result'][1]
- else:
- # XX todo: raise exc
- print("Error: unexpected answer from config manager:")
- print(answer)
- return None
+ def get_data_specification(self, conn):
+ return conn.send_GET('/config_spec')
def set(self, identifier, value):
# check against definition
@@ -371,5 +332,5 @@
def revert(self):
self.config_changes = {}
- def commit(self, cc):
- self.send_changes(cc)
+ def commit(self, conn):
+ self.send_changes(conn)
More information about the bind10-changes
mailing list