374 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			374 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from django.db import models
 | 
						|
from agents.models import Agent
 | 
						|
from core.models import CoreSettings
 | 
						|
from logs.models import BaseAuditModel
 | 
						|
 | 
						|
 | 
						|
class Policy(BaseAuditModel):
 | 
						|
    name = models.CharField(max_length=255, unique=True)
 | 
						|
    desc = models.CharField(max_length=255, null=True, blank=True)
 | 
						|
    active = models.BooleanField(default=False)
 | 
						|
    enforced = models.BooleanField(default=False)
 | 
						|
    alert_template = models.ForeignKey(
 | 
						|
        "alerts.AlertTemplate",
 | 
						|
        related_name="policies",
 | 
						|
        on_delete=models.SET_NULL,
 | 
						|
        null=True,
 | 
						|
        blank=True,
 | 
						|
    )
 | 
						|
 | 
						|
    def save(self, *args, **kwargs):
 | 
						|
        from automation.tasks import generate_agent_checks_from_policies_task
 | 
						|
 | 
						|
        # get old policy if exists
 | 
						|
        old_policy = type(self).objects.get(pk=self.pk) if self.pk else None
 | 
						|
        super(BaseAuditModel, self).save(*args, **kwargs)
 | 
						|
 | 
						|
        # generate agent checks only if active and enforced were changed
 | 
						|
        if old_policy:
 | 
						|
            if old_policy.active != self.active or old_policy.enforced != self.enforced:
 | 
						|
                generate_agent_checks_from_policies_task.delay(
 | 
						|
                    policypk=self.pk,
 | 
						|
                    create_tasks=True,
 | 
						|
                )
 | 
						|
 | 
						|
    def delete(self, *args, **kwargs):
 | 
						|
        from automation.tasks import generate_agent_checks_task
 | 
						|
 | 
						|
        agents = list(self.related_agents().only("pk").values_list("pk", flat=True))
 | 
						|
        super(BaseAuditModel, self).delete(*args, **kwargs)
 | 
						|
 | 
						|
        generate_agent_checks_task.delay(agents, create_tasks=True)
 | 
						|
 | 
						|
    @property
 | 
						|
    def is_default_server_policy(self):
 | 
						|
        return self.default_server_policy.exists()
 | 
						|
 | 
						|
    @property
 | 
						|
    def is_default_workstation_policy(self):
 | 
						|
        return self.default_workstation_policy.exists()
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return self.name
 | 
						|
 | 
						|
    def related_agents(self):
 | 
						|
        return self.get_related("server") | self.get_related("workstation")
 | 
						|
 | 
						|
    def get_related(self, mon_type):
 | 
						|
        explicit_agents = self.agents.filter(monitoring_type=mon_type)
 | 
						|
        explicit_clients = getattr(self, f"{mon_type}_clients").all()
 | 
						|
        explicit_sites = getattr(self, f"{mon_type}_sites").all()
 | 
						|
 | 
						|
        filtered_agents_pks = Policy.objects.none()
 | 
						|
 | 
						|
        filtered_agents_pks |= Agent.objects.filter(
 | 
						|
            site__in=[
 | 
						|
                site for site in explicit_sites if site.client not in explicit_clients
 | 
						|
            ],
 | 
						|
            monitoring_type=mon_type,
 | 
						|
        ).values_list("pk", flat=True)
 | 
						|
 | 
						|
        filtered_agents_pks |= Agent.objects.filter(
 | 
						|
            site__client__in=[client for client in explicit_clients],
 | 
						|
            monitoring_type=mon_type,
 | 
						|
        ).values_list("pk", flat=True)
 | 
						|
 | 
						|
        return Agent.objects.filter(
 | 
						|
            models.Q(pk__in=filtered_agents_pks)
 | 
						|
            | models.Q(pk__in=explicit_agents.only("pk"))
 | 
						|
        )
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def serialize(policy):
 | 
						|
        # serializes the policy and returns json
 | 
						|
        from .serializers import PolicySerializer
 | 
						|
 | 
						|
        return PolicySerializer(policy).data
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def cascade_policy_tasks(agent):
 | 
						|
        from autotasks.tasks import delete_win_task_schedule
 | 
						|
 | 
						|
        from autotasks.models import AutomatedTask
 | 
						|
        from logs.models import PendingAction
 | 
						|
 | 
						|
        # List of all tasks to be applied
 | 
						|
        tasks = list()
 | 
						|
        added_task_pks = list()
 | 
						|
 | 
						|
        agent_tasks_parent_pks = [
 | 
						|
            task.parent_task for task in agent.autotasks.filter(managed_by_policy=True)
 | 
						|
        ]
 | 
						|
 | 
						|
        # Get policies applied to agent and agent site and client
 | 
						|
        client = agent.client
 | 
						|
        site = agent.site
 | 
						|
 | 
						|
        default_policy = None
 | 
						|
        client_policy = None
 | 
						|
        site_policy = None
 | 
						|
        agent_policy = agent.policy
 | 
						|
 | 
						|
        # Get the Client/Site policy based on if the agent is server or workstation
 | 
						|
        if agent.monitoring_type == "server":
 | 
						|
            default_policy = CoreSettings.objects.first().server_policy
 | 
						|
            client_policy = client.server_policy
 | 
						|
            site_policy = site.server_policy
 | 
						|
        elif agent.monitoring_type == "workstation":
 | 
						|
            default_policy = CoreSettings.objects.first().workstation_policy
 | 
						|
            client_policy = client.workstation_policy
 | 
						|
            site_policy = site.workstation_policy
 | 
						|
 | 
						|
        if agent_policy and agent_policy.active:
 | 
						|
            for task in agent_policy.autotasks.all():
 | 
						|
                if task.pk not in added_task_pks:
 | 
						|
                    tasks.append(task)
 | 
						|
                    added_task_pks.append(task.pk)
 | 
						|
        if site_policy and site_policy.active:
 | 
						|
            for task in site_policy.autotasks.all():
 | 
						|
                if task.pk not in added_task_pks:
 | 
						|
                    tasks.append(task)
 | 
						|
                    added_task_pks.append(task.pk)
 | 
						|
        if client_policy and client_policy.active:
 | 
						|
            for task in client_policy.autotasks.all():
 | 
						|
                if task.pk not in added_task_pks:
 | 
						|
                    tasks.append(task)
 | 
						|
                    added_task_pks.append(task.pk)
 | 
						|
 | 
						|
        if default_policy and default_policy.active:
 | 
						|
            for task in default_policy.autotasks.all():
 | 
						|
                if task.pk not in added_task_pks:
 | 
						|
                    tasks.append(task)
 | 
						|
                    added_task_pks.append(task.pk)
 | 
						|
 | 
						|
        # remove policy tasks from agent not included in policy
 | 
						|
        for task in agent.autotasks.filter(
 | 
						|
            parent_task__in=[
 | 
						|
                taskpk
 | 
						|
                for taskpk in agent_tasks_parent_pks
 | 
						|
                if taskpk not in added_task_pks
 | 
						|
            ]
 | 
						|
        ):
 | 
						|
            delete_win_task_schedule.delay(task.pk)
 | 
						|
 | 
						|
        # handle matching tasks that haven't synced to agent yet or pending deletion due to agent being offline
 | 
						|
        for action in agent.pendingactions.filter(action_type="taskaction").exclude(
 | 
						|
            status="completed"
 | 
						|
        ):
 | 
						|
            task = AutomatedTask.objects.get(pk=action.details["task_id"])
 | 
						|
            if (
 | 
						|
                task.parent_task in agent_tasks_parent_pks
 | 
						|
                and task.parent_task in added_task_pks
 | 
						|
            ):
 | 
						|
                agent.remove_matching_pending_task_actions(task.id)
 | 
						|
 | 
						|
                PendingAction(
 | 
						|
                    agent=agent,
 | 
						|
                    action_type="taskaction",
 | 
						|
                    details={"action": "taskcreate", "task_id": task.id},
 | 
						|
                ).save()
 | 
						|
                task.sync_status = "notsynced"
 | 
						|
                task.save(update_fields=["sync_status"])
 | 
						|
 | 
						|
        return [task for task in tasks if task.pk not in agent_tasks_parent_pks]
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def cascade_policy_checks(agent):
 | 
						|
        # Get checks added to agent directly
 | 
						|
        agent_checks = list(agent.agentchecks.filter(managed_by_policy=False))
 | 
						|
 | 
						|
        agent_checks_parent_pks = [
 | 
						|
            check.parent_check
 | 
						|
            for check in agent.agentchecks.filter(managed_by_policy=True)
 | 
						|
        ]
 | 
						|
 | 
						|
        # Get policies applied to agent and agent site and client
 | 
						|
        client = agent.client
 | 
						|
        site = agent.site
 | 
						|
 | 
						|
        default_policy = None
 | 
						|
        client_policy = None
 | 
						|
        site_policy = None
 | 
						|
        agent_policy = agent.policy
 | 
						|
 | 
						|
        if agent.monitoring_type == "server":
 | 
						|
            default_policy = CoreSettings.objects.first().server_policy
 | 
						|
            client_policy = client.server_policy
 | 
						|
            site_policy = site.server_policy
 | 
						|
        elif agent.monitoring_type == "workstation":
 | 
						|
            default_policy = CoreSettings.objects.first().workstation_policy
 | 
						|
            client_policy = client.workstation_policy
 | 
						|
            site_policy = site.workstation_policy
 | 
						|
 | 
						|
        # Used to hold the policies that will be applied and the order in which they are applied
 | 
						|
        # Enforced policies are applied first
 | 
						|
        enforced_checks = list()
 | 
						|
        policy_checks = list()
 | 
						|
 | 
						|
        if agent_policy and agent_policy.active:
 | 
						|
            if agent_policy.enforced:
 | 
						|
                for check in agent_policy.policychecks.all():
 | 
						|
                    enforced_checks.append(check)
 | 
						|
            else:
 | 
						|
                for check in agent_policy.policychecks.all():
 | 
						|
                    policy_checks.append(check)
 | 
						|
 | 
						|
        if site_policy and site_policy.active:
 | 
						|
            if site_policy.enforced:
 | 
						|
                for check in site_policy.policychecks.all():
 | 
						|
                    enforced_checks.append(check)
 | 
						|
            else:
 | 
						|
                for check in site_policy.policychecks.all():
 | 
						|
                    policy_checks.append(check)
 | 
						|
 | 
						|
        if client_policy and client_policy.active:
 | 
						|
            if client_policy.enforced:
 | 
						|
                for check in client_policy.policychecks.all():
 | 
						|
                    enforced_checks.append(check)
 | 
						|
            else:
 | 
						|
                for check in client_policy.policychecks.all():
 | 
						|
                    policy_checks.append(check)
 | 
						|
 | 
						|
        if default_policy and default_policy.active:
 | 
						|
            if default_policy.enforced:
 | 
						|
                for check in default_policy.policychecks.all():
 | 
						|
                    enforced_checks.append(check)
 | 
						|
            else:
 | 
						|
                for check in default_policy.policychecks.all():
 | 
						|
                    policy_checks.append(check)
 | 
						|
 | 
						|
        # Sorted Checks already added
 | 
						|
        added_diskspace_checks = list()
 | 
						|
        added_ping_checks = list()
 | 
						|
        added_winsvc_checks = list()
 | 
						|
        added_script_checks = list()
 | 
						|
        added_eventlog_checks = list()
 | 
						|
        added_cpuload_checks = list()
 | 
						|
        added_memory_checks = list()
 | 
						|
 | 
						|
        # Lists all agent and policy checks that will be created
 | 
						|
        diskspace_checks = list()
 | 
						|
        ping_checks = list()
 | 
						|
        winsvc_checks = list()
 | 
						|
        script_checks = list()
 | 
						|
        eventlog_checks = list()
 | 
						|
        cpuload_checks = list()
 | 
						|
        memory_checks = list()
 | 
						|
 | 
						|
        # Loop over checks in with enforced policies first, then non-enforced policies
 | 
						|
        for check in enforced_checks + agent_checks + policy_checks:
 | 
						|
            if check.check_type == "diskspace":
 | 
						|
                # Check if drive letter was already added
 | 
						|
                if check.disk not in added_diskspace_checks:
 | 
						|
                    added_diskspace_checks.append(check.disk)
 | 
						|
                    # Dont create the check if it is an agent check
 | 
						|
                    if not check.agent:
 | 
						|
                        diskspace_checks.append(check)
 | 
						|
                elif check.agent:
 | 
						|
                    check.overriden_by_policy = True
 | 
						|
                    check.save()
 | 
						|
 | 
						|
            if check.check_type == "ping":
 | 
						|
                # Check if IP/host was already added
 | 
						|
                if check.ip not in added_ping_checks:
 | 
						|
                    added_ping_checks.append(check.ip)
 | 
						|
                    # Dont create the check if it is an agent check
 | 
						|
                    if not check.agent:
 | 
						|
                        ping_checks.append(check)
 | 
						|
                elif check.agent:
 | 
						|
                    check.overriden_by_policy = True
 | 
						|
                    check.save()
 | 
						|
 | 
						|
            if check.check_type == "cpuload":
 | 
						|
                # Check if cpuload list is empty
 | 
						|
                if not added_cpuload_checks:
 | 
						|
                    added_cpuload_checks.append(check)
 | 
						|
                    # Dont create the check if it is an agent check
 | 
						|
                    if not check.agent:
 | 
						|
                        cpuload_checks.append(check)
 | 
						|
                elif check.agent:
 | 
						|
                    check.overriden_by_policy = True
 | 
						|
                    check.save()
 | 
						|
 | 
						|
            if check.check_type == "memory":
 | 
						|
                # Check if memory check list is empty
 | 
						|
                if not added_memory_checks:
 | 
						|
                    added_memory_checks.append(check)
 | 
						|
                    # Dont create the check if it is an agent check
 | 
						|
                    if not check.agent:
 | 
						|
                        memory_checks.append(check)
 | 
						|
                elif check.agent:
 | 
						|
                    check.overriden_by_policy = True
 | 
						|
                    check.save()
 | 
						|
 | 
						|
            if check.check_type == "winsvc":
 | 
						|
                # Check if service name was already added
 | 
						|
                if check.svc_name not in added_winsvc_checks:
 | 
						|
                    added_winsvc_checks.append(check.svc_name)
 | 
						|
                    # Dont create the check if it is an agent check
 | 
						|
                    if not check.agent:
 | 
						|
                        winsvc_checks.append(check)
 | 
						|
                elif check.agent:
 | 
						|
                    check.overriden_by_policy = True
 | 
						|
                    check.save()
 | 
						|
 | 
						|
            if check.check_type == "script":
 | 
						|
                # Check if script id was already added
 | 
						|
                if check.script.id not in added_script_checks:
 | 
						|
                    added_script_checks.append(check.script.id)
 | 
						|
                    # Dont create the check if it is an agent check
 | 
						|
                    if not check.agent:
 | 
						|
                        script_checks.append(check)
 | 
						|
                elif check.agent:
 | 
						|
                    check.overriden_by_policy = True
 | 
						|
                    check.save()
 | 
						|
 | 
						|
            if check.check_type == "eventlog":
 | 
						|
                # Check if events were already added
 | 
						|
                if [check.log_name, check.event_id] not in added_eventlog_checks:
 | 
						|
                    added_eventlog_checks.append([check.log_name, check.event_id])
 | 
						|
                    if not check.agent:
 | 
						|
                        eventlog_checks.append(check)
 | 
						|
                elif check.agent:
 | 
						|
                    check.overriden_by_policy = True
 | 
						|
                    check.save()
 | 
						|
 | 
						|
        final_list = (
 | 
						|
            diskspace_checks
 | 
						|
            + ping_checks
 | 
						|
            + cpuload_checks
 | 
						|
            + memory_checks
 | 
						|
            + winsvc_checks
 | 
						|
            + script_checks
 | 
						|
            + eventlog_checks
 | 
						|
        )
 | 
						|
 | 
						|
        # remove policy checks from agent that fell out of policy scope
 | 
						|
        agent.agentchecks.filter(
 | 
						|
            parent_check__in=[
 | 
						|
                checkpk
 | 
						|
                for checkpk in agent_checks_parent_pks
 | 
						|
                if checkpk not in [check.pk for check in final_list]
 | 
						|
            ]
 | 
						|
        ).delete()
 | 
						|
 | 
						|
        return [
 | 
						|
            check for check in final_list if check.pk not in agent_checks_parent_pks
 | 
						|
        ]
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def generate_policy_checks(agent):
 | 
						|
        checks = Policy.cascade_policy_checks(agent)
 | 
						|
 | 
						|
        if checks:
 | 
						|
            for check in checks:
 | 
						|
                check.create_policy_check(agent)
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def generate_policy_tasks(agent):
 | 
						|
        tasks = Policy.cascade_policy_tasks(agent)
 | 
						|
 | 
						|
        if tasks:
 | 
						|
            for task in tasks:
 | 
						|
                task.create_policy_task(agent)
 |