mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-26 00:41:25 -06:00
174 lines
4.4 KiB
Python
174 lines
4.4 KiB
Python
|
#
|
||
|
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||
|
#
|
||
|
"""IPA API initialization for Sphinx
|
||
|
"""
|
||
|
import os
|
||
|
import re
|
||
|
import sys
|
||
|
|
||
|
from sphinx.util import progress_message
|
||
|
from sphinx.ext.autodoc import mock as autodoc_mock
|
||
|
|
||
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
|
ROOT = os.path.abspath(os.path.join(HERE, os.pardir))
|
||
|
VERSION_M4 = os.path.abspath(os.path.join(ROOT, "VERSION.m4"))
|
||
|
|
||
|
if ROOT not in sys.path:
|
||
|
sys.path.insert(0, ROOT)
|
||
|
|
||
|
|
||
|
ipa_mock_imports = [
|
||
|
# no binary wheels available
|
||
|
"dbus",
|
||
|
"gssapi",
|
||
|
"ldap",
|
||
|
"ldif", # python-ldap
|
||
|
"ldapurl", # python-ldap
|
||
|
# dogtag-pki is client-only
|
||
|
"pki",
|
||
|
# PyPI packages not available
|
||
|
"pyhbac",
|
||
|
"pysss",
|
||
|
"pysss_murmur",
|
||
|
"pysss_nss_idmap",
|
||
|
"samba",
|
||
|
"SSSDConfig",
|
||
|
]
|
||
|
|
||
|
|
||
|
def parse_version_m4(filename=VERSION_M4):
|
||
|
"""Poor man's macro parser for VERSION.m4
|
||
|
"""
|
||
|
def_re = re.compile(r"^define\(([\w]+)+,\s*(.*)\)\s*$")
|
||
|
defs = {}
|
||
|
|
||
|
with open(filename) as f:
|
||
|
for line in f:
|
||
|
mo = def_re.match(line)
|
||
|
if mo is not None:
|
||
|
k, v = mo.groups()
|
||
|
try:
|
||
|
v = int(v)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
defs[k] = v
|
||
|
|
||
|
defs["IPA_NUM_VERSION"] = (
|
||
|
"{IPA_VERSION_MAJOR:d}"
|
||
|
"{IPA_VERSION_MINOR:02d}"
|
||
|
"{IPA_VERSION_RELEASE:02d}"
|
||
|
).format(**defs)
|
||
|
|
||
|
defs["IPA_API_VERSION"] = (
|
||
|
"{IPA_API_VERSION_MAJOR}.{IPA_API_VERSION_MINOR}"
|
||
|
).format(**defs)
|
||
|
|
||
|
if defs["IPA_VERSION_IS_GIT_SNAPSHOT"] == "yes":
|
||
|
defs["IPA_GIT_VERSION"] = ".dev"
|
||
|
else:
|
||
|
defs["IPA_GIT_VERSION"] = ""
|
||
|
|
||
|
defs["IPA_VERSION"] = (
|
||
|
"{IPA_VERSION_MAJOR}."
|
||
|
"{IPA_VERSION_MINOR}."
|
||
|
"{IPA_VERSION_RELEASE}"
|
||
|
"{IPA_VERSION_PRE_RELEASE}"
|
||
|
"{IPA_GIT_VERSION}"
|
||
|
).format(**defs)
|
||
|
return defs
|
||
|
|
||
|
|
||
|
def fake_ipaython_version(defs):
|
||
|
"""Fake ipapython.version module
|
||
|
|
||
|
We don't want and cannot run autoconf on read the docs. Fake the auto-
|
||
|
generated ipapython.version module.
|
||
|
"""
|
||
|
|
||
|
class FakeIpapythonVersion:
|
||
|
__name__ = "ipapython.version"
|
||
|
|
||
|
VERSION = defs["IPA_VERSION"]
|
||
|
VENDOR_VERSION = defs["IPA_VERSION"]
|
||
|
NUM_VERSION = defs["IPA_NUM_VERSION"]
|
||
|
API_VERSION = defs["IPA_API_VERSION"]
|
||
|
DEFAULT_PLUGINS = frozenset()
|
||
|
|
||
|
fake = FakeIpapythonVersion()
|
||
|
sys.modules[fake.__name__] = fake
|
||
|
|
||
|
|
||
|
def init_api(
|
||
|
context="doc",
|
||
|
domain="ipa.example",
|
||
|
server="server.ipa.example",
|
||
|
in_server=True,
|
||
|
):
|
||
|
import ipalib
|
||
|
|
||
|
ipalib.api.bootstrap(
|
||
|
context=context,
|
||
|
in_server=in_server,
|
||
|
logdir=None,
|
||
|
log=None,
|
||
|
domain=domain,
|
||
|
realm=domain.upper(),
|
||
|
server=server,
|
||
|
)
|
||
|
ipalib.api.finalize()
|
||
|
return ipalib.api
|
||
|
|
||
|
|
||
|
def inject_mock_imports(app, config):
|
||
|
"""Add additional module mocks for ipaserver
|
||
|
"""
|
||
|
mock_imports = set(getattr(config, "autodoc_mock_imports", []))
|
||
|
mock_imports.update(ipa_mock_imports)
|
||
|
config.autodoc_mock_imports = list(mock_imports)
|
||
|
|
||
|
# ldap is a mocked package
|
||
|
# ensure that ipapython.dn still use ctypes wrappers for str2dn/dn2str
|
||
|
# otherwise api won't be able to initialize properly
|
||
|
import ipapython.dn
|
||
|
|
||
|
assert ipapython.dn.str2dn("cn=ipa") == [[("cn", "ipa", 1)]]
|
||
|
|
||
|
|
||
|
def init_ipalib_api(app, config):
|
||
|
"""Initialize ipalib.api
|
||
|
|
||
|
1. Parse VERSION.m4
|
||
|
2. Create fake ipapython.version module
|
||
|
3. Initialize the API with mocked imports
|
||
|
"""
|
||
|
defs = parse_version_m4()
|
||
|
fake_ipaython_version(defs)
|
||
|
|
||
|
with progress_message("initializing ipalib.api"):
|
||
|
with autodoc_mock(config.autodoc_mock_imports):
|
||
|
init_api(
|
||
|
context=config.ipa_context,
|
||
|
domain=config.ipa_domain,
|
||
|
server=config.ipa_server_fqdn,
|
||
|
in_server=config.ipa_in_server,
|
||
|
)
|
||
|
|
||
|
|
||
|
def setup(app):
|
||
|
app.setup_extension("sphinx.ext.autodoc")
|
||
|
|
||
|
app.add_config_value("ipa_context", "doc", "env")
|
||
|
app.add_config_value("ipa_domain", "ipa.example", "env")
|
||
|
app.add_config_value("ipa_server_fqdn", "server.ipa.example", "env")
|
||
|
app.add_config_value("ipa_in_server", True, "env")
|
||
|
|
||
|
app.connect("config-inited", inject_mock_imports)
|
||
|
app.connect("config-inited", init_ipalib_api)
|
||
|
|
||
|
return {
|
||
|
"version": "0.1",
|
||
|
"parallel_read_safe": True,
|
||
|
"parallel_write_safe": True,
|
||
|
}
|