mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-22 15:13:50 -06:00
lite-setup: configure lite-server test env
Introduce a script that configures a local testing environment with ipa default.conf, krb5.conf, and ca.crt from a server hostname. The lite server configuration allows easy and convenient testing of IPA server and client code. It uses an existing 389-DS and KRB5 KDC server on another machine: $ contrib/lite-setup.py master.ipa.example $ source ~/.ipa/activate.sh (ipaenv) $ kinit username (ipaenv) $ make lite-server IPA server UI is available on http://localhost:8888/ipa/ Signed-off-by: Christian Heimes <cheimes@redhat.com> Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
parent
0a55e82d91
commit
e9ae7c4b89
118
contrib/README.md
Normal file
118
contrib/README.md
Normal file
@ -0,0 +1,118 @@
|
||||
# In-tree development debugging and testing
|
||||
|
||||
lite-server and lite-client enable fast development, debugging, and
|
||||
performance analysis of server or client code from an in-tree source
|
||||
directory. The lite-server runs a local web server that uses a remote
|
||||
LDAP and KRB5 server.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Remote IPA server
|
||||
|
||||
Lite-server and lite-client require a running IPA server. The server
|
||||
should have a similar LDAP schema and IPA version as the in-tree
|
||||
sources. Some features may not work if the differences are too great.
|
||||
|
||||
The lite-server only needs a working LDAP server and KRB5 server. For
|
||||
KdcProxy or CA-related features the Apache HTTPd and pki-tomcatd service
|
||||
must be running, too.
|
||||
|
||||
If the lite-client is configured for remote-server instead of
|
||||
lite-server, then the lite-client uses the HTTP API of the remote
|
||||
server.
|
||||
|
||||
### Local setup
|
||||
|
||||
1. Configure and build FreeIPA according to ``BUILD.txt``, TL;DR
|
||||
|
||||
```
|
||||
$ sudo dnf builddep -b --spec freeipa.spec.in --best --allowerasing --setopt=install_weak_deps=False
|
||||
$ ./autogen.sh
|
||||
$ make
|
||||
```
|
||||
|
||||
2. Install additional dependencies for the lite-server
|
||||
|
||||
```
|
||||
sudo dnf install -y python3-werkzeug python3-watchdog
|
||||
```
|
||||
|
||||
3. The FQDN of the remote IPA server must be resolvable. In case the
|
||||
server does not have a valid DNS entry, it is possible to add the
|
||||
hostname and IP address to ``/etc/hosts``.
|
||||
|
||||
4. Create configuration files in ``~/.ipa``. The lite-server requires
|
||||
an IPA configuration, CA certificate file, KRB5 configuration,
|
||||
Kerberos TGT and a file based credential cache. The script
|
||||
``contrib/lite-setup.py`` can create a all necessary files for you
|
||||
and sets up ``default.conf``, ``krb5.conf``, ``ca.crt``, and
|
||||
even ``ldap.conf``:
|
||||
|
||||
```
|
||||
$ contrib/lite-setup.py master.ipa.example
|
||||
```
|
||||
|
||||
5. Setup environment variables: the lite-setup script also creates a
|
||||
shell source file that activates a virtualenv like environment. The
|
||||
source files sets several environment variables for PATH, KRB5, LDAP,
|
||||
IPA, and Python. The env allows you to run the lite server, ``ipa``
|
||||
client commands, or OpenLDAP commands:
|
||||
|
||||
```
|
||||
$ source ~/.ipa/activate.sh
|
||||
```
|
||||
|
||||
4. Acquire a TGT
|
||||
|
||||
```
|
||||
(ipaenv) $ kinit username
|
||||
```
|
||||
|
||||
5. Run the lite-server
|
||||
|
||||
```
|
||||
(ipaenv) $ make lite-server
|
||||
```
|
||||
|
||||
6. Run ``ipa`` client commands in another shell session. The lite-setup
|
||||
scripts provides a wrapper that uses the development sources, too.
|
||||
|
||||
```
|
||||
$ source ~/.ipa/activate.sh
|
||||
(ipaenv) $ which ipa
|
||||
~/.ipa/ipa
|
||||
(ipaenv) $ ipa ping
|
||||
```
|
||||
|
||||
7. Deactivate the environment
|
||||
|
||||
```
|
||||
(ipaenv) $ deactivate_ipaenv
|
||||
```
|
||||
|
||||
## Limitations
|
||||
|
||||
The lite-server does not have access to the ra-agent certificate.
|
||||
Therefore most CA and KRA (vault) operations are not supported.
|
||||
|
||||
## Tricks and tips
|
||||
|
||||
The lite-server has a functional Web UI at
|
||||
http://localhost:8888/ipa/xml. The session is already authenticated
|
||||
with the current TGT.
|
||||
|
||||
The lite-setup script has additional options
|
||||
|
||||
* ``--kdcproxy`` configures ``krb5.conf`` for Kerberos over HTTPS
|
||||
* ``--debug`` enables IPA and KRB5 debugging
|
||||
* ``--remote-server`` lets you run local client commands without a
|
||||
local lite-server.
|
||||
|
||||
The ``make lite-server`` command supports arguments like
|
||||
``PYTHON=/path/to/custom/interpreter`` or
|
||||
``LITESERVER_ARGS='--enable-profiler=-'``.
|
||||
|
||||
By default the dev server supports HTTP only. To switch to HTTPS, you
|
||||
can put a PEM file at ~/.ipa/lite.pem. The PEM file must contain a
|
||||
server certificate, its unencrypted private key and intermediate chain
|
||||
certs (if applicable).
|
@ -4,45 +4,7 @@
|
||||
#
|
||||
"""In-tree development server
|
||||
|
||||
The dev server requires a Kerberos TGT and a file based credential cache:
|
||||
|
||||
$ mkdir -p ~/.ipa
|
||||
$ export KRB5CCNAME=~/.ipa/ccache
|
||||
$ kinit admin
|
||||
$ make lite-server
|
||||
|
||||
Optionally you can set KRB5_CONFIG to use a custom Kerberos configuration
|
||||
instead of /etc/krb5.conf.
|
||||
|
||||
To run the lite-server with another Python interpreter:
|
||||
|
||||
$ make lite-server PYTHON=/path/to/bin/python
|
||||
|
||||
To enable profiling:
|
||||
|
||||
$ make lite-server LITESERVER_ARGS='--enable-profiler=-'
|
||||
|
||||
By default the dev server supports HTTP only. To switch to HTTPS, you can put
|
||||
a PEM file at ~/.ipa/lite.pem. The PEM file must contain a server certificate,
|
||||
its unencrypted private key and intermediate chain certs (if applicable).
|
||||
|
||||
Prerequisite
|
||||
------------
|
||||
|
||||
Additionally to build and runtime requirements of FreeIPA, the dev server
|
||||
depends on the werkzeug framework and optionally watchdog for auto-reloading.
|
||||
You may also have to enable a development COPR.
|
||||
|
||||
$ sudo dnf install -y dnf-plugins-core
|
||||
$ sudo dnf builddep --spec freeipa.spec.in
|
||||
$ sudo dnf install -y python3-werkzeug python3-watchdog
|
||||
$ ./autogen.sh
|
||||
|
||||
For more information see
|
||||
|
||||
* http://www.freeipa.org/page/Build
|
||||
* http://www.freeipa.org/page/Testing
|
||||
|
||||
See README.md for more details.
|
||||
"""
|
||||
import logging
|
||||
import linecache
|
||||
@ -244,7 +206,7 @@ def init_api(ccname):
|
||||
)
|
||||
api.finalize()
|
||||
api_time = time.time()
|
||||
logger.info("API initialized in %03f sec", api_time - start_time)
|
||||
logger.info("API initialized in %0.3f sec", api_time - start_time)
|
||||
|
||||
# Validate LDAP connection and pre-fetch schema
|
||||
# Pre-fetching makes the lite-server behave similar to mod_wsgi. werkzeug's
|
||||
@ -268,7 +230,7 @@ def init_api(ccname):
|
||||
# must have its own connection.
|
||||
ldap2.disconnect()
|
||||
ldap_time = time.time()
|
||||
logger.info("LDAP schema retrieved %03f sec", ldap_time - api_time)
|
||||
logger.info("LDAP schema retrieved %0.3f sec", ldap_time - api_time)
|
||||
|
||||
return api
|
||||
|
||||
|
192
contrib/lite-setup.py
Executable file
192
contrib/lite-setup.py
Executable file
@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""Configure lite-server environment.
|
||||
|
||||
See README.md for more details.
|
||||
"""
|
||||
import argparse
|
||||
import os
|
||||
import socket
|
||||
from urllib.request import urlopen
|
||||
|
||||
DEFAULT_CONF = """\
|
||||
[global]
|
||||
host = {args.hostname}
|
||||
server = {args.servername}
|
||||
basedn = {args.basedn}
|
||||
realm = {args.realm}
|
||||
domain = {args.domain}
|
||||
xmlrpc_uri = {args.xmlrpc_uri}
|
||||
ldap_uri = ldap://{args.servername}
|
||||
debug = {args.debug}
|
||||
enable_ra = False
|
||||
ra_plugin = dogtag
|
||||
dogtag_version = 10
|
||||
"""
|
||||
|
||||
KRB5_CONF = """\
|
||||
[libdefaults]
|
||||
default_realm = {args.realm}
|
||||
dns_lookup_realm = false
|
||||
dns_lookup_kdc = false
|
||||
rdns = false
|
||||
ticket_lifetime = 24h
|
||||
forwardable = true
|
||||
udp_preference_limit = 0
|
||||
default_ccache_name = FILE:{args.ccache}
|
||||
|
||||
[realms]
|
||||
{args.realm} = {{
|
||||
kdc = {args.kdc}
|
||||
master_kdc = {args.kdc}
|
||||
admin_server = {args.kadmin}
|
||||
default_domain = ipa.example
|
||||
pkinit_anchors = FILE:{args.ca_crt}
|
||||
pkinit_pool = FILE:{args.ca_crt}
|
||||
http_anchors = FILE:{args.ca_crt}
|
||||
}}
|
||||
|
||||
[domain_realm]
|
||||
.ipa.example = {args.realm}
|
||||
ipa.example = {args.realm}
|
||||
{args.servername} = {args.realm}
|
||||
"""
|
||||
|
||||
LDAP_CONF = """\
|
||||
URI ldaps://{args.servername}
|
||||
BASE {args.basedn}
|
||||
TLS_CACERT {args.ca_crt}
|
||||
SASL_MECH GSSAPI
|
||||
SASL_NOCANON on
|
||||
"""
|
||||
|
||||
IPA_BIN = """\
|
||||
#!/bin/sh
|
||||
exec python3 -m ipaclient $*
|
||||
"""
|
||||
|
||||
ACTIVATE = """\
|
||||
deactivate_ipaenv () {{
|
||||
export PS1="${{_OLD_IPAENV_PS1}}"
|
||||
export PATH="${{_OLD_IPAENV_PATH}}"
|
||||
unset _OLD_IPAENV_PS1
|
||||
unset _OLD_IPAENV_PATH
|
||||
unset KRB5_CONFIG
|
||||
unset KRB5CCNAME
|
||||
unset LDAPCONF
|
||||
unset IPA_CONFDIR
|
||||
unset PYTHONPATH
|
||||
unset -f deactivate_ipaenv
|
||||
}}
|
||||
|
||||
export _OLD_IPAENV_PS1="${{PS1:-}}"
|
||||
export _OLD_IPAENV_PATH="${{PATH:-}}"
|
||||
export PS1="(ipaenv) ${{PS1:-}}"
|
||||
export PATH="{args.dot_ipa}:${{PATH:-}}"
|
||||
export KRB5_CONFIG="{args.krb5_conf}"
|
||||
export KRB5CCNAME="{args.ccache}"
|
||||
{args.tracecomment}export KRB5_TRACE=/dev/stderr
|
||||
export LDAPCONF="{args.ldap_conf}"
|
||||
export IPA_CONFDIR="{args.dot_ipa}"
|
||||
export PYTHONPATH="{args.basedir}"
|
||||
"""
|
||||
|
||||
MSG = """\
|
||||
Configured for server '{args.servername}' and realm '{args.realm}'.
|
||||
|
||||
To activate the IPA test env:
|
||||
|
||||
source {args.activate}
|
||||
kinit
|
||||
make lite-server
|
||||
|
||||
To deactivate the IPA test env and to unset the env vars:
|
||||
|
||||
deactivate_ipaenv
|
||||
|
||||
The source file configures the env vars:
|
||||
|
||||
export KRB5_CONFIG="{args.krb5_conf}"
|
||||
export KRB5CCNAME="{args.ccache}"
|
||||
export LDAPCONF="{args.ldap_conf}"
|
||||
export IPA_CONFDIR="{args.dot_ipa}"
|
||||
export PYTHONPATH="{args.basedir}"
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("servername", help="IPA server name")
|
||||
parser.add_argument("domain", default=None, nargs="?")
|
||||
parser.add_argument(
|
||||
"--kdcproxy", action="store_true", help="Use KRB5 over HTTPS (KDC-Proxy)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--debug",
|
||||
action="store_true",
|
||||
help="Enable debug mode for lite-server and KRB5",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--remote-server",
|
||||
action="store_true",
|
||||
help="Configure client to use a remote server instead of lite-server",
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
args = parser.parse_args()
|
||||
if args.domain is None:
|
||||
args.domain = args.servername.lower().split(".", 1)[1]
|
||||
else:
|
||||
args.domain = args.domain.lower().rstrip(".")
|
||||
args.realm = args.domain.upper()
|
||||
args.hostname = socket.gethostname()
|
||||
args.basedn = ",".join(f"dc={part}" for part in args.domain.split("."))
|
||||
args.tracecomment = "" if args.debug else "#"
|
||||
|
||||
if args.kdcproxy:
|
||||
args.kdc = f"https://{args.servername}/KdcProxy"
|
||||
args.kadmin = f"https://{args.servername}/KdcProxy"
|
||||
else:
|
||||
args.kdc = f"{args.servername}:88"
|
||||
args.kadmin = f"{args.servername}:749"
|
||||
|
||||
if args.remote_server:
|
||||
args.xmlrpc_uri = f"https://{args.servername}/ipa/xml"
|
||||
else:
|
||||
args.xmlrpc_uri = f"http://localhost:8888/ipa/xml"
|
||||
|
||||
args.basedir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
args.dot_ipa = os.path.expanduser("~/.ipa")
|
||||
args.default_conf = os.path.join(args.dot_ipa, "default.conf")
|
||||
args.ca_crt = os.path.join(args.dot_ipa, "ca.crt")
|
||||
args.krb5_conf = os.path.join(args.dot_ipa, "krb5.conf")
|
||||
args.ldap_conf = os.path.join(args.dot_ipa, "ldap.conf")
|
||||
args.ccache = os.path.join(args.dot_ipa, "ccache")
|
||||
args.ipa_bin = os.path.join(args.dot_ipa, "ipa")
|
||||
args.activate = os.path.join(args.dot_ipa, "activate.sh")
|
||||
|
||||
if not os.path.isdir(args.dot_ipa):
|
||||
os.makedirs(args.dot_ipa, mode=0o750)
|
||||
|
||||
with urlopen(f"http://{args.servername}/ipa/config/ca.crt") as req:
|
||||
ca_data = req.read()
|
||||
with open(args.ca_crt, "wb") as f:
|
||||
f.write(ca_data)
|
||||
with open(args.default_conf, "w") as f:
|
||||
f.write(DEFAULT_CONF.format(args=args))
|
||||
with open(args.krb5_conf, "w") as f:
|
||||
f.write(KRB5_CONF.format(args=args))
|
||||
with open(args.ldap_conf, "w") as f:
|
||||
f.write(LDAP_CONF.format(args=args))
|
||||
with open(args.ipa_bin, "w") as f:
|
||||
f.write(IPA_BIN.format(args=args))
|
||||
os.fchmod(f.fileno(), 0o755)
|
||||
with open(args.activate, "w") as f:
|
||||
f.write(ACTIVATE.format(args=args))
|
||||
|
||||
print(MSG.format(args=args))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user