Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move csrgen templates into ipaclient package #534

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion configure.ac
Expand Up @@ -463,7 +463,6 @@ AC_CONFIG_FILES([
install/share/Makefile
install/share/advise/Makefile
install/share/advise/legacy/Makefile
install/share/csrgen/Makefile
install/share/profiles/Makefile
install/share/schema.d/Makefile
install/ui/Makefile
Expand Down
13 changes: 6 additions & 7 deletions freeipa.spec.in
Expand Up @@ -1229,13 +1229,6 @@ fi
%{_usr}/share/ipa/advise/legacy/*.template
%dir %{_usr}/share/ipa/profiles
%{_usr}/share/ipa/profiles/*.cfg
%dir %{_usr}/share/ipa/csrgen
%dir %{_usr}/share/ipa/csrgen/templates
%{_usr}/share/ipa/csrgen/templates/*.tmpl
%dir %{_usr}/share/ipa/csrgen/profiles
%{_usr}/share/ipa/csrgen/profiles/*.json
%dir %{_usr}/share/ipa/csrgen/rules
%{_usr}/share/ipa/csrgen/rules/*.json
%dir %{_usr}/share/ipa/html
%{_usr}/share/ipa/html/ffconfig.js
%{_usr}/share/ipa/html/ffconfig_page.js
Expand Down Expand Up @@ -1362,6 +1355,9 @@ fi
%{python_sitelib}/ipaclient/plugins/*.py*
%{python_sitelib}/ipaclient/remote_plugins/*.py*
%{python_sitelib}/ipaclient/remote_plugins/2_*/*.py*
%{python_sitelib}/ipaclient/csrgen/profiles/*.json
%{python_sitelib}/ipaclient/csrgen/rules/*.json
%{python_sitelib}/ipaclient/csrgen/templates/*.tmpl
%{python_sitelib}/ipaclient-*.egg-info


Expand All @@ -1382,6 +1378,9 @@ fi
%{python3_sitelib}/ipaclient/remote_plugins/__pycache__/*.py*
%{python3_sitelib}/ipaclient/remote_plugins/2_*/*.py
%{python3_sitelib}/ipaclient/remote_plugins/2_*/__pycache__/*.py*
%{python3_sitelib}/ipaclient/csrgen/profiles/*.json
%{python3_sitelib}/ipaclient/csrgen/rules/*.json
%{python3_sitelib}/ipaclient/csrgen/templates/*.tmpl
%{python3_sitelib}/ipaclient-*.egg-info

%endif # with_python3
Expand Down
1 change: 0 additions & 1 deletion install/share/Makefile.am
Expand Up @@ -2,7 +2,6 @@ NULL =

SUBDIRS = \
advise \
csrgen \
profiles \
schema.d \
$(NULL)
Expand Down
35 changes: 0 additions & 35 deletions install/share/csrgen/Makefile.am

This file was deleted.

64 changes: 50 additions & 14 deletions ipaclient/csrgen.py
Expand Up @@ -3,19 +3,22 @@
#

import collections
import errno
import json
import os.path
import pipes
import traceback

import pkg_resources

import jinja2
import jinja2.ext
import jinja2.sandbox
import six

from ipalib import api
from ipalib import errors
from ipalib.text import _
from ipaplatform.paths import paths
from ipapython.ipa_log_manager import log_mgr

if six.PY3:
Expand Down Expand Up @@ -72,10 +75,23 @@ class Formatter(object):
"""
base_template_name = None

def __init__(self, csr_data_dir=paths.CSR_DATA_DIR):
def __init__(self, csr_data_dir=None):
# chain loaders:
# 1) csr_data_dir/templates
# 2) /etc/ipa/csrgen/templates
# 3) ipaclient/csrgen/templates
loaders = []
if csr_data_dir is not None:
loaders.append(jinja2.FileSystemLoader(
os.path.join(csr_data_dir, 'templates'))
)
loaders.append(jinja2.FileSystemLoader(
os.path.join(api.env.confdir, 'csrgen/templates'))
)
loaders.append(jinja2.PackageLoader('ipaclient', 'csrgen/templates'))

self.jinja2 = jinja2.sandbox.SandboxedEnvironment(
loader=jinja2.FileSystemLoader(
os.path.join(csr_data_dir, 'templates')),
loader=jinja2.ChoiceLoader(loaders),
extensions=[jinja2.ext.ExprStmtExtension, IPAExtension],
keep_trailing_newline=True, undefined=IndexableUndefined)

Expand Down Expand Up @@ -277,17 +293,39 @@ def rules_for_profile(self, profile_id, helper):


class FileRuleProvider(RuleProvider):
def __init__(self, csr_data_dir=paths.CSR_DATA_DIR):
def __init__(self, csr_data_dir=None):
self.rules = {}
self.csr_data_dir = csr_data_dir
self._csrgen_data_dirs = []
if csr_data_dir is not None:
self._csrgen_data_dirs.append(csr_data_dir)
self._csrgen_data_dirs.append(
os.path.join(api.env.confdir, 'csrgen')
)
self._csrgen_data_dirs.append(
pkg_resources.resource_filename('ipaclient', 'csrgen')
)

def _open(self, subdir, filename):
for data_dir in self._csrgen_data_dirs:
path = os.path.join(data_dir, subdir, filename)
try:
return open(path)
except IOError as e:
if e.errno != errno.ENOENT:
raise
raise IOError(
errno.ENOENT,
"'{}' not found in {}".format(
os.path.join(subdir, filename),
", ".join(self._csrgen_data_dirs)
)
)

def _rule(self, rule_name, helper):
if (rule_name, helper) not in self.rules:
rule_path = os.path.join(self.csr_data_dir, 'rules',
'%s.json' % rule_name)
try:
with open(rule_path) as rule_file:
ruleset = json.load(rule_file)
with self._open('rules', '%s.json' % rule_name) as f:
ruleset = json.load(f)
except IOError:
raise errors.NotFound(
reason=_('Ruleset %(ruleset)s does not exist.') %
Expand Down Expand Up @@ -317,11 +355,9 @@ def _rule(self, rule_name, helper):
return self.rules[(rule_name, helper)]

def rules_for_profile(self, profile_id, helper):
profile_path = os.path.join(self.csr_data_dir, 'profiles',
'%s.json' % profile_id)
try:
with open(profile_path) as profile_file:
profile = json.load(profile_file)
with self._open('profiles', '%s.json' % profile_id) as f:
profile = json.load(f)
except IOError:
raise errors.NotFound(
reason=_('No CSR generation rules are defined for profile'
Expand Down
10 changes: 9 additions & 1 deletion ipaclient/setup.py
Expand Up @@ -43,6 +43,13 @@
"ipaclient.remote_plugins.2_156",
"ipaclient.remote_plugins.2_164",
],
package_data={
'ipaclient': [
'csrgen/profiles/*.json',
'csrgen/rules/*.json',
'csrgen/templates/*.tmpl',
],
},
install_requires=[
"cryptography",
"ipalib",
Expand All @@ -56,5 +63,6 @@
extras_require={
"install": ["ipaplatform"],
"otptoken_yubikey": ["yubico", "usb"]
}
},
zip_safe=False,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed? According to http://setuptools.readthedocs.io/en/latest/setuptools.html#setting-the-zip-safe-flag "And if the project uses pkg_resources for all its data file access, then C extensions and other data files shouldn’t be a problem at all." zip_safe=true seems to work when I build it locally, but I'm not sure if I'm testing it properly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, Jinja uses a pkg_resources ResourceManager to access files. So in theory, zip loading would work.

In practice the option and feature is longer relevant. Python eggs are a dying species and Python wheels no longer use zip deployment.

)
1 change: 0 additions & 1 deletion ipaplatform/base/paths.py
Expand Up @@ -238,7 +238,6 @@ class BasePathNamespace(object):
SCHEMA_COMPAT_ULDIF = "/usr/share/ipa/schema_compat.uldif"
IPA_JS_PLUGINS_DIR = "/usr/share/ipa/ui/js/plugins"
UPDATES_DIR = "/usr/share/ipa/updates/"
CSR_DATA_DIR = "/usr/share/ipa/csrgen"
DICT_WORDS = "/usr/share/dict/words"
CACHE_IPA_SESSIONS = "/var/cache/ipa/sessions"
VAR_KERBEROS_KRB5KDC_DIR = "/var/kerberos/krb5kdc/"
Expand Down