Browse Source

[5108] keactrl supports Kea Control Agent.

Marcin Siodelski 7 years ago
parent
commit
2d57a80976
3 changed files with 190 additions and 51 deletions
  1. 4 0
      src/bin/keactrl/keactrl.conf.in
  2. 20 2
      src/bin/keactrl/keactrl.in
  3. 166 49
      src/bin/keactrl/tests/keactrl_tests.sh.in

+ 4 - 0
src/bin/keactrl/keactrl.conf.in

@@ -13,6 +13,7 @@ exec_prefix=@exec_prefix@
 dhcp4_srv=@sbindir@/kea-dhcp4
 dhcp6_srv=@sbindir@/kea-dhcp6
 dhcp_ddns_srv=@sbindir@/kea-dhcp-ddns
+ctrl_agent_srv=@sbindir@/kea-ctrl-agent
 
 # Start DHCPv4 server?
 dhcp4=yes
@@ -23,5 +24,8 @@ dhcp6=yes
 # Start DHCP DDNS server?
 dhcp_ddns=no
 
+# Start Control Agent?
+ctrl_agent=yes
+
 # Be verbose?
 kea_verbose=no

+ 20 - 2
src/bin/keactrl/keactrl.in

@@ -202,7 +202,7 @@ to process ${proc_name}, PID ${_pid}.\n"
 #   and be set to yes, e.g. ${dhcp4} should be equal to yes if server name
 #   is dhcp4
 run_conditional() {
-    local server=${1}         # Server name: dhcp4, dhcp6, dhcp_ddns
+    local server=${1}         # Server name: dhcp4, dhcp6, dhcp_ddns, ctrl_agent
     local command="${2}"      # Command to execute
     local check_file_cfg=${3} # Check if server enabled in the configuration file
 
@@ -301,7 +301,7 @@ do
             # Validate that the specified server names are correct.
             for s in ${servers}
             do
-                is_in_list "${s}" "all dhcp4 dhcp6 dhcp_ddns"
+                is_in_list "${s}" "all dhcp4 dhcp6 dhcp_ddns ctrl_agent"
                 if [ ${_inlist} -eq 0 ]; then
                     log_error "invalid server name: ${s}"
                     exit 1
@@ -343,11 +343,19 @@ if [ -z ${dhcp_ddns} ]; then
     exit 1
 fi
 
+# Get location of the Control Agent binary.
+if [ -z ${ctrl_agent_srv} ]; then
+    log_error "ctrl_agent_srv parameter not specified"
+    exit 1
+fi
+
 # dhcp4 and dhcp6 (=yes) indicate if we should start DHCPv4 and DHCPv6 server
 # respectively.
 dhcp4=$( printf "%s" ${dhcp4} | tr [:upper:] [:lower:] )
 dhcp6=$( printf "%s" ${dhcp6} | tr [:upper:] [:lower:] )
 dhcp_ddns=$( printf "%s" ${dhcp_ddns} | tr [:upper:] [:lower:] )
+ctrl_agent=$( printf "%s" ${ctrl_agent} | tr [:upper:] [:lower:] )
+
 
 case ${command} in
     # Start the servers.
@@ -365,6 +373,7 @@ case ${command} in
         run_conditional "dhcp4" "start_server ${dhcp4_srv} \"${args}\"" 1
         run_conditional "dhcp6" "start_server ${dhcp6_srv} \"${args}\"" 1
         run_conditional "dhcp_ddns" "start_server ${dhcp_ddns_srv} \"${args}\"" 1
+        run_conditional "ctrl_agent" "start_server ${ctrl_agent_srv} \"${args}\"" 1
 
         exit 0 ;;
 
@@ -376,6 +385,7 @@ case ${command} in
         run_conditional "dhcp4" "stop_server ${dhcp4_srv}" 0
         run_conditional "dhcp6" "stop_server ${dhcp6_srv}" 0
         run_conditional "dhcp_ddns" "stop_server ${dhcp_ddns_srv}" 0
+        run_conditional "ctrl_agent" "stop_server ${ctrl_agent_srv}" 0
 
         exit 0 ;;
 
@@ -387,6 +397,7 @@ case ${command} in
         run_conditional "dhcp4" "reload_server ${dhcp4_srv}" 0
         run_conditional "dhcp6" "reload_server ${dhcp6_srv}" 0
         run_conditional "dhcp_ddns" "reload_server ${dhcp_ddns_srv}" 0
+        run_conditional "ctrl_agent" "reload_server ${ctrl_agent_srv}" 0
 
         exit 0 ;;
 
@@ -411,6 +422,13 @@ case ${command} in
             d2_status="active"
         fi
         printf "DHCP DDNS: %s\n" ${d2_status}
+
+        agent_status="inactive"
+        check_running $(basename ${ctrl_agent_srv})
+        if [ ${_running} -eq 1 ]; then
+            agent_status="active"
+        fi
+        printf "Control Agent: %s\n" ${agent_status}
         printf "Kea configuration file: %s\n" ${kea_config_file}
         printf "keactrl configuration file: %s\n" ${keactrl_conf}
 

+ 166 - 49
src/bin/keactrl/tests/keactrl_tests.sh.in

@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -21,10 +21,11 @@ KEACTRL_CFG_FILE=@abs_top_builddir@/src/bin/keactrl/tests/keactrl_test.conf
 # Path to the Kea log file.
 LOG_FILE=@abs_top_builddir@/src/bin/keactrl/tests/test.log
 # Binaries' names
-wildcard_name="kea-dhcp"
-kea4_name="${wildcard_name}4"
-kea6_name="${wildcard_name}6"
-d2_name="${wildcard_name}-ddns"
+wildcard_name="kea-"
+kea4_name="${wildcard_name}dhcp4"
+kea6_name="${wildcard_name}dhcp6"
+d2_name="${wildcard_name}dhcp-ddns"
+agent_name="${wildcard_name}ctrl-agent"
 # Kea configuration
 config="{
     \"Dhcp4\":
@@ -78,7 +79,10 @@ config="{
         \"forward-ddns\" : {},
         \"reverse-ddns\" : {}
     },
-
+    \"Control-agent\": {
+        \"http-host\": \"127.0.0.1\",
+        \"http-port\": 18080
+    },
     \"Logging\":
     {
         \"loggers\": [
@@ -108,6 +112,15 @@ config="{
                 }
             ],
             \"severity\": \"INFO\"
+        },
+        {
+            \"name\": \"kea-ctrl-agent\",
+            \"output_options\": [
+                {
+                    \"output\": \"$LOG_FILE\"
+                }
+            ],
+            \"severity\": \"INFO\"
         }
         ]
     }
@@ -116,15 +129,16 @@ config="{
 # Fixed part of the keactrl configuration file.
 keactrl_fixed_config="dhcp4_srv=${KEACTRL_BUILD_DIR}/src/bin/dhcp4/kea-dhcp4\n\
 dhcp6_srv=${KEACTRL_BUILD_DIR}/src/bin/dhcp6/kea-dhcp6\n\
-dhcp_ddns_srv=${KEACTRL_BUILD_DIR}/src/bin/d2/kea-dhcp-ddns\n"
+dhcp_ddns_srv=${KEACTRL_BUILD_DIR}/src/bin/d2/kea-dhcp-ddns\n\
+ctrl_agent_srv=${KEACTRL_BUILD_DIR}/src/bin/agent/kea-ctrl-agent\n"
 
 # This test checks that DHCPv4, DHCPv6 and D2 server can be started and
 # shut down.
 start_all_servers_no_verbose_test() {
     # Create configuration file for keactrl. This configuration enables
-    # DHCPv4, DHCPv6 and D2 server.
+    # DHCPv4, DHCPv6, D2 and CA.
     keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\n\
-dhcp_ddns=yes\nkea_verbose=no\n${keactrl_fixed_config}"
+dhcp_ddns=yes\nctrl_agent=yes\nkea_verbose=no\n${keactrl_fixed_config}"
 
     test_start "keactrl.start_all_servers_no_verbose_test"
 
@@ -156,11 +170,22 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
-    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 1
+    # Wait for D2 and CA to configure.
+    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 2
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for CPL daemons to start. \
+Expected wait_for_message return %d, returned %d."
+
+    wait_for_message 20 "DHCP_DDNS_STARTED" 1
     assert_eq 1 ${_WAIT_FOR_MESSAGE} \
         "Timeout waiting for ${d2_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
+    wait_for_message 20 "CTRL_AGENT_HTTP_SERVICE_STARTED" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${agent_name} to start. \
+Expected wait_for_message return %d, returned %d."
+
     # Make sure that debug messages are logged for neither
     # server (non-verbose mode).
     get_log_messages "DHCP6_START_INFO"
@@ -192,6 +217,10 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${d2_name} process running, found %d processes running"
 
+    get_pid ${agent_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop  -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -c ${KEACTRL_CFG_FILE}
@@ -210,8 +239,8 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
-    # Wait up to 10s for the D2 server to stop.
-    wait_for_message 10 "DCTL_SHUTDOWN" 1
+    # Wait up to 10s for the D2 and CA to stop.
+    wait_for_message 10 "DCTL_SHUTDOWN" 2
     assert_eq 1 ${_WAIT_FOR_MESSAGE} \
         "Timeout waiting for ${d2_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
@@ -230,7 +259,7 @@ start_all_servers_verbose_test() {
     # Create configuration file for keactrl. This configuration enables
     # all servers.
     keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\n\
-dhcp_ddns=yes\nkea_verbose=yes\n${keactrl_fixed_config}"
+dhcp_ddns=yes\nctrl_agent=yes\nkea_verbose=yes\n${keactrl_fixed_config}"
 
     test_start "keactrl.start_all_servers_verbose_test"
 
@@ -259,12 +288,21 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
-    # Wait up to 20s for the D2 server to configure.
-    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 1
+    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 2
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for CPL daemons to start. \
+Expected wait_for_message return %d, returned %d."
+
+    wait_for_message 20 "DHCP_DDNS_STARTED" 1
     assert_eq 1 ${_WAIT_FOR_MESSAGE} \
         "Timeout waiting for ${d2_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
+    wait_for_message 20 "CTRL_AGENT_HTTP_SERVICE_STARTED" 1
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${agent_name} to start. \
+Expected wait_for_message return %d, returned %d."
+
     # Check if the debug messages are present, which should only be
     # the case if the verbose mode is on.
     get_log_messages "DHCP6_START_INFO" 1
@@ -275,8 +313,8 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_LOG_MESSAGES} \
         "Expected get_log_messages for DHCP4_START_INFO return %d, returned %d."
 
-    get_log_messages "DCTL_STANDALONE" 1
-    assert_eq 1 ${_GET_LOG_MESSAGES} \
+    get_log_messages "DCTL_STANDALONE" 2
+    assert_eq 2 ${_GET_LOG_MESSAGES} \
         "Expected get_log_messages for DCT_STANDALONE return %d, returned %d."
 
     # Server may shut down imediatelly after configuration has competed.
@@ -296,6 +334,10 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${d2_name} process running, found %d processes running"
 
+    get_pid ${agent_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -c ${KEACTRL_CFG_FILE}
@@ -314,10 +356,10 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
-    # Wait up to 10s for the D2 server to stop.
-    wait_for_message 10 "DCTL_SHUTDOWN" 1
+    # Wait up to 10s for the D2 and CA to stop.
+    wait_for_message 10 "DCTL_SHUTDOWN" 2
     assert_eq 1 ${_WAIT_FOR_MESSAGE} \
-        "Timeout waiting for ${d2_name} to shutdown. \
+        "Timeout waiting for ${d2_name} and ${agent_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
     # Make sure that all servers are down.
@@ -335,7 +377,7 @@ start_v4_server_test() {
     # Create configuration file for keactrl. This configuration enables
     # DHCPv4 server but disables other servers.
     keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=no\n\
-dhcp_ddns=no\nkea_verbose=no\n${keactrl_fixed_config}"
+dhcp_ddns=no\nctrl_agent=no\nkea_verbose=no\n${keactrl_fixed_config}"
 
     test_start "keactrl.start_v4_server_test"
 
@@ -377,6 +419,11 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 0 ${_GET_PIDS_NUM} \
         "Expected %d ${d2_name} process running, found %d processes running"
 
+    # Make sure that CA is not running.
+    get_pid ${agent_name}
+    assert_eq 0 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
     # Make sure that the status command returns appropriate status.
     printf "Getting status of Kea modules: %s\n" "${keactrl} status \
 -c ${KEACTRL_CFG_FILE}"
@@ -389,6 +436,8 @@ Expected wait_for_message return %d, returned %d."
         "Expected keactrl status command return %s"
     assert_string_contains "DHCP DDNS: inactive" "${output}" \
         "Expected keactrl status command return %s"
+    assert_string_contains "Control Agent: inactive" "${output}" \
+        "Expected keactrl status command return %s"
 
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
@@ -416,7 +465,7 @@ start_v6_server_test() {
     # Create configuration file for keactrl. This configuration enables
     # DHCPv6 server but disables other servers..
     keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=no\ndhcp6=yes\n\
-dhcp_ddns=no\nkea_verbose=no\n${keactrl_fixed_config}"
+dhcp_ddns=no\nctrl_agent=no\nkea_verbose=no\n${keactrl_fixed_config}"
 
     test_start "keactrl.start_v6_server_test"
 
@@ -458,6 +507,11 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 0 ${_GET_PIDS_NUM} \
         "Expected %d ${d2_name} process running, found %d processes running"
 
+    # Make sure that CA is not running.
+    get_pid ${agent_name}
+    assert_eq 0 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
     # Make sure that the status command returns appropriate status.
     printf "Getting status of Kea modules: %s\n" "${keactrl} status -c ${KEACTRL_CFG_FILE}"
     output=$( ${keactrl} status -c ${KEACTRL_CFG_FILE} )
@@ -469,7 +523,8 @@ Expected wait_for_message return %d, returned %d."
         "Expected keactrl status command return %s"
     assert_string_contains "DHCP DDNS: inactive" "${output}" \
         "Expected keactrl status command return %s"
-
+    assert_string_contains "Control Agent: inactive" "${output}" \
+        "Expected keactrl status command return %s"
 
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
@@ -498,7 +553,7 @@ late_start_v4_server_test() {
     # Create configuration file for keactrl. This configuration enables
     # DHCPv6 server but disables other servers.
     keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=no\ndhcp6=yes\n\
-dhcp_ddns=no\nkea_verbose=no\n${keactrl_fixed_config}"
+dhcp_ddns=no\nctrl_agent=no\nkea_verbose=no\n${keactrl_fixed_config}"
 
     test_start "keactrl.late_start_v4_server_test"
 
@@ -535,6 +590,16 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 0 ${_GET_PIDS_NUM} \
         "Expected %d ${kea4_name} process running, found %d processes running"
 
+    # Make sure that D2 server is not running.
+    get_pid ${d2_name}
+    assert_eq 0 ${_GET_PIDS_NUM} \
+        "Expected %d ${d2_name} process running, found %d processes running"
+
+    # Make sure that CA is not running.
+    get_pid ${agent_name}
+    assert_eq 0 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
     # Trigger reconfiguration, make sure that the DHCPv6 server reconfigured.
     printf "Reconfiguring the DHCPv6 server: ${keactrl} reload -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} reload -c ${KEACTRL_CFG_FILE}
@@ -548,7 +613,7 @@ Expected wait_for_message to return %d, returned %d."
 
     # Update keactrl config to enable other servers.
     keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\n\
-dhcp_ddns=yes\nkea_verbose=yes\n${keactrl_fixed_config}"
+dhcp_ddns=yes\nctrl_agent=yes\nkea_verbose=yes\n${keactrl_fixed_config}"
     create_keactrl_config "${keactrl_config}"
 
     # Start other servers using keactrl script.
@@ -563,13 +628,12 @@ dhcp_ddns=yes\nkea_verbose=yes\n${keactrl_fixed_config}"
         "Timeout waiting for ${kea4_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
-    # Wait up to 20s for the D2 server to configure.
-    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 1
+    # Wait up to 20s for the D2 and CA to configure.
+    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 2
     assert_eq 1 ${_WAIT_FOR_MESSAGE} \
-        "Timeout waiting for ${kea4_name} to start. \
+        "Timeout waiting for ${d2_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
-
     # Make sure that DHCPv6 server is running.
     get_pid ${kea6_name}
     assert_eq 1 ${_GET_PIDS_NUM} \
@@ -585,6 +649,10 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${d2_name} process running, found %d processes running"
 
+    # Make sure that CA is running.
+    get_pid ${agent_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
 
     # Trigger reconfiguration, make sure that servers are reconfigured.
     printf "Reconfiguring all servers: ${keactrl} reload \
@@ -603,10 +671,11 @@ Expected wait_for_message to return %d, returned %d."
     assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${kea4_name} to reconfigure. \
 Expected wait_for_message to return %d, returned %d."
 
-    # There should be two completed configurations of D2 server.
-    wait_for_message 10 "DCTL_CONFIG_COMPLETE" 2
-    assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${d2_name} to reconfigure. \
-Expected wait_for_message to return %d, returned %d."
+    # There should be two completed configurations of D2 and two
+    # configurations of CA.
+    wait_for_message 10 "DCTL_CONFIG_COMPLETE" 4
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${d2_name} or ${ca_name} \
+to reconfigure. Expected wait_for_message to return %d, returned %d."
 
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
@@ -626,10 +695,10 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
-    # Wait up to 10s for the D2 server to stop.
-    wait_for_message 10 "DCTL_SHUTDOWN" 1
+    # Wait up to 10s for the D2 and CA to stop.
+    wait_for_message 10 "DCTL_SHUTDOWN" 2
     assert_eq 1 ${_WAIT_FOR_MESSAGE} \
-        "Timeout waiting for ${d2_name} to shutdown. \
+        "Timeout waiting for ${d2_name} and ${ca_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
     # Make sure that all servers are down.
@@ -647,7 +716,7 @@ late_start_v6_server_test() {
     # Create configuration file for keactrl. This configuration enables
     # DHCPv4 server but disables DHCPv6 server.
     keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=no\n\
-dhcp_ddns=no\nkea_verbose=yes\n${keactrl_fixed_config}"
+dhcp_ddns=no\nctrl_agent=yes\nkea_verbose=yes\n${keactrl_fixed_config}"
 
     test_start "keactrl.late_start_v6_server_test"
 
@@ -689,6 +758,11 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 0 ${_GET_PIDS_NUM} \
         "Expected %d ${d2_name} process running, found %d processes running"
 
+    # Make sure that CA is not running.
+    get_pid ${d2_name}
+    assert_eq 0 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
     # Trigger reconfiguration, make sure that the DHCPv4 server is reconfigured.
     printf "Reconfiguring the DHCPv4 server: ${keactrl} reload -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} reload -c ${KEACTRL_CFG_FILE}
@@ -702,7 +776,7 @@ Expected wait_for_message to return %d, returned %d."
 
     # Update keactrl config to enable other servers.
     keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\n\
-dhcp_ddns=yes\nkea_verbose=no\n${keactrl_fixed_config}"
+dhcp_ddns=yes\nctrl_agent=yes\nkea_verbose=no\n${keactrl_fixed_config}"
     create_keactrl_config "${keactrl_config}"
 
     # Start other servers using keactrl script.
@@ -717,8 +791,8 @@ dhcp_ddns=yes\nkea_verbose=no\n${keactrl_fixed_config}"
         "Timeout waiting for ${kea4_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
-    # Wait up to 20s for the D2 server to configure.
-    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 1
+    # Wait up to 20s for the D2 and CA to configure.
+    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 2
     assert_eq 1 ${_WAIT_FOR_MESSAGE} \
         "Timeout waiting for ${d2_name} to start. \
 Expected wait_for_message return %d, returned %d."
@@ -739,6 +813,11 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${d2_name} process running, found %d processes running"
 
+    # Make sure that CA is running.
+    get_pid ${agent_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
     # Trigger reconfiguration, make sure that servers are reconfigured.
     printf "Reconfiguring DHCPv6 and DHCPv4 servers: ${keactrl} reload \
 -c ${KEACTRL_CFG_FILE}\n"
@@ -756,12 +835,12 @@ Expected wait_for_message to return %d, returned %d."
     assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${kea6_name} to reconfigure. \
 Expected wait_for_message to return %d, returned %d."
 
-    # There should be two completed configurations of Dd2 server.
-    wait_for_message 10 "DCTL_CONFIG_COMPLETE" 2
+    # There should be two completed configurations of D2 and two
+    # configurations of the CA.
+    wait_for_message 10 "DCTL_CONFIG_COMPLETE" 4
     assert_eq 1 ${_WAIT_FOR_MESSAGE} "Timeout waiting for ${d2_name} to reconfigure. \
 Expected wait_for_message to return %d, returned %d."
 
-
     # Use keactrl stop to shutdown the servers.
     printf "Stopping Kea: ${keactrl} stop -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -c ${KEACTRL_CFG_FILE}
@@ -780,8 +859,8 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
 
-    # Wait up to 10s for the d2 server to stop.
-    wait_for_message 10 "DCTL_SHUTDOWN" 1
+    # Wait up to 10s for the D2 and CA to stop.
+    wait_for_message 10 "DCTL_SHUTDOWN" 2
     assert_eq 1 ${_WAIT_FOR_MESSAGE} \
         "Timeout waiting for ${d2_name} to shutdown. \
 Expected wait_for_message return %d, returned %d."
@@ -799,7 +878,7 @@ stop_selected_server_test() {
     # Create configuration file for keactrl. This configuration enables
     # all servers.
     keactrl_config="kea_config_file=${CFG_FILE}\ndhcp4=yes\ndhcp6=yes\n\
-dhcp_ddns=yes\nkea_verbose=no\n${keactrl_fixed_config}"
+dhcp_ddns=yes\nctrl_agent=yes\nkea_verbose=no\n${keactrl_fixed_config}"
 
     test_start "keactrl.stop_selected_server_test"
 
@@ -828,8 +907,8 @@ Expected wait_for_message return %d, returned %d."
         "Timeout waiting for ${kea4_name} to start. \
 Expected wait_for_message return %d, returned %d."
 
-    # Wait up to 20s for the D2 server to configure.
-    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 1
+    # Wait up to 20s for the D2 and CA to configure.
+    wait_for_message 20 "DCTL_CONFIG_COMPLETE" 2
     assert_eq 1 ${_WAIT_FOR_MESSAGE} \
         "Timeout waiting for ${d2_name} to start. \
 Expected wait_for_message return %d, returned %d."
@@ -851,7 +930,7 @@ Expected wait_for_message return %d, returned %d."
     # Give it some time to shutdown.
     sleep 3
 
-    # Make sure that both servers are running.
+    # Make sure that all servers are running.
     get_pid ${kea4_name}
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${kea4_name} process running, found %d processes running"
@@ -864,6 +943,10 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${d2_name} process running, found %d processes running"
 
+    get_pid ${agent_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
     # Use keactrl stop to shutdown DHCPv4 server.
     printf "Stopping DHCPv4 server: ${keactrl} stop -s dhcp4 -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -s dhcp4 -c ${KEACTRL_CFG_FILE}
@@ -891,6 +974,11 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${d2_name} process running, found %d processes running"
 
+    # Make sure CA is still running
+    get_pid ${agent_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
     # Use keactrl stop to shutdown DHCPv6 server.
     printf "Stopping DHCPv6 server: ${keactrl} stop -s dhcp6 -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -s dhcp6 -c ${KEACTRL_CFG_FILE}
@@ -913,6 +1001,11 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_GET_PIDS_NUM} \
         "Expected %d ${d2_name} process running, found %d processes running"
 
+    # Make sure CA is still running
+    get_pid ${agent_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
     # Use keactrl stop to shutdown D2 server.
     printf "Stopping DHCP DDNS server: ${keactrl} stop -s dhcp_ddns -c ${KEACTRL_CFG_FILE}\n"
     ${keactrl} stop -s dhcp_ddns -c ${KEACTRL_CFG_FILE}
@@ -930,6 +1023,28 @@ Expected wait_for_message return %d, returned %d."
     assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
         "Expected wait_for_server_down return %d, returned %d"
 
+    # Make sure CA is still running
+    get_pid ${agent_name}
+    assert_eq 1 ${_GET_PIDS_NUM} \
+        "Expected %d ${agent_name} process running, found %d processes running"
+
+    # Use keactrl stop to shutdown CA.
+    printf "Stopping DHCP DDNS server: ${keactrl} stop -s ctrl_agent -c ${KEACTRL_CFG_FILE}\n"
+    ${keactrl} stop -s ctrl_agent -c ${KEACTRL_CFG_FILE}
+    ret=${?}
+    assert_eq 0 ${ret} "Expected keactrl to return %d, returned value was %d."
+
+    # Wait up to 10s for the CA to stop.
+    wait_for_message 10 "DCTL_SHUTDOWN" 2
+    assert_eq 1 ${_WAIT_FOR_MESSAGE} \
+        "Timeout waiting for ${agent_name} to shutdown. \
+Expected wait_for_message return %d, returned %d."
+
+    # Make sure that the CA is down.
+    wait_for_server_down 5 ${agent_name}
+    assert_eq 1 ${_WAIT_FOR_SERVER_DOWN} \
+        "Expected wait_for_server_down return %d, returned %d"
+
     test_finish 0
 }
 
@@ -957,6 +1072,8 @@ status_no_config_test() {
         "Expected keactrl status command return %s"
     assert_string_contains "DHCP DDNS: inactive" "${output}" \
         "Expected keactrl status command return %s"
+    assert_string_contains "Control Agent: inactive" "${output}" \
+        "Expected keactrl status command return %s"
     assert_string_contains "Configuration file for Kea does not exist" \
         "${output}" "Expected keactrl status command return %s"