diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8825656abcc390566716dd7d1aa901099332650e..1decf69a2d455e125c9b3dbb97558207a23a9cd1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,3 +15,13 @@ include: variables: DOCUMENTATION_DISABLED: "1" + DAST_DISABLED: "1" + +test: + artifacts: + reports: + coverage_report: + coverage_format: cobertura + path: ./artefacts/**/coverage.xml + variables: + TOX_ENVLIST: "black,flake8,py3" diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a3831426a63f72038e877585040412d1a4ef554..59f4b9fa116456284adaea1f3fc80f239bbf46a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.0] - 2023-06-22 + +### Changed + +- Change `--really-do-this` to `--write`. + ## [0.14.2] - 2023-05-23 ### Changed diff --git a/README.md b/README.md index fa85963d91f0ad3ee6c5aaaf2bfa9cdc14d77400..7576beda80876c9efb41b0183b9fc74abb53b2a0 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,10 @@ By default this will log what will be done. To actually perform the synchronisation: ```console -$ gsuitesync --really-do-this +$ gsuitesync --write # And with group settings -$ gsuitesync --group-settings --really-do-this +$ gsuitesync --group-settings --write ``` The default socket timeout for batch operations is 300 seconds. To change this diff --git a/gsuitesync/__init__.py b/gsuitesync/__init__.py index 5fa3c5c2266c8df854e8a034b14b51b6cd451569..360d1915a2979e3814a5d34ee62ed6528c260705 100644 --- a/gsuitesync/__init__.py +++ b/gsuitesync/__init__.py @@ -4,27 +4,24 @@ Synchronise users to GSuite Usage: gsuitesync (-h | --help) gsuitesync [--configuration=FILE] [--quiet] [--group-settings] [--just-users] - [--licensing] [--delete-users] [--really-do-this] [--timeout=SECONDS] + [--licensing] [--delete-users] [--write] [--timeout=SECONDS] [--cache-dir=DIR] Options: -h, --help Show a brief usage summary. - --quiet Reduce logging verbosity. + -q, --quiet Reduce logging verbosity. - --configuration=FILE Specify configuration file to load. + -c, --configuration=FILE Specify configuration file to load. - --group-settings Also update group settings on all groups. + -w, --write Actually try to make the changes. + --group-settings Also update group settings on all groups. --just-users Just compare users not groups and institutions. - --licensing Also update user licence allocations. - --delete-users Delete suspended users. - --really-do-this Actually try to make the changes. - - --timeout=SECONDS Integer timeout for socket when performing batch + -t, --timeout=SECONDS Integer timeout for socket when performing batch operations. [default: 300] --cache-dir=DIR Directory to cache API responses, if provided. @@ -57,10 +54,9 @@ def main(): timeout_val = int(opts["--timeout"]) # Safety check - could write with out of date cached data - if opts["--really-do-this"] and opts["--cache-dir"]: + if opts["--write"] and opts["--cache-dir"]: LOG.error( - "Option --really-do-this with --cache-dir is blocked to avoid " - "writing outdated cached data." + "Option --write with --cache-dir is blocked to avoid writing outdated cached data." ) exit(1) @@ -70,7 +66,7 @@ def main(): # Perform sync sync.sync( configuration, - read_only=not opts["--really-do-this"], + write_mode=opts["--write"], timeout=timeout_val, group_settings=opts["--group-settings"], just_users=opts["--just-users"], diff --git a/gsuitesync/gapiutil.py b/gsuitesync/gapiutil.py index 2a4f8f0eaac65a559226910d8e9df9edc9f26c50..f71e6326c1ee4da98480a7fc70bf1bc56d8218e3 100644 --- a/gsuitesync/gapiutil.py +++ b/gsuitesync/gapiutil.py @@ -228,7 +228,7 @@ def get_all_in_list( return resources -def process_requests(service, requests, sync_config, read_only=True): +def process_requests(service, requests, sync_config, write_mode=False): """ Process an iterable list of requests to the specified Google service in batches. These APIs support a maximum batch size of 1000. See: @@ -241,9 +241,9 @@ def process_requests(service, requests, sync_config, read_only=True): for request in request_batch: batch.add(request, callback=_handle_batch_response) - # Execute the batch request if not in read only mode. Otherwise log that we would + # Execute the batch request if in write mode. Otherwise log that we would # have. - if not read_only: + if write_mode: LOG.info("Issuing batch request to Google.") sleep(sync_config.inter_batch_delay) retries = sync_config.http_retries diff --git a/gsuitesync/sync/base.py b/gsuitesync/sync/base.py index adb6296cd628228187bdbfe174d3f26c61f9d59b..12347e9580b8371229f898c338e3e681eabffa35 100644 --- a/gsuitesync/sync/base.py +++ b/gsuitesync/sync/base.py @@ -7,11 +7,11 @@ Base classes for retrievers, comparator and updater classes that consume configu class ConfigurationStateConsumer: required_config = None - def __init__(self, configuration, state, read_only=True, delete_users=False, cache_dir=None): + def __init__(self, configuration, state, write_mode=False, delete_users=False, cache_dir=None): # For convenience, create properties for required configuration for c in self.required_config if self.required_config is not None else []: setattr(self, f"{c}_config", configuration.get(c, {})) self.state = state - self.read_only = read_only + self.write_mode = write_mode self.delete_users = delete_users self.cache_dir = cache_dir diff --git a/gsuitesync/sync/gapi.py b/gsuitesync/sync/gapi.py index 4856f85b586d0ba16ee15974631da6127535fab2..3946c2ed475f7ccac31021ee39e9ba66ed55c1c7 100644 --- a/gsuitesync/sync/gapi.py +++ b/gsuitesync/sync/gapi.py @@ -52,7 +52,7 @@ class GAPIRetriever(ConfigurationStateConsumer): def connect(self, timeout=300): # load credentials - self.creds = self._get_credentials(self.read_only) + self.creds = self._get_credentials(read_only=not self.write_mode) # Build the directory service using Google API discovery. socket.setdefaulttimeout(timeout) directory_service = discovery.build("admin", "directory_v1", credentials=self.creds) @@ -89,7 +89,7 @@ class GAPIRetriever(ConfigurationStateConsumer): } ) - def _get_credentials(self, read_only): + def _get_credentials(self, read_only=True): """ Create a Google credentials object from the configuration. Use *read_only* to indicate if read-only credentials are preferred. diff --git a/gsuitesync/sync/main.py b/gsuitesync/sync/main.py index 1f0e17ae19768cc9a0adf07c0de702f6362a87b2..15b7a1721d278f286464f22dbfa6a002fcc83d46 100644 --- a/gsuitesync/sync/main.py +++ b/gsuitesync/sync/main.py @@ -17,19 +17,17 @@ LOG = logging.getLogger(__name__) def sync( configuration, *, - read_only=True, + write_mode=False, timeout=300, group_settings=False, just_users=False, licensing=False, cache_dir=None, - delete_users=False + delete_users=False, ): """Perform sync given configuration dictionary.""" - if read_only: - LOG.info("Performing synchronisation in READ ONLY mode.") - else: - LOG.info("Performing synchronisation in WRITE mode.") + + LOG.info(f'Performing synchronisation in {"WRITE" if write_mode else "READ ONLY"} mode.') # Parse configuration into Configuration dict of appropriate dataclasses configuration = config.parse_configuration(configuration) @@ -45,7 +43,7 @@ def sync( lookup.retrieve_groups() # Get users and optionally groups from Google - gapi = GAPIRetriever(configuration, state, read_only=read_only, cache_dir=cache_dir) + gapi = GAPIRetriever(configuration, state, write_mode=write_mode, cache_dir=cache_dir) gapi.connect(timeout) gapi.retrieve_users() if licensing: @@ -73,7 +71,7 @@ def sync( comparator.enforce_limits(just_users, licensing) # Update Google with necessary updates found doing comparison - updater = GAPIUpdater(configuration, state, read_only=read_only, delete_users=delete_users) + updater = GAPIUpdater(configuration, state, write_mode=write_mode, delete_users=delete_users) updater.update_users() if licensing: updater.update_licensing() diff --git a/gsuitesync/sync/update.py b/gsuitesync/sync/update.py index 8bbe98bd388a4491d3bc860da8c5cf65b1e50e7e..57b0703e771e99cddab831b0526cd08f8645369c 100644 --- a/gsuitesync/sync/update.py +++ b/gsuitesync/sync/update.py @@ -1,5 +1,5 @@ """ -Perform the actual updates in Google (unless in read_only mode) +Perform the actual updates in Google (unless not in write_mode) """ import crypt @@ -22,7 +22,7 @@ class GAPIUpdater(ConfigurationStateConsumer): self.state.directory_service, self.user_api_requests(), self.sync_config, - self.read_only, + write_mode=self.write_mode, ) def update_licensing(self): @@ -33,7 +33,7 @@ class GAPIUpdater(ConfigurationStateConsumer): self.state.licensing_service, self.licensing_api_requests(), self.sync_config, - self.read_only, + write_mode=self.write_mode, ) def update_groups(self): @@ -41,20 +41,20 @@ class GAPIUpdater(ConfigurationStateConsumer): self.state.directory_service, self.group_api_requests(), self.sync_config, - self.read_only, + write_mode=self.write_mode, ) # Still need to do this even if `not group_settings` as new groups need their settings process_requests( self.state.groupssettings_service, self.group_settings_api_requests(), self.sync_config, - self.read_only, + write_mode=self.write_mode, ) process_requests( self.state.directory_service, self.member_api_requests(), self.sync_config, - self.read_only, + write_mode=self.write_mode, ) def user_api_requests(self): diff --git a/setup.py b/setup.py index 50cf79a769b9d503c432cc9915c5706abc4e21a6..4ef1d12f659f69ca0447f92f79d5d08375d72fd3 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ def load_requirements(): setup( name="gsuitesync", - version="0.14.2", + version="1.0.0", packages=find_packages(), install_requires=load_requirements(), entry_points={ diff --git a/tox.sh b/test.sh similarity index 59% rename from tox.sh rename to test.sh index 2f6654affcd3fc8e4c8d2388aed9ba6cee9124b8..8a07dc79dc46562ab624e1a48c6ea07987704785 100755 --- a/tox.sh +++ b/test.sh @@ -11,4 +11,8 @@ cd "$( dirname "$0")" # Execute tox runner, logging command used set -x docker build -t gsuite-synctool . -docker run -it --rm -e TOXINI_SITEPACKAGES=True --entrypoint /bin/sh gsuite-synctool -c "tox $*" \ No newline at end of file +docker run \ + -it --rm \ + -v $(pwd)/htmlcov:/usr/src/app/build/py3/htmlcov:rw \ + -e TOXINI_SITEPACKAGES=True \ + --entrypoint /bin/sh gsuite-synctool -c "tox $*"