[Pki-devel] CLI for editing profiles
Fraser Tweedale
ftweedal at redhat.com
Wed Jul 23 07:09:24 UTC 2014
On Wed, Jul 23, 2014 at 11:27:11AM +1000, Fraser Tweedale wrote:
> Along with LDAP profiles, we will be adding modules to the CLI for
> adding and editing profiles in the ConfigStore format that was used
> for file-based profiles. For more info, see:
>
> http://pki.fedoraproject.org/wiki/LDAP_Profile_Storage#Command-line_utilities
>
> There is an existing CLI for adding and modifying profiles, in the
> XML format, e.g. ``pki ca profile add caCustomProfile.xml``. The
> XML format carries information including the profile ID and
> class_id, but these data must be supplied out-of-band when dealing
> with the ConfigStore format.
>
> Because of this, I intend to:
>
> - add new commands to the existing profile CLI for working with the
> "raw" (i.e., ConfigStore) format, e.g. "edit-raw", "add-raw".
> Where necessary, these commands will take compulsory
> ``--profile-id`` and/or ``--class-id`` arguments, to account for
> the absense of such information in the profile ConfigStore format;
>
> and
>
> - transport this information in the XML format - not in the "raw"
> format - so that it will be unnecessary to make changes to
> ProfileClient or the ProfileService API.
>
> As usual, I welcome feedback - especially if you feel I am going the
> wrong way ^_^
>
An update: due to the various Profile and ProfileInput/Output/Policy
classes not being distributed in the pki-tools package (or
dependencies thereof), I /did/ end up adding methods to the REST
API.
The `pki ca profile show-raw <profileId>` command is implemented in
the attached patch 0009. I expected I will complete the edit-raw
and add-raw commands tomorrow, and after that will move on to
testing replication and polling/monitoring for changes to profiles.
Cheers,
Fraser
> _______________________________________________
> Pki-devel mailing list
> Pki-devel at redhat.com
> https://www.redhat.com/mailman/listinfo/pki-devel
-------------- next part --------------
>From 019e82e4987659f1f1e066dff943355a254f2179 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Mon, 7 Jul 2014 23:35:35 -0400
Subject: [PATCH] add schema for LDAP-based profiles
---
base/ca/shared/conf/db.ldif | 9 +++++++++
base/ca/shared/conf/schema.ldif | 30 ++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/base/ca/shared/conf/db.ldif b/base/ca/shared/conf/db.ldif
index 00fa919b7df38ed97f0bc21b5616a9998845c7d4..b0f36b6d85f70900d0b2c5e0ee92d9fb8c1cb3e8 100644
--- a/base/ca/shared/conf/db.ldif
+++ b/base/ca/shared/conf/db.ldif
@@ -160,4 +160,13 @@ objectClass: top
objectClass: organizationalUnit
ou: certificateRepository
+dn: ou=certProfiles,{rootSuffix}
+objectClass: top
+objectClass: organizationalUnit
+ou: certProfiles
+dn: cn=certProfilesInfo,{rootSuffix}
+objectClass: top
+objectClass: certProfilesInfo
+cn: certProfilesInfo
+certProfilesLastModified: 197001010000Z
diff --git a/base/ca/shared/conf/schema.ldif b/base/ca/shared/conf/schema.ldif
index 70578e21ce4e102909a1b7b45fa84c184a997bdf..4f74869da1e46b39469dd17ddb2517e111300b43 100644
--- a/base/ca/shared/conf/schema.ldif
+++ b/base/ca/shared/conf/schema.ldif
@@ -487,3 +487,33 @@ dn: cn=schema
changetype: modify
add: objectClasses
objectClasses: ( securityDomainSessionEntry-oid NAME 'securityDomainSessionEntry' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ host $ uid $ cmsUserGroup $ dateOfCreate ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( classId-oid NAME 'classId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( certProfileIsDefault-oid NAME 'certProfileIsDefault' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( certProfileConfig-oid NAME 'certProfileConfig' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( certProfile-oid NAME 'certProfile' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( classId $ certProfileIsDefault $ certProfileConfig ) X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( certProfilesLastModified-oid NAME 'certProfilesLastModified' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 X-ORIGIN 'user defined' )
+
+dn: cn=schema
+changetype: modify
+add: objectClasses
+objectClasses: ( certProfilesInfo-oid NAME 'certProfilesInfo' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY certProfilesLastModified X-ORIGIN 'user defined' )
--
1.9.3
-------------- next part --------------
>From 732286e87aadc1bca90232b4af8c29106cbb27eb Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <frase at frase.id.au>
Date: Tue, 15 Jul 2014 02:48:35 -0400
Subject: [PATCH] add LDAPConfigStore class
The LDAPConfigStore class is an IConfigStore that reads and writes
its configuration to a given attribute and DN in an LDAP database.
---
.../com/netscape/cmscore/base/LDAPConfigStore.java | 190 +++++++++++++++++++++
1 file changed, 190 insertions(+)
create mode 100644 base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java
diff --git a/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java b/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ff477bb3cdad02092c56834e043bcd6e0108625
--- /dev/null
+++ b/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java
@@ -0,0 +1,190 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// 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; version 2 of the License.
+//
+// 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, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007, 2014 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cmscore.base;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPModification;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+
+/**
+ * LDAPConfigStore:
+ * Extends PropConfigStore with methods to load/save from/to file for
+ * persistent storage. This is a configuration store agent who
+ * reads data from an LDAP entry.
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ * @see PropConfigStore
+ */
+public class LDAPConfigStore extends PropConfigStore implements IConfigStore {
+
+ private ILdapConnFactory mDbFactory;
+ private String mDn;
+ private String mAttr;
+ private LDAPAttribute[] mAttrs;
+ private boolean mInDatabase;
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3642124526598175633L;
+
+ /**
+ * Constructs a file configuration store.
+ * <P>
+ *
+ * @param dbFactory Database connection factory
+ * @param cn Common name of record containing config store
+ * @param dn Distinguished name of record containing config store
+ * @param attr Name of attribute containing config store
+ * @param attrs Set of initial attributes if creating the entry. Should
+ * contain cn, objectclass and possibly other attributes.
+ *
+ * @exception EBaseException failed to create file configuration
+ */
+ public LDAPConfigStore(
+ ILdapConnFactory dbFactory,
+ String dn, LDAPAttribute[] attrs, String attr
+ ) throws EBaseException {
+ super(null); // top-level store without a name
+
+ mDbFactory = dbFactory;
+ mDn = dn;
+ mAttrs = attrs;
+ mAttr = attr;
+
+ LDAPConnection conn = mDbFactory.getConn();
+
+ String[] readAttrs = {mAttr};
+ try {
+ LDAPEntry ldapEntry = conn.read(mDn, readAttrs);
+
+ InputStream data = new ByteArrayInputStream( (byte[])
+ ldapEntry.getAttribute(mAttr).getByteValues().nextElement());
+ load(data);
+ }
+ catch (LDAPException e) {
+ // if there is no such object, we will create it on commit()
+ if (e.getLDAPResultCode() != LDAPException.NO_SUCH_OBJECT) {
+ throw new EBaseException(
+ "Error reading LDAPConfigStore '"
+ + mDn + "': " + e.toString()
+ );
+ }
+ }
+ catch (IOException e) {
+ throw new EBaseException(
+ "Error reading LDAPConfigStore '"
+ + mDn + "': " + e.toString()
+ );
+ }
+ finally {
+ mDbFactory.returnConn(conn);
+ }
+ }
+
+ /**
+ * Commit the configuration to the database.
+ *
+ * All uses of LDAPProfileStore at time of writing call with
+ * backup=false, so the argument is ignored.
+ *
+ * If backup becomes necessary, the constructor should be
+ * modified to take a String backupAttr, and the existing
+ * content be copied to that attribute.
+ *
+ * @param backup Ignored.
+ */
+ public void commit(boolean createBackup) throws EBaseException {
+ ByteArrayOutputStream data = new ByteArrayOutputStream();
+ save(data, null);
+
+ LDAPAttribute configAttr = new LDAPAttribute(mAttr, data.toByteArray());
+
+ LDAPConnection conn = mDbFactory.getConn();
+
+ // first attempt to modify; if modification fails (due
+ // to no such object), try and add the entry instead.
+ try {
+ try {
+ commitModify(conn, configAttr);
+ }
+ catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT) {
+ commitAdd(conn, configAttr);
+ }
+ else {
+ throw e;
+ }
+ }
+ }
+ catch (LDAPException e) {
+ throw new EBaseException(
+ "Error writing LDAPConfigStore '"
+ + mDn + "': " + e.toString()
+ );
+ }
+ finally {
+ mDbFactory.returnConn(conn);
+ }
+ }
+
+ /**
+ * Update the record via an LDAPModification.
+ *
+ * @param conn LDAP connection.
+ * @param configAttr Config store attribute.
+ * @return true on success, false if the entry does not exist.
+ */
+ private void commitModify(LDAPConnection conn, LDAPAttribute configAttr)
+ throws LDAPException
+ {
+ LDAPModification ldapMod =
+ new LDAPModification(LDAPModification.REPLACE, configAttr);
+ conn.modify(mDn, ldapMod);
+ }
+
+ /**
+ * Add the LDAPEntry via LDAPConnection.add.
+ *
+ * @param conn LDAP connection.
+ * @param configAttr Config store attribute.
+ * @return true on success, false if the entry already exists.
+ */
+ private void commitAdd(LDAPConnection conn, LDAPAttribute configAttr)
+ throws LDAPException
+ {
+ LDAPAttributeSet attrSet = new LDAPAttributeSet(mAttrs);
+ attrSet.add(configAttr);
+ LDAPEntry ldapEntry = new LDAPEntry(mDn, attrSet);
+ conn.add(ldapEntry);
+ }
+}
--
1.9.3
-------------- next part --------------
>From 392f22cd77497434e6db9af73399b4593124fdb1 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <frase at frase.id.au>
Date: Thu, 17 Jul 2014 00:24:06 -0400
Subject: [PATCH] change ProfileSubsystem to use LDAP database
---
.../dogtagpki/server/ca/rest/ProfileService.java | 14 +-
base/server/cmsbundle/src/UserMessages.properties | 2 +
.../com/netscape/cmscore/base/FileConfigStore.java | 4 +-
.../netscape/cmscore/profile/ProfileSubsystem.java | 175 ++++++++++++---------
4 files changed, 108 insertions(+), 87 deletions(-)
diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java b/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java
index 3b2f8a50ebcd18fe0098b2e92e0300645b904fa3..cf0d4db7f8bed44baf6d2abbf70a61406ddb4b7c 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java
@@ -18,7 +18,6 @@
package org.dogtagpki.server.ca.rest;
-import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.security.Principal;
@@ -244,7 +243,7 @@ public class ProfileService extends PKIService implements ProfileResource {
data.setAuthenticatorId(profile.getAuthenticatorId());
data.setAuthzAcl(profile.getAuthzAcl());
- data.setClassId(cs.getString(profileId + ".class_id"));
+ data.setClassId(ps.getProfileClassId(profileId));
data.setDescription(profile.getDescription(getLocale(headers)));
data.setEnabled(ps.isProfileEnable(profileId));
data.setEnabledBy(ps.getProfileEnableBy(profileId));
@@ -472,18 +471,15 @@ public class ProfileService extends PKIService implements ProfileResource {
auditParams.put("description", data.getDescription());
auditParams.put("visible", Boolean.toString(data.isVisible()));
- String config = CMS.getConfigStore().getString("instanceRoot") + "/ca/profiles/ca/" +
- profileId + ".cfg";
- File configFile = new File(config);
- configFile.createNewFile();
IPluginInfo info = registry.getPluginInfo("profile", data.getClassId());
- profile = ps.createProfile(profileId, data.getClassId(), info.getClassName(), config);
+ String dn = "cn=" + profileId + ",ou=certProfiles,"
+ + CMS.getConfigStore().getString("internaldb.basedn");
+ profile = ps.createProfile(profileId, data.getClassId(), info.getClassName(), dn);
profile.setName(getLocale(headers), data.getName());
profile.setDescription(getLocale(headers), data.getDescription());
profile.setVisible(data.isVisible());
profile.getConfigStore().commit(false);
- ps.createProfileConfig(profileId, data.getClassId(), config);
if (profile instanceof IProfileEx) {
// populates profile specific plugins such as
@@ -504,7 +500,7 @@ public class ProfileService extends PKIService implements ProfileResource {
return createCreatedResponse(profileData, profileData.getLink().getHref());
- } catch (EBaseException | IOException e) {
+ } catch (EBaseException e) {
CMS.debug("createProfile: error in creating profile: " + e);
e.printStackTrace();
diff --git a/base/server/cmsbundle/src/UserMessages.properties b/base/server/cmsbundle/src/UserMessages.properties
index fe43094e6b2a0531502570bc626da557fc9061ae..cd7fa18bfb1e17bc4ab4aa9e0dac06f815861291 100644
--- a/base/server/cmsbundle/src/UserMessages.properties
+++ b/base/server/cmsbundle/src/UserMessages.properties
@@ -754,6 +754,8 @@ CMS_PROFILE_CONFIG_KEY_USAGE_EXTENSION_CHECKING=Allow duplicate subject names wi
CMS_PROFILE_INTERNAL_ERROR=Profile internal error: {0}
CMS_PROFILE_DENY_OPERATION=Not authorized to do this operation.
CMS_PROFILE_DELETE_ENABLEPROFILE=Cannot delete enabled profile: {0}
+CMS_PROFILE_DELETE_UNKNOWNPROFILE=Cannot delete unknown profile: {0}
+CMS_PROFILE_DELETE_DATABASEERROR=Failed to delete profile: {0}
CMS_PROFILE_INVALID_REQUEST=Invalid Request
CMS_PROFILE_EMPTY_REQUEST_TYPE=Request type is not specified. Check your profile input.
CMS_PROFILE_CREATE_POLICY_FAILED=Failed to create profile policy: {0}
diff --git a/base/server/cmscore/src/com/netscape/cmscore/base/FileConfigStore.java b/base/server/cmscore/src/com/netscape/cmscore/base/FileConfigStore.java
index b77f86d781995e27bb0fe16135fc45a7d6fc4da3..4f8cb2743fdecc354338042a5219a9aaf6e27880 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/base/FileConfigStore.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/base/FileConfigStore.java
@@ -33,12 +33,10 @@ import com.netscape.cmsutil.util.Utils;
/**
* FileConfigStore:
- * Extends HashConfigStore with methods to load/save from/to file for
+ * Extends PropConfigStore with methods to load/save from/to file for
* persistent storage. This is a configuration store agent who
* reads data from a file.
* <P>
- * Note that a LdapConfigStore can be implemented so that it reads the configuration stores from the Ldap directory.
- * <P>
*
* @version $Revision$, $Date$
* @see PropConfigStore
diff --git a/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java
index 27e72352ef22c742b5ea09a180d440d58452dd49..aaa3b29b46ae4579a59cee9f5f7bab750a40a057 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java
@@ -17,26 +17,30 @@
// --- END COPYRIGHT BLOCK ---
package com.netscape.cmscore.profile;
-import java.io.File;
import java.util.Enumeration;
import java.util.Hashtable;
-import java.util.StringTokenizer;
import java.util.Vector;
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.IConfigStore;
import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
import com.netscape.certsrv.profile.EProfileException;
import com.netscape.certsrv.profile.IProfile;
import com.netscape.certsrv.profile.IProfileSubsystem;
import com.netscape.certsrv.registry.IPluginInfo;
import com.netscape.certsrv.registry.IPluginRegistry;
+import com.netscape.cmscore.base.LDAPConfigStore;
public class ProfileSubsystem implements IProfileSubsystem {
- private static final String PROP_LIST = "list";
- private static final String PROP_CLASS_ID = "class_id";
- private static final String PROP_CONFIG = "config";
private static final String PROP_CHECK_OWNER = "checkOwner";
private static final String PROP_ENABLE = "enable";
@@ -45,9 +49,12 @@ public class ProfileSubsystem implements IProfileSubsystem {
private IConfigStore mConfig = null;
@SuppressWarnings("unused")
private ISubsystem mOwner;
- private Vector<String> mProfileIds = new Vector<String>();
- private Hashtable<String, IProfile> mProfiles = new Hashtable<String, IProfile>();
- private Hashtable<String, String> mProfileClassIds = new Hashtable<String, String>();
+ private Vector<String> mProfileIds;
+ private Hashtable<String, IProfile> mProfiles;
+ private Hashtable<String, String> mProfileClassIds;
+ private Hashtable<String, String> mProfileDNs;
+
+ private ILdapConnFactory dbFactory;
/**
* Retrieves the name of this subsystem.
@@ -74,9 +81,21 @@ public class ProfileSubsystem implements IProfileSubsystem {
public void init(ISubsystem owner, IConfigStore config)
throws EBaseException {
CMS.debug("ProfileSubsystem: start init");
+
+ // (re)init member collections
+ mProfileIds = new Vector<String>();
+ mProfiles = new Hashtable<String, IProfile>();
+ mProfileClassIds = new Hashtable<String, String>();
+ mProfileDNs = new Hashtable<String, String>();
+
IPluginRegistry registry = (IPluginRegistry)
CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+ IConfigStore cs = CMS.getConfigStore();
+ IConfigStore dbCfg = cs.getSubStore("internaldb");
+ dbFactory = CMS.getLdapBoundConnFactory();
+ dbFactory.init(dbCfg);
+
mConfig = config;
mOwner = owner;
@@ -88,24 +107,45 @@ public class ProfileSubsystem implements IProfileSubsystem {
// *.profile2.config=config/profiles/profile2.cfg
// read profile id, implementation, and its configuration files
- String ids = config.getString(PROP_LIST, "");
- StringTokenizer st = new StringTokenizer(ids, ",");
-
- while (st.hasMoreTokens()) {
- String id = st.nextToken();
- IConfigStore subStore = config.getSubStore(id);
- String classid = subStore.getString(PROP_CLASS_ID);
- IPluginInfo info = registry.getPluginInfo("profile", classid);
- if (info == null) {
- throw new EBaseException("No plugins for type : profile, with id " + classid);
- }
- String configPath = subStore.getString(PROP_CONFIG);
+ String basedn = cs.getString("internaldb.basedn");
+ String dn = "ou=certProfiles," + basedn;
+ LDAPConnection conn = dbFactory.getConn();
+
+ String[] attrs = {"cn", "classId"};
+ try {
+ LDAPSearchResults ldapProfiles = conn.search(
+ dn, LDAPConnection.SCOPE_ONE, "(objectclass=*)", attrs, false);
+
+ while (ldapProfiles.hasMoreElements()) {
+ LDAPEntry ldapProfile = ldapProfiles.next();
+
+ String id = (String)
+ ldapProfile.getAttribute("cn").getStringValues().nextElement();
+
+ String classid = (String)
+ ldapProfile.getAttribute("classId").getStringValues().nextElement();
- CMS.debug("Start Profile Creation - " + id + " " + classid + " " + info.getClassName());
- createProfile(id, classid, info.getClassName(),
- configPath);
+ IPluginInfo info = registry.getPluginInfo("profile", classid);
+ if (info == null) {
+ throw new EBaseException("No plugins for type : profile, with id " + classid);
+ }
- CMS.debug("Done Profile Creation - " + id);
+ CMS.debug("Start Profile Creation - " + id + " " + classid + " " + info.getClassName());
+
+ createProfile(id, classid, info.getClassName(), ldapProfile.getDN());
+
+ CMS.debug("Done Profile Creation - " + id);
+ }
+ }
+ catch (LDAPException e) {
+ throw new EBaseException("Error reading profiles: " + e.toString());
+ }
+ finally {
+ try {
+ dbFactory.returnConn(conn);
+ } catch (Exception e) {
+ throw new EProfileException("Error releasing the ldap connection" + e.toString());
+ }
}
Enumeration<String> ee = getProfileIds();
@@ -121,20 +161,27 @@ public class ProfileSubsystem implements IProfileSubsystem {
* Creates a profile instance.
*/
public IProfile createProfile(String id, String classid, String className,
- String configPath)
+ String dn)
throws EProfileException {
- IProfile profile = null;
-
try {
- profile = (IProfile) Class.forName(className).newInstance();
- IConfigStore subStoreConfig = CMS.createFileConfigStore(configPath);
+ String[] objectClasses = {"top", "certProfile"};
+ LDAPAttribute[] createAttrs = {
+ new LDAPAttribute("objectclass", objectClasses),
+ new LDAPAttribute("cn", id),
+ new LDAPAttribute("classId", classid)
+ };
+
+ IConfigStore subStoreConfig = new LDAPConfigStore(
+ dbFactory, dn, createAttrs, "certProfileConfig");
CMS.debug("ProfileSubsystem: initing " + className);
+ IProfile profile = (IProfile) Class.forName(className).newInstance();
profile.setId(id);
profile.init(this, subStoreConfig);
mProfileIds.addElement(id);
mProfiles.put(id, profile);
mProfileClassIds.put(id, classid);
+ mProfileDNs.put(id, dn);
return profile;
} catch (Exception e) {
// throw exceptions
@@ -145,62 +192,46 @@ public class ProfileSubsystem implements IProfileSubsystem {
}
public void deleteProfile(String id, String configPath) throws EProfileException {
-
if (isProfileEnable(id)) {
throw new EProfileException("CMS_PROFILE_DELETE_ENABLEPROFILE");
}
- String ids = "";
- try {
- ids = mConfig.getString(PROP_LIST, "");
- } catch (Exception e) {
+ String dn = mProfileDNs.get(id);
+ if (dn == null) {
+ throw new EProfileException("CMS_PROFILE_DELETE_UNKNOWNPROFILE");
}
- StringTokenizer tokenizer = new StringTokenizer(ids, ",");
- StringBuffer list = new StringBuffer();
-
- while (tokenizer.hasMoreTokens()) {
- String element = tokenizer.nextToken();
-
- if (!element.equals(id)) {
- list.append(element + ",");
+ LDAPConnection conn;
+ try {
+ conn = dbFactory.getConn();
+ }
+ catch (ELdapException e) {
+ throw new EProfileException("Error acquiring the ldap connection" + e.toString());
+ }
+ try {
+ conn.delete(dn);
+ }
+ catch (LDAPException e) {
+ throw new EProfileException("CMS_PROFILE_DELETE_DATABASEERROR");
+ }
+ finally {
+ try {
+ dbFactory.returnConn(conn);
+ } catch (Exception e) {
+ throw new EProfileException("Error releasing the ldap connection" + e.toString());
}
}
- if (list.length() != 0)
- list.deleteCharAt(list.length() - 1);
- mConfig.putString(PROP_LIST, list.toString());
- mConfig.removeSubStore(id);
- File file1 = new File(configPath);
-
- if (!file1.delete()) {
- CMS.debug("ProfileSubsystem: deleteProfile: Cannot delete the configuration file : " + configPath);
- }
mProfileIds.removeElement(id);
mProfiles.remove(id);
mProfileClassIds.remove(id);
- try {
- CMS.getConfigStore().commit(false);
- } catch (Exception e) {
- }
+ mProfileDNs.remove(id);
}
public void createProfileConfig(String id, String classId,
String configPath)
throws EProfileException {
- try {
- if (mProfiles.size() > 0) {
- mConfig.putString(PROP_LIST,
- mConfig.getString(PROP_LIST) + "," + id);
- } else {
- mConfig.putString(PROP_LIST, id);
- }
- mConfig.putString(id + "." + PROP_CLASS_ID, classId);
- mConfig.putString(id + "." + PROP_CONFIG, configPath);
- CMS.getConfigStore().commit(true);
- } catch (EBaseException e) {
- CMS.debug(e.toString());
- }
+ // nothing to do
}
/**
@@ -219,6 +250,7 @@ public class ProfileSubsystem implements IProfileSubsystem {
mProfileIds.clear();
mProfiles.clear();
mProfileClassIds.clear();
+ mProfileDNs.clear();
}
/**
@@ -231,13 +263,6 @@ public class ProfileSubsystem implements IProfileSubsystem {
return mConfig;
}
- /**
- * Adds a profile.
- */
- public void addProfile(String id, IProfile profile)
- throws EProfileException {
- }
-
public boolean isProfileEnable(String id) {
IProfile profile = mProfiles.get(id);
String enable = null;
--
1.9.3
-------------- next part --------------
>From 4813bf7d9052bbf6d1d68771f05329891c1acbc4 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <frase at frase.id.au>
Date: Tue, 22 Jul 2014 00:03:47 -0400
Subject: [PATCH] add configuration to disable a dynamic subsystem
Add the ability to disable a dynamic subsystem by configuring it
with `enabled=false' in CS.cfg. Subsystems are enabled by default.
This will be used during `pkispawn' to disable the ProfileSubsystem
until the database configuration is established.
---
.../src/com/netscape/cmscore/apps/CMSEngine.java | 36 +++++++++++++---------
1 file changed, 21 insertions(+), 15 deletions(-)
diff --git a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
index 68c64824e37bcad282a5bbeabf6b943fabf39481..b6e92bfbdd372d3980c584ba8c9571a4ec52ec8d 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
@@ -208,25 +208,25 @@ public class CMSEngine implements ICMSEngine {
// static subsystems - must be singletons
private static SubsystemInfo[] mStaticSubsystems = {
new SubsystemInfo(
- Debug.ID, Debug.getInstance()),
+ Debug.ID, Debug.getInstance(), true),
new SubsystemInfo(LogSubsystem.ID,
- LogSubsystem.getInstance()),
+ LogSubsystem.getInstance(), true),
new SubsystemInfo(
- JssSubsystem.ID, JssSubsystem.getInstance()),
+ JssSubsystem.ID, JssSubsystem.getInstance(), true),
new SubsystemInfo(
- DBSubsystem.ID, DBSubsystem.getInstance()),
+ DBSubsystem.ID, DBSubsystem.getInstance(), true),
new SubsystemInfo(
- UGSubsystem.ID, UGSubsystem.getInstance()),
+ UGSubsystem.ID, UGSubsystem.getInstance(), true),
new SubsystemInfo(
- PluginRegistry.ID, new PluginRegistry()),
+ PluginRegistry.ID, new PluginRegistry(), true),
new SubsystemInfo(
- OidLoaderSubsystem.ID, OidLoaderSubsystem.getInstance()),
+ OidLoaderSubsystem.ID, OidLoaderSubsystem.getInstance(), true),
new SubsystemInfo(
- X500NameSubsystem.ID, X500NameSubsystem.getInstance()),
+ X500NameSubsystem.ID, X500NameSubsystem.getInstance(), true),
// skip TP subsystem;
// problem in needing dbsubsystem in constructor. and it's not used.
new SubsystemInfo(
- RequestSubsystem.ID, RequestSubsystem.getInstance()),
+ RequestSubsystem.ID, RequestSubsystem.getInstance(), true),
};
// dynamic subsystems are loaded at init time, not neccessarily singletons.
@@ -235,11 +235,11 @@ public class CMSEngine implements ICMSEngine {
// final static subsystems - must be singletons.
private static SubsystemInfo[] mFinalSubsystems = {
new SubsystemInfo(
- AuthSubsystem.ID, AuthSubsystem.getInstance()),
+ AuthSubsystem.ID, AuthSubsystem.getInstance(), true),
new SubsystemInfo(
- AuthzSubsystem.ID, AuthzSubsystem.getInstance()),
+ AuthzSubsystem.ID, AuthzSubsystem.getInstance(), true),
new SubsystemInfo(
- JobsScheduler.ID, JobsScheduler.getInstance()),
+ JobsScheduler.ID, JobsScheduler.getInstance(), true),
};
private static final int IP = 0;
@@ -892,6 +892,7 @@ public class CMSEngine implements ICMSEngine {
ssconfig.getSubStore(String.valueOf(i));
String id = config.getString(PROP_ID);
String classname = config.getString(PROP_CLASS);
+ boolean enabled = config.getBoolean("enabled", true);
ISubsystem ss = null;
try {
@@ -906,7 +907,7 @@ public class CMSEngine implements ICMSEngine {
throw new EBaseException(
CMS.getUserMessage("CMS_BASE_LOAD_FAILED_1", id, e.toString()));
}
- mDynSubsystems[i] = new SubsystemInfo(id, ss);
+ mDynSubsystems[i] = new SubsystemInfo(id, ss, enabled);
Debug.trace("loaded dyn subsystem " + id);
}
}
@@ -928,6 +929,10 @@ public class CMSEngine implements ICMSEngine {
IConfigStore ssConfig = mConfig.getSubStore(id);
CMS.debug("CMSEngine: initSubsystem id=" + id);
+ if (!ssinfo.mEnabled) {
+ CMS.debug("CMSEngine: subsystem disabled id=" + id);
+ return;
+ }
if (doSetId)
ss.setId(id);
CMS.debug("CMSEngine: ready to init id=" + id);
@@ -2000,10 +2005,11 @@ class WarningListener implements ILogEventListener {
class SubsystemInfo {
public final String mId;
public final ISubsystem mInstance;
+ public final boolean mEnabled;
- public SubsystemInfo(String id, ISubsystem ssInstance) {
+ public SubsystemInfo(String id, ISubsystem ssInstance, boolean enabled) {
mId = id;
mInstance = ssInstance;
+ mEnabled = enabled;
}
-
}
--
1.9.3
-------------- next part --------------
>From fe1c42feb64fdc21b185e2aa62c58c2908b5fd2d Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <frase at frase.id.au>
Date: Fri, 18 Jul 2014 02:01:58 -0400
Subject: [PATCH] import profiles when spawning CA instance
---
base/ca/shared/conf/CS.cfg.in | 1 +
.../server/ca/rest/CAInstallerService.java | 118 +++++++++++++++++++++
2 files changed, 119 insertions(+)
diff --git a/base/ca/shared/conf/CS.cfg.in b/base/ca/shared/conf/CS.cfg.in
index 4ab8974e6340d81d23bb7f5ea05a07b0936b6463..13ed9c4b9f43f8e76c6f5faffbc78c4a61ccf718 100644
--- a/base/ca/shared/conf/CS.cfg.in
+++ b/base/ca/shared/conf/CS.cfg.in
@@ -1139,6 +1139,7 @@ subsystem.0.class=com.netscape.ca.CertificateAuthority
subsystem.0.id=ca
subsystem.1.class=com.netscape.cmscore.profile.ProfileSubsystem
subsystem.1.id=profile
+subsystem.1.enabled=false
subsystem.2.class=com.netscape.cmscore.selftests.SelfTestSubsystem
subsystem.2.id=selftests
subsystem.3.class=com.netscape.cmscore.cert.CrossCertPairSubsystem
diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CAInstallerService.java b/base/ca/src/org/dogtagpki/server/ca/rest/CAInstallerService.java
index bb823eece4729599b6badd9ca0e24ef560b9f279..431a0c548818c1810051d47a6484520dccd8e142 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/CAInstallerService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/CAInstallerService.java
@@ -17,13 +17,27 @@
// --- END COPYRIGHT BLOCK ---
package org.dogtagpki.server.ca.rest;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+import netscape.ldap.LDAPAttribute;
+
import org.dogtagpki.server.rest.SystemConfigService;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
import com.netscape.certsrv.base.PKIException;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.registry.IPluginInfo;
+import com.netscape.certsrv.registry.IPluginRegistry;
import com.netscape.certsrv.system.ConfigurationRequest;
import com.netscape.cms.servlet.csadmin.ConfigurationUtils;
+import com.netscape.cmscore.base.LDAPConfigStore;
+
/**
* @author alee
@@ -64,5 +78,109 @@ public class CAInstallerService extends SystemConfigService {
CMS.debug(e);
throw new PKIException("Errors in determining if security domain host is a master CA");
}
+
+ try {
+ cs.remove("subsystem.1.enabled");
+ } catch (Exception e) {
+ CMS.debug(e);
+ throw new PKIException("Error enabling ProfileSubsystem");
+ }
+ }
+
+ @Override
+ public void initializeDatabase(ConfigurationRequest data) {
+ super.initializeDatabase(data);
+
+ if (!data.isClone()) {
+ try {
+ importProfiles("/usr/share/pki");
+ } catch (Exception e) {
+ throw new PKIException("Error importing profiles.");
+ }
+ }
+ }
+
+ /**
+ * Import profiles from the filesystem into the database.
+ *
+ * @param configRoot Where to look for the profile files. For a
+ * fresh installation this should be
+ * "/usr/share/pki". For existing installations it
+ * should be CMS.getConfigStore().getString("instanceRoot").
+ *
+ */
+ public static void importProfiles(String configRoot)
+ throws EBaseException, ELdapException {
+ IPluginRegistry registry = (IPluginRegistry)
+ CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+ IConfigStore cfg = CMS.getConfigStore();
+ IConfigStore profileCfg = cfg.getSubStore("profile");
+ String profileIds = profileCfg.getString("list", "");
+ StringTokenizer st = new StringTokenizer(profileIds, ",");
+
+ IConfigStore dbCfg = cfg.getSubStore("internaldb");
+ ILdapConnFactory dbFactory = CMS.getLdapBoundConnFactory();
+ dbFactory.init(dbCfg);
+
+ while (st.hasMoreTokens()) {
+ String profileId = st.nextToken();
+ IConfigStore profileSubCfg = profileCfg.getSubStore(profileId);
+ String classId = profileSubCfg.getString("class_id", "");
+ try {
+ IPluginInfo info = registry.getPluginInfo("profile", classId);
+ if (info == null) {
+ throw new EBaseException("No plugins for type : profile, with id " + classId);
+ }
+ String className = info.getClassName();
+
+ String profilePath = configRoot + "/ca/profiles/ca/" + profileId + ".cfg";
+ CMS.debug("Importing profile '" + profileId + "' from " + profilePath);
+ importProfile(dbFactory, classId, profileId, profilePath);
+ }
+ catch (EBaseException e) {
+ CMS.debug("Error importing profile '" + profileId + "': " + e.toString());
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * Import one profile from the filesystem into the database.
+ *
+ * @param dbFactory LDAP connection factory.
+ * @param profileFile The profile to import.
+ */
+ public static void importProfile(
+ ILdapConnFactory dbFactory, String classId,
+ String profileId, String profilePath)
+ throws EBaseException {
+
+ IConfigStore cfg = CMS.getConfigStore();
+ String basedn = cfg.getString("internaldb.basedn", "");
+
+ String dn = "cn=" + profileId + ",ou=certProfiles," + basedn;
+
+ String[] objectClasses = {"top", "certProfile"};
+ LDAPAttribute[] createAttrs = {
+ new LDAPAttribute("objectclass", objectClasses),
+ new LDAPAttribute("cn", profileId),
+ new LDAPAttribute("classId", classId)
+ };
+
+ IConfigStore configStore = new LDAPConfigStore(
+ dbFactory, dn, createAttrs, "certProfileConfig");
+
+ try {
+ FileInputStream input = new FileInputStream(profilePath);
+ configStore.load(input);
+ }
+ catch (FileNotFoundException e) {
+ throw new EBaseException("Could not find file for profile: " + profileId);
+ }
+ catch (IOException e) {
+ throw new EBaseException("Error loading data for profile: " + profileId);
+ }
+
+ configStore.commit(false /* no backup */);
}
}
--
1.9.3
-------------- next part --------------
>From 7eca0dd3f819588d53e71dea84ce23a21186c586 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <frase at frase.id.au>
Date: Wed, 23 Jul 2014 02:40:07 -0400
Subject: [PATCH] add "pki ca profile show-raw" CLI command
---
.../dogtagpki/server/ca/rest/ProfileService.java | 47 +++++-----
.../netscape/certsrv/profile/ProfileClient.java | 5 +
.../netscape/certsrv/profile/ProfileResource.java | 8 +-
.../com/netscape/cmstools/profile/ProfileCLI.java | 1 +
.../cmstools/profile/ProfileShowRawCLI.java | 102 +++++++++++++++++++++
5 files changed, 141 insertions(+), 22 deletions(-)
create mode 100644 base/java-tools/src/com/netscape/cmstools/profile/ProfileShowRawCLI.java
diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java b/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java
index cf0d4db7f8bed44baf6d2abbf70a61406ddb4b7c..9d851145f5e681f1044f81654130a2d0114ce36d 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java
@@ -18,6 +18,7 @@
package org.dogtagpki.server.ca.rest;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;
import java.security.Principal;
@@ -163,9 +164,7 @@ public class ProfileService extends PKIService implements ProfileResource {
return createOKResponse(infos);
}
- @Override
- public Response retrieveProfile(String profileId) throws ProfileNotFoundException {
- ProfileData data = null;
+ private IProfile getProfile(String profileId) throws ProfileNotFoundException {
boolean visibleOnly = true;
if (profileId == null) {
@@ -185,24 +184,12 @@ public class ProfileService extends PKIService implements ProfileResource {
visibleOnly = false;
}
- Enumeration<String> profileIds = ps.getProfileIds();
-
- IProfile profile = null;
- if (profileIds != null) {
- while (profileIds.hasMoreElements()) {
- String id = profileIds.nextElement();
-
- if (id.equals(profileId)) {
-
- try {
- profile = ps.getProfile(profileId);
- } catch (EProfileException e) {
- e.printStackTrace();
- throw new ProfileNotFoundException(profileId);
- }
- break;
- }
- }
+ IProfile profile;
+ try {
+ profile = ps.getProfile(profileId);
+ } catch (EProfileException e) {
+ e.printStackTrace();
+ throw new ProfileNotFoundException(profileId);
}
if (profile == null) {
@@ -213,6 +200,14 @@ public class ProfileService extends PKIService implements ProfileResource {
throw new ProfileNotFoundException(profileId);
}
+ return profile;
+ }
+
+ @Override
+ public Response retrieveProfile(String profileId) throws ProfileNotFoundException {
+ IProfile profile = getProfile(profileId);
+
+ ProfileData data = null;
try {
data = createProfileData(profileId);
} catch (EBaseException e) {
@@ -228,6 +223,16 @@ public class ProfileService extends PKIService implements ProfileResource {
return createOKResponse(data);
}
+ @Override
+ public Response retrieveProfileRaw(String profileId)
+ throws ProfileNotFoundException {
+ IProfile profile = getProfile(profileId);
+ ByteArrayOutputStream data = new ByteArrayOutputStream();
+ profile.getConfigStore().save(data, null);
+ return createOKResponse(data.toByteArray());
+ }
+
+
public ProfileData createProfileData(String profileId) throws EBaseException {
IProfile profile;
diff --git a/base/common/src/com/netscape/certsrv/profile/ProfileClient.java b/base/common/src/com/netscape/certsrv/profile/ProfileClient.java
index 51d159aca687719a2dace939da5b09c4809872ec..94b087230d46db342dff365da3c57734d98f02dc 100644
--- a/base/common/src/com/netscape/certsrv/profile/ProfileClient.java
+++ b/base/common/src/com/netscape/certsrv/profile/ProfileClient.java
@@ -45,6 +45,11 @@ public class ProfileClient extends Client {
return client.getEntity(response, ProfileData.class);
}
+ public byte[] retrieveProfileRaw(String id) {
+ Response response = profileClient.retrieveProfileRaw(id);
+ return client.getEntity(response, byte[].class);
+ }
+
public ProfileDataInfos listProfiles(Integer start, Integer size) {
Response response = profileClient.listProfiles(start, size);
return client.getEntity(response, ProfileDataInfos.class);
diff --git a/base/common/src/com/netscape/certsrv/profile/ProfileResource.java b/base/common/src/com/netscape/certsrv/profile/ProfileResource.java
index 87449b27e749c6088f65b53192eb5ac101263f1e..d0b84eeb61688fe4bbc107c2bdd368f848e568cd 100644
--- a/base/common/src/com/netscape/certsrv/profile/ProfileResource.java
+++ b/base/common/src/com/netscape/certsrv/profile/ProfileResource.java
@@ -31,6 +31,12 @@ public interface ProfileResource {
@ACLMapping("profiles.read")
public Response retrieveProfile(@PathParam("id") String id);
+ @GET
+ @Path("{id}/raw")
+ @ClientResponseType(entityType=byte[].class)
+ @ACLMapping("profiles.read")
+ public Response retrieveProfileRaw(@PathParam("id") String id);
+
@POST
@ClientResponseType(entityType=ProfileData.class)
@ACLMapping("profiles.create")
@@ -53,4 +59,4 @@ public interface ProfileResource {
@ClientResponseType(entityType=Void.class)
@ACLMapping("profiles.delete")
public Response deleteProfile(@PathParam("id") String id);
-}
\ No newline at end of file
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java b/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java
index 732b597afd1dbb5b9440d451f34b2f39e20fb904..a57c741946b40f0cc02a10acaf6d895081b151d9 100644
--- a/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java
@@ -30,6 +30,7 @@ public class ProfileCLI extends CLI {
addModule(new ProfileFindCLI(this));
addModule(new ProfileShowCLI(this));
+ addModule(new ProfileShowRawCLI(this));
addModule(new ProfileAddCLI(this));
addModule(new ProfileModifyCLI(this));
addModule(new ProfileRemoveCLI(this));
diff --git a/base/java-tools/src/com/netscape/cmstools/profile/ProfileShowRawCLI.java b/base/java-tools/src/com/netscape/cmstools/profile/ProfileShowRawCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..a15c4e08629a759a2cd66ecfa79578fd9eab6e2e
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/profile/ProfileShowRawCLI.java
@@ -0,0 +1,102 @@
+//--- BEGIN COPYRIGHT BLOCK ---
+//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; version 2 of the License.
+//
+//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, write to the Free Software Foundation, Inc.,
+//51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+//(C) 2014 Red Hat, Inc.
+//All rights reserved.
+//--- END COPYRIGHT BLOCK ---
+
+package com.netscape.cmstools.profile;
+
+import java.io.FileOutputStream;
+import java.util.Arrays;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
+
+import com.netscape.certsrv.profile.ProfileData;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+public class ProfileShowRawCLI extends CLI {
+
+ public ProfileCLI profileCLI;
+
+ public ProfileShowRawCLI(ProfileCLI profileCLI) {
+ super("show-raw", "Show profiles (config-store format)", profileCLI);
+ this.profileCLI = profileCLI;
+
+ createOptions();
+ }
+
+ public void printHelp() {
+ formatter.printHelp(getFullName() + " <Profile ID> [OPTIONS...]", options);
+ }
+
+ public void createOptions() {
+ Option option = new Option(null, "output", true, "Output filename");
+ option.setArgName("filename");
+ options.addOption(option);
+ }
+
+ public void execute(String[] args) throws Exception {
+ // Always check for "--help" prior to parsing
+ if (Arrays.asList(args).contains("--help")) {
+ // Display usage
+ printHelp();
+ System.exit(0);
+ }
+
+ CommandLine cmd = null;
+
+ try {
+ cmd = parser.parse(options, args);
+ } catch (ParseException e) {
+ System.err.println("Error: " + e.getMessage());
+ printHelp();
+ System.exit(-1);
+ }
+
+ String[] cmdArgs = cmd.getArgs();
+
+ if (cmdArgs.length < 1) {
+ System.err.println("Error: No Profile ID specified.");
+ printHelp();
+ System.exit(-1);
+ }
+
+ String profileId = cmdArgs[0];
+
+ String filename = null;
+ if (cmd.hasOption("output")) {
+ filename = cmd.getOptionValue("output");
+
+ if (filename == null || filename.trim().length() == 0) {
+ System.err.println("Error: Missing output file name.");
+ printHelp();
+ System.exit(-1);
+ }
+ }
+
+ byte[] profileConfig = profileCLI.profileClient.retrieveProfileRaw(profileId);
+
+ MainCLI.printMessage("Profile \"" + profileId + "\"");
+
+ if (filename != null) {
+ (new FileOutputStream(filename)).write(profileConfig);
+ } else {
+ System.out.println(new String(profileConfig));
+ }
+ }
+}
--
1.9.3
More information about the Pki-devel
mailing list