[svn] commit: r3643 - in /branches/trac405/src: bin/auth/auth.spec.pre.in bin/bindctl/bindcmd.py bin/bindctl/bindctl-source.py.in lib/python/isc/cc/data.py lib/python/isc/cc/tests/data_test.py lib/python/isc/config/config_data.py
BIND 10 source code commits
bind10-changes at lists.isc.org
Sun Nov 28 21:36:22 UTC 2010
Author: jelte
Date: Sun Nov 28 21:36:22 2010
New Revision: 3643
Log:
'checkpoint' commit, can address individual list items, not set them yet, need a bit of refactoring first
Modified:
branches/trac405/src/bin/auth/auth.spec.pre.in
branches/trac405/src/bin/bindctl/bindcmd.py
branches/trac405/src/bin/bindctl/bindctl-source.py.in
branches/trac405/src/lib/python/isc/cc/data.py
branches/trac405/src/lib/python/isc/cc/tests/data_test.py
branches/trac405/src/lib/python/isc/config/config_data.py
Modified: branches/trac405/src/bin/auth/auth.spec.pre.in
==============================================================================
--- branches/trac405/src/bin/auth/auth.spec.pre.in (original)
+++ branches/trac405/src/bin/auth/auth.spec.pre.in Sun Nov 28 21:36:22 2010
@@ -7,6 +7,17 @@
"item_type": "string",
"item_optional": true,
"item_default": "@@LOCALSTATEDIR@@/@PACKAGE@/zone.sqlite3"
+ },
+ { "item_name": "simple_list_int",
+ "item_type": "list",
+ "item_optional": true,
+ "item_default": [ 1, 2, 3],
+ "list_item_spec":
+ { "item_name": "int_element",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 0
+ }
}
],
"commands": [
Modified: branches/trac405/src/bin/bindctl/bindcmd.py
==============================================================================
--- branches/trac405/src/bin/bindctl/bindcmd.py (original)
+++ branches/trac405/src/bin/bindctl/bindcmd.py Sun Nov 28 21:36:22 2010
@@ -553,6 +553,9 @@
if cmd.command == "show":
values = self.config_data.get_value_maps(identifier)
+ print("[XX] VALUE MAPS:")
+ print(str(values))
+ print("[XX] END VALUE MAPS")
for value_map in values:
line = value_map['name']
if value_map['type'] in [ 'module', 'map', 'list' ]:
@@ -593,8 +596,8 @@
self.go(identifier)
except isc.cc.data.DataTypeError as dte:
print("Error: " + str(dte))
- except isc.cc.data.DataNotFoundError as dnfe:
- print("Error: " + identifier + " not found")
+ #except isc.cc.data.DataNotFoundError as dnfe:
+ # print("Error: " + identifier + " not found")
except KeyError as ke:
print("Error: missing " + str(ke))
raise ke
Modified: branches/trac405/src/bin/bindctl/bindctl-source.py.in
==============================================================================
--- branches/trac405/src/bin/bindctl/bindctl-source.py.in (original)
+++ branches/trac405/src/bin/bindctl/bindctl-source.py.in Sun Nov 28 21:36:22 2010
@@ -112,7 +112,7 @@
help = 'PEM formatted server certificate validation chain file')
if __name__ == '__main__':
- try:
+ #try:
parser = OptionParser(version = __version__)
set_bindctl_options(parser)
(options, args) = parser.parse_args()
@@ -120,7 +120,7 @@
tool = BindCmdInterpreter(server_addr, pem_file=options.cert_chain)
prepare_config_commands(tool)
tool.run()
- except Exception as e:
- print(e, "\nFailed to connect with b10-cmdctl module, is it running?")
+ #except Exception as e:
+ # print(e, "\nFailed to connect with b10-cmdctl module, is it running?")
Modified: branches/trac405/src/lib/python/isc/cc/data.py
==============================================================================
--- branches/trac405/src/lib/python/isc/cc/data.py (original)
+++ branches/trac405/src/lib/python/isc/cc/data.py Sun Nov 28 21:36:22 2010
@@ -63,15 +63,40 @@
return id_parts
def _find_child_el(element, id):
+ """Finds the child of element with the given id. If the id contains
+ [i], where i is a number, and the child element is a list, the
+ i-th element of that list is returned instead of the list itself.
+ Raises a DataTypeError if the element is of wrong type, if id
+ is not a string, or if the id string contains a bad value.
+ Raises a DataNotFoundError if the element at id could not be
+ found.
+ """
+ i = id.find('[')
+ e = id.find(']')
+ list_index = None
+ if i >= 0 and e > i + 1:
+ try:
+ list_index = int(id[i + 1:e])
+ except ValueError as ve:
+ # repack as datatypeerror
+ raise DataTypeError(ve)
+ id = id[:i]
if type(element) == dict and id in element.keys():
- return element[id]
+ result = element[id]
else:
raise DataNotFoundError(id + " in " + str(element))
+ if type(result) == list and list_index is not None:
+ print("[XX] GETTING ELEMENT NUMBER " + str(list_index) + " (of " + str(len(result)) + ")")
+ if list_index >= len(result):
+ print("[XX] OUT OF RANGE")
+ raise DataNotFoundError("Element " + str(list_index) + " in " + str(result))
+ result = result[list_index]
+ return result
def find(element, identifier):
"""Returns the subelement in the given data element, raises DataNotFoundError if not found"""
if (type(element) != dict and identifier != ""):
- raise DataTypeError("element in merge() is not a dict")
+ raise DataTypeError("element in find() is not a dict")
id_parts = _split_identifier(identifier)
cur_el = element
for id in id_parts:
@@ -88,12 +113,17 @@
el.set().set().set() is possible)"""
if type(element) != dict:
raise DataTypeError("element in set() is not a dict")
+ print("[XX] full identifier: " + identifier)
id_parts = _split_identifier(identifier)
cur_el = element
+ print("[XX] Full element:")
+ print(element)
for id in id_parts[:-1]:
try:
+ print("[XX] find " + id)
cur_el = _find_child_el(cur_el, id)
except DataNotFoundError:
+ print("[XX] DNF for " + id)
if value is None:
# ok we are unsetting a value that wasn't set in
# the first place. Simply stop.
@@ -102,6 +132,7 @@
cur_el = cur_el[id]
# value can be an empty list or dict, so check for None eplicitely
+ print("[XX] Current value: " + str(cur_el))
if value is not None:
cur_el[id_parts[-1]] = value
elif id_parts[-1] in cur_el:
Modified: branches/trac405/src/lib/python/isc/cc/tests/data_test.py
==============================================================================
--- branches/trac405/src/lib/python/isc/cc/tests/data_test.py (original)
+++ branches/trac405/src/lib/python/isc/cc/tests/data_test.py Sun Nov 28 21:36:22 2010
@@ -95,6 +95,17 @@
self.assertRaises(data.DataTypeError, data.find, None, 1)
self.assertRaises(data.DataTypeError, data.find, "123", "123")
self.assertEqual(data.find("123", ""), "123")
+
+ d2 = { 'a': [ 1, 2, 3 ] }
+ self.assertEqual(data.find(d2, 'a[0]'), 1)
+ self.assertEqual(data.find(d2, 'a[1]'), 2)
+ self.assertEqual(data.find(d2, 'a[2]'), 3)
+ self.assertRaises(data.DataNotFoundError, data.find, d2, 'a[3]')
+ self.assertRaises(data.DataTypeError, data.find, d2, 'a[a]')
+
+ d3 = { 'a': [ { 'b': [ {}, { 'c': 'd' } ] } ] }
+ self.assertEqual(data.find(d3, 'a[0]/b[1]/c'), 'd')
+ self.assertRaises(data.DataNotFoundError, data.find, d3, 'a[1]/b[1]/c')
def test_set(self):
d1 = { 'a': 'a', 'b': 1, 'c': { 'd': 'd', 'e': 2 } }
Modified: branches/trac405/src/lib/python/isc/config/config_data.py
==============================================================================
--- branches/trac405/src/lib/python/isc/config/config_data.py (original)
+++ branches/trac405/src/lib/python/isc/config/config_data.py Sun Nov 28 21:36:22 2010
@@ -109,6 +109,12 @@
id_parts[:] = (value for value in id_parts if value != "")
cur_el = element
for id in id_parts:
+ # strip list selector part
+ # don't need it for the spec part, so just drop it
+ i = id.find('[')
+ e = id.find(']')
+ if i >= 0 and e > i + 1:
+ id = id[:i]
if type(cur_el) == dict and 'map_item_spec' in cur_el.keys():
found = False
for cur_el_item in cur_el['map_item_spec']:
@@ -121,12 +127,20 @@
found = False
for cur_el_item in cur_el:
if cur_el_item['item_name'] == id:
+ #print("[XX] full list item:")
+ #print(cur_el_item)
+ #if 'list_item_spec' in cur_el_item:
+ # cur_el = cur_el_item['list_item_spec']
+ #else:
cur_el = cur_el_item
found = True
if not found:
raise isc.cc.data.DataNotFoundError(id + " in " + str(cur_el))
else:
raise isc.cc.data.DataNotFoundError("Not a correct config specification")
+ print("[XX] Returning: ")
+ print(cur_el)
+ print("[XX] end")
return cur_el
def spec_name_list(spec, prefix="", recurse=False):
@@ -336,28 +350,47 @@
try:
spec = find_spec_part(self._specifications[module].get_config_spec(), id)
if 'item_default' in spec:
- return spec['item_default']
+ i = id.find('[')
+ e = id.find(']')
+ if i >= 0 and e > i + 1 \
+ and type(spec['item_default']) == list:
+ default_list = spec['item_default']
+ index = int(id[i + 1:e])
+ if index < len(default_list):
+ return default_list[index]
+ else:
+ return None
+ else:
+ return spec['item_default']
else:
return None
except isc.cc.data.DataNotFoundError as dnfe:
return None
- def get_value(self, identifier):
+ def get_value(self, identifier, default = True):
"""Returns a tuple containing value,status.
The value contains the configuration value for the given
identifier. The status reports where this value came from;
it is one of: LOCAL, CURRENT, DEFAULT or NONE, corresponding
(local change, current setting, default as specified by the
- specification, or not found at all)."""
+ specification, or not found at all). Does not check and
+ set DEFAULT if the argument 'default' is False (default
+ defaults to True)"""
value = self.get_local_value(identifier)
+ print("[XX] mcd get_value() for: " + identifier)
+ print("[XX] mcd get_value() local: " + str(value))
if value != None:
return value, self.LOCAL
value = self.get_current_value(identifier)
+ print("[XX] mcd get_value() current: " + str(value))
if value != None:
return value, self.CURRENT
- value = self.get_default_value(identifier)
- if value != None:
- return value, self.DEFAULT
+ if default:
+ value = self.get_default_value(identifier)
+ print("[XX] mcd get_value() default: " + str(value))
+ if value != None:
+ return value, self.DEFAULT
+ print("[XX] mcd get_value() nothing found")
return None, self.NONE
def get_value_maps(self, identifier = None):
@@ -393,6 +426,7 @@
entry = {}
entry['name'] = item['item_name']
entry['type'] = item['item_type']
+ print("[XX] GET VALUE FOR: " + str("/" + identifier + "/" + item['item_name']))
value, status = self.get_value("/" + identifier + "/" + item['item_name'])
entry['value'] = value
if status == self.LOCAL:
@@ -408,32 +442,53 @@
item = spec_part
if item['item_type'] == 'list':
li_spec = item['list_item_spec']
- item_list, status = self.get_value("/" + identifier)
- if item_list != None:
- for value in item_list:
+ print("[XX] GET VALUE FOR: " + str("/" + identifier))
+ value, status = self.get_value("/" + identifier)
+ print("[XX] ITEM_LIST: " + str(value))
+ if type(value) == list:
+ for list_value in value:
result_part2 = {}
result_part2['name'] = li_spec['item_name']
- result_part2['value'] = value
+ result_part2['value'] = list_value
result_part2['type'] = li_spec['item_type']
result_part2['default'] = False
result_part2['modified'] = False
result.append(result_part2)
+ elif value is not None:
+ entry = {}
+ entry['name'] = li_spec['item_name']
+ entry['type'] = li_spec['item_type']
+ entry['value'] = value
+ if status == self.LOCAL:
+ entry['modified'] = True
+ else:
+ entry['modified'] = False
+ if status == self.DEFAULT:
+ entry['default'] = False
+ else:
+ entry['default'] = False
+ result.append(entry)
else:
- entry = {}
- entry['name'] = item['item_name']
- entry['type'] = item['item_type']
#value, status = self.get_value("/" + identifier + "/" + item['item_name'])
- value, status = self.get_value("/" + identifier)
- entry['value'] = value
- if status == self.LOCAL:
- entry['modified'] = True
- else:
- entry['modified'] = False
- if status == self.DEFAULT:
- entry['default'] = False
- else:
- entry['default'] = False
- result.append(entry)
+ print("[XX] GET VALUE FOR: " + str("/" + identifier))
+ # The type of the config data is a list,
+ # so we do not want to have a default if it's
+ # out of range
+ value, status = self.get_value("/" + identifier, False)
+ if value is not None:
+ entry = {}
+ entry['name'] = item['item_name']
+ entry['type'] = item['item_type']
+ entry['value'] = value
+ if status == self.LOCAL:
+ entry['modified'] = True
+ else:
+ entry['modified'] = False
+ if status == self.DEFAULT:
+ entry['default'] = False
+ else:
+ entry['default'] = False
+ result.append(entry)
return result
def set_value(self, identifier, value):
@@ -441,8 +496,15 @@
there is a specification for the given identifier, the type
is checked."""
spec_part = self.find_spec_part(identifier)
+ print("[XX] SPEC PART FOR " + identifier + ": ")
+ print(spec_part)
if spec_part != None:
+ i = identifier.find('[')
+ e = identifier.find(']')
+ if i >= 0 and e > i and spec_part['item_type'] == 'list':
+ spec_part = spec_part['list_item_spec']
check_type(spec_part, value)
+ # TODO: get the local list to value
isc.cc.data.set(self._local_changes, identifier, value)
def get_config_item_list(self, identifier = None, recurse = False):
More information about the bind10-changes
mailing list