def list(self, request): if not request.user.has_perm("extras.view_job"): raise PermissionDenied( "This user does not have permission to view jobs.") job_content_type = ContentType.objects.get(app_label="extras", model="job") results = { r.name: r for r in JobResult.objects.filter( obj_type=job_content_type, status__in=JobResultStatusChoices.TERMINAL_STATE_CHOICES, ).defer("data").order_by("created") } jobs = get_jobs() jobs_list = [] for grouping, modules in jobs.items(): for module_name, entry in modules.items(): for job_class in entry["jobs"].values(): job = job_class() job.result = results.get(job.class_path, None) jobs_list.append(job) serializer = serializers.JobSerializer(jobs_list, many=True, context={"request": request}) return Response(serializer.data)
def test_jobs_registration(self): """ Check that plugin jobs are registered correctly and discoverable. """ from dummy_plugin.jobs import DummyJob self.assertIn(DummyJob, registry.get("plugin_jobs", [])) self.assertEqual( DummyJob, get_job("plugins/dummy_plugin.jobs/DummyJob"), ) self.assertIn( "plugins/dummy_plugin.jobs/DummyJob", get_job_classpaths(), ) jobs_dict = get_jobs() self.assertIn("plugins", jobs_dict) self.assertIn("dummy_plugin.jobs", jobs_dict["plugins"]) self.assertEqual( "DummyPlugin jobs", jobs_dict["plugins"]["dummy_plugin.jobs"].get("name"), ) self.assertIn("jobs", jobs_dict["plugins"]["dummy_plugin.jobs"]) self.assertIn( "DummyJob", jobs_dict["plugins"]["dummy_plugin.jobs"]["jobs"], ) self.assertEqual( DummyJob, jobs_dict["plugins"]["dummy_plugin.jobs"]["jobs"]["DummyJob"], )
def test_jobs_registration(self): """ Check that plugin jobs are registered correctly and discoverable. """ from example_plugin.jobs import ExampleJob self.assertIn(ExampleJob, registry.get("plugin_jobs", [])) self.assertEqual( ExampleJob, get_job("plugins/example_plugin.jobs/ExampleJob"), ) self.assertIn( "plugins/example_plugin.jobs/ExampleJob", get_job_classpaths(), ) jobs_dict = get_jobs() self.assertIn("plugins", jobs_dict) self.assertIn("example_plugin.jobs", jobs_dict["plugins"]) self.assertEqual( "ExamplePlugin jobs", jobs_dict["plugins"]["example_plugin.jobs"].get("name"), ) self.assertIn("jobs", jobs_dict["plugins"]["example_plugin.jobs"]) self.assertIn( "ExampleJob", jobs_dict["plugins"]["example_plugin.jobs"]["jobs"], ) self.assertEqual( ExampleJob, jobs_dict["plugins"]["example_plugin.jobs"]["jobs"]["ExampleJob"], )
def refresh_job_models(sender, *, apps, **kwargs): """ Callback for the nautobot_database_ready signal; updates Jobs in the database based on Job source file availability. """ Job = apps.get_model("extras", "Job") GitRepository = apps.get_model("extras", "GitRepository") # To make reverse migrations safe if not hasattr(Job, "job_class_name") or not hasattr( Job, "git_repository"): logger.info( "Skipping refresh_job_models() as it appears Job model has not yet been migrated to latest." ) return from nautobot.extras.jobs import get_jobs # TODO: eventually this should be inverted so that get_jobs() relies on the database models... job_classes = get_jobs() job_models = [] for source, modules in job_classes.items(): git_repository = None if source.startswith("git."): try: git_repository = GitRepository.objects.get(slug=source[4:]) except GitRepository.DoesNotExist: logger.warning('GitRepository "%s" not found?', source[4:]) source = "git" for module_name, module_details in modules.items(): for job_class_name, job_class in module_details["jobs"].items(): # TODO: catch DB error in case where multiple Jobs have the same grouping + name job_model, _ = refresh_job_model_from_job_class( Job, source, job_class, git_repository=git_repository) if job_model is not None: job_models.append(job_model) for job_model in Job.objects.all(): if job_model.installed and job_model not in job_models: logger.info( "Job %s%s/%s/%s is no longer installed", job_model.source, f"/{job_model.git_repository.slug}" if job_model.git_repository is not None else "", job_model.module_name, job_model.job_class_name, ) job_model.installed = False job_model.save()