def handle(self, *args, dry_run=False, **options): remote_settings = RemoteSettings() local_recipes = Recipe.objects.filter( approved_revision__enabled_state__enabled=True) remote_records = remote_settings.published_recipes() # Compare the two sets: local recipes that are missing remotely will # be published, recipes that differ will be updated, and recipes that # are only on the remote server will be unpublished. to_publish = [] to_update = [] local_by_id = {str(r.id): r for r in local_recipes} remote_by_id = {r["id"]: r for r in remote_records} for rid, local_recipe in local_by_id.items(): if rid in remote_by_id: remote_record = remote_by_id.pop(rid) if not compare_remote(local_recipe, remote_record): to_update.append(local_recipe) else: to_publish.append(local_recipe) # Lookup locally the recipes that are published but should not. to_unpublish = [] for rid in remote_by_id.keys(): try: to_unpublish.append(Recipe.objects.get(id=rid)) except Recipe.DoesNotExist: to_unpublish.append(Recipe(id=rid)) # If there is nothing to do, exit. if not to_publish and not to_update and not to_unpublish: self.stdout.write(self.style.SUCCESS("Sync OK. Nothing to do.")) return # Show differences on stdout, and un/publish if not dry-run. style = self.style.SUCCESS if not to_publish else self.style.MIGRATE_LABEL self.stdout.write(style(f"{len(to_publish)} recipes to publish:")) for r in to_publish: self.stdout.write(f" * {r.approved_revision.name!r} (id={r.id!r})") if not dry_run: remote_settings.publish(r) style = self.style.SUCCESS if not to_update else self.style.MIGRATE_LABEL self.stdout.write(style(f"{len(to_update)} recipes to update:")) for r in to_update: self.stdout.write(f" * {r.approved_revision.name!r} (id={r.id!r})") if not dry_run: remote_settings.publish(r) style = self.style.SUCCESS if not to_unpublish else self.style.MIGRATE_LABEL self.stdout.write(style(f"{len(to_unpublish)} recipes to unpublish:")) for r in to_unpublish: name = (r.approved_revision.name if r.approved_revision else self.style.WARNING("Unknown locally")) self.stdout.write(f" * {name!r} (id={r.id!r})") if not dry_run: remote_settings.unpublish(r)
def disable(self, user): if not self.enabled: raise EnabledState.NotActionable( "This revision is already disabled.") self._create_new_enabled_state(creator=user, enabled=False) RemoteSettings().unpublish(self.recipe)
def handle(self, *args, dry_run=False, **options): remote_settings = RemoteSettings() local_recipes = Recipe.objects.filter(approved_revision__enabled_state__enabled=True) remote_records = remote_settings.published_recipes() # Compare the two sets: local recipes that are missing remotely will # be published, recipes that differ will be updated, and recipes that # are only on the remote server will be unpublished. to_publish = [] to_update = [] local_by_id = {str(r.id): r for r in local_recipes} remote_by_id = {r["id"]: r for r in remote_records} for rid, local_recipe in local_by_id.items(): if rid in remote_by_id: remote_record = remote_by_id.pop(rid) if not compare_remote(local_recipe, remote_record): to_update.append(local_recipe) else: to_publish.append(local_recipe) # Lookup locally the recipes that are published but should not. to_unpublish = [] for rid in remote_by_id.keys(): try: to_unpublish.append(Recipe.objects.get(id=rid)) except Recipe.DoesNotExist: to_unpublish.append(Recipe(id=rid)) # If there is nothing to do, exit. if not to_publish and not to_update and not to_unpublish: self.stdout.write(self.style.SUCCESS("Sync OK. Nothing to do.")) return # Show differences on stdout, and un/publish if not dry-run. style = self.style.SUCCESS if not to_publish else self.style.MIGRATE_LABEL self.stdout.write(style(f"{len(to_publish)} recipes to publish:")) for r in to_publish: self.stdout.write(f" * {r.name!r} (id={r.id!r})") if not dry_run: remote_settings.publish(r) style = self.style.SUCCESS if not to_update else self.style.MIGRATE_LABEL self.stdout.write(style(f"{len(to_update)} recipes to update:")) for r in to_update: self.stdout.write(f" * {r.name!r} (id={r.id!r})") if not dry_run: remote_settings.publish(r) style = self.style.SUCCESS if not to_unpublish else self.style.MIGRATE_LABEL self.stdout.write(style(f"{len(to_unpublish)} recipes to unpublish:")) for r in to_unpublish: name = r.name if r.name else self.style.WARNING("Unknown locally") self.stdout.write(f" * {name!r} (id={r.id!r})") if not dry_run: remote_settings.unpublish(r)
def enable(self, user, carryover_from=None): if self.enabled: raise EnabledState.NotActionable( "This revision is already enabled.") self._create_new_enabled_state(creator=user, enabled=True, carryover_from=carryover_from) RemoteSettings().publish(self.recipe)
def enable(self, user, carryover_from=None): if self.enabled: raise EnabledState.NotActionable( "This revision is already enabled.") self._validate_preference_rollout_rollback_enabled_invariance() self._create_new_enabled_state(creator=user, enabled=True, carryover_from=carryover_from) RemoteSettings().publish(self.recipe)
def handle(self, *args, force=False, **options): remote_settings = RemoteSettings() if force: recipes_to_update = Recipe.objects.only_enabled() else: recipes_to_update = self.get_outdated_recipes() count = recipes_to_update.count() if count == 0: self.stdout.write("No out of date recipes to sign") else: self.stdout.write(f"Signing {count} recipes:") for recipe in recipes_to_update: self.stdout.write(" * " + recipe.approved_revision.name) recipe.update_signature() recipe.save() remote_settings.publish(recipe, approve_changes=False) # Approve all Remote Settings changes. remote_settings.approve_changes() metrics.gauge("signed", count, tags=["force"] if force else []) recipes_to_unsign = Recipe.objects.only_disabled().exclude( signature=None) count = recipes_to_unsign.count() if count == 0: self.stdout.write("No disabled recipes to unsign") else: self.stdout.write(f"Unsigning {count} disabled recipes:") for recipe in recipes_to_unsign: self.stdout.write(" * " + recipe.approved_revision.name) sig = recipe.signature recipe.signature = None recipe.save() sig.delete() metrics.gauge("unsigned", count, tags=["force"] if force else []) self.stdout.write("all signing done")
def ready(self): checks.register() RemoteSettings().check_config() load_geoip_database()