diff --git a/README.md b/README.md index 51bf769..1c1684c 100644 --- a/README.md +++ b/README.md @@ -1,205 +1,205 @@ -# Executable LSC Plugin - -[![Build Status](https://github.com/lsc-project/lsc-executable-plugin/actions/workflows/maven.yml/badge.svg)](https://github.com/lsc-project/lsc-executable-plugin/actions/workflows/maven.yml) - -Presentation -============ - -This plugin enables any sysadmin to use LSC on a custom source or destination without writing Java code, only by wrapping each method through a script command. - -Scripts must return on the standard output the attended content. Error stream is reserved for messages that must be handle like error message. A non null return code indicates that the script encountered an error. - -The design of a source connector only requires two scripts : - -* the LIST script which provides the entries DN list -* the GET script which returns an full entry based on its DN - -The design of a destination connector requires 4 more scripts : - -* the ADD script which adds a new entry (add operation) -* the UPDATE script which updates an existing entry (modify operation) -* the REMOVE script which deletes an existing entry (delete operation) -* the RENAME script which changes the DN of an existing entry (modrdn operation) - -There are two different destination connectors: - -* Executable LDAP destination service: LIST and GET operations are done with LDAP destination service (see LSC main documentation about **LDAP destination service**) -* Executable LDIF destination service: LIST and GET operations are done by scripts, like the one used in Executable LDIF source service - -Installation -============ - -Get the Executable plugin. Then copy the plugin (.jar file) inside LSC lib directory. (for example `/usr/lib/lsc`) - -Configuration -============= - -XML namespace -------------- - -You need to adapt the namespace of the main markup to import `exec` namespace: - -```xml - - -... - -``` - -Connection ----------- - -You need to define a fake connection for the plugin: - -```xml - - executable - fake - fake - fake - -``` - -Executable LDIF Source Service ------------------------------- - -The configuration part of the source service is: - -```xml - - user-src-service - - - user-src-service-exec - - path/to/listscript - path/to/getscript - - keyvalue - key2value2 - - - -``` - -Parameters are: - -* `listScript`: Path to the script used to list all entries. The script must be executable. -* `getScript`: Path to the script used to list a specific entry. The script must be executable. -* `variables`: allow to define variables that will be passed as environment variables to scripts. - -Executable LDAP Destination Service ------------------------------------ - -The configuration part of the destination service is: - -```xml - - user-dst-service - - - user-dst-service-exec - - ou=users,dc=example,dc=com - - uid - - - cn - givenName - objectclass - sn - uid - - - - path/to/addscript - path/to/updatescript - path/to/removescript - path/to/renamescript - - keyvalue - key2value2 - - - -``` - -> **_NOTE:_** Here the connection do not refer to fake plugin connection, but to a LDAP connection. (see LSC main documentation about **LDAP connection**) - -Parameters are: - -* `addScript`: Path to the script used to add an entry. The script must be executable. -* `updateScript`: Path to the script used to update an entry. The script must be executable. -* `removeScript`: Path to the script used to remove an entry. The script must be executable. -* `renameScript`: Path to the script used to rename an entry. The script must be executable. -* `variables`: allow to define variables that will be passed as environment variables to scripts. -* `Other parameters`: see LSC main documentation about **LDAP destination service**. - -Executable LDIF Destination Service ------------------------------------ - -The configuration part of the destination service is: - -```xml - - user-dst-service - - - user-dst-service-exec - - path/to/listscript - path/to/getscript - path/to/addscript - path/to/updatescript - path/to/removescript - path/to/renamescript - - keyvalue - key2value2 - - - uid - nom - prenom - - - -``` - -Parameters are: - -* `listScript`: Path to the script used to list all entries. The script must be executable. -* `getScript`: Path to the script used to list a specific entry. The script must be executable. -* `addScript`: Path to the script used to add an entry. The script must be executable. -* `updateScript`: Path to the script used to update an entry. The script must be executable. -* `removeScript`: Path to the script used to remove an entry. The script must be executable. -* `renameScript`: Path to the script used to rename an entry. The script must be executable. -* `variables`: allow to define variables that will be passed as environment variables to scripts. -* `fetchedAttributes`: list of destination attributes that should be taken into account for the synchronization. - -Plugin loading -============== - -To load the plugin into LSC, you need to modify `JAVA_OPTS`: - -```xml -JAVA_OPTS="-DLSC.PLUGINS.PACKAGEPATH=org.lsc.plugins.connectors.executable.generated" -``` - -For example, to run a user synchronization: -``` -JAVA_OPTS="-DLSC.PLUGINS.PACKAGEPATH=org.lsc.plugins.connectors.executable.generated" /usr/bin/lsc -f /etc/lsc/executable/ -s user -t 1 -``` - -> **_NOTE:_** The use of -t 1 limits LSC to one thread. - -Scripts -======= - -* [How to write your own scripts](./doc/howto-scripts.md) -* Sample scripts: - * [Shell wrappers to LDAP clients](./doc/bash-ldapclients.md) (GET, LIST, ADD, REMOVE, UPDATE, RENAME) - * [Perl wrappers to CSV file](./doc/perl-csv.md) (GET, LIST) - * [Perl wrappers for LDIF inputs](./doc/perl-ldif.md) (ADD, REMOVE, UPDATE, RENAME) - +# Executable LSC Plugin + +[![Build Status](https://github.com/lsc-project/lsc-executable-plugin/actions/workflows/maven.yml/badge.svg)](https://github.com/lsc-project/lsc-executable-plugin/actions/workflows/maven.yml) + +Presentation +============ + +This plugin enables any sysadmin to use LSC on a custom source or destination without writing Java code, only by wrapping each method through a script command. + +Scripts must return on the standard output the attended content. Error stream is reserved for messages that must be handle like error message. A non null return code indicates that the script encountered an error. + +The design of a source connector only requires two scripts : + +* the LIST script which provides the entries DN list +* the GET script which returns an full entry based on its DN + +The design of a destination connector requires 4 more scripts : + +* the ADD script which adds a new entry (add operation) +* the UPDATE script which updates an existing entry (modify operation) +* the REMOVE script which deletes an existing entry (delete operation) +* the RENAME script which changes the DN of an existing entry (modrdn operation) + +There are two different destination connectors: + +* Executable LDAP destination service: LIST and GET operations are done with LDAP destination service (see LSC main documentation about **LDAP destination service**) +* Executable LDIF destination service: LIST and GET operations are done by scripts, like the one used in Executable LDIF source service + +Installation +============ + +Get the Executable plugin. Then copy the plugin (.jar file) inside LSC lib directory. (for example `/usr/lib/lsc`) + +Configuration +============= + +XML namespace +------------- + +You need to adapt the namespace of the main markup to import `exec` namespace: + +```xml + + +... + +``` + +Connection +---------- + +You need to define a fake connection for the plugin: + +```xml + + executable + fake + fake + fake + +``` + +Executable LDIF Source Service +------------------------------ + +The configuration part of the source service is: + +```xml + + user-src-service + + + user-src-service-exec + + path/to/listscript + path/to/getscript + + keyvalue + key2value2 + + + +``` + +Parameters are: + +* `listScript`: Path to the script used to list all entries. The script must be executable. +* `getScript`: Path to the script used to list a specific entry. The script must be executable. +* `variables`: allow to define variables that will be passed as environment variables to scripts. + +Executable LDAP Destination Service +----------------------------------- + +The configuration part of the destination service is: + +```xml + + user-dst-service + + + user-dst-service-exec + + ou=users,dc=example,dc=com + + uid + + + cn + givenName + objectclass + sn + uid + + + + path/to/addscript + path/to/updatescript + path/to/removescript + path/to/renamescript + + keyvalue + key2value2 + + + +``` + +> **_NOTE:_** Here the connection do not refer to fake plugin connection, but to a LDAP connection. (see LSC main documentation about **LDAP connection**) + +Parameters are: + +* `addScript`: Path to the script used to add an entry. The script must be executable. +* `updateScript`: Path to the script used to update an entry. The script must be executable. +* `removeScript`: Path to the script used to remove an entry. The script must be executable. +* `renameScript`: Path to the script used to rename an entry. The script must be executable. +* `variables`: allow to define variables that will be passed as environment variables to scripts. +* `Other parameters`: see LSC main documentation about **LDAP destination service**. + +Executable LDIF Destination Service +----------------------------------- + +The configuration part of the destination service is: + +```xml + + user-dst-service + + + user-dst-service-exec + + path/to/listscript + path/to/getscript + path/to/addscript + path/to/updatescript + path/to/removescript + path/to/renamescript + + keyvalue + key2value2 + + + uid + nom + prenom + + + +``` + +Parameters are: + +* `listScript`: Path to the script used to list all entries. The script must be executable. +* `getScript`: Path to the script used to list a specific entry. The script must be executable. +* `addScript`: Path to the script used to add an entry. The script must be executable. +* `updateScript`: Path to the script used to update an entry. The script must be executable. +* `removeScript`: Path to the script used to remove an entry. The script must be executable. +* `renameScript`: Path to the script used to rename an entry. The script must be executable. +* `variables`: allow to define variables that will be passed as environment variables to scripts. +* `fetchedAttributes`: list of destination attributes that should be taken into account for the synchronization. + +Plugin loading +============== + +To load the plugin into LSC, you need to modify `JAVA_OPTS`: + +```xml +JAVA_OPTS="-DLSC.PLUGINS.PACKAGEPATH=org.lsc.plugins.connectors.executable.generated" +``` + +For example, to run a user synchronization: +``` +JAVA_OPTS="-DLSC.PLUGINS.PACKAGEPATH=org.lsc.plugins.connectors.executable.generated" /usr/bin/lsc -f /etc/lsc/executable/ -s user -t 1 +``` + +> **_NOTE:_** The use of -t 1 limits LSC to one thread. + +Scripts +======= + +* [How to write your own scripts](./doc/howto-scripts.md) +* Sample scripts: + * [Shell wrappers to LDAP clients](./doc/bash-ldapclients.md) (GET, LIST, ADD, REMOVE, UPDATE, RENAME) + * [Perl wrappers to CSV file](./doc/perl-csv.md) (GET, LIST) + * [Perl wrappers for LDIF inputs](./doc/perl-ldif.md) (ADD, REMOVE, UPDATE, RENAME) + diff --git a/pom.xml b/pom.xml index a2fba07..84ddf6d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.lsc.plugins.connectors executable LDAP Synchronization Connector Executable connector - 1.4-SNAPSHOT + 1.4 This project provides a Executable source / destination plugin for LSC @@ -92,9 +92,9 @@ - org.jvnet.jaxb2.maven2 - maven-jaxb2-plugin - 0.15.3 + org.jvnet.jaxb + jaxb-maven-plugin + 4.0.16 @@ -103,7 +103,7 @@ - false + true src/main/java org.lsc.plugins.connectors.executable.generated src/main/resources/schemas @@ -111,17 +111,37 @@ *.episode src/main/resources/schemas + + lsc-executable-1.0.xsd + true - -Xdefault-value + -Xannotate - false + true + + + org.jvnet.jaxb + jaxb-plugin-annotate + 4.0.16 + + - org.jvnet.jaxb2_commons - jaxb2-default-value - 1.1 + com.sun.xml.bind + jaxb-core + 4.0.9 + + + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.5 + + + com.sun.xml.bind + jaxb-impl + 4.0.9 @@ -392,9 +412,14 @@ org.lsc lsc-core - 2.2 + 2.3 jar + + com.sleepycat + je + 18.3.12 + junit junit diff --git a/src/main/java/org/lsc/plugins/connectors/executable/AbstractExecutableLdifService.java b/src/main/java/org/lsc/plugins/connectors/executable/AbstractExecutableLdifService.java index 1eb59c7..29fc34e 100644 --- a/src/main/java/org/lsc/plugins/connectors/executable/AbstractExecutableLdifService.java +++ b/src/main/java/org/lsc/plugins/connectors/executable/AbstractExecutableLdifService.java @@ -25,6 +25,7 @@ import org.apache.directory.api.ldap.model.ldif.LdifEntry; import org.apache.directory.api.ldap.model.ldif.LdifReader; import org.lsc.LscDatasets; +import org.lsc.Task; import org.lsc.beans.IBean; import org.lsc.configuration.ConnectionType; import org.lsc.exception.LscServiceException; @@ -62,7 +63,7 @@ public abstract class AbstractExecutableLdifService implements IService { * @return The bean, or null if not found * @throws LscServiceException May throw a {@link LscServiceException} if there is any error with LDIF conversion */ - public IBean getBean(String pivotName, LscDatasets pivotAttributes, boolean fromSameService) throws LscServiceException { + public IBean getBean(Task task, String pivotName, LscDatasets pivotAttributes, boolean fromSameService) throws LscServiceException { String output = executeWithReturn(getParameters(getScript, pivotName), getEnv(), toLdif(pivotAttributes)); Collection entries = fromLdif(output); if (entries.size() != 1) { @@ -79,7 +80,7 @@ public IBean getBean(String pivotName, LscDatasets pivotAttributes, boolean from * attribute names and values (never null) * @throws LscServiceException */ - public Map getListPivots() throws LscServiceException { + public Map getListPivots(Task task) throws LscServiceException { Map map = null; String output = executeWithReturn(getParameters(listScript), getEnv(), ""); Collection beans = fromLdif(output); diff --git a/src/main/java/org/lsc/plugins/connectors/executable/ExecutableLdapDestinationService.java b/src/main/java/org/lsc/plugins/connectors/executable/ExecutableLdapDestinationService.java index f7be748..5eabe7e 100644 --- a/src/main/java/org/lsc/plugins/connectors/executable/ExecutableLdapDestinationService.java +++ b/src/main/java/org/lsc/plugins/connectors/executable/ExecutableLdapDestinationService.java @@ -59,6 +59,7 @@ import org.lsc.LscDatasets; import org.lsc.LscModifications; +import org.lsc.Task; import org.lsc.beans.IBean; import org.lsc.configuration.ConnectionType; import org.lsc.configuration.KeysValuesMap.Entry; @@ -154,8 +155,8 @@ public ExecutableLdapDestinationService(TaskType task) throws LscServiceConfigur * directory, or if more than one object would be returned. */ @Override - public IBean getBean(String pivotName, LscDatasets pivotAttributes, boolean fromSameService) throws LscServiceException { - return sjds.getBean(pivotName, pivotAttributes, fromSameService); + public IBean getBean(Task task, String pivotName, LscDatasets pivotAttributes, boolean fromSameService) throws LscServiceException { + return sjds.getBean(task, pivotName, pivotAttributes, fromSameService); } /** @@ -166,8 +167,8 @@ public IBean getBean(String pivotName, LscDatasets pivotAttributes, boolean from * @throws LscServiceException */ @Override - public Map getListPivots() throws LscServiceException { - return sjds.getListPivots(); + public Map getListPivots(Task task) throws LscServiceException { + return sjds.getListPivots(task); } @Override @@ -209,4 +210,4 @@ public Collection> getSupportedConnectionType() public void close() throws IOException { sjds.close(); } -} \ No newline at end of file +} diff --git a/src/main/resources/schemas/lsc-core-2.2.xsd b/src/main/resources/schemas/lsc-core-2.3.xsd similarity index 85% rename from src/main/resources/schemas/lsc-core-2.2.xsd rename to src/main/resources/schemas/lsc-core-2.3.xsd index 46f6823..0757316 100644 --- a/src/main/resources/schemas/lsc-core-2.2.xsd +++ b/src/main/resources/schemas/lsc-core-2.3.xsd @@ -48,11 +48,13 @@ No new version is released because it has never been implemented before and won't break any existing and functional configuration --> + xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb" + jaxb:version="3.0" + xmlns:annox="urn:jaxb.jvnet.org:annox" + jaxb:extensionBindingPrefixes="annox"> @@ -322,12 +324,56 @@ - - + + + + + + + @java.lang.Deprecated + @java.lang.Deprecated + @java.lang.Deprecated + @java.lang.Deprecated + + + + + + + + @java.lang.Deprecated + @java.lang.Deprecated + @java.lang.Deprecated + @java.lang.Deprecated + + + - - + + + + + + + @java.lang.Deprecated + @java.lang.Deprecated + @java.lang.Deprecated + @java.lang.Deprecated + + + + + + + + @java.lang.Deprecated + @java.lang.Deprecated + @java.lang.Deprecated + @java.lang.Deprecated + + + @@ -338,14 +384,29 @@ - + + + + + + + + @java.lang.Deprecated + @java.lang.Deprecated + @java.lang.Deprecated + @java.lang.Deprecated + + + + + @@ -487,6 +548,8 @@ + + diff --git a/src/main/resources/schemas/lsc-executable-1.0.xsd b/src/main/resources/schemas/lsc-executable-1.0.xsd index 7e8e7ff..860d5f7 100755 --- a/src/main/resources/schemas/lsc-executable-1.0.xsd +++ b/src/main/resources/schemas/lsc-executable-1.0.xsd @@ -30,10 +30,16 @@ + elementFormDefault="qualified" + xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb" + jaxb:version="3.0" + xmlns:annox="urn:jaxb.jvnet.org:annox" + xmlns:lsc="http://lsc-project.org/XSD/lsc-core-2.3.xsd" + jaxb:extensionBindingPrefixes="annox"> + + + - diff --git a/src/main/resources/schemas/lsc.episode b/src/main/resources/schemas/lsc.episode deleted file mode 100644 index e4ffb5f..0000000 --- a/src/main/resources/schemas/lsc.episode +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/schemas/sun-jaxb.episode b/src/main/resources/schemas/sun-jaxb.episode new file mode 100644 index 0000000..102bbbb --- /dev/null +++ b/src/main/resources/schemas/sun-jaxb.episode @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/org/lsc/plugins/connectors/executable/Ldap2ExecutableSyncTest.java b/src/test/java/org/lsc/plugins/connectors/executable/Ldap2ExecutableSyncTest.java index cc6acb7..ba2bddb 100644 --- a/src/test/java/org/lsc/plugins/connectors/executable/Ldap2ExecutableSyncTest.java +++ b/src/test/java/org/lsc/plugins/connectors/executable/Ldap2ExecutableSyncTest.java @@ -61,10 +61,12 @@ import org.junit.BeforeClass; import org.lsc.LscDatasets; import org.lsc.SimpleSynchronize; +import org.lsc.Task; import org.lsc.beans.IBean; import org.lsc.configuration.JaxbXmlConfigurationHelper; import org.lsc.configuration.LdapConnectionType; import org.lsc.configuration.LscConfiguration; +import org.lsc.configuration.TaskType; import org.lsc.exception.LscConfigurationException; import org.lsc.exception.LscServiceException; import org.lsc.jndi.JndiServices; @@ -131,7 +133,13 @@ public final void testReadUserPasswordFromLdap() throws Exception { IService srcService = new SimpleJndiSrcService(LscConfiguration.getTask(TASK_NAME)); Entry obj = ids.entrySet().iterator().next(); - IBean srcBean = srcService.getBean(obj.getKey(), obj.getValue(), true); + // Ininitialize the task + TaskType taskType = LscConfiguration.getTask(TASK_NAME); + Task task = null; + if (taskType != null) { + task = new Task(taskType); + } + IBean srcBean = srcService.getBean(task, obj.getKey(), obj.getValue(), true); String userPassword = srcBean.getDatasetFirstValueById("userPassword"); // OpenDS automatically hashes the password using seeded SHA, diff --git a/src/test/resources/etc/lsc.xml b/src/test/resources/etc/lsc.xml index cd443b5..3d9fa69 100644 --- a/src/test/resources/etc/lsc.xml +++ b/src/test/resources/etc/lsc.xml @@ -1,5 +1,5 @@ - @@ -68,9 +68,9 @@ telephoneNumber seeAlso - (&(sn=*)) - (sn={sn}) - (sn={sn}) + "(&(sn=*))" + "(sn=" + pivotAttributes["sn"] + ")" + "(sn=" + pivotAttributes["sn"] + ")" OpenDS telephoneNumber seeAlso - (objectClass=person) - (&(objectClass=person)(sn={sn})) + "(objectClass=person)" + "(&(objectClass=person)(sn=" + pivotAttributes["sn"] + "))" src/test/resources/org/lsc/plugins/connectors/executable/add.sh @@ -220,8 +220,8 @@ telephoneNumber seeAlso - (objectClass=person) - (&(objectClass=person)(sn={sn})) + "(objectClass=person)" + "(&(objectClass=person)(sn=" + pivotAttributes["sn"] + "))" src/test/resources/org/lsc/plugins/connectors/executable/add.sh src/test/resources/org/lsc/plugins/connectors/executable/update.sh src/test/resources/org/lsc/plugins/connectors/executable/delete.sh @@ -255,9 +255,9 @@ sn uid - (&(uid=*)) - (uid={uid}) - (uid={uid}) + "(&(uid=*))" + "(uid=" + pivotAttributes["uid"] + ")" + "(uid=" + pivotAttributes["uid"] + ")" OpenDS