BIND 10 master, updated. c73ffa69fd26e03b0879a7773f7f6796f19aee2e [master] update changelog for merge of #1843

BIND 10 source code commits bind10-changes at lists.isc.org
Wed May 2 12:41:32 UTC 2012


The branch, master has been updated
       via  c73ffa69fd26e03b0879a7773f7f6796f19aee2e (commit)
       via  551657702a4197ef302c567b5c0eaf2fded3e121 (commit)
       via  4429acb90d47320d20e9126457594a1f38191b28 (commit)
       via  9a76caecbc29f35dad73a2f9874e8e3a64e4154f (commit)
       via  3de6e881f69c6462cf3da43c662cbc1a35595504 (commit)
       via  4cfab0d82574c3501502a9ed9b84c39112d411a8 (commit)
       via  bed1681e323f5c278a4271b7c948a44b0605e73b (commit)
       via  53a7c709b06e670dacf81907a7360ea030341b1d (commit)
       via  50d20d7206fad792c4eb035a9e643f4d47518505 (commit)
       via  a6cc81d79b42baf06058c25f404b8ec61de0c2d6 (commit)
       via  a9b59f8a7728418038125bfb3ed2335bf5524b3f (commit)
       via  1c3fe6e537bf9e7bc742f84a36efbbbb49a6365d (commit)
       via  64f69a14336846132a5588f6523c3f5aadf63382 (commit)
       via  233c7295de7021fe24b8342db5d966d3d9b354e6 (commit)
      from  58757c09f3b72768da9a43f1affa7120ebbdeba8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c73ffa69fd26e03b0879a7773f7f6796f19aee2e
Author: Jelte Jansen <jelte at isc.org>
Date:   Wed May 2 14:41:13 2012 +0200

    [master] update changelog for merge of #1843

commit 551657702a4197ef302c567b5c0eaf2fded3e121
Merge: 58757c09f3b72768da9a43f1affa7120ebbdeba8 4429acb90d47320d20e9126457594a1f38191b28
Author: Jelte Jansen <jelte at isc.org>
Date:   Wed May 2 14:28:59 2012 +0200

    [master] Merge branch 'trac1843'

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                          |    7 +
 src/bin/bindctl/Makefile.am                        |    2 +-
 src/bin/bindctl/bindcmd.py                         |  106 +++++++++-
 src/bin/bindctl/bindctl_main.py.in                 |    2 +
 src/bin/bindctl/command_sets.py                    |   95 +++++++++
 src/lib/python/isc/config/config_data.py           |   12 +-
 .../python/isc/config/tests/config_data_test.py    |   13 +-
 .../bindctl.config.orig}                           |    1 -
 tests/lettuce/data/commands/bad_command            |    9 +
 tests/lettuce/data/commands/directives             |   19 ++
 AUTHORS => tests/lettuce/data/commands/empty       |    0 
 tests/lettuce/data/commands/nested                 |    2 +
 tests/lettuce/data/commands/nested1                |    2 +
 tests/lettuce/features/bindctl_commands.feature    |  213 ++++++++++++++------
 tests/lettuce/features/terrain/terrain.py          |    2 +
 15 files changed, 408 insertions(+), 77 deletions(-)
 create mode 100644 src/bin/bindctl/command_sets.py
 copy tests/lettuce/configurations/{example.org.config.orig => bindctl/bindctl.config.orig} (87%)
 create mode 100644 tests/lettuce/data/commands/bad_command
 create mode 100644 tests/lettuce/data/commands/directives
 copy AUTHORS => tests/lettuce/data/commands/empty (100%)
 create mode 100644 tests/lettuce/data/commands/nested
 create mode 100644 tests/lettuce/data/commands/nested1

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index fc74da2..a456635 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+429.	[func]		jelte
+	Added an 'execute' component to bindctl, which executes either a set
+	of commands from a file or a built-in set of commands. Currently,
+	only 'init_authoritative_server' is provided as a built-in set, but
+	it is expected that more will be added later.
+	(Trac #1843, git 551657702a4197ef302c567b5c0eaf2fded3e121)
+
 428.	[bug]		marcin
 	perfdhcp: bind to local address to allow reception of replies from IPv6
 	DHCP servers.
diff --git a/src/bin/bindctl/Makefile.am b/src/bin/bindctl/Makefile.am
index 700f26e..52a5145 100644
--- a/src/bin/bindctl/Makefile.am
+++ b/src/bin/bindctl/Makefile.am
@@ -8,7 +8,7 @@ EXTRA_DIST = $(man_MANS) bindctl.xml
 noinst_SCRIPTS = run_bindctl.sh
 
 python_PYTHON = __init__.py bindcmd.py cmdparse.py exception.py moduleinfo.py \
-		mycollections.py
+		mycollections.py command_sets.py
 pythondir = $(pyexecdir)/bindctl
 
 bindctldir = $(pkgdatadir)
diff --git a/src/bin/bindctl/bindcmd.py b/src/bin/bindctl/bindcmd.py
index 0271c9c..f1a622e 100644
--- a/src/bin/bindctl/bindcmd.py
+++ b/src/bin/bindctl/bindcmd.py
@@ -23,6 +23,7 @@ from cmd import Cmd
 from bindctl.exception import *
 from bindctl.moduleinfo import *
 from bindctl.cmdparse import BindCmdParse
+from bindctl import command_sets
 from xml.dom import minidom
 import isc
 import isc.cc.data
@@ -37,6 +38,7 @@ from hashlib import sha1
 import csv
 import pwd
 import getpass
+import copy
 
 try:
     from collections import OrderedDict
@@ -393,8 +395,9 @@ class BindCmdInterpreter(Cmd):
                 param_nr += 1
 
         # Convert parameter value according parameter spec file.
-        # Ignore check for commands belongs to module 'config'
-        if cmd.module != CONFIG_MODULE_NAME:
+        # Ignore check for commands belongs to module 'config' or 'execute
+        if cmd.module != CONFIG_MODULE_NAME and\
+           cmd.module != command_sets.EXECUTE_MODULE_NAME:
             for param_name in cmd.params:
                 param_spec = command_info.get_param_with_name(param_name).param_spec
                 try:
@@ -408,16 +411,9 @@ class BindCmdInterpreter(Cmd):
         if cmd.command == "help" or ("help" in cmd.params.keys()):
             self._handle_help(cmd)
         elif cmd.module == CONFIG_MODULE_NAME:
-            try:
-                self.apply_config_cmd(cmd)
-            except isc.cc.data.DataTypeError as dte:
-                print("Error: " + str(dte))
-            except isc.cc.data.DataNotFoundError as dnfe:
-                print("Error: " + str(dnfe))
-            except isc.cc.data.DataAlreadyPresentError as dape:
-                print("Error: " + str(dape))
-            except KeyError as ke:
-                print("Error: missing " + str(ke))
+            self.apply_config_cmd(cmd)
+        elif cmd.module == command_sets.EXECUTE_MODULE_NAME:
+            self.apply_execute_cmd(cmd)
         else:
             self.apply_cmd(cmd)
 
@@ -576,6 +572,14 @@ class BindCmdInterpreter(Cmd):
             self._print_correct_usage(err)
         except isc.cc.data.DataTypeError as err:
             print("Error! ", err)
+        except isc.cc.data.DataTypeError as dte:
+            print("Error: " + str(dte))
+        except isc.cc.data.DataNotFoundError as dnfe:
+            print("Error: " + str(dnfe))
+        except isc.cc.data.DataAlreadyPresentError as dape:
+            print("Error: " + str(dape))
+        except KeyError as ke:
+            print("Error: missing " + str(ke))
 
     def _print_correct_usage(self, ept):
         if isinstance(ept, CmdUnknownModuleSyntaxError):
@@ -728,6 +732,84 @@ class BindCmdInterpreter(Cmd):
 
         self.location = new_location
 
+    def apply_execute_cmd(self, command):
+        '''Handles the 'execute' command, which executes a number of
+           (preset) statements. The command set to execute is either
+           read from a file (e.g. 'execute file <file>'.) or one
+           of the sets as defined in command_sets.py'''
+        if command.command == 'file':
+            try:
+                with open(command.params['filename']) as command_file:
+                    commands = command_file.readlines()
+            except IOError as ioe:
+                print("Error: " + str(ioe))
+                return
+        elif command_sets.has_command_set(command.command):
+            commands = command_sets.get_commands(command.command)
+        else:
+            # Should not be reachable; parser should've caught this
+            raise Exception("Unknown execute command type " + command.command)
+
+        # We have our set of commands now, depending on whether 'show' was
+        # specified, show or execute them
+        if 'show' in command.params and command.params['show'] == 'show':
+            self.__show_execute_commands(commands)
+        else:
+            self.__apply_execute_commands(commands)
+
+    def __show_execute_commands(self, commands):
+        '''Prints the command list without executing them'''
+        for line in commands:
+            print(line.strip())
+
+    def __apply_execute_commands(self, commands):
+        '''Applies the configuration commands from the given iterator.
+           This is the method that catches, comments, echo statements, and
+           other directives. All commands not filtered by this method are
+           interpreted as if they are directly entered in an active session.
+           Lines starting with any of the following characters are not
+           passed directly:
+           # - These are comments
+           ! - These are directives
+               !echo: print the rest of the line
+               !verbose on/off: print the commands themselves too
+               Unknown directives are ignored (with a warning)
+           The execution is stopped if there are any errors.
+        '''
+        verbose = False
+        try:
+            for line in commands:
+                line = line.strip()
+                if verbose:
+                    print(line)
+                if line.startswith('#') or len(line) == 0:
+                    continue
+                elif line.startswith('!'):
+                    if re.match('^!echo ', line, re.I) and len(line) > 6:
+                        print(line[6:])
+                    elif re.match('^!verbose\s+on\s*$', line, re.I):
+                        verbose = True
+                    elif re.match('^!verbose\s+off$', line, re.I):
+                        verbose = False
+                    else:
+                        print("Warning: ignoring unknown directive: " + line)
+                else:
+                    cmd = BindCmdParse(line)
+                    self._validate_cmd(cmd)
+                    self._handle_cmd(cmd)
+        except (isc.config.ModuleCCSessionError,
+                IOError, http.client.HTTPException,
+                BindCtlException, isc.cc.data.DataTypeError,
+                isc.cc.data.DataNotFoundError,
+                isc.cc.data.DataAlreadyPresentError,
+                KeyError) as err:
+            print('Error: ', err)
+            print()
+            print('Depending on the contents of the script, and which')
+            print('commands it has called, there can be committed and')
+            print('local changes. It is advised to check your settings,')
+            print('and revert local changes with "config revert".')
+
     def apply_cmd(self, cmd):
         '''Handles a general module command'''
         url = '/' + cmd.module + '/' + cmd.command
diff --git a/src/bin/bindctl/bindctl_main.py.in b/src/bin/bindctl/bindctl_main.py.in
index 58c03eb..1685355 100755
--- a/src/bin/bindctl/bindctl_main.py.in
+++ b/src/bin/bindctl/bindctl_main.py.in
@@ -22,6 +22,7 @@ import sys; sys.path.append ('@@PYTHONPATH@@')
 
 from bindctl.moduleinfo import *
 from bindctl.bindcmd import *
+from bindctl import command_sets
 import pprint
 from optparse import OptionParser, OptionValueError
 import isc.util.process
@@ -146,5 +147,6 @@ if __name__ == '__main__':
     tool = BindCmdInterpreter(server_addr, pem_file=options.cert_chain,
                               csv_file_dir=options.csv_file_dir)
     prepare_config_commands(tool)
+    command_sets.prepare_execute_commands(tool)
     result = tool.run()
     sys.exit(result)
diff --git a/src/bin/bindctl/command_sets.py b/src/bin/bindctl/command_sets.py
new file mode 100644
index 0000000..9e2c2ef
--- /dev/null
+++ b/src/bin/bindctl/command_sets.py
@@ -0,0 +1,95 @@
+# Copyright (C) 2012  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# This file provides a built-in set of 'execute' commands, for common
+# functions, such as adding an initial auth server.
+# By calling the function prepare_execute_commands, the
+# commands in the command_sets map are added to the virtual
+# component called 'execute'. This is done in bindctl_main.
+
+from bindctl.moduleinfo import *
+# The name of the 'virtual' command set execution module in bindctl
+EXECUTE_MODULE_NAME = 'execute'
+
+# This is a map of command names to lists
+# Each element in the set should itself be a dict containing:
+# 'description': A string with a description of the command set
+# 'commands': A list of bindctl commands
+command_sets = {
+    'init_authoritative_server': {
+        'description':
+            'Configure and run a basic Authoritative server, with default '+
+            'SQLite3 backend, and xfrin and xfrout functionality',
+        'commands':
+            [
+            '!echo adding Authoritative server component',
+            'config add /Boss/components b10-auth',
+            'config set /Boss/components/b10-auth/kind needed',
+            'config set /Boss/components/b10-auth/special auth',
+            '!echo adding Xfrin component',
+            'config add /Boss/components b10-xfrin',
+            'config set /Boss/components/b10-xfrin/address Xfrin',
+            'config set /Boss/components/b10-xfrin/kind dispensable',
+            '!echo adding Xfrout component',
+            'config add /Boss/components b10-xfrout',
+            'config set /Boss/components/b10-xfrout/address Xfrout',
+            'config set /Boss/components/b10-xfrout/kind dispensable',
+            '!echo adding Zone Manager component',
+            'config add /Boss/components b10-zonemgr',
+            'config set /Boss/components/b10-zonemgr/address Zonemgr',
+            'config set /Boss/components/b10-zonemgr/kind dispensable',
+            '!echo Components added. Please enter "config commit" to',
+            '!echo finalize initial setup and run the components.'
+            ]
+    }
+}
+
+def has_command_set(name):
+    return name in command_sets
+
+def get_commands(name):
+    return command_sets[name]['commands']
+
+def get_description(name):
+    return command_sets[name]['description']
+
+# For each
+def prepare_execute_commands(tool):
+    """This function is called by bindctl_main, and sets up the commands
+       defined here for use in bindctl."""
+    # common parameter
+    param_show = ParamInfo(name="show", type="string", optional=True,
+        desc="Show the list of commands without executing them")
+
+    # The command module
+    module = ModuleInfo(name=EXECUTE_MODULE_NAME,
+                        desc="Execute a given set of commands")
+
+    # Command to execute a file
+    cmd = CommandInfo(name="file", desc="Read commands from file")
+    param = ParamInfo(name="filename", type="string", optional=False,
+                      desc="File to read the set of commands from.")
+    cmd.add_param(param)
+    cmd.add_param(param_show)
+    module.add_command(cmd)
+
+    # and loop through all command sets defined above
+    for name in command_sets:
+        cmd = CommandInfo(name=name, desc=get_description(name))
+        cmd.add_param(param_show)
+        module.add_command(cmd)
+
+    tool.add_module_info(module)
+
diff --git a/src/lib/python/isc/config/config_data.py b/src/lib/python/isc/config/config_data.py
index 346585b..b7adef8 100644
--- a/src/lib/python/isc/config/config_data.py
+++ b/src/lib/python/isc/config/config_data.py
@@ -23,6 +23,7 @@ two through the classes in ccsession)
 import isc.cc.data
 import isc.config.module_spec
 import ast
+import copy
 
 class ConfigDataError(Exception): pass
 
@@ -210,7 +211,8 @@ def find_spec_part(element, identifier, strict_identifier = True):
         cur_el = _get_map_or_list(cur_el)
 
     cur_el = _find_spec_part_single(cur_el, id_parts[-1])
-    return cur_el
+    # Due to the raw datatypes we use, it is safer to return a deep copy here
+    return copy.deepcopy(cur_el)
 
 def spec_name_list(spec, prefix="", recurse=False):
     """Returns a full list of all possible item identifiers in the
@@ -418,6 +420,14 @@ class MultiConfigData:
            manager or the modules."""
         return self._local_changes
 
+    def set_local_changes(self, new_local_changes):
+        """Sets the entire set of local changes, used when reverting
+           changes done automatically in case there was a problem (e.g.
+           when executing commands from a script that fails halfway
+           through).
+        """
+        self._local_changes = new_local_changes
+
     def clear_local_changes(self):
         """Reverts all local changes"""
         self._local_changes = {}
diff --git a/src/lib/python/isc/config/tests/config_data_test.py b/src/lib/python/isc/config/tests/config_data_test.py
index 864fe70..cea452b 100644
--- a/src/lib/python/isc/config/tests/config_data_test.py
+++ b/src/lib/python/isc/config/tests/config_data_test.py
@@ -186,6 +186,10 @@ class TestConfigData(unittest.TestCase):
         spec_part = find_spec_part(config_spec, "item6/value1")
         self.assertEqual({'item_name': 'value1', 'item_type': 'string', 'item_optional': True, 'item_default': 'default'}, spec_part)
 
+        # make sure the returned data is a copy
+        spec_part['item_default'] = 'foo'
+        self.assertNotEqual(spec_part, find_spec_part(config_spec, "item6/value1"))
+
     def test_find_spec_part_lists(self):
         # A few specific tests for list data
         module_spec = isc.config.module_spec_from_file(self.data_path +
@@ -420,7 +424,14 @@ class TestMultiConfigData(unittest.TestCase):
         self.mcd.set_value("Spec2/item1", 2)
         local_changes = self.mcd.get_local_changes()
         self.assertEqual({"Spec2": { "item1": 2}}, local_changes)
-        
+
+    def test_set_local_changes(self):
+        module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
+        self.mcd.set_specification(module_spec)
+        self.assertEqual({}, self.mcd.get_local_changes())
+        new_local_changes = {"Spec2": { "item1": 2}}
+        self.mcd.set_local_changes(new_local_changes)
+        self.assertEqual(new_local_changes, self.mcd.get_local_changes())
 
     def test_clear_local_changes(self):
         module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
diff --git a/tests/lettuce/configurations/bindctl/bindctl.config.orig b/tests/lettuce/configurations/bindctl/bindctl.config.orig
new file mode 100644
index 0000000..bf623c5
--- /dev/null
+++ b/tests/lettuce/configurations/bindctl/bindctl.config.orig
@@ -0,0 +1,22 @@
+{
+    "version": 2,
+    "Logging": {
+        "loggers": [ {
+            "debuglevel": 99,
+            "severity": "DEBUG",
+            "name": "*"
+        } ]
+    },
+    "Auth": {
+        "database_file": "data/example.org.sqlite3",
+        "listen_on": [ {
+            "port": 47806,
+            "address": "127.0.0.1"
+        } ]
+    },
+    "Boss": {
+        "components": {
+            "b10-cmdctl": { "special": "cmdctl", "kind": "needed" }
+        }
+    }
+}
diff --git a/tests/lettuce/data/commands/bad_command b/tests/lettuce/data/commands/bad_command
new file mode 100644
index 0000000..95d1694
--- /dev/null
+++ b/tests/lettuce/data/commands/bad_command
@@ -0,0 +1,9 @@
+!echo shouldshow
+# just add something so the test can verify it's reverted
+config add /Boss/components b10-auth
+config set /Boss/components/b10-auth/kind needed
+config set /Boss/components/b10-auth/special auth
+bad command
+# this should not be reached
+!echo shouldnotshow
+config commit
diff --git a/tests/lettuce/data/commands/directives b/tests/lettuce/data/commands/directives
new file mode 100644
index 0000000..4fe10f5
--- /dev/null
+++ b/tests/lettuce/data/commands/directives
@@ -0,0 +1,19 @@
+# this is a comment: commentexample1
+!echo this is an echo: echoexample2
+!verbose on
+# this is a comment with verbose on: verbosecommentexample3
+!verbose off
+# this is a comment with verbose off again: commentexample4
+# empty lines and lines with only whitespace should be ignored
+
+
+
+	
+	    	
+# directives are case insensitive, and should handle whitespace
+!ECHO echoexample5
+!eChO echoexample6
+!Verbose     ON
+# verbosecommentexample7
+!verBOSE		off	
+# commentexample8
diff --git a/tests/lettuce/data/commands/empty b/tests/lettuce/data/commands/empty
new file mode 100644
index 0000000..e69de29
diff --git a/tests/lettuce/data/commands/nested b/tests/lettuce/data/commands/nested
new file mode 100644
index 0000000..c153694
--- /dev/null
+++ b/tests/lettuce/data/commands/nested
@@ -0,0 +1,2 @@
+# include a different file
+execute file data/commands/nested1
diff --git a/tests/lettuce/data/commands/nested1 b/tests/lettuce/data/commands/nested1
new file mode 100644
index 0000000..8f984d5
--- /dev/null
+++ b/tests/lettuce/data/commands/nested1
@@ -0,0 +1,2 @@
+# this is included by nested
+!echo shouldshow
diff --git a/tests/lettuce/features/bindctl_commands.feature b/tests/lettuce/features/bindctl_commands.feature
index 03a04bf..1ab506d 100644
--- a/tests/lettuce/features/bindctl_commands.feature
+++ b/tests/lettuce/features/bindctl_commands.feature
@@ -1,65 +1,156 @@
 Feature: control with bindctl
     Assorted tests using bindctl for the administration of BIND 10.
 
+
     Scenario: Removing modules
-    # This test runs the original example configuration, which has
-    # a number of modules. It then removes all non-essential modules,
-    # and checks whether they do disappear from the list of running
-    # modules (note that it 'misuses' the help command for this,
-    # there is a Boss command 'show_processes' but it's output is
-    # currently less standardized than 'help')
-    Given I have bind10 running with configuration bindctl_commands.config
-    And wait for bind10 stderr message BIND10_STARTED_CC
-    And wait for bind10 stderr message CMDCTL_STARTED
-    And wait for bind10 stderr message ZONEMGR_STARTED
-    And wait for bind10 stderr message AUTH_SERVER_STARTED
-    And wait for bind10 stderr message XFRIN_STARTED
-    And wait for bind10 stderr message XFROUT_STARTED
-    And wait for bind10 stderr message STATS_STARTING
-    And wait for bind10 stderr message STATHTTPD_STARTED
-
-    Then remove bind10 configuration Boss/components/NOSUCHMODULE
-    last bindctl output should contain Error
-
-    bind10 module Xfrout should be running
-    bind10 module Stats should be running
-    bind10 module Zonemgr should be running
-    bind10 module Xfrin should be running
-    bind10 module Auth should be running
-    bind10 module StatsHttpd should be running
-    bind10 module Resolver should not be running
-
-    Then remove bind10 configuration Boss/components value b10-xfrout
-    And wait for new bind10 stderr message BIND10_PROCESS_ENDED
-    last bindctl output should not contain Error
-
-    # assuming it won't error for further modules (if it does, the final
-    # 'should not be running' tests would fail anyway)
-    Then remove bind10 configuration Boss/components value b10-stats-httpd
-    And wait for new bind10 stderr message BIND10_PROCESS_ENDED
-    last bindctl output should not contain Error
-
-    Then remove bind10 configuration Boss/components value b10-stats
-    And wait for new bind10 stderr message BIND10_PROCESS_ENDED
-    last bindctl output should not contain Error
-
-    Then remove bind10 configuration Boss/components value b10-zonemgr
-    And wait for new bind10 stderr message BIND10_PROCESS_ENDED
-    last bindctl output should not contain Error
-
-    Then remove bind10 configuration Boss/components value b10-xfrin
-    And wait for new bind10 stderr message BIND10_PROCESS_ENDED
-    last bindctl output should not contain Error
-
-    Then remove bind10 configuration Boss/components value b10-auth
-    And wait for new bind10 stderr message BIND10_PROCESS_ENDED
-    last bindctl output should not contain Error
-
-    # After these ^^^ have been stopped...
-    bind10 module Xfrout should not be running
-    bind10 module Zonemgr should not be running
-    bind10 module Xfrin should not be running
-    bind10 module Auth should not be running
-    bind10 module StatsHttpd should not be running
-    bind10 module Stats should not be running
-    bind10 module Resolver should not be running
+        # This test runs the original example configuration, which has
+        # a number of modules. It then removes all non-essential modules,
+        # and checks whether they do disappear from the list of running
+        # modules (note that it 'misuses' the help command for this,
+        # there is a Boss command 'show_processes' but it's output is
+        # currently less standardized than 'help')
+        Given I have bind10 running with configuration bindctl_commands.config
+        And wait for bind10 stderr message BIND10_STARTED_CC
+        And wait for bind10 stderr message CMDCTL_STARTED
+        And wait for bind10 stderr message ZONEMGR_STARTED
+        And wait for bind10 stderr message AUTH_SERVER_STARTED
+        And wait for bind10 stderr message XFRIN_STARTED
+        And wait for bind10 stderr message XFROUT_STARTED
+        And wait for bind10 stderr message STATS_STARTING
+        And wait for bind10 stderr message STATHTTPD_STARTED
+
+        Then remove bind10 configuration Boss/components/NOSUCHMODULE
+        last bindctl output should contain Error
+
+        bind10 module Xfrout should be running
+        bind10 module Stats should be running
+        bind10 module Zonemgr should be running
+        bind10 module Xfrin should be running
+        bind10 module Auth should be running
+        bind10 module StatsHttpd should be running
+        bind10 module Resolver should not be running
+
+        Then remove bind10 configuration Boss/components value b10-xfrout
+        And wait for new bind10 stderr message BIND10_PROCESS_ENDED
+        last bindctl output should not contain Error
+
+        # assuming it won't error for further modules (if it does, the final
+        # 'should not be running' tests would fail anyway)
+        Then remove bind10 configuration Boss/components value b10-stats-httpd
+        And wait for new bind10 stderr message BIND10_PROCESS_ENDED
+        last bindctl output should not contain Error
+
+        Then remove bind10 configuration Boss/components value b10-stats
+        And wait for new bind10 stderr message BIND10_PROCESS_ENDED
+        last bindctl output should not contain Error
+
+        Then remove bind10 configuration Boss/components value b10-zonemgr
+        And wait for new bind10 stderr message BIND10_PROCESS_ENDED
+        last bindctl output should not contain Error
+
+        Then remove bind10 configuration Boss/components value b10-xfrin
+        And wait for new bind10 stderr message BIND10_PROCESS_ENDED
+        last bindctl output should not contain Error
+
+        Then remove bind10 configuration Boss/components value b10-auth
+        And wait for new bind10 stderr message BIND10_PROCESS_ENDED
+        last bindctl output should not contain Error
+
+        # After these ^^^ have been stopped...
+        bind10 module Xfrout should not be running
+        bind10 module Zonemgr should not be running
+        bind10 module Xfrin should not be running
+        bind10 module Auth should not be running
+        bind10 module StatsHttpd should not be running
+        bind10 module Stats should not be running
+        bind10 module Resolver should not be running
+
+    Scenario: Executing scripts from files
+        # This test tests the 'execute' command, which reads and executes
+        # bindctl commands from a file
+        Given I have bind10 running with configuration bindctl/bindctl.config
+        And wait for bind10 stderr message BIND10_STARTED_CC
+        And wait for bind10 stderr message CMDCTL_STARTED
+
+        # first a few bad commands
+        When I send bind10 the command execute
+        last bindctl output should contain Error
+        When I send bind10 the command execute file
+        last bindctl output should contain Error
+        When I send bind10 the command execute file data/commands/nosuchfile
+        last bindctl output should contain Error
+
+        # empty list should be no-op
+        When I send bind10 the command execute file data/commands/empty
+        last bindctl output should not contain Error
+
+        # some tests of directives like !echo and !verbose
+        When I send bind10 the command execute file data/commands/directives
+        last bindctl output should not contain Error
+        last bindctl output should not contain commentexample1
+        last bindctl output should contain echoexample2
+        last bindctl output should contain verbosecommentexample3
+        last bindctl output should not contain commentexample4
+        last bindctl output should contain echoexample5
+        last bindctl output should contain echoexample6
+        last bindctl output should contain verbosecommentexample7
+        last bindctl output should not contain commentexample8
+
+        # bad_command contains a bad command, at which point execution should stop
+        When I send bind10 the command execute file data/commands/bad_command
+        last bindctl output should contain shouldshow
+        last bindctl output should contain Error
+        last bindctl output should not contain shouldnotshow
+        # This would fail if the entire list was passed, or the configuration
+        # was committed
+        send bind10 the command config show Boss/components
+        last bindctl output should not contain b10-auth
+
+        # nested_command contains another execute script
+        When I send bind10 the command execute file data/commands/nested
+        last bindctl output should contain shouldshow
+        last bindctl output should not contain Error    
+
+        # show commands from a file
+        When I send bind10 the command execute file data/commands/bad_command show
+        last bindctl output should not contain Error
+        last bindctl output should contain shouldshow
+        last bindctl output should contain shouldnotshow
+
+    Scenario: Executing builting script init_authoritative_server
+        Given I have bind10 running with configuration bindctl/bindctl.config
+        And wait for bind10 stderr message BIND10_STARTED_CC
+        And wait for bind10 stderr message CMDCTL_STARTED
+
+        When I send bind10 the command execute init_authoritative_server show
+        # just test some parts of the output
+        last bindctl output should contain /Boss/components/b10-auth/special
+        last bindctl output should contain /Boss/components/b10-zonemgr/kind
+        last bindctl output should contain Please
+
+        # nothing should have been changed
+        When I send bind10 the command config diff
+        last bindctl output should contain {}
+
+        # ok now make sure modules aren't running, execute it, and make
+        # sure modules are running
+        bind10 module Auth should not be running
+        bind10 module Xfrout should not be running
+        bind10 module Xfrin should not be running
+        bind10 module Zonemgr should not be running
+
+        When I send bind10 the following commands:
+        """
+        execute init_authoritative_server
+        config commit
+        """
+        And wait for bind10 stderr message AUTH_SERVER_STARTED
+        And wait for bind10 stderr message ZONEMGR_STARTED
+        And wait for bind10 stderr message XFRIN_STARTED
+        And wait for bind10 stderr message XFROUT_STARTED
+
+        last bindctl output should not contain Error
+        bind10 module Auth should be running
+        bind10 module Xfrout should be running
+        bind10 module Xfrin should be running
+        bind10 module Zonemgr should be running
diff --git a/tests/lettuce/features/terrain/terrain.py b/tests/lettuce/features/terrain/terrain.py
index 5ae6cd6..9a04bf5 100644
--- a/tests/lettuce/features/terrain/terrain.py
+++ b/tests/lettuce/features/terrain/terrain.py
@@ -47,6 +47,8 @@ copylist = [
      "configurations/bindctl_commands.config"],
     ["configurations/example.org.config.orig",
      "configurations/example.org.config"],
+    ["configurations/bindctl/bindctl.config.orig",
+     "configurations/bindctl/bindctl.config"],
     ["configurations/resolver/resolver_basic.config.orig",
      "configurations/resolver/resolver_basic.config"],
     ["configurations/multi_instance/multi_auth.config.orig",



More information about the bind10-changes mailing list