Beispiel #1
0
    def handle_async(self, *args, **options):  # noqa C901

        (
            baseurl,
            facility_id,
            chunk_size,
            username,
            password,
            no_push,
            no_pull,
            noninteractive,
            no_provision,
        ) = (
            options["baseurl"],
            options["facility"],
            options["chunk_size"],
            options["username"],
            options["password"],
            options["no_push"],
            options["no_pull"],
            options["noninteractive"],
            options["no_provision"],
        )

        PORTAL_SYNC = baseurl == DATA_PORTAL_SYNCING_BASE_URL

        # validate url that is passed in
        if not PORTAL_SYNC:
            baseurl = get_baseurl(baseurl)

        # call this in case user directly syncs without migrating database
        if not ScopeDefinition.objects.filter():
            call_command("loaddata", "scopedefinitions")

        dataset_cache.clear()

        # try to connect to server
        controller = MorangoProfileController(PROFILE_FACILITY_DATA)
        network_connection = controller.create_network_connection(baseurl)

        # if instance_ids are equal, this means device is trying to sync with itself, which we don't allow
        if (InstanceIDModel.get_or_create_current_instance()[0].id ==
                network_connection.server_info["instance_id"]):
            raise CommandError(
                "Device can not sync with itself. Please recheck base URL and try again."
            )

        if PORTAL_SYNC:  # do portal sync setup
            facility = get_facility(facility_id=facility_id,
                                    noninteractive=noninteractive)

            # check for the certs we own for the specific facility
            client_cert = (facility.dataset.get_owned_certificates().filter(
                scope_definition_id=ScopeDefinitions.FULL_FACILITY).first())
            if not client_cert:
                raise CommandError(
                    "This device does not own a certificate for Facility: {}".
                    format(facility.name))

            # get primary partition
            scope_params = json.loads(client_cert.scope_params)
            dataset_id = scope_params["dataset_id"]

            # check if the server already has a cert for this facility
            server_certs = network_connection.get_remote_certificates(
                dataset_id, scope_def_id=ScopeDefinitions.FULL_FACILITY)

            # if necessary, push a cert up to the server
            server_cert = (
                server_certs[0] if server_certs else
                network_connection.push_signed_client_certificate_chain(
                    local_parent_cert=client_cert,
                    scope_definition_id=ScopeDefinitions.FULL_FACILITY,
                    scope_params=scope_params,
                ))

        else:  # do P2P setup
            dataset_id = get_dataset_id(baseurl,
                                        identifier=facility_id,
                                        noninteractive=noninteractive)

            client_cert, server_cert, username = get_client_and_server_certs(
                username,
                password,
                dataset_id,
                network_connection,
                noninteractive=noninteractive,
            )

        logger.info("Syncing has been initiated (this may take a while)...")
        sync_session_client = network_connection.create_sync_session(
            client_cert, server_cert, chunk_size=chunk_size)

        try:
            # pull from server
            if not no_pull:
                self._handle_pull(sync_session_client, noninteractive,
                                  dataset_id)
            # and push our own data to server
            if not no_push:
                self._handle_push(sync_session_client, noninteractive,
                                  dataset_id)

            if not no_provision:
                with self._lock():
                    create_superuser_and_provision_device(
                        username, dataset_id, noninteractive=noninteractive)
        except UserCancelledError:
            if self.job:
                self.job.extra_metadata.update(sync_state=State.CANCELLED)
                self.job.save_meta()
            logger.info("Syncing has been cancelled.")
            return

        network_connection.close()

        if self.job:
            self.job.extra_metadata.update(sync_state=State.COMPLETED)
            self.job.save_meta()

        logger.info("Syncing has been completed.")
Beispiel #2
0
    def handle_async(self, *args, **options):
        noninteractive = options["noninteractive"]
        strict = options["strict"]
        facility = get_facility(facility_id=options["facility"],
                                noninteractive=noninteractive)
        dataset_id = facility.dataset_id

        logger.info("Found facility {} <{}> for deletion".format(
            facility.id, dataset_id))

        if not noninteractive:
            # ensure the user REALLY wants to do this!
            confirm_or_exit(
                "Are you sure you wish to permanently delete this facility? This will DELETE ALL DATA FOR THE FACILITY."
            )
            confirm_or_exit(
                "ARE YOU SURE? If you do this, there is no way to recover the facility data on this device."
            )

        # everything should get cascade deleted from the facility, but we'll check anyway
        delete_group = GroupDeletion(
            "Main",
            groups=[
                self._get_morango_models(dataset_id),
                self._get_log_models(dataset_id),
                self._get_class_models(dataset_id),
                self._get_users(dataset_id),
                self._get_facility_dataset(dataset_id),
            ],
        )

        logger.info(
            "Proceeding with facility deletion. Deleting all data for facility <{}>"
            .format(dataset_id))

        with self._delete_context():
            total_deleted = 0

            # run the counting step
            with self.start_progress(
                    total=delete_group.group_count()) as update_progress:
                update_progress(increment=0,
                                message="Counting database objects")
                total_count = delete_group.count(update_progress)

            # no the deleting step
            with self.start_progress(total=total_count) as update_progress:
                update_progress(increment=0,
                                message="Deleting database objects")
                count, stats = delete_group.delete(update_progress)
                total_deleted += count
                # clear related cache
                dataset_cache.clear()

            # if count doesn't match, something doesn't seem right
            if total_count != total_deleted:
                msg = "Deleted count does not match total ({} != {})".format(
                    total_count, total_deleted)
                if strict:
                    raise CommandError("{}, aborting!".format(msg))
                else:
                    logger.warning(msg)

        logger.info("Deletion complete.")
Beispiel #3
0
 def started(transfer_session):
     dataset_cache.clear()
     if noninteractive or tracker.progressbar is None:
         logger.info(message)