summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--API.txt74
-rw-r--r--VERSION4
-rw-r--r--install/share/60basev3.ldif1
-rw-r--r--install/updates/40-vault.update19
-rw-r--r--install/updates/Makefile.am1
-rw-r--r--ipa-client/man/default.conf.51
-rw-r--r--ipalib/constants.py1
-rw-r--r--ipalib/plugins/vault.py321
-rw-r--r--ipatests/test_xmlrpc/test_vault_plugin.py445
9 files changed, 865 insertions, 2 deletions
diff --git a/API.txt b/API.txt
index 0808f3c64..38deafefa 100644
--- a/API.txt
+++ b/API.txt
@@ -4717,6 +4717,80 @@ option: Str('version?', exclude='webui')
output: Output('result', <type 'bool'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: PrimaryKey('value', None, None)
+command: vault_add
+args: 1,9,3
+arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, required=True)
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Str('service?')
+option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('user?')
+option: Str('version?', exclude='webui')
+output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
+output: PrimaryKey('value', None, None)
+command: vault_del
+args: 1,5,3
+arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=True, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
+option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('service?')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('user?')
+option: Str('version?', exclude='webui')
+output: Output('result', <type 'dict'>, None)
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
+output: ListOfPrimaryKeys('value', None, None)
+command: vault_find
+args: 1,11,4
+arg: Str('criteria?', noextrawhitespace=False)
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Str('cn', attribute=True, autofill=False, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=False)
+option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
+option: Flag('pkey_only?', autofill=True, default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Str('service?')
+option: Flag('shared?', autofill=True, default=False)
+option: Int('sizelimit?', autofill=False, minvalue=0)
+option: Int('timelimit?', autofill=False, minvalue=0)
+option: Str('user?')
+option: Str('version?', exclude='webui')
+output: Output('count', <type 'int'>, None)
+output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list of LDAP entries', domain='ipa', localedir=None))
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
+output: Output('truncated', <type 'bool'>, None)
+command: vault_mod
+args: 1,11,3
+arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Str('delattr*', cli_name='delattr', exclude='webui')
+option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Flag('rights', autofill=True, default=False)
+option: Str('service?')
+option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('user?')
+option: Str('version?', exclude='webui')
+output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
+output: PrimaryKey('value', None, None)
+command: vault_show
+args: 1,7,3
+arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Flag('rights', autofill=True, default=False)
+option: Str('service?')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('user?')
+option: Str('version?', exclude='webui')
+output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
+output: PrimaryKey('value', None, None)
capability: messages 2.52
capability: optional_uid_params 2.54
capability: permissions2 2.69
diff --git a/VERSION b/VERSION
index c20755850..33e7bebe4 100644
--- a/VERSION
+++ b/VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
# #
########################################################
IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=118
-# Last change: tbordaz - Add stageuser_find, stageuser_mod, stageuser_del, stageuser_show
+IPA_API_VERSION_MINOR=119
+# Last change: edewata - Added vault plugin
diff --git a/install/share/60basev3.ldif b/install/share/60basev3.ldif
index eb1c1298b..33f4804e3 100644
--- a/install/share/60basev3.ldif
+++ b/install/share/60basev3.ldif
@@ -79,3 +79,4 @@ objectClasses: (2.16.840.1.113730.3.8.12.24 NAME 'ipaPublicKeyObject' DESC 'Wrap
objectClasses: (2.16.840.1.113730.3.8.12.25 NAME 'ipaPrivateKeyObject' DESC 'Wrapped private keys' SUP top AUXILIARY MUST ( ipaPrivateKey $ ipaWrappingKey $ ipaWrappingMech ) X-ORIGIN 'IPA v4.1' )
objectClasses: (2.16.840.1.113730.3.8.12.26 NAME 'ipaSecretKeyObject' DESC 'Wrapped secret keys' SUP top AUXILIARY MUST ( ipaSecretKey $ ipaWrappingKey $ ipaWrappingMech ) X-ORIGIN 'IPA v4.1' )
objectClasses: (2.16.840.1.113730.3.8.12.34 NAME 'ipaSecretKeyRefObject' DESC 'Indirect storage for encoded key material' SUP top AUXILIARY MUST ( ipaSecretKeyRef ) X-ORIGIN 'IPA v4.1' )
+objectClasses: (2.16.840.1.113730.3.8.18.1.1 NAME 'ipaVault' DESC 'IPA vault' SUP top STRUCTURAL MUST ( cn ) MAY ( description ) X-ORIGIN 'IPA v4.2' )
diff --git a/install/updates/40-vault.update b/install/updates/40-vault.update
new file mode 100644
index 000000000..5a6b8c6a0
--- /dev/null
+++ b/install/updates/40-vault.update
@@ -0,0 +1,19 @@
+dn: cn=vaults,$SUFFIX
+default: objectClass: top
+default: objectClass: nsContainer
+default: cn: vaults
+
+dn: cn=services,cn=vaults,$SUFFIX
+default: objectClass: top
+default: objectClass: nsContainer
+default: cn: services
+
+dn: cn=shared,cn=vaults,$SUFFIX
+default: objectClass: top
+default: objectClass: nsContainer
+default: cn: shared
+
+dn: cn=users,cn=vaults,$SUFFIX
+default: objectClass: top
+default: objectClass: nsContainer
+default: cn: users
diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am
index 0d63d9ea8..66f6b9d37 100644
--- a/install/updates/Makefile.am
+++ b/install/updates/Makefile.am
@@ -33,6 +33,7 @@ app_DATA = \
40-dns.update \
40-automember.update \
40-otp.update \
+ 40-vault.update \
45-roles.update \
50-7_bit_check.update \
50-dogtag10-migration.update \
diff --git a/ipa-client/man/default.conf.5 b/ipa-client/man/default.conf.5
index dbc8a5b46..0973f1a07 100644
--- a/ipa-client/man/default.conf.5
+++ b/ipa-client/man/default.conf.5
@@ -221,6 +221,7 @@ The following define the containers for the IPA server. Containers define where
container_sudocmdgroup: cn=sudocmdgroups,cn=sudo
container_sudorule: cn=sudorules,cn=sudo
container_user: cn=users,cn=accounts
+ container_vault: cn=vaults
container_virtual: cn=virtual operations,cn=etc
.SH "FILES"
diff --git a/ipalib/constants.py b/ipalib/constants.py
index f1e14702f..195938a35 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -99,6 +99,7 @@ DEFAULT_CONFIG = (
('container_hbacservice', DN(('cn', 'hbacservices'), ('cn', 'hbac'))),
('container_hbacservicegroup', DN(('cn', 'hbacservicegroups'), ('cn', 'hbac'))),
('container_dns', DN(('cn', 'dns'))),
+ ('container_vault', DN(('cn', 'vaults'))),
('container_virtual', DN(('cn', 'virtual operations'), ('cn', 'etc'))),
('container_sudorule', DN(('cn', 'sudorules'), ('cn', 'sudo'))),
('container_sudocmd', DN(('cn', 'sudocmds'), ('cn', 'sudo'))),
diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
new file mode 100644
index 000000000..ebb9f9fd3
--- /dev/null
+++ b/ipalib/plugins/vault.py
@@ -0,0 +1,321 @@
+# Authors:
+# Endi S. Dewata <edewata@redhat.com>
+#
+# Copyright (C) 2015 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from ipalib import api, errors
+from ipalib import Str, Flag
+from ipalib import output
+from ipalib.plugable import Registry
+from ipalib.plugins.baseldap import LDAPObject, LDAPCreate, LDAPDelete,\
+ LDAPSearch, LDAPUpdate, LDAPRetrieve
+from ipalib.request import context
+from ipalib.plugins.user import split_principal
+from ipalib import _, ngettext
+from ipapython.dn import DN
+
+__doc__ = _("""
+Vaults
+""") + _("""
+Manage vaults.
+""") + _("""
+EXAMPLES:
+""") + _("""
+ List private vaults:
+ ipa vault-find
+""") + _("""
+ List service vaults:
+ ipa vault-find --service <service name>
+""") + _("""
+ List shared vaults:
+ ipa vault-find --shared
+""") + _("""
+ List user vaults:
+ ipa vault-find --user <username>
+""") + _("""
+ Add a private vault:
+ ipa vault-add <name>
+""") + _("""
+ Add a service vault:
+ ipa vault-add <name> --service <service name>
+""") + _("""
+ Add a shared vault:
+ ipa vault-add <ame> --shared
+""") + _("""
+ Add a user vault:
+ ipa vault-add <name> --user <username>
+""") + _("""
+ Show a private vault:
+ ipa vault-show <name>
+""") + _("""
+ Show a service vault:
+ ipa vault-show <name> --service <service name>
+""") + _("""
+ Show a shared vault:
+ ipa vault-show <name> --shared
+""") + _("""
+ Show a user vault:
+ ipa vault-show <name> --user <username>
+""") + _("""
+ Modify a private vault:
+ ipa vault-mod <name> --desc <description>
+""") + _("""
+ Modify a service vault:
+ ipa vault-mod <name> --service <service name> --desc <description>
+""") + _("""
+ Modify a shared vault:
+ ipa vault-mod <name> --shared --desc <description>
+""") + _("""
+ Modify a user vault:
+ ipa vault-mod <name> --user <username> --desc <description>
+""") + _("""
+ Delete a private vault:
+ ipa vault-del <name>
+""") + _("""
+ Delete a service vault:
+ ipa vault-del <name> --service <service name>
+""") + _("""
+ Delete a shared vault:
+ ipa vault-del <name> --shared
+""") + _("""
+ Delete a user vault:
+ ipa vault-del <name> --user <username>
+""")
+
+register = Registry()
+
+
+vault_options = (
+ Str(
+ 'service?',
+ doc=_('Service name'),
+ ),
+ Flag(
+ 'shared?',
+ doc=_('Shared vault'),
+ ),
+ Str(
+ 'user?',
+ doc=_('Username'),
+ ),
+)
+
+
+@register()
+class vault(LDAPObject):
+ __doc__ = _("""
+ Vault object.
+ """)
+
+ container_dn = api.env.container_vault
+
+ object_name = _('vault')
+ object_name_plural = _('vaults')
+
+ object_class = ['ipaVault']
+ default_attributes = [
+ 'cn',
+ 'description',
+ ]
+
+ label = _('Vaults')
+ label_singular = _('Vault')
+
+ takes_params = (
+ Str(
+ 'cn',
+ cli_name='name',
+ label=_('Vault name'),
+ primary_key=True,
+ pattern='^[a-zA-Z0-9_.-]+$',
+ pattern_errmsg='may only include letters, numbers, _, ., and -',
+ maxlength=255,
+ ),
+ Str(
+ 'description?',
+ cli_name='desc',
+ label=_('Description'),
+ doc=_('Vault description'),
+ ),
+ )
+
+ def get_dn(self, *keys, **options):
+ """
+ Generates vault DN from parameters.
+ """
+
+ service = options.get('service')
+ shared = options.get('shared')
+ user = options.get('user')
+
+ count = 0
+ if service:
+ count += 1
+
+ if shared:
+ count += 1
+
+ if user:
+ count += 1
+
+ if count > 1:
+ raise errors.MutuallyExclusiveError(
+ reason=_('Service, shared, and user options ' +
+ 'cannot be specified simultaneously'))
+
+ # TODO: create container_dn after object initialization then reuse it
+ container_dn = DN(self.container_dn, self.api.env.basedn)
+
+ dn = super(vault, self).get_dn(*keys, **options)
+ assert dn.endswith(container_dn)
+ rdns = DN(*dn[:-len(container_dn)])
+
+ if not count:
+ principal = getattr(context, 'principal')
+
+ if principal.startswith('host/'):
+ raise errors.NotImplementedError(
+ reason=_('Host is not supported'))
+
+ (name, realm) = split_principal(principal)
+ if '/' in name:
+ service = name
+ else:
+ user = name
+
+ if service:
+ parent_dn = DN(('cn', service), ('cn', 'services'), container_dn)
+ elif shared:
+ parent_dn = DN(('cn', 'shared'), container_dn)
+ else:
+ parent_dn = DN(('cn', user), ('cn', 'users'), container_dn)
+
+ return DN(rdns, parent_dn)
+
+ def create_container(self, dn):
+ """
+ Creates vault container and its parents.
+ """
+
+ # TODO: create container_dn after object initialization then reuse it
+ container_dn = DN(self.container_dn, self.api.env.basedn)
+
+ entries = []
+
+ while dn:
+ assert dn.endswith(container_dn)
+
+ rdn = dn[0]
+ entry = self.backend.make_entry(
+ dn,
+ {
+ 'objectclass': ['nsContainer'],
+ 'cn': rdn['cn'],
+ })
+
+ # if entry can be added, return
+ try:
+ self.backend.add_entry(entry)
+ break
+
+ except errors.NotFound:
+ pass
+
+ # otherwise, create parent entry first
+ dn = DN(*dn[1:])
+ entries.insert(0, entry)
+
+ # then create the entries again
+ for entry in entries:
+ self.backend.add_entry(entry)
+
+
+@register()
+class vault_add(LDAPCreate):
+ __doc__ = _('Create a new vault.')
+
+ takes_options = LDAPCreate.takes_options + vault_options
+
+ msg_summary = _('Added vault "%(value)s"')
+
+ def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys,
+ **options):
+ assert isinstance(dn, DN)
+
+ try:
+ parent_dn = DN(*dn[1:])
+ self.obj.create_container(parent_dn)
+ except errors.DuplicateEntry, e:
+ pass
+
+ return dn
+
+
+@register()
+class vault_del(LDAPDelete):
+ __doc__ = _('Delete a vault.')
+
+ takes_options = LDAPDelete.takes_options + vault_options
+
+ msg_summary = _('Deleted vault "%(value)s"')
+
+
+@register()
+class vault_find(LDAPSearch):
+ __doc__ = _('Search for vaults.')
+
+ takes_options = LDAPSearch.takes_options + vault_options
+
+ msg_summary = ngettext(
+ '%(count)d vault matched',
+ '%(count)d vaults matched',
+ 0,
+ )
+
+ def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args,
+ **options):
+ assert isinstance(base_dn, DN)
+
+ base_dn = self.obj.get_dn(*args, **options)
+
+ return (filter, base_dn, scope)
+
+ def exc_callback(self, args, options, exc, call_func, *call_args,
+ **call_kwargs):
+ if call_func.__name__ == 'find_entries':
+ if isinstance(exc, errors.NotFound):
+ # ignore missing containers since they will be created
+ # automatically on vault creation.
+ raise errors.EmptyResult(reason=str(exc))
+
+ raise exc
+
+
+@register()
+class vault_mod(LDAPUpdate):
+ __doc__ = _('Modify a vault.')
+
+ takes_options = LDAPUpdate.takes_options + vault_options
+
+ msg_summary = _('Modified vault "%(value)s"')
+
+
+@register()
+class vault_show(LDAPRetrieve):
+ __doc__ = _('Display information about a vault.')
+
+ takes_options = LDAPRetrieve.takes_options + vault_options
diff --git a/ipatests/test_xmlrpc/test_vault_plugin.py b/ipatests/test_xmlrpc/test_vault_plugin.py
new file mode 100644
index 000000000..44d397c58
--- /dev/null
+++ b/ipatests/test_xmlrpc/test_vault_plugin.py
@@ -0,0 +1,445 @@
+# Authors:
+# Endi S. Dewata <edewata@redhat.com>
+#
+# Copyright (C) 2015 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Test the `ipalib/plugins/vault.py` module.
+"""
+
+from ipalib import api, errors
+from xmlrpc_test import Declarative, fuzzy_string
+
+vault_name = u'test_vault'
+service_name = u'HTTP/server.example.com'
+user_name = u'testuser'
+
+
+class test_vault_plugin(Declarative):
+
+ cleanup_commands = [
+ ('vault_del', [vault_name], {'continue': True}),
+ ('vault_del', [vault_name], {
+ 'service': service_name,
+ 'continue': True
+ }),
+ ('vault_del', [vault_name], {'shared': True, 'continue': True}),
+ ('vault_del', [vault_name], {'user': user_name, 'continue': True}),
+ ]
+
+ tests = [
+
+ {
+ 'desc': 'Create private vault',
+ 'command': (
+ 'vault_add',
+ [vault_name],
+ {},
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': 'Added vault "%s"' % vault_name,
+ 'result': {
+ 'dn': u'cn=%s,cn=admin,cn=users,cn=vaults,%s'
+ % (vault_name, api.env.basedn),
+ 'objectclass': [u'top', u'ipaVault'],
+ 'cn': [vault_name],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Find private vaults',
+ 'command': (
+ 'vault_find',
+ [],
+ {},
+ ),
+ 'expected': {
+ 'count': 1,
+ 'truncated': False,
+ 'summary': u'1 vault matched',
+ 'result': [
+ {
+ 'dn': u'cn=%s,cn=admin,cn=users,cn=vaults,%s'
+ % (vault_name, api.env.basedn),
+ 'cn': [vault_name],
+ },
+ ],
+ },
+ },
+
+ {
+ 'desc': 'Show private vault',
+ 'command': (
+ 'vault_show',
+ [vault_name],
+ {},
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': None,
+ 'result': {
+ 'dn': u'cn=%s,cn=admin,cn=users,cn=vaults,%s'
+ % (vault_name, api.env.basedn),
+ 'cn': [vault_name],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Modify private vault',
+ 'command': (
+ 'vault_mod',
+ [vault_name],
+ {
+ 'description': u'Test vault',
+ },
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': u'Modified vault "%s"' % vault_name,
+ 'result': {
+ 'cn': [vault_name],
+ 'description': [u'Test vault'],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Delete private vault',
+ 'command': (
+ 'vault_del',
+ [vault_name],
+ {},
+ ),
+ 'expected': {
+ 'value': [vault_name],
+ 'summary': u'Deleted vault "%s"' % vault_name,
+ 'result': {
+ 'failed': (),
+ },
+ },
+ },
+
+ {
+ 'desc': 'Create service vault',
+ 'command': (
+ 'vault_add',
+ [vault_name],
+ {
+ 'service': service_name,
+ },
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': u'Added vault "%s"' % vault_name,
+ 'result': {
+ 'dn': u'cn=%s,cn=%s,cn=services,cn=vaults,%s'
+ % (vault_name, service_name, api.env.basedn),
+ 'objectclass': [u'top', u'ipaVault'],
+ 'cn': [vault_name],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Find service vaults',
+ 'command': (
+ 'vault_find',
+ [],
+ {
+ 'service': service_name,
+ },
+ ),
+ 'expected': {
+ 'count': 1,
+ 'truncated': False,
+ 'summary': u'1 vault matched',
+ 'result': [
+ {
+ 'dn': u'cn=%s,cn=%s,cn=services,cn=vaults,%s'
+ % (vault_name, service_name, api.env.basedn),
+ 'cn': [vault_name],
+ },
+ ],
+ },
+ },
+
+ {
+ 'desc': 'Show service vault',
+ 'command': (
+ 'vault_show',
+ [vault_name],
+ {
+ 'service': service_name,
+ },
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': None,
+ 'result': {
+ 'dn': u'cn=%s,cn=%s,cn=services,cn=vaults,%s'
+ % (vault_name, service_name, api.env.basedn),
+ 'cn': [vault_name],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Modify service vault',
+ 'command': (
+ 'vault_mod',
+ [vault_name],
+ {
+ 'service': service_name,
+ 'description': u'Test vault',
+ },
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': u'Modified vault "%s"' % vault_name,
+ 'result': {
+ 'cn': [vault_name],
+ 'description': [u'Test vault'],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Delete service vault',
+ 'command': (
+ 'vault_del',
+ [vault_name],
+ {
+ 'service': service_name,
+ },
+ ),
+ 'expected': {
+ 'value': [vault_name],
+ 'summary': u'Deleted vault "%s"' % vault_name,
+ 'result': {
+ 'failed': (),
+ },
+ },
+ },
+
+ {
+ 'desc': 'Create shared vault',
+ 'command': (
+ 'vault_add',
+ [vault_name],
+ {
+ 'shared': True
+ },
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': u'Added vault "%s"' % vault_name,
+ 'result': {
+ 'dn': u'cn=%s,cn=shared,cn=vaults,%s'
+ % (vault_name, api.env.basedn),
+ 'objectclass': [u'top', u'ipaVault'],
+ 'cn': [vault_name],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Find shared vaults',
+ 'command': (
+ 'vault_find',
+ [],
+ {
+ 'shared': True
+ },
+ ),
+ 'expected': {
+ 'count': 1,
+ 'truncated': False,
+ 'summary': u'1 vault matched',
+ 'result': [
+ {
+ 'dn': u'cn=%s,cn=shared,cn=vaults,%s'
+ % (vault_name, api.env.basedn),
+ 'cn': [vault_name],
+ },
+ ],
+ },
+ },
+
+ {
+ 'desc': 'Show shared vault',
+ 'command': (
+ 'vault_show',
+ [vault_name],
+ {
+ 'shared': True
+ },
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': None,
+ 'result': {
+ 'dn': u'cn=%s,cn=shared,cn=vaults,%s'
+ % (vault_name, api.env.basedn),
+ 'cn': [vault_name],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Modify shared vault',
+ 'command': (
+ 'vault_mod',
+ [vault_name],
+ {
+ 'shared': True,
+ 'description': u'Test vault',
+ },
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': u'Modified vault "%s"' % vault_name,
+ 'result': {
+ 'cn': [vault_name],
+ 'description': [u'Test vault'],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Delete shared vault',
+ 'command': (
+ 'vault_del',
+ [vault_name],
+ {
+ 'shared': True
+ },
+ ),
+ 'expected': {
+ 'value': [vault_name],
+ 'summary': u'Deleted vault "%s"' % vault_name,
+ 'result': {
+ 'failed': (),
+ },
+ },
+ },
+
+ {
+ 'desc': 'Create user vault',
+ 'command': (
+ 'vault_add',
+ [vault_name],
+ {
+ 'user': user_name,
+ },
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': u'Added vault "%s"' % vault_name,
+ 'result': {
+ 'dn': u'cn=%s,cn=%s,cn=users,cn=vaults,%s'
+ % (vault_name, user_name, api.env.basedn),
+ 'objectclass': [u'top', u'ipaVault'],
+ 'cn': [vault_name],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Find user vaults',
+ 'command': (
+ 'vault_find',
+ [],
+ {
+ 'user': user_name,
+ },
+ ),
+ 'expected': {
+ 'count': 1,
+ 'truncated': False,
+ 'summary': u'1 vault matched',
+ 'result': [
+ {
+ 'dn': u'cn=%s,cn=%s,cn=users,cn=vaults,%s'
+ % (vault_name, user_name, api.env.basedn),
+ 'cn': [vault_name],
+ },
+ ],
+ },
+ },
+
+ {
+ 'desc': 'Show user vault',
+ 'command': (
+ 'vault_show',
+ [vault_name],
+ {
+ 'user': user_name,
+ },
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': None,
+ 'result': {
+ 'dn': u'cn=%s,cn=%s,cn=users,cn=vaults,%s'
+ % (vault_name, user_name, api.env.basedn),
+ 'cn': [vault_name],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Modify user vault',
+ 'command': (
+ 'vault_mod',
+ [vault_name],
+ {
+ 'user': user_name,
+ 'description': u'Test vault',
+ },
+ ),
+ 'expected': {
+ 'value': vault_name,
+ 'summary': u'Modified vault "%s"' % vault_name,
+ 'result': {
+ 'cn': [vault_name],
+ 'description': [u'Test vault'],
+ },
+ },
+ },
+
+ {
+ 'desc': 'Delete user vault',
+ 'command': (
+ 'vault_del',
+ [vault_name],
+ {
+ 'user': user_name,
+ },
+ ),
+ 'expected': {
+ 'value': [vault_name],
+ 'summary': u'Deleted vault "%s"' % vault_name,
+ 'result': {
+ 'failed': (),
+ },
+ },
+ },
+
+ ]