Skip to content

Provisioner Properties

John Gasper edited this page Aug 27, 2018 · 21 revisions

The Google Apps provisioner comes with many properties that can be set. These properties should be stored in grouper-loader.properties.

Items are listed with their default values. An asterisks(*) indicates a required value (thus has no default).

The provisioner supports multiple instances of itself, each having different configurations. This facilitates having a provisioner that does things differently with course groups than it might with ad hoc groups. Each set of properties needs to have a unique name. In the details below, the consumer name should be substituted for <consumerName>.

While these properties have a changeLog.consumer. namespace, they apply equally to the full sync functionality.

Grouper Settings

These properties are used internally by Grouper to invoke the change log consumer:

  • changeLog.consumer.<consumerName>.class = edu.internet2.middleware.changelogconsumer.googleapps.GoogleAppsChangeLogConsumer
    This tells Grouper which class to invoke when running the change log consumer. It is required if using the change log consumer functionality.

  • changeLog.consumer.<consumerName>.quartzCron =
    You may optional override the default time that the Grouper Loader invokes the consumer.

Google Authentication & Connections

A Google Apps admin must follow the steps at Perform Google Apps Domain-Wide Delegation of Authority to create a service application/account that is used by the provisioner to connect to Google. The steps can be followed as written with one exception. The account will need to be given these grants: https://www.googleapis.com/auth/admin.directory.user, https://www.googleapis.com/auth/admin.directory.group, https://www.googleapis.com/auth/apps.groups.settings.

  • changeLog.consumer.<consumerName>.domain*
    The Google managed domain name. (e.g. example.org)

  • changeLog.consumer.<consumerName>.serviceAccountEmail*
    The service account email address created by Google.

  • changeLog.consumer.<consumerName>.serviceAccountPKCS12FilePath*
    The path of the PKCS12 file created and downloaded from Google. The OS account running the Grouper Loader process or full sync functionality needs to have read permissions to this file. Access to this file should be limited.

  • changeLog.consumer.<consumerName>.serviceImpersonationUser*
    This is the account that all actions will be made by. It needs to exists and will be the creator and modifier account associated with the Google auditing logs.

Processing Controls

  • changeLog.consumer.<consumerName>.provisionUsers=false
    Should users missing from Google be provisioned?

  • changeLog.consumer.<consumerName>.deprovisionUsers=false
    Should users be deprovisioned when they do not exists in any other groups? (future item, has no affect now)

  • changeLog.consumer.<consumerName>.googleGroupFilter=.* (since v1.0.1)
    When a full sync is running, this regular expression (regex) will be used to limit which Google Groups are brought in for comparison. The domain is removed for the comparison.

    For example, crs-.* will process crs-acct-251@gtest.school.edu, but will ignore clubs-golf@gtest.school.edu.

    The default setting is .* (all groups), which will bring in every group for full syncing. Any groups not flagged for syncing in Grouper will be handled per the setting in changeLog.consumer.<consumerName>.handleDeletedGroup.

  • changeLog.consumer.<consumerName>.ignoreExtraGoogleMembers=true (since v1.0.1)
    When a full sync is running, should extra members of a Google group be ignored? If false then extras group members will be removed.

  • changeLog.consumer.<consumerName>.handleDeletedGroup=ignore
    Specifies how Google groups are treated when their corresponding Grouper group drops out of the managed scope, either by deletion or being moved from a managed stem/folder. Possible values are:

    • ignore - Nothing happens to the Google group. (default)
    • archive - The Google group's Archive Only flag is set to true.
    • delete - The Google group is deleted.
  • changeLog.consumer.<consumerName>.whoCanManage=none
    Specifies which users are set as group managers:

    • none - no users are configured as managers. (default)
    • admin - Members with the Admin Grouper privilege are set as Google group managers.
    • update - Members with the Update Grouper privilege are set as Google group managers.
    • both - Members with the Admin & Update Grouper privilege are set as Google group managers.
    • scripted - permits a JEXL expression to decide what management rights a user has (since v1.2.0)
  • changeLog.consumer.<consumerName>.whoCanManageJexl (since v1.2.0)
    Specifies an expression that determines what role a user has. The expression is provider group and member and should return MEMBER, MANAGER, or null (as of v1.3.3, NONE should be used instead of null). Theoretically OWNER could also be returned. An example expression that sets admins as managers only if they are also members might be: ${ member.canAdmin(group) && member.isMember(group) ? "MANAGER" : (member.isMember(group) ? "MEMBER" : null) }. This expression is only used if, changeLog.consumer.<consumerName>.whoCanManage is set to scripted.

  • changeLog.consumer.<consumerName>.groupIdentifierExpression*
    This gives the admin the option to manipulate/match the Grouper group's identifier/path with the Google group's mailbox identifier. For example, school:courses:Fall2014:MATH251 uniquely identifies a group, and we don't likely want the Google group's identifier/email address to be school-courses-Fall2014-MATH251@gdomain.school.edu. Using the groupIdentifierExpression, we can manipulate the identifier by using JEXL expressions.

    groupPath is a Java string object, so any string methods can be used with it. The simplest expression possible is ${groupPath}, which only converts the colons to hyphens and appends the @ domain name. An expression of crs-${groupPath.replace("school:courses:", "")}-managed would return crs-fall2014-math251-managed@gdomain.school.edu for the above example. It should be noted that Google lower cases the identifier and does not permit colons (:) in the identifier, so the identifier is lower cased and colons are converted to hyphens (-). (If it you want a different delineator, just add additional replace() method call.)

    It is your job to ensure that the outputting expression is unique. If two groups return the same value they will be merged/overwritten in Google. In the case of our example if the Fall2014 element was edited out, MATH251 from multiple terms would conflict.

  • changeLog.consumer.<consumerName>.subjectIdentifierExpression*
    This gives the admin the option to manipulate/match the Grouper subject's identifier/path with the Google user's mailbox identifier/email address. Using the subjectIdentifierExpression, we can manipulate the identifier by using JEXL expressions.

    subject is a Java Subject object, and all of its methods/properties can be used when building up the subject's Google email. The simplest expression would be ${subject.getId + "@domain.edu"} or ${subject.getAttributeValue("mail", false)}. The latter expression requires an attribute named mail to be configured in the subject source. (since v1.2.0)

    Deprecated: subjectId is a Java string object, so any string methods can be used with it. The simplest expression possible is ${subjectId}, which appends the @ domain name. An expression of user-${subjectId}-managed would return user-jdoe-managed@gdomain.school.edu for a hypothetical jdoe subject. It should be noted that Google lower cases the identifier, so the identifier is lower cased.

    It is your job to ensure that the outputting expression is unique. If two subjects return the same value they will be merged/overwritten in Google. This would only likely happen if parts of the subjectId are removed.

  • changeLog.consumer.<consumerName>.retryOnError=false
    Are change log events that fail retried? This essentially re-runs the Change Log Event the next time that the change log consumer is run. (Only applies to the Change Log Consumer).

Provisioning Properties

Provisioning properties are used if provisionUsers=true.

  • changeLog.consumer.<consumerName>.includeUserInGlobalAddressList=true
    Should the provisioned user be included in Google's Global Address List? (This setting only applies when provisionUser=true.)

  • changeLog.consumer.<consumerName>.simpleSubjectNaming=true
    Google requires provisioned accounts to have a separate given name and family name. If simpleSubjectNaming=true, the fields are populated by splitting the Subject Name with the first element being assigned as the given name and the last element being assigned as the family name. If simpleSubjectNaming=false, the subjectGivenNameField and subjectSurnameField is used to lookup the given and family name.

  • changeLog.consumer.<consumerName>.subjectGivenNameField=givenName
    If provisionUsers=true and simpleSubjectNaming=false, the subjectGivenNameField is the name of the subject source's attribute to query to return the user's given name. The subject source will need additional configuration to return this value.

  • changeLog.consumer.<consumerName>.subjectSurnameField=sn
    If provisionUsers=true and simpleSubjectNaming=false, the subjectSurnameNameField is the name of the subject source's attribute to query to return the user's family name/surname. The subject source will need additional configuration to return this value.

  • changeLog.consumer.<consumerName>.recentlyManipulatedQueueSize=5 (since v1.0.1)
    The number of recently manipulated Google objects that should be tracked. If an object is found on the list then a sleep operation is imposed (see recentlyManipulatedQueueDelay) before the requested action is processed.

  • changeLog.consumer.<consumerName>.recentlyManipulatedQueueDelay=2 (since v1.0.1)
    Number of seconds that processing should delay if hitting a recently manipulated Google object before proceeding with another action against the object. Decreasing this too low may result in objects not being available quickly enough. Setting the value too high will impose a perceived performance hit.

Caching Controls

Calls to Google APIs are limited by service account. Although it is a large amount of calls, the provisioner tries to reduce the number of group and user look up calls by caching the group and user objects. Upon start up, all groups are cached in batch requests from Google. As the provisioner works with various groups and users update information is placed into the cache. By default the cache lives for 30 minutes, however this can be adjusted.

  • changeLog.consumer.<consumerName>.prefillGoogleCachesForConsumer=false (since v1.0.1)
    Whether or not the Google object (group and user) caches are pre-populated or filled as the objects are needed. This setting applies to the change log consumer.

  • changeLog.consumer.<consumerName>.prefillGoogleCachesForFullSync=true (since v1.0.1)
    Whether or not the Google object (group and user) caches are pre-populated or filled as the objects are needed. This setting applies to the full sync module.

  • changeLog.consumer.<consumerName>.googleUserCacheValidityPeriod=30
    The amount of time, in minutes, that Google user objects are cached.

  • changeLog.consumer.<consumerName>.googleGroupCacheValidityPeriod=30
    The amount of time, in minutes, that Google group objects are cached.

Google Groups Settings

Google Groups have a variety of settings that can be applied to a group. Details on what each does can be found in the Admin SDK Reference. These settings apply only when provisioning of the group.

  • changeLog.consumer.<consumerName>.whoCanViewMembership=ALL_IN_DOMAIN_CAN_VIEW
  • changeLog.consumer.<consumerName>.whoCanViewGroup=ALL_MEMBERS_CAN_VIEW
  • changeLog.consumer.<consumerName>.whoCanInvite=ALL_MANAGERS_CAN_INVITE (since v1.2.0)
  • changeLog.consumer.<consumerName>.whoCanAdd=NONE_CAN_ADD (since v1.2.0)
  • changeLog.consumer.<consumerName>.allowExternalMembers=false
  • changeLog.consumer.<consumerName>.whoCanPostMessage=ALL_IN_DOMAIN_CAN_POST
  • changeLog.consumer.<consumerName>.allowWebPosting=true
  • changeLog.consumer.<consumerName>.primaryLanguage=en
  • changeLog.consumer.<consumerName>.maxMessageBytes=10240
  • changeLog.consumer.<consumerName>.isArchived=true
  • changeLog.consumer.<consumerName>.messageModerationLevel=MODERATE_NONE
  • changeLog.consumer.<consumerName>.spamModerationLevel=ALLOW
  • changeLog.consumer.<consumerName>.replyTo=REPLY_TO_IGNORE
  • changeLog.consumer.<consumerName>.customReplyTo=(empty/null)
  • changeLog.consumer.<consumerName>.sendMessageDenyNotification=true
  • changeLog.consumer.<consumerName>.defaultMessageDenyNotificationText=Your message has been denied.
  • changeLog.consumer.<consumerName>.showInGroupDirectory=false
  • changeLog.consumer.<consumerName>.allowGoogleCommunication=false
  • changeLog.consumer.<consumerName>.membersCanPostAsTheGroup=false
  • changeLog.consumer.<consumerName>.messageDisplayFont=DEFAULT_FONT
  • changeLog.consumer.<consumerName>.includeInGlobalAddressList=true
  • changeLog.consumer.<consumerName>.includeCustomFooter=false (since v1.2.0)
  • changeLog.consumer.<consumerName>.customFooterText=(empty/null) (since v1.2.0)