...
- Setting gsh.useLegacy = true in grouper.properties.
- Using a command line argument (gsh.sh -forceLegacyGsh)
GrouperShell is for Grouper admins. End users can script with the grouper client command line utility
Escape
Escape things in groovysh with single backslash. e.g.
Code Block |
---|
attributeValueDelegate.assignValue(RuleUtils.ruleIfConditionElName(), "\${subject.sourceId != 'g:gsa'}"); |
API Compability
gsh is now a core part of the Grouper API and so is always compatible with the current release.
...
Code Block | ||||
---|---|---|---|---|
| ||||
grouperSession = GrouperSession.startRootSession(); g = GroupFinder.findByName(sessiongrouperSession, "admin:loader_groups"); type = typeAdd("sync_group"); type.addAttribute(sessiongrouperSession, "sync_group", false, "sync"); groupAddType("admin:loader_groups", "sync_group"); g.setAttribute("sync", "true"); |
...
Command | Description |
---|---|
addComposite(group name, composite type, left group name, right group name) | Add composite membership. e.g. CompositeType.UNION |
addMember(group name, subject id) | Add member to the members list for the group. |
addMember(group name, subject id, field) | Add member to the specified list for the group. |
delComposite(group name) | Delete composite membership from group |
delMember(group name, subject id) | Delete member from the members list for the group |
delMember(group name, subject id, field) | Delete member from the specified list for the group |
getMembers(group name) | Get members of group |
hasMember(group name, subject id) | Check whether subject is member of the members list |
hasMember(group name, subject id, field) | Check whether subject is member of the specified list |
Privileges
GrouperSession grouperSession = GrouperSession.startRootSession(); Group group = GroupFinder.findByName(grouperSession, "a:b:c", true); group.addMember(SubjectFinder.findByIdAndSource("someId", "sourceId", true), false); | Add member with subjectId and sourceId |
GrouperSession grouperSession = GrouperSession.startRootSession(); Group group = GroupFinder.findByName(grouperSession, "a:b:c", true); group.addMember(SubjectFinder.findByIdentifierAndSource("someIdentifier", "sourceId", true), false); | Add member with subjectIdentifier and sourceId |
Privileges
Command | Description |
---|---|
grantPriv(group name, subject id, privilege) | Grant privilege on group. privilege must be an AccessPrivilege (e.g. |
grantPriv( | |
Command | Description |
grantPriv(group name, subject id, privilege) | Grant privilege on group. privilege must be an AccessPrivilege (e.g. |
grantPriv(stem name, subject id, privilege) | Grant privilege on stem. privilege must be a NamingPrivilege (e.g. |
hasPriv(group name, subject id, privilege) | Check whether subject has privilege on group. privilege must be an AccessPrivilege (e.g. |
hasPriv(stem name, subject id, privilege) | Check whether subject has privilege on strem. privilege must be a NamingPrivilege (e.g. |
revokePriv(group name, subject id, privilege) | Revoke privilege on group. privilege must be an AccessPrivilege (e.g. |
revokePriv(stem name, subject id, privilege) | Revoke privilege on stem. privilege must be a NamingPrivilege (e.g. |
...
Command | Description | ||
---|---|---|---|
addRootStem(extension, displayExtension) | Add top-level stem to the registry | ||
addStem(parent stem name, extension, displayExtension) | Add stem to registry | ||
delStem(stem name) | Delete stem from registry | ||
obliterateStem(stem name, testOnlyBoolean, deleteFromPointInTimeBoolean) (Grouper v2.0.2+) | Delete stem, and subobjects. | ||
getStemAttr(stem name, attr) | Get value of stem attribute | ||
getStems(name) | Find all stems with a matching naming attribute value, returns a Set of stems | ||
setStemAttr(stem name, attr, value) | Set value of stem attribute | ||
StemFinder.findByName(grouperSession, name) | Find one stem by name | ||
StemFinder.findByUuid(grouperSession, uuid) | Find one stem by uuid | ||
Delete stem and subcontents |
| ||
Delete stem and subcontents |
Subjects
Subjects
Command | Description | ||
---|---|---|---|
addSubject(id, type, name) | Add local subject to registry. You need the jdbc source for this to work. The type parameter describes the type of subject (e.g. "people"), and is required non-null even though there are few useful api methods to query it. In 2.4.0.api.41+ patch, this will also create the id, name, description, and loginid attribute (unless grouper.properties create.attributes.when.creating.registry.subjects is false) | ||
RegistrySubject.addOrUpdate(grouperSession, id, type, name, nameAttributeValue, loginid, description, email) | In 2.4.0.api.41+ patch, add a registry subject like addSubject, but specify the attribute values of name, loginid, etc e.g. RegistrySubject.addOrUpdate(grouperSession, "someTestSubject", "person", "Some Testsubject", "Name Some Test Subject", "stsub", "Some Testsubject - employee - also alumni", "some@test.subject"); | ||
RegistrySubject.find(id, errorOnNotFound) | In 2.4.0.api.41+ patch, get a registry subject e.g. registrySubject = RegistrySubject.find("someTestSubject", false); | ||
registrySubject.delete(grouperSession) | In 2.4.0.api.41+ patch, delete a registry subject e.g. registrySubject.delete(grouperSession); | ||
RegistrySubjectAttribute.addOrUpdate(subjectId, attributeName, attributeValue) | In 2.4.0.api.41+ patch, add or update a registry subject attribute | ||
registrySubjectAttribute.delete() | In 2.4.0.api.41+ patch, delete an attribute value | ||
findSubject(idOrIdentifier) | Find a subject by id or identifier | ||
findSubject(idOrIdentifier, type) | Find a subject by id or identifier; type is a deprecated parameter that is ignored | ||
findSubject(idOrIdentifier, type, source) | Find a subject by id or identifier for a specific subject source; type is a deprecated parameter that is ignored | ||
getSources() | Find all Subject sources | ||
grouperSession = GrouperSession.startRootSession(); | Find all subjects in a source by search string | ||
grouperSession = GrouperSession.startRootSession(); | Find a subject by id in a certain source | ||
grouperSession = GrouperSession.startRootSession(); | Find a subject by identifier in a certain source | ||
grouperSession = GrouperSession.startRootSession(); | Find a subject by id or identifier in a certain source | ||
add test subjects to registry (e.g. test.subject.0 through 9) | grouperSession = GrouperSession.startRootSession(); | ||
Edit subject (in this case name) | RegistrySubject registrySubject = GrouperDAOFactory.getFactory().getRegistrySubject().find("user1a", "person", true); | ||
add a subject application principal with attributes (GSH) |
| ||
remove a subject with attributes (GSH) |
|
System
...
Command
...
Description
...
sqlRun(file)
...
Execute each line of a sql file, just like ant would. This can run the files generated by registryInitializeSchema()
...
sqlRun(string)
...
Executes a single sql statement
...
:exit
...
Terminate shell
...
help()
...
Display usage information
...
p(command)
...
Pretty print results.
...
:quit
...
Terminate shell
...
version()
...
Return version information
subject api diagnostics | grouper.properties (temporarily)
gsh
|
System
Command | Description |
---|---|
sqlRun(file) | Execute each line of a sql file, just like ant would. This can run the files generated by registryInitializeSchema() |
sqlRun(string) | Executes a single sql statement |
:exit | Terminate shell |
help() | Display usage information |
p(command) | Pretty print results. |
:quit | Terminate shell |
version() | Return version information |
Unresolvable subject deletion utility (USDU)
Unresolvable subject deletion utility (USDU)
usdu finds which memberships are with subjects which cannot be found in a subject source, and prints them on the screen
- if the usdu.DELETE option is passed in, then the memberships will be deleted
- a grouper session must be open when this command is run.
...
Command | Description |
---|---|
help("transaction") | print help information |
transactionStatus() | print the list of nested transactions |
transactionStart("<GrouperTransactionType>") | start a transaction, or make sure one is already started |
transactionCommit("<GrouperCommitType>") | commit a transaction |
transactionRollback("<GrouperRollbackType>") | rollback a transaction |
transactionEnd() | end a transaction |
Daemon
You can schedule daemon jobs (and in UI) in v2.5.23+
Code Block |
---|
GrouperSession.startRootSession();
edu.internet2.middleware.grouper.app.loader.GrouperLoader.scheduleJobs(); |
Loader
Above, it describes how you can kick off the loader in daemon mode. You can also execute one job with:
...
Command | Description |
---|---|
loaderRunOneJobAttr(attirbuteDef) | Run an attribute definition loader job |
You can run the loader as a linux servicethe loader as a linux service
Jobs not firing in daemon
- Stop all daemons
Run these sqls from a file: fixLoaderScheduler.sql
Code Block UPDATE GROUPER_QZ_TRIGGERS SET TRIGGER_STATE = 'WAITING'; DELETE FROM GROUPER_QZ_FIRED_TRIGGERS; commit;
Code Block gsh.sh -registry -runsqlfile fixLoaderScheduler.sql
- Restart daemons
It took a couple of hours to catch up on a few days of changes, but it seems to be back to normal. Thanks again, guys!
GrouperShell Variables (BeanShell only)
...
Code Block |
---|
# (1) Print tab-separated summary of all group members, and flags for direct, indirect, or both # Depending on the results, you could use the data to create a scrutinized list of Ids to delete, then import it and delete in a loop me = SubjectFinder.findByIdentifierAndSource("my-username", "pid", true); session = GrouperSession.start(me); // OR: session = GrouperSession.startRootSession(True) group = GroupFinder.findByName(session, "tmp:my:group", true); effectiveMembers = group.getEffectiveMembers(); immediateMembers = group.getImmediateMembers(); System.out.println(String.join("\t", "id", "name", "Effective", "Immediate")); for (Member m: group.getMembers()) { System.out.print(m.getSubject().getId() + "\t" + m.getSubject().getName() + "\t"); System.out.print(effectiveMembers.contains(m).toString() + "\t"); System.out.println(immediateMembers.contains(m).toString() + "\t"); } # (2) Get the immediate and effective members for a specific source ("pid" in this example), intersect them to find the redundant ones # This has a dryRun flag, so you can test first sources = new HashSet<Source>() sources.add(SourceManager.getInstance().getSource("pid")) effectiveUsers = group.getEffectiveMembers(Group.getDefaultList(), sources, null) immediateUsers = group.getImmediateMembers(Group.getDefaultList(), sources, null) # use retainAll() to find the intersection; i.e., users both as effective and immediate member immediateUsers.retainAll(effectiveUsers) System.out.println("There are " + immediateUsers.size() + " users having both direct + indirect memberships"); dryRun = true for (Member m: immediateUsers) { if (dryRun) { System.out.println("Ok to delete " + m.getSubject().getId()); } else { System.out.println("Deleting " + m.getSubject().getId()); group.deleteMember(m, false); } } # (3) Get the groups this subject is a member of. Note that a group is a kind of subject, and has a toSubject() method to convert it. import edu.internet2.middleware.grouper.membership.MembershipSubjectContainer GrouperSession grouperSession = GrouperSession.startRootSession(); Group group = GroupFinder.findByName(grouperSession, "test:testGroup", true); Subject subject = g.toSubject(); Set<MembershipSubjectContainer> msc = new MembershipFinder().addSubject(subject).findMembershipResult().getMembershipSubjectContainers(); for (MembershipSubjectContainer membershipSubjectContainer : msc) { println(membershipSubjectContainer.getGroupOwner().getName());} //Note there are a few other options for the search. Add these to the MembershipFinder method chain before calling findMembershipResult(): // - search immediate, effective, etc. (needs to import MembershipType) import edu.internet2.middleware.grouper.membership.MembershipType membershipFinder.assignMembershipType(MembershipType.IMMEDIATE) // options are IMMEDIATE|NONIMMEDIATE|EFFECTIVE|COMPOSITE // - retrieve specific groups based on pattern membershipFinder.assignScope("%:test:%") // - Enabled status -- true means enabled only, false, means disabled only, and null means all membershipFinder.assignEnabled(false) // For other methods, refer to the Javadoc at httphttps://software.internet2.github.ioedu/grouper/doc/master/grouper-parent/apidocs/index.html?edu/internet2/middleware/grouper/MembershipFinder.html |
...
Code Block | ||
---|---|---|
| ||
gcDbAccess = new edu.internet2.middleware.grouperClient.jdbc.GcDbAccess(); // "loaderConnection" is the string used in the grouper-loader.properties ( Example: db.warehouse.url --> "warehouse") gcDbAccess.connectionName("loaderConnection").sql("select count(1) from test1").select(int.class); "warehouse") gcDbAccess.connectionName("loaderConnection").sql("select count(1) from test1").select(int.class); |
Code Block |
---|
List results = new edu.internet2.middleware.grouperClient.jdbc.GcDbAccess().sql("select name, id from grouper_groups").selectList(Object[].class);
for (Object[] row : results) { System.out.println(row[0] + ", " + row[1]);} |
See the WIKI for running the Grouper Report manually
...
Code Block |
---|
GrouperSession grouperSession = GrouperSession.startRootSession(); AttributeAssign attributeAssign = AttributeAssignFinder.findById("b629bd8170964663be507968752f4f17", true); attributeAssign.delete();); attributeAssign.delete(); |
NOTE: You can also use the AttributeAssignFinder.findById(String id, boolean exceptionIfNull) to find attribute assignments from the logs too.
Example log "ERROR RuleEngine$3.callback(560) - - Error with daemon on rule: attributeAssignTypeId: 3d6ccb6c5a584f32919682ae154c0523". id="3d6ccb6c5a584f32919682ae154c0523". The returned AttributeAssign object will show you the stem/group that the attribute is attached to.
Grouper Builtin Messaging
...
Code Block |
---|
String provisionTarget = "ad"; GrouperSession grouperSession = GrouperSession.startRootSession(); Set stemsToProvisionToSet = HibernateSession.byHqlStatic().createQuery("select s from Stem s, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where s.id = aa.ownerStemId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'stem' and aa.enabledDb = 'T' and adn.extensionDb = 'provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class); for (Object stemObject : stemsToProvisionToSet) { Stem stem = (Stem)stemObject; System.out.println("provision_to assigned to stem: " + stem.getName()); } Set stemsToNotProvisionToSet = HibernateSession.byHqlStatic().createQuery("select s from Stem s, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where s.id = aa.ownerStemId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'stem' and aa.enabledDb = 'T' and adn.extensionDb = 'do_not_provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class); for (Object stemObject : stemsToNotProvisionToSet) { Stem stem = (Stem)stemObject; System.out.println("do_not_provision_to assigned to stem: " + stem.getName()); } Set groupsToProvisionToSet = HibernateSession.byHqlStatic().createQuery("select g from Group g, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where g.id = aa.ownerGroupId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'group' and aa.enabledDb = 'T' and adn.extensionDb = 'provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class); for (Object groupObject : groupsToProvisionToSet) { Group group = (Group)groupObject; System.out.println("provision_to assigned to group: " + group.getName()); } Set groupsToNotProvisionToSet = HibernateSession.byHqlStatic().createQuery("select g from Group g, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where g.id = aa.ownerGroupId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'group' and aa.enabledDb = 'T' and adn.extensionDb = 'do_not_provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class); for (Object groupObject : groupsToNotProvisionToSet) { Group group = (Group)groupObject; System.out.println("do_not_provision_to assigned to group: " + group.getName()); } Set allGroups = new LinkedHashSet(); Set allGroupsToProvision = new TreeSet(); allGroupsToProvision.addAll(groupsToProvisionToSet); Set stemNamesToNotProvisionTo = new HashSet(); Set stemNamesToProvisionTo = new HashSet(); for (Object stemToProvision : stemsToProvisionToSet) { stemNamesToProvisionTo.add(((Stem)stemToProvision).getName()); } for (Object stemNotToProvision : stemsToNotProvisionToSet) { stemNamesToNotProvisionTo.add(((Stem)stemNotToProvision).getName()); } for (Object stemToProvision : stemsToProvisionToSet) { allGroups.addAll(((Stem)stemToProvision).getChildGroups(edu.internet2.middleware.grouper.Stem.Scope.SUB)); } Map groupToPaths = new HashMap(); for (Object groupObject : allGroups) { Group group = (Group)groupObject; if (allGroupsToProvision.contains(group)) {continue;} if (groupsToNotProvisionToSet.contains(group)) {continue;} List paths = new ArrayList(); groupToPaths.put(group, paths); String currentName = group.getName(); paths.add(currentName); while(true) { currentName = GrouperUtil.parentStemNameFromName(currentName); if (GrouperUtil.isBlank(currentName)) {break;} paths.add(currentName); } } for (Object groupObject : groupToPaths.keySet()) {Group group = (Group)groupObject; List paths = (List)groupToPaths.get(group); for (Object pathObject : paths) { String path = (String)pathObject; if (stemNamesToProvisionTo.contains(path)) { allGroupsToProvision.add(group); break; } if (stemNamesToNotProvisionTo.contains(path)) { break; } } } for (Object groupObject : allGroupsToProvision) { Group group = (Group)groupObject; System.out.println("configured to provision to: " + provisionTarget + ": " + group.getName())); } |
Stem move
try this:
; }
|
Stem move
try this:
Code Block |
---|
GrouperSession.startRootSession();
stemFrom = StemFinder.findByName(grouperSession, "a:b", true);
stemTo = StemFinder.findByName(grouperSession, "a:c", true);
new edu.internet2.middleware.grouper.StemMove(stemFrom, stemTo).assignAlternateName(false).save(); |
Check health of database connection or run a query
(in 2.4.0 api patch 93+)
Code Block |
---|
gcDbAccess = new edu.internet2.middleware.grouperClient.jdbc.GcDbAccess();
gcDbAccess.connectionName("warehouse").sql("select count(1) from grouper_groups").select(int.class); |
Set password using Grouper built-in authentication
Code Block |
---|
v2.5.29+
new GrouperPasswordSave().assignApplication(GrouperPassword.Application.UI).assignUsername("username").assignPassword("password" |
Code Block |
GrouperSession.startRootSession();
stemFrom = StemFinder.findByName(grouperSession, "a:b", true);
stemTo = StemFinder.findByName(grouperSession, "a:c", true);
new edu.internet2.middleware.grouper.StemMove(stemFrom, stemTo).assignAlternateName(false).save(); |