mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add "Extending FreeIPA" developer guide
"Extending FreeIPA" is a developer guide of FreeIPA core framework. Please make sure to improve the guide every time parts of the core framework are affected by your changes. This document ideally should correspond to the current state of the framework. The Guide is written using Emacs Org Mode but can be edited with any plain text editing tool. Emacs is only required to convert it to distribution formats like HTML and TXT. See guide/Makefile for building the guide and README for details of the build environment.
This commit is contained in:
parent
17cc52a154
commit
d09389ab6f
36
doc/guide/Makefile
Normal file
36
doc/guide/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
FILE=guide.org
|
||||
XML=$(addsuffix .xml, $(basename $(FILE)))
|
||||
PDF=$(addsuffix .pdf, $(basename $(FILE)))
|
||||
TXT=$(addsuffix .txt, $(basename $(FILE)))
|
||||
HTML=$(addsuffix .html, $(basename $(FILE)))
|
||||
FO=$(addsuffix .fo, $(basename $(FILE)))
|
||||
|
||||
all: $(PDF) $(TXT) $(HTML)
|
||||
@echo Finished: $? are created
|
||||
|
||||
plain: $(FILE)
|
||||
@echo -n "Building HTML, Docbook, and plain text ..."
|
||||
@emacs -batch -q --no-site-file -eval "(require 'org)" \
|
||||
--visit $< -f org-export-as-html \
|
||||
--visit $< -f org-export-as-docbook \
|
||||
--visit $< -f org-export-as-ascii 2>/dev/null
|
||||
@echo "done, see $(HTML), $(XML), $(TXT)"
|
||||
|
||||
$(TXT): plain
|
||||
|
||||
$(HTML): plain
|
||||
|
||||
$(XML): plain
|
||||
|
||||
$(FO): $(XML)
|
||||
@xmlto --skip-validation fo $< 2>/dev/null
|
||||
|
||||
$(PDF): $(FO)
|
||||
@echo -n "Building PDF ... "
|
||||
@fop -fo $< -pdf $@ -l en -a 2>/dev/null
|
||||
@echo "done, see $(PDF)"
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
@rm -f *.html *.txt *.xml *.fo *.pdf *~
|
36
doc/guide/README
Normal file
36
doc/guide/README
Normal file
@ -0,0 +1,36 @@
|
||||
Extending FreeIPA
|
||||
-----------------
|
||||
|
||||
"Extending FreeIPA" is a developer guide to understand how FreeIPA core
|
||||
framework is built and how to extend it.
|
||||
|
||||
The Guide is written using Emacs Org Mode, see http://orgmode.org/org.html
|
||||
for extensive manual of supported markup features.
|
||||
|
||||
You don't need to use Emacs to edit it, the markup is a plain text.
|
||||
|
||||
Building the guide
|
||||
------------------
|
||||
|
||||
There is Makefile which can be used to convert the Guide from
|
||||
Emacs Org Mode format to different targets.
|
||||
|
||||
Prerequisites:
|
||||
==============
|
||||
On Fedora system following packages are required to generate The Guide:
|
||||
|
||||
docbook-style-xsl
|
||||
fop
|
||||
emacs
|
||||
xmlto
|
||||
|
||||
HTML, Docbook, and plain text
|
||||
---
|
||||
As Org Mode is part of Emacs since version 22, building HTML, TXT, and
|
||||
Docbook targets requires Emacs v22 and above (tested with v23.3 in Fedora).
|
||||
|
||||
PDF
|
||||
---
|
||||
Building PDF is done first generating Docbook source, converting it to FO format,
|
||||
and then running 'fop' processor.
|
||||
|
1060
doc/guide/guide.org
Normal file
1060
doc/guide/guide.org
Normal file
File diff suppressed because it is too large
Load Diff
62
doc/guide/netgroup.js
Normal file
62
doc/guide/netgroup.js
Normal file
@ -0,0 +1,62 @@
|
||||
IPA.netgroup = {};
|
||||
|
||||
IPA.netgroup.entity = function(spec) {
|
||||
var that = IPA.entity(spec);
|
||||
that.init = function(params) {
|
||||
params.builder.search_facet({
|
||||
columns: [
|
||||
'cn',
|
||||
'description'
|
||||
]
|
||||
}).
|
||||
details_facet({
|
||||
sections: [
|
||||
{
|
||||
name: 'identity',
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
factory: IPA.textarea_widget,
|
||||
name: 'description'
|
||||
},
|
||||
'nisdomainname'
|
||||
]
|
||||
}
|
||||
]
|
||||
}).
|
||||
association_facet({
|
||||
name: 'memberhost_host',
|
||||
facet_group: 'member'
|
||||
}).
|
||||
association_facet({
|
||||
name: 'memberhost_hostgroup',
|
||||
facet_group: 'member'
|
||||
}).
|
||||
association_facet({
|
||||
name: 'memberuser_user',
|
||||
facet_group: 'member'
|
||||
}).
|
||||
association_facet({
|
||||
name: 'memberuser_group',
|
||||
facet_group: 'member'
|
||||
}).
|
||||
association_facet({
|
||||
name: 'memberof_netgroup',
|
||||
associator: IPA.serial_associator
|
||||
}).
|
||||
standard_association_facets().
|
||||
adder_dialog({
|
||||
fields: [
|
||||
'cn',
|
||||
{
|
||||
factory: IPA.textarea_widget,
|
||||
name: 'description'
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
return that;
|
||||
};
|
||||
|
||||
IPA.register('netgroup', IPA.netgroup.entity);
|
140
doc/guide/role.py
Normal file
140
doc/guide/role.py
Normal file
@ -0,0 +1,140 @@
|
||||
from ipalib.plugins.baseldap import *
|
||||
from ipalib import api, Str, _, ngettext
|
||||
from ipalib import Command
|
||||
from ipalib.plugins import privilege
|
||||
|
||||
class role(LDAPObject):
|
||||
"""
|
||||
Role object.
|
||||
"""
|
||||
container_dn = api.env.container_rolegroup
|
||||
object_name = _('role')
|
||||
object_name_plural = _('roles')
|
||||
object_class = ['groupofnames', 'nestedgroup']
|
||||
default_attributes = ['cn', 'description', 'member', 'memberof',
|
||||
'memberindirect', 'memberofindirect',
|
||||
]
|
||||
attribute_members = {
|
||||
'member': ['user', 'group', 'host', 'hostgroup'],
|
||||
'memberof': ['privilege'],
|
||||
}
|
||||
reverse_members = {
|
||||
'member': ['privilege'],
|
||||
}
|
||||
rdnattr='cn'
|
||||
|
||||
label = _('Roles')
|
||||
label_singular = _('Role')
|
||||
|
||||
takes_params = (
|
||||
Str('cn',
|
||||
cli_name='name',
|
||||
label=_('Role name'),
|
||||
primary_key=True,
|
||||
),
|
||||
Str('description',
|
||||
cli_name='desc',
|
||||
label=_('Description'),
|
||||
doc=_('A description of this role-group'),
|
||||
),
|
||||
)
|
||||
|
||||
api.register(role)
|
||||
|
||||
|
||||
class role_add(LDAPCreate):
|
||||
__doc__ = _('Add a new role.')
|
||||
|
||||
msg_summary = _('Added role "%(value)s"')
|
||||
|
||||
api.register(role_add)
|
||||
|
||||
|
||||
class role_del(LDAPDelete):
|
||||
__doc__ = _('Delete a role.')
|
||||
|
||||
msg_summary = _('Deleted role "%(value)s"')
|
||||
|
||||
api.register(role_del)
|
||||
|
||||
|
||||
class role_mod(LDAPUpdate):
|
||||
__doc__ = _('Modify a role.')
|
||||
|
||||
msg_summary = _('Modified role "%(value)s"')
|
||||
|
||||
api.register(role_mod)
|
||||
|
||||
|
||||
class role_find(LDAPSearch):
|
||||
__doc__ = _('Search for roles.')
|
||||
|
||||
msg_summary = ngettext(
|
||||
'%(count)d role matched', '%(count)d roles matched', 0
|
||||
)
|
||||
|
||||
api.register(role_find)
|
||||
|
||||
|
||||
class role_show(LDAPRetrieve):
|
||||
__doc__ = _('Display information about a role.')
|
||||
|
||||
api.register(role_show)
|
||||
|
||||
|
||||
class role_add_member(LDAPAddMember):
|
||||
__doc__ = _('Add members to a role.')
|
||||
|
||||
api.register(role_add_member)
|
||||
|
||||
|
||||
class role_remove_member(LDAPRemoveMember):
|
||||
__doc__ = _('Remove members from a role.')
|
||||
|
||||
api.register(role_remove_member)
|
||||
|
||||
|
||||
class role_add_privilege(LDAPAddReverseMember):
|
||||
__doc__ = _('Add privileges to a role.')
|
||||
|
||||
show_command = 'role_show'
|
||||
member_command = 'privilege_add_member'
|
||||
reverse_attr = 'privilege'
|
||||
member_attr = 'role'
|
||||
|
||||
has_output = (
|
||||
output.Entry('result'),
|
||||
output.Output('failed',
|
||||
type=dict,
|
||||
doc=_('Members that could not be added'),
|
||||
),
|
||||
output.Output('completed',
|
||||
type=int,
|
||||
doc=_('Number of privileges added'),
|
||||
),
|
||||
)
|
||||
|
||||
api.register(role_add_privilege)
|
||||
|
||||
|
||||
class role_remove_privilege(LDAPRemoveReverseMember):
|
||||
__doc__ = _('Remove privileges from a role.')
|
||||
|
||||
show_command = 'role_show'
|
||||
member_command = 'privilege_remove_member'
|
||||
reverse_attr = 'privilege'
|
||||
member_attr = 'role'
|
||||
|
||||
has_output = (
|
||||
output.Entry('result'),
|
||||
output.Output('failed',
|
||||
type=dict,
|
||||
doc=_('Members that could not be added'),
|
||||
),
|
||||
output.Output('completed',
|
||||
type=int,
|
||||
doc=_('Number of privileges removed'),
|
||||
),
|
||||
)
|
||||
|
||||
api.register(role_remove_privilege)
|
26
doc/guide/wsgi.py
Normal file
26
doc/guide/wsgi.py
Normal file
@ -0,0 +1,26 @@
|
||||
from ipalib import api
|
||||
from ipalib.config import Env
|
||||
from ipalib.constants import DEFAULT_CONFIG
|
||||
|
||||
# Determine what debug level is configured. We can only do this
|
||||
# by reading in the configuration file(s). The server always reads
|
||||
# default.conf and will also read in `context'.conf.
|
||||
env = Env()
|
||||
env._bootstrap(context='server', log=None)
|
||||
env._finalize_core(**dict(DEFAULT_CONFIG))
|
||||
|
||||
# Initialize the API with the proper debug level
|
||||
api.bootstrap(context='server', debug=env.debug, log=None) (ref:wsgi-app-bootstrap)
|
||||
try:
|
||||
api.finalize() (ref:wsgi-app-finalize)
|
||||
except StandardError, e:
|
||||
api.log.error('Failed to start IPA: %s' % e)
|
||||
else:
|
||||
api.log.info('*** PROCESS START ***')
|
||||
|
||||
# This is the WSGI callable:
|
||||
def application(environ, start_response): (ref:wsgi-app-start)
|
||||
if not environ['wsgi.multithread']:
|
||||
return api.Backend.session(environ, start_response)
|
||||
else:
|
||||
api.log.error("IPA does not work with the threaded MPM, use the pre-fork MPM") (ref:wsgi-app-end)
|
Loading…
Reference in New Issue
Block a user