Commit 816dc5cc authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[master] Merge branch 'trac5137' (kea-shell)

parents c5ceebc6 5e03c7da
......@@ -473,44 +473,36 @@ case "$host" in
;;
esac
m4_define([_AM_PYTHON_INTERPRETER_LIST], [python python3.4 python3.3 python3.2 python3.1 python3])
AC_ARG_WITH([pythonpath],
AC_HELP_STRING([--with-pythonpath=PATH],
[specify an absolute path to python executable when automatic version check (incorrectly) fails]),
[python_path="$withval"], [python_path="auto"])
if test "$python_path" = auto; then
AM_PATH_PYTHON([3.1],,[PYTHON=no])
# Kea-shell is written in python. It can work with python 2.7 or any 3.x.
# It may likely work with earlier versions, but 2.7 was the oldest one we tested
# it with. We require python only if kea-shell was enabled. It is disabled
# by default to not introduce hard dependency on python.
AC_ARG_ENABLE(shell, [AC_HELP_STRING([--enable-shell],
[enable kea-shell, a text management client for Control Agent [default=no]])],
enable_shell=$enableval, enable_shell=no)
if test "x$enable_shell" != xno ; then
# If kea-shell is enabled, we really need python. 2.7 or anything newer will do.
# We try to find 3.x first. If not found, we can do with 2.7.
AM_PATH_PYTHON([3], [found="yes"], [found="no"])
if test "x$found" = xno ; then
AM_PATH_PYTHON([2.7])
fi
else
# Older versions of automake can't handle python3 well. This is an
# in-house workaround for them.
PYTHON=$python_path
AC_SUBST(PYTHON)
PYTHON_PREFIX='${prefix}'
AC_SUBST(PYTHON_PREFIX)
PYTHON_EXEC_PREFIX='$(exec_prefix)'
AC_SUBST(PYTHON_EXEC_PREFIX)
PYTHON_VERSION=[`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"`]
if test `echo "$PYTHON_VERSION >= 3.1" | bc` != 1 ; then
AC_MSG_ERROR(["Python version too old: $PYTHON_VERSION, need 3.1 or higher"])
fi
AC_SUBST(PYTHON_VERSION)
PYTHON_PLATFORM=`$PYTHON -c "import sys; print(sys.platform)"`
AC_SUBST(PYTHON_PLATFORM)
pythondir='${prefix}/lib/python'$PYTHON_VERSION'/site-packages'
AC_SUBST(pythondir)
pkgpythondir='${pythondir}/'$PACKAGE
AC_SUBST(pkgpythondir)
pyexecdir='${exec_prefix}/lib/python'$PYTHON_VERSION'/site-packages'
AC_SUBST(pyexecdir)
pkgpyexecdir='${pyexecdir}/'$PACKAGE
AC_SUBST(pkgpyexecdir)
PYTHON=no
fi
# Export to makefiles the info whether we have shell enabled or not
AM_CONDITIONAL(KEA_SHELL, test x$enable_shell != xno)
# produce PIC unless we disable shared libraries. need this for python bindings.
if test $enable_shared != "no" -a "X$GXX" = "Xyes"; then
KEA_CXXFLAGS="$KEA_CXXFLAGS -fPIC"
fi
AC_SUBST(KEA_CXXFLAGS)
# Checks for libraries.
......@@ -1653,6 +1645,11 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/bin/admin/tests/pgsql_tests.sh
src/bin/admin/tests/cql_tests.sh
src/bin/agent/tests/test_libraries.h
src/bin/shell/Makefile
src/bin/shell/kea-shell
src/bin/shell/tests/Makefile
src/bin/shell/tests/shell_process_tests.sh
src/bin/shell/tests/shell_unittest.py
src/hooks/Makefile
src/hooks/dhcp/Makefile
src/hooks/dhcp/user_chk/Makefile
......@@ -1743,11 +1740,14 @@ AC_CONFIG_FILES([compatcheck/Makefile
])
AC_CONFIG_COMMANDS([permissions], [
chmod +x src/bin/admin/kea-admin
chmod +x src/bin/dhcp4/tests/dhcp4_process_tests.sh
chmod +x src/bin/dhcp6/tests/dhcp6_process_tests.sh
chmod +x src/bin/keactrl/keactrl
chmod +x src/bin/keactrl/tests/keactrl_tests.sh
chmod +x src/bin/admin/kea-admin
chmod +x src/bin/shell/kea-shell
chmod +x src/bin/shell/tests/shell_process_tests.sh
chmod +x src/bin/shell/tests/shell_unittest.py
chmod +x src/lib/dns/gen-rdatacode.py
chmod +x src/lib/log/tests/console_test.sh
chmod +x src/lib/log/tests/destination_test.sh
......@@ -1822,19 +1822,16 @@ END
if test "$PYTHON" != "no" ; then
cat >> config.report << END
Python3:
Python:
PYTHON: ${PYTHON}
PYTHON_VERSION: ${PYTHON_VERSION}
PYTHON_INCLUDES: ${PYTHON_INCLUDES}
PYTHON_CXXFLAGS: ${PYTHON_CXXFLAGS}
PYTHON_LDFLAGS: ${PYTHON_LDFLAGS}
PYTHON_LIB: ${PYTHON_LIB}
END
else
cat >> config.report << END
Python3:
not installed
Python:
PYTHON_VERSION: not needed (because kea-shell is disabled)
END
fi
......@@ -1936,6 +1933,7 @@ Developer:
Logger checks: $enable_logger_checks
Generate Documentation: $enable_generate_docs
Parser Generation: $enable_generate_parser
Kea-shell: $enable_shell
END
......
# The following build order must be maintained.
SUBDIRS = dhcp4 dhcp6 d2 agent perfdhcp admin lfc keactrl
SUBDIRS = dhcp4 dhcp6 d2 agent perfdhcp admin lfc keactrl shell
check-recursive: all-recursive
......@@ -5,7 +5,6 @@ SHTESTS += ca_process_tests.sh
noinst_SCRIPTS = ca_process_tests.sh
EXTRA_DIST = ca_process_tests.sh.in
noinst_LTLIBRARIES = libbasic.la
# test using command-line arguments, so use check-local target instead of TESTS
check-local:
......@@ -40,6 +39,8 @@ TESTS_ENVIRONMENT = \
TESTS =
if HAVE_GTEST
noinst_LTLIBRARIES = libbasic.la
TESTS += ca_unittests
ca_unittests_SOURCES = ca_cfg_mgr_unittests.cc
......
kea-shell
kea-shell.8
*.pyc
SUBDIRS = . tests
EXTRA_DIST =
if KEA_SHELL
# Kea-shell is enabled, here are proper rules for it.
kea_shell_PYTHON = kea_conn.py kea_connector2.py kea_connector3.py
kea_shelldir = @localstatedir@/@PACKAGE@
bin_SCRIPTS = kea-shell
else
# Kea-shell is disabled, simply keep the files for make dist
EXTRA_DIST += kea-shell kea_conn.py kea_connector2.py kea_connector3.py
endif
CLEANFILES = *.pyc
man_MANS = kea-shell.8
DISTCLEANFILES = $(man_MANS)
EXTRA_DIST += $(man_MANS) kea-shell.xml
if GENERATE_DOCS
kea-shell.8: kea-shell.xml
@XSLTPROC@ --novalid --xinclude --nonet -o $@ \
http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \
$(srcdir)/kea-shell.xml
else
$(man_MANS):
@echo Man generation disabled. Creating dummy $@. Configure with --enable-generate-docs to enable it.
@echo Man generation disabled. Remove this file, configure with --enable-generate-docs, and rebuild Kea > $@
endif
install-data-local:
$(mkinstalldirs) $(DESTDIR)/@localstatedir@/@PACKAGE@
install-data-hook:
-chmod 2770 $(DESTDIR)/@localstatedir@/@PACKAGE@
CLEANDIRS = __pycache__
clean-local:
rm -rf $(CLEANDIRS)
#!@PYTHON@
# Copyright (C) 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
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
Text client for Control Agent process
"""
# First, let's import the right kea_connector.
# We have two versions: one for python 2.x and another for python 3.x.
# Sadly, there's no unified way to handle http connections. The recommended
# way is to use Requests (http://docs.python-requests.org/en/master/), but
# that's a stand alone package that requires separate installation. One of
# the design requirements was to not require any additional packages, so
# the code uses standard libraries available in python. Hence two versions.
import sys
import signal
import argparse
from kea_conn import CARequest # CAResponse
if sys.version_info[0] == 2:
# This is Python 2.x
import kea_connector2 as kea_connector
elif sys.version_info[0] == 3:
# This is Python 3.x
import kea_connector3 as kea_connector
else:
# This is... have no idea what it is.
raise SystemExit("Unknown python version:" + str(sys.version_info[0]))
def timeout_handler(signum, frame):
"""Connection timeoout handler"""
del signum, frame
print("Connection timeout")
sys.exit(1)
VERSION = "@PACKAGE_VERSION@"
def shell_body():
"""
Second step: Need to parse command line parameters. We will use
argparse for that purpose. It does great job with having default
values, taking care of the help and sanity checking input
parameters.
"""
parser = argparse.ArgumentParser(description='kea-shell is a simple text '
'client that uses REST interface to '
'connect to Kea Control Agent.')
parser.add_argument('--host', type=str, default='127.0.0.1',
help='hostname of the CA to connect to '
'(defaul:; 127.0.0.1)')
parser.add_argument('--port', type=int, default=8000,
help='TCP port of the CA to connect to '
'(default: 8000)')
parser.add_argument('--timeout', type=int, default='10',
help='Timeout (in seconds) when attempting to '
'connect to CA (default: 10)')
parser.add_argument('command', type=str, nargs="?",
default='list-commands',
help='command to be executed. If not specified, '
'"list-commands" is used')
parser.add_argument('-v', action="store_true", help="Prints version")
cmd_args = parser.parse_args()
if cmd_args.v:
print(VERSION)
exit(0)
# Ok, now it's time to put the parameters parsed into the structure to be
# used by the connection.
params = CARequest()
params.command = cmd_args.command
params.http_host = cmd_args.host
params.http_port = cmd_args.port
params.timeout = cmd_args.timeout
params.version = VERSION
params.generate_body()
params.generate_headers()
# Load command processor
# @todo - command specific processing will be added as part of
# future work (either #5138 or #5139, whichever is implemented
# first)
# Read parameters from stdin (they're optional for some commands)
for line in sys.stdin:
params.params += line
# Set the timeout timer. If the connection takes too long,
# it will send a signal to us.
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(params.timeout)
# Ok, everything is ready. Let's send the command and get a response.
try:
resp = kea_connector.send_to_control_agent(params)
except Exception as exc:
print("Failed to run: " + str(exc))
sys.exit(1)
resp.print_response()
sys.exit(0)
if __name__ == "__main__":
shell_body()
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- Copyright (C) 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
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<refentry>
<refentryinfo>
<productname>ISC Kea</productname>
<date>2017 Mar 8</date>
<edition>1.2.0</edition>
<author>
<contrib>The Kea software has been written by a number of
engineers working for ISC: Tomek Mrugalski, Stephen Morris, Marcin
Siodelski, Thomas Markwalder, Francis Dupont, Jeremy C. Reed,
Wlodek Wencel and Shawn Routhier. That list is roughly in the
chronological order in which the authors made their first
contribution. For a complete list of authors and
contributors, see AUTHORS file.</contrib>
<orgname>Internet Systems Consortium, Inc.</orgname>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>kea-shell</refentrytitle>
<manvolnum>8</manvolnum>
<refmiscinfo class="manual">Kea</refmiscinfo>
</refmeta>
<refnamediv>
<refname>kea-shell</refname>
<refpurpose>Text client for Control Agent process</refpurpose>
</refnamediv>
<docinfo>
<copyright>
<year>2016</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
<refsynopsisdiv>
<cmdsynopsis>
<command>kea-shell</command>
<arg><option>-h</option></arg>
<arg><option>-v</option></arg>
<arg><option>--host</option></arg>
<arg><option>--port</option></arg>
<arg><option>--timeout</option></arg>
<arg><option>command</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>DESCRIPTION</title>
<para>
The <command>kea-shell</command> provides a REST client for the
Kea Control Agent (CA). It takes command as a command-line parameter
that is being sent to CA with proper JSON
encapsulation. Optional parameters may be specified on the
standard input. The request it sent of HTTP and a response is
retrieved. That response is displayed out on the standard output.
</para>
</refsect1>
<refsect1>
<title>ARGUMENTS</title>
<para>The arguments are as follows:</para>
<variablelist>
<varlistentry>
<term><option>-h</option></term>
<listitem><para>
Displays help regarding command line parameters.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-v</option></term>
<listitem><para>
Display the version.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--host</option></term>
<listitem><para>
Specifies the host to connect to. Control Agent must be
running at specified host. If not specified, 127.0.0.1 is used.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--port</option></term>
<listitem><para>
Specifies the TCP port to connect to. Control Agent must be
listening at specified port. If not specified, 8000 is used.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--timeout</option></term>
<listitem><para>
Specifies the connection timeout in seconds. If not
specified, 10 (seconds) is used.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>command</option></term>
<listitem><para>
Specifies the command to be sent to CA. If not
specified, "list-commands" is used.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>DOCUMENTATION</title>
<para>Kea comes with an extensive Kea User's Guide documentation
that covers all aspects of running the Kea software -
compilation, installation, configuration, configuration examples
and many more. Kea also features a Kea Messages Manual, which
lists all possible messages Kea can print with a brief
description for each of them. Both documents are typically
available in various formats (txt, html, pdf) with your Kea
distribution. The on-line version is available at
http://kea.isc.org/docs/.</para>
<para>
Kea source code is documented in the Kea Developer's Guide. It's
on-line version is available at http://kea.isc.org. Please
follow Developer's Guide link.
</para>
<para>
Kea project website is available at: http://kea.isc.org.
</para>
</refsect1>
<refsect1>
<title>MAILING LISTS AND SUPPORT</title>
<para>
There are two mailing lists available for Kea project. kea-users
(kea-users at lists.isc.org) is intended for Kea users, while kea-dev
(kea-dev at lists.isc.org) is intended for Kea developers, prospective
contributors and other advanced users. Both lists are available at
http://lists.isc.org. The community provides best effort type of support
on both of those lists.
</para>
<para>
ISC provides professional support for Kea services. See
https://www.isc.org/kea/ for details.
</para>
</refsect1>
<refsect1>
<title>HISTORY</title>
<para>
The <command>kea-shell</command> was first coded in March 2017
by Tomek Mrugalski.
</para>
</refsect1>
<refsect1>
<title>SEE ALSO</title>
<para>
<citerefentry>
<refentrytitle>kea-ctrl-agent</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>kea-dhcp4</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>kea-dhcp6</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>kea-dhcp-ddns</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>kea-admin</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>keactrl</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>perfdhcp</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>kea-lfc</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>,
<citetitle>Kea Administrator's Guide</citetitle>.
</para>
</refsect1>
</refentry><!--
- Local variables:
- mode: sgml
- End:
-->
# Copyright (C) 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
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
This file contains classes used for communication with Control Agent.
"""
class CARequest:
"""
This class defines the HTTP request to be sent.
The supported parameters listed are:
- path (specifies the path on the server, CA uses only /)
- http_host - hostname of the CA
- http-port - TCP port of the CA
- command - specifies the command to send (e.g. list-commands)
- timeout - timeout (in ms)
- headers - extra HTTP headers may be added here
- version - version to be reported in HTTP header
"""
path = '/'
http_host = ''
http_port = 0
command = ''
timeout = 0
params = ''
headers = {}
version = ""
# This is a storage for generated command (input data to be sent over POST)
content = ''
def generate_body(self):
"""
Generates the content, out of specified command line
and optional content.
@todo: Add support for parameters
this stores the output in self.content
"""
self.content = '{ "command": "' + self.command + '"'
if len(self.params):
self.content += ', "parameters": { ' + self.params + ' }'
self.content += ' }'
def generate_headers(self):
"""
Generate HTTP headers
In particular, this method generates Content-Length and its value.
"""
self.headers['Content-Type'] = 'application/json'
self.headers['User-Agent'] = "Kea-shell/%s"%(self.version)
self.headers['Accept'] = '*/*'
self.headers['Content-Length'] = "%d"%(len(self.content))
class CAResponse:
"""
This class represents the HTTP response
"""
def __init__(self, status, reason, body):
"""
Constructor
Three mandatory parameters are:
status - numerical number the describe the status (e.g. 200 = OK)
reason - textual explanation of what happened
body - the actual body structure of the response
"""
self.status = status
self.reason = reason
self.body = body
status = 0
reason = ''
body = ''
def print_response(self, debug=False):
"""
Used for debugging
if debug is true, this prints even more information
"""
if debug:
print(self.status)
print(self.reason)
print(self.body)
# Copyright (C) 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
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
This is PYTHON 2.x version of HTTP connection establishment
"""