diff --git a/README.md b/README.md index 8f017c500317da48692baacb3e8723368ff65c0d..78c15d43d7d2e06770ad10ea2e5c7f268133784a 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ The tool can be invoked from the command line: ```console $ gsuitesync + +# To also update the group settings on all groups +$ gsuitesync --group-settings ``` By default this will log what will be done. To actually perform the @@ -20,6 +23,9 @@ synchronisation: ```console $ gsuitesync --really-do-this + +# And with group settings +$ gsuitesync --group-settings --really-do-this ``` See the output of ``gsuitesync --help`` for more information on valid diff --git a/gsuitesync/__init__.py b/gsuitesync/__init__.py index 3677d732b116622e1b99a3f41b305cce5be649a1..29451ffcda9d106b720c496230140dfe564853db 100644 --- a/gsuitesync/__init__.py +++ b/gsuitesync/__init__.py @@ -3,7 +3,7 @@ Synchronise users to GSuite Usage: gsuitesync (-h | --help) - gsuitesync [--configuration=FILE] [--quiet] [--really-do-this] + gsuitesync [--configuration=FILE] [--quiet] [--group-settings] [--really-do-this] Options: -h, --help Show a brief usage summary. @@ -12,6 +12,8 @@ Options: --configuration=FILE Specify configuration file to load. + --group-settings Also update group settings on all groups + --really-do-this Actually try to make the changes. """ @@ -42,4 +44,6 @@ def main(): configuration = config.load_configuration(opts['--configuration']) # Perform sync - sync.sync(configuration, read_only=not opts['--really-do-this']) + sync.sync(configuration, + read_only=not opts['--really-do-this'], + group_settings=opts['--group-settings']) diff --git a/gsuitesync/sync.py b/gsuitesync/sync.py index dd32e993c06734ba824ccb6ea7a450c4818b7def..73b0a7c45032733976b550dbf6361d3250b74345 100644 --- a/gsuitesync/sync.py +++ b/gsuitesync/sync.py @@ -87,7 +87,7 @@ class Configuration(config.ConfigurationDataclassMixin): http_retry_delay: numbers.Real = 5 -def sync(configuration, *, read_only=True): +def sync(configuration, *, read_only=True, group_settings=False): """Perform sync given configuration dictionary.""" if read_only: LOG.info('Performing synchronisation in READ ONLY mode.') @@ -359,23 +359,26 @@ def sync(configuration, *, read_only=True): if len(all_google_gids) != len(all_google_groups): raise RuntimeError('Sanity check failed: group list changed length') - # Retrieve all Google group settings. - fields = ['email', *[k for k in sync_config.group_settings.keys()]] - all_google_group_settings = gapiutil.get_all_in_list( - groupssettings_service, groupssettings_service.groups().get, - item_ids=[g['email'] for g in all_google_groups], id_key='groupUniqueId', - batch_size=sync_config.batch_size, fields=','.join(fields), - retries=sync_config.http_retries, retry_delay=sync_config.http_retry_delay, - ) + if group_settings: + # Retrieve all Google group settings. + fields = ['email', *[k for k in sync_config.group_settings.keys()]] + all_google_group_settings = gapiutil.get_all_in_list( + groupssettings_service, groupssettings_service.groups().get, + item_ids=[g['email'] for g in all_google_groups], id_key='groupUniqueId', + batch_size=sync_config.batch_size, fields=','.join(fields), + retries=sync_config.http_retries, retry_delay=sync_config.http_retry_delay, + ) - # Form a mapping from gid to Google group settings. - all_google_group_settings_by_gid = { - email_to_gid(g['email']): g for g in all_google_group_settings - } + # Form a mapping from gid to Google group settings. + all_google_group_settings_by_gid = { + email_to_gid(g['email']): g for g in all_google_group_settings + } - # Santiy check. We should have settings for each managed group. - if len(all_google_group_settings_by_gid) != len(all_google_groups): - raise RuntimeError('Sanity check failed: group settings list does not match group list') + # Sanity check. We should have settings for each managed group. + if len(all_google_group_settings_by_gid) != len(all_google_groups): + raise RuntimeError( + 'Sanity check failed: group settings list does not match group list' + ) # Retrieve all Google group memberships. This is a mapping from internal Google group ids to # lists of member resources, corresponding to both Lookup groups and institutions. @@ -732,13 +735,17 @@ def sync(configuration, *, read_only=True): LOG.info('Updating settings for new group "%s": %s', gid, settings) yield groupssettings_service.groups().patch(groupUniqueId=email, body=settings) - # Apply any settings that differ to pre-existing groups. - for gid, settings in all_google_group_settings_by_gid.items(): - patch = {k: v for k, v in sync_config.group_settings.items() if settings.get(k) != v} - if patch: - email = gid_to_email(gid) - LOG.info('Updating settings for existing group "%s": %s', gid, patch) - yield groupssettings_service.groups().patch(groupUniqueId=email, body=patch) + if group_settings: + # Apply any settings that differ to pre-existing groups. + for gid, settings in all_google_group_settings_by_gid.items(): + patch = {k: v for k, v in sync_config.group_settings.items() + if settings.get(k) != v} + if patch: + email = gid_to_email(gid) + LOG.info('Updating settings for existing group "%s": %s', gid, patch) + yield groupssettings_service.groups().patch(groupUniqueId=email, body=patch) + else: + LOG.info('Skipping updating settings for existing groups') # A generator which will generate insert() and delete() calls to the directory service to # perform the actions required to update group members diff --git a/setup.py b/setup.py index 88662b8632aa761f9a84e6146be8d8bfbbf7d655..d6608612e2b51b4ce2f2804ced95acedb00085d3 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ def load_requirements(): setup( name='gsuitesync', - version='0.9.2', + version='0.9.3', packages=find_packages(), install_requires=load_requirements(), entry_points={