This commit is contained in:
wh1te909
2020-09-11 02:38:16 +00:00
parent 0af30aa92a
commit 62da21609b
83 changed files with 769 additions and 379 deletions

View File

@@ -119,6 +119,8 @@ class Migration(migrations.Migration):
"verbose_name_plural": "users", "verbose_name_plural": "users",
"abstract": False, "abstract": False,
}, },
managers=[("objects", django.contrib.auth.models.UserManager()),], managers=[
("objects", django.contrib.auth.models.UserManager()),
],
), ),
] ]

View File

@@ -6,13 +6,15 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('accounts', '0001_initial'), ("accounts", "0001_initial"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='user', model_name="user",
name='first_name', name="first_name",
field=models.CharField(blank=True, max_length=150, verbose_name='first name'), field=models.CharField(
blank=True, max_length=150, verbose_name="first name"
),
), ),
] ]

View File

@@ -9,7 +9,6 @@ from .models import User
class UserSerializer(ModelSerializer): class UserSerializer(ModelSerializer):
class Meta: class Meta:
model = User model = User
fields = ( fields = (
@@ -22,6 +21,7 @@ class UserSerializer(ModelSerializer):
"last_login", "last_login",
) )
class TOTPSetupSerializer(ModelSerializer): class TOTPSetupSerializer(ModelSerializer):
qr_url = SerializerMethodField() qr_url = SerializerMethodField()
@@ -35,4 +35,6 @@ class TOTPSetupSerializer(ModelSerializer):
) )
def get_qr_url(self, obj): def get_qr_url(self, obj):
return pyotp.totp.TOTP(obj.totp_key).provisioning_uri(obj.username, issuer_name="Tactical RMM") return pyotp.totp.TOTP(obj.totp_key).provisioning_uri(
obj.username, issuer_name="Tactical RMM"
)

View File

@@ -148,4 +148,3 @@ class TOTPSetup(APIView):
return Response(TOTPSetupSerializer(user).data) return Response(TOTPSetupSerializer(user).data)
return Response("TOTP token already set") return Response("TOTP token already set")

View File

@@ -10,7 +10,10 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RemoveField(model_name="agent", name="checks_last_generated",), migrations.RemoveField(
model_name="agent",
name="checks_last_generated",
),
migrations.AddField( migrations.AddField(
model_name="agent", model_name="agent",
name="policies_pending", name="policies_pending",

View File

@@ -10,6 +10,12 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RemoveField(model_name="agent", name="uninstall_inprogress",), migrations.RemoveField(
migrations.RemoveField(model_name="agent", name="uninstall_pending",), model_name="agent",
name="uninstall_inprogress",
),
migrations.RemoveField(
model_name="agent",
name="uninstall_pending",
),
] ]

View File

@@ -10,5 +10,8 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RemoveField(model_name="agent", name="policies_pending",), migrations.RemoveField(
model_name="agent",
name="policies_pending",
),
] ]

View File

@@ -11,6 +11,8 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.RenameField( migrations.RenameField(
model_name="agent", old_name="is_updating", new_name="update_pending", model_name="agent",
old_name="is_updating",
new_name="update_pending",
), ),
] ]

View File

@@ -6,13 +6,13 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('agents', '0008_auto_20200702_2221'), ("agents", "0008_auto_20200702_2221"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='agent', model_name="agent",
name='salt_id', name="salt_id",
field=models.CharField(blank=True, max_length=255, null=True), field=models.CharField(blank=True, max_length=255, null=True),
), ),
] ]

View File

@@ -6,18 +6,18 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('agents', '0009_agent_salt_id'), ("agents", "0009_agent_salt_id"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='agent', model_name="agent",
name='salt_update_pending', name="salt_update_pending",
field=models.BooleanField(default=False), field=models.BooleanField(default=False),
), ),
migrations.AddField( migrations.AddField(
model_name='agent', model_name="agent",
name='salt_ver', name="salt_ver",
field=models.CharField(default='1.0.3', max_length=255), field=models.CharField(default="1.0.3", max_length=255),
), ),
] ]

View File

@@ -7,18 +7,44 @@ import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('agents', '0010_auto_20200809_0133'), ("agents", "0010_auto_20200809_0133"),
] ]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='RecoveryAction', name="RecoveryAction",
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('mode', models.CharField(choices=[('salt', 'Salt'), ('mesh', 'Mesh'), ('command', 'Command')], default='mesh', max_length=50)), "id",
('command', models.TextField(blank=True, null=True)), models.AutoField(
('last_run', models.DateTimeField(blank=True, null=True)), auto_created=True,
('agent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recoveryactions', to='agents.Agent')), primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"mode",
models.CharField(
choices=[
("salt", "Salt"),
("mesh", "Mesh"),
("command", "Command"),
],
default="mesh",
max_length=50,
),
),
("command", models.TextField(blank=True, null=True)),
("last_run", models.DateTimeField(blank=True, null=True)),
(
"agent",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="recoveryactions",
to="agents.Agent",
),
),
], ],
), ),
] ]

View File

@@ -6,23 +6,23 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('agents', '0011_recoveryaction'), ("agents", "0011_recoveryaction"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='agent', model_name="agent",
name='disks', name="disks",
field=models.JSONField(null=True), field=models.JSONField(null=True),
), ),
migrations.AlterField( migrations.AlterField(
model_name='agent', model_name="agent",
name='services', name="services",
field=models.JSONField(null=True), field=models.JSONField(null=True),
), ),
migrations.AlterField( migrations.AlterField(
model_name='agent', model_name="agent",
name='wmi_detail', name="wmi_detail",
field=models.JSONField(null=True), field=models.JSONField(null=True),
), ),
] ]

View File

@@ -6,13 +6,13 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('agents', '0012_auto_20200810_0544'), ("agents", "0012_auto_20200810_0544"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='agent', model_name="agent",
name='patches_last_installed', name="patches_last_installed",
field=models.DateTimeField(blank=True, null=True), field=models.DateTimeField(blank=True, null=True),
), ),
] ]

View File

@@ -6,12 +6,12 @@ from django.db import migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('agents', '0013_agent_patches_last_installed'), ("agents", "0013_agent_patches_last_installed"),
] ]
operations = [ operations = [
migrations.RemoveField( migrations.RemoveField(
model_name='agent', model_name="agent",
name='managed_by_wsus', name="managed_by_wsus",
), ),
] ]

View File

@@ -272,7 +272,8 @@ class Agent(models.Model):
# if patch policy still doesn't exist check default policy # if patch policy still doesn't exist check default policy
elif ( elif (
core_settings.server_policy and core_settings.server_policy.winupdatepolicy core_settings.server_policy
and core_settings.server_policy.winupdatepolicy
): ):
patch_policy = core_settings.server_policy.winupdatepolicy.get() patch_policy = core_settings.server_policy.winupdatepolicy.get()
@@ -293,7 +294,8 @@ class Agent(models.Model):
# if patch policy still doesn't exist check default policy # if patch policy still doesn't exist check default policy
elif ( elif (
core_settings.workstation_policy and core_settings.workstation_policy.winupdatepolicy core_settings.workstation_policy
and core_settings.workstation_policy.winupdatepolicy
): ):
patch_policy = core_settings.workstation_policy.winupdatepolicy.get() patch_policy = core_settings.workstation_policy.winupdatepolicy.get()
@@ -321,7 +323,7 @@ class Agent(models.Model):
patch_policy.run_time_frequency = agent_policy.run_time_frequency patch_policy.run_time_frequency = agent_policy.run_time_frequency
patch_policy.run_time_hour = agent_policy.run_time_hour patch_policy.run_time_hour = agent_policy.run_time_hour
patch_policy.run_time_days = agent_policy.run_time_days patch_policy.run_time_days = agent_policy.run_time_days
if agent_policy.reboot_after_install != "inherit": if agent_policy.reboot_after_install != "inherit":
patch_policy.reboot_after_install = agent_policy.reboot_after_install patch_policy.reboot_after_install = agent_policy.reboot_after_install
@@ -586,7 +588,7 @@ class Agent(models.Model):
self.winupdates.filter(pk__in=pks).delete() self.winupdates.filter(pk__in=pks).delete()
except: except:
pass pass
# define how the agent should handle pending actions # define how the agent should handle pending actions
def handle_pending_actions(self): def handle_pending_actions(self):
pending_actions = self.pendingactions.all() pending_actions = self.pendingactions.all()
@@ -598,12 +600,15 @@ class Agent(models.Model):
enable_or_disable_win_task, enable_or_disable_win_task,
delete_win_task_schedule, delete_win_task_schedule,
) )
task_id = action.details.task_id task_id = action.details.task_id
if action.details.action == "taskcreate": if action.details.action == "taskcreate":
create_win_task_schedule.delay(task_id, pending_action=action.id) create_win_task_schedule.delay(task_id, pending_action=action.id)
elif action.details.action == "tasktoggle": elif action.details.action == "tasktoggle":
enable_or_disable_win_task.delay(task_id, action.details.value, pending_action=action.id) enable_or_disable_win_task.delay(
task_id, action.details.value, pending_action=action.id
)
elif action.details.action == "taskdelete": elif action.details.action == "taskdelete":
delete_win_task_schedule.delay(task_id, pending_action=action.id) delete_win_task_schedule.delay(task_id, pending_action=action.id)

View File

@@ -64,6 +64,7 @@ class AgentTableSerializer(serializers.ModelSerializer):
"logged_in_username", "logged_in_username",
] ]
class AgentEditSerializer(serializers.ModelSerializer): class AgentEditSerializer(serializers.ModelSerializer):
winupdatepolicy = WinUpdatePolicySerializer(many=True, read_only=True) winupdatepolicy = WinUpdatePolicySerializer(many=True, read_only=True)
all_timezones = serializers.SerializerMethodField() all_timezones = serializers.SerializerMethodField()
@@ -90,6 +91,7 @@ class AgentEditSerializer(serializers.ModelSerializer):
"winupdatepolicy", "winupdatepolicy",
] ]
class WinAgentSerializer(serializers.ModelSerializer): class WinAgentSerializer(serializers.ModelSerializer):
# for the windows agent # for the windows agent
patches_pending = serializers.ReadOnlyField(source="has_patches_pending") patches_pending = serializers.ReadOnlyField(source="has_patches_pending")

View File

@@ -28,7 +28,12 @@ from accounts.models import User
from core.models import CoreSettings from core.models import CoreSettings
from scripts.models import Script from scripts.models import Script
from .serializers import AgentSerializer, AgentHostnameSerializer, AgentTableSerializer, AgentEditSerializer from .serializers import (
AgentSerializer,
AgentHostnameSerializer,
AgentTableSerializer,
AgentEditSerializer,
)
from winupdate.serializers import WinUpdatePolicySerializer from winupdate.serializers import WinUpdatePolicySerializer
from .tasks import uninstall_agent_task, send_agent_update_task from .tasks import uninstall_agent_task, send_agent_update_task
@@ -181,7 +186,9 @@ def kill_proc(request, pk, pid):
def get_event_log(request, pk, logtype, days): def get_event_log(request, pk, logtype, days):
agent = get_object_or_404(Agent, pk=pk) agent = get_object_or_404(Agent, pk=pk)
r = agent.salt_api_cmd( r = agent.salt_api_cmd(
timeout=30, func="win_agent.get_eventlog", arg=[logtype, int(days)], timeout=30,
func="win_agent.get_eventlog",
arg=[logtype, int(days)],
) )
if r == "timeout" or r == "error": if r == "timeout" or r == "error":
@@ -198,7 +205,10 @@ def power_action(request):
if action == "rebootnow": if action == "rebootnow":
logger.info(f"{agent.hostname} was scheduled for immediate reboot") logger.info(f"{agent.hostname} was scheduled for immediate reboot")
r = agent.salt_api_cmd( r = agent.salt_api_cmd(
timeout=30, func="system.reboot", arg=3, kwargs={"in_seconds": True}, timeout=30,
func="system.reboot",
arg=3,
kwargs={"in_seconds": True},
) )
if r == "timeout" or r == "error" or (isinstance(r, bool) and not r): if r == "timeout" or r == "error" or (isinstance(r, bool) and not r):
return notify_error("Unable to contact the agent") return notify_error("Unable to contact the agent")
@@ -240,11 +250,13 @@ def list_agents_no_detail(request):
agents = Agent.objects.all() agents = Agent.objects.all()
return Response(AgentHostnameSerializer(agents, many=True).data) return Response(AgentHostnameSerializer(agents, many=True).data)
@api_view() @api_view()
def agent_edit_details(request, pk): def agent_edit_details(request, pk):
agent = get_object_or_404(Agent, pk=pk) agent = get_object_or_404(Agent, pk=pk)
return Response(AgentEditSerializer(agent).data) return Response(AgentEditSerializer(agent).data)
@api_view() @api_view()
def by_client(request, client): def by_client(request, client):
agents = Agent.objects.filter(client=client) agents = Agent.objects.filter(client=client)
@@ -529,4 +541,3 @@ def run_script(request):
return Response(f"{script.name} will now be run on {agent.hostname}") return Response(f"{script.name} will now be run on {agent.hostname}")
else: else:
return notify_error("Something went wrong") return notify_error("Something went wrong")

View File

@@ -2,4 +2,4 @@ from django.apps import AppConfig
class AlertsConfig(AppConfig): class AlertsConfig(AppConfig):
name = 'alerts' name = "alerts"

View File

@@ -9,20 +9,37 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('agents', '0012_auto_20200810_0544'), ("agents", "0012_auto_20200810_0544"),
] ]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Alert', name="Alert",
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('subject', models.TextField(blank=True, null=True)), "id",
('message', models.TextField(blank=True, null=True)), models.AutoField(
('alert_time', models.DateTimeField(blank=True, null=True)), auto_created=True,
('snooze_until', models.DateTimeField(blank=True, null=True)), primary_key=True,
('resolved', models.BooleanField(default=False)), serialize=False,
('agent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='agent', to='agents.agent')), verbose_name="ID",
),
),
("subject", models.TextField(blank=True, null=True)),
("message", models.TextField(blank=True, null=True)),
("alert_time", models.DateTimeField(blank=True, null=True)),
("snooze_until", models.DateTimeField(blank=True, null=True)),
("resolved", models.BooleanField(default=False)),
(
"agent",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="agent",
to="agents.agent",
),
),
], ],
), ),
] ]

View File

@@ -6,17 +6,25 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('alerts', '0001_initial'), ("alerts", "0001_initial"),
] ]
operations = [ operations = [
migrations.RemoveField( migrations.RemoveField(
model_name='alert', model_name="alert",
name='subject', name="subject",
), ),
migrations.AddField( migrations.AddField(
model_name='alert', model_name="alert",
name='severity', name="severity",
field=models.CharField(choices=[('info', 'Informational'), ('warning', 'Warning'), ('error', 'Error')], default='info', max_length=100), field=models.CharField(
choices=[
("info", "Informational"),
("warning", "Warning"),
("error", "Error"),
],
default="info",
max_length=100,
),
), ),
] ]

View File

@@ -7,6 +7,7 @@ SEVERITY_CHOICES = [
("error", "Error"), ("error", "Error"),
] ]
class Alert(models.Model): class Alert(models.Model):
agent = models.ForeignKey( agent = models.ForeignKey(
"agents.Agent", "agents.Agent",

View File

@@ -8,7 +8,7 @@ from .models import Alert
class AlertSerializer(ModelSerializer): class AlertSerializer(ModelSerializer):
hostname = ReadOnlyField(source="agent.hostname") hostname = ReadOnlyField(source="agent.hostname")
client = ReadOnlyField(source="agent.client") client = ReadOnlyField(source="agent.client")
site = ReadOnlyField(source="agent.site") site = ReadOnlyField(source="agent.site")

View File

@@ -9,6 +9,7 @@ from .models import Alert
from .serializers import AlertSerializer from .serializers import AlertSerializer
class GetAddAlerts(APIView): class GetAddAlerts(APIView):
def get(self, request): def get(self, request):
alerts = Alert.objects.all() alerts = Alert.objects.all()

View File

@@ -10,8 +10,20 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RemoveField(model_name="policy", name="agents",), migrations.RemoveField(
migrations.RemoveField(model_name="policy", name="clients",), model_name="policy",
migrations.RemoveField(model_name="policy", name="sites",), name="agents",
migrations.RemoveField(model_name="policyexclusions", name="clients",), ),
migrations.RemoveField(
model_name="policy",
name="clients",
),
migrations.RemoveField(
model_name="policy",
name="sites",
),
migrations.RemoveField(
model_name="policyexclusions",
name="clients",
),
] ]

View File

@@ -18,7 +18,6 @@ class Policy(models.Model):
def is_default_workstation_policy(self): def is_default_workstation_policy(self):
return self.default_workstation_policy.exists() return self.default_workstation_policy.exists()
def __str__(self): def __str__(self):
return self.name return self.name

View File

@@ -20,7 +20,9 @@ def generate_agent_checks_from_policies_task(
clear=clear, parent_checks=parent_checks clear=clear, parent_checks=parent_checks
) )
if create_tasks: if create_tasks:
agent.generate_tasks_from_policies(clear=clear,) agent.generate_tasks_from_policies(
clear=clear,
)
else: else:
policy = Policy.objects.get(pk=policypk) policy = Policy.objects.get(pk=policypk)
for agent in policy.related_agents(): for agent in policy.related_agents():
@@ -28,7 +30,9 @@ def generate_agent_checks_from_policies_task(
clear=clear, parent_checks=parent_checks clear=clear, parent_checks=parent_checks
) )
if create_tasks: if create_tasks:
agent.generate_tasks_from_policies(clear=clear,) agent.generate_tasks_from_policies(
clear=clear,
)
@app.task @app.task
@@ -42,6 +46,7 @@ def generate_agent_checks_by_location_task(
if create_tasks: if create_tasks:
agent.generate_tasks_from_policies(clear=clear) agent.generate_tasks_from_policies(clear=clear)
@app.task @app.task
def generate_all_agent_checks_task(mon_type, clear=False, create_tasks=False): def generate_all_agent_checks_task(mon_type, clear=False, create_tasks=False):
for agent in Agent.objects.filter(monitoring_type=mon_type): for agent in Agent.objects.filter(monitoring_type=mon_type):
@@ -50,6 +55,7 @@ def generate_all_agent_checks_task(mon_type, clear=False, create_tasks=False):
if create_tasks: if create_tasks:
agent.generate_tasks_from_policies(clear=clear) agent.generate_tasks_from_policies(clear=clear)
@app.task @app.task
def delete_policy_check_task(checkpk): def delete_policy_check_task(checkpk):

View File

@@ -178,7 +178,9 @@ class TestPolicyViews(BaseTestCase):
@patch("agents.models.Agent.generate_checks_from_policies") @patch("agents.models.Agent.generate_checks_from_policies")
@patch("automation.tasks.generate_agent_checks_by_location_task.delay") @patch("automation.tasks.generate_agent_checks_by_location_task.delay")
def test_update_policy_add( def test_update_policy_add(
self, mock_checks_location_task, mock_checks_task, self,
mock_checks_location_task,
mock_checks_task,
): ):
url = f"/automation/related/" url = f"/automation/related/"
@@ -473,7 +475,9 @@ class TestPolicyTasks(BaseTestCase):
) )
policy = Policy.objects.create( policy = Policy.objects.create(
name="Policy Relate Tests", desc="my awesome policy", active=True, name="Policy Relate Tests",
desc="my awesome policy",
active=True,
) )
# Add Client to Policy # Add Client to Policy

View File

@@ -82,7 +82,7 @@ class GetAddPolicies(APIView):
fail_when=check.fail_when, fail_when=check.fail_when,
search_last_days=check.search_last_days, search_last_days=check.search_last_days,
) )
tasks = copyPolicy.autotasks.all() tasks = copyPolicy.autotasks.all()
for task in tasks: for task in tasks:
@@ -173,7 +173,7 @@ class OverviewPolicy(APIView):
class GetRelated(APIView): class GetRelated(APIView):
def get(self, request, pk): def get(self, request, pk):
response = {} response = {}
policy = ( policy = (
@@ -426,6 +426,7 @@ class GetRelated(APIView):
content = {"error": "Data was submitted incorrectly"} content = {"error": "Data was submitted incorrectly"}
return Response(content, status=status.HTTP_400_BAD_REQUEST) return Response(content, status=status.HTTP_400_BAD_REQUEST)
class UpdatePatchPolicy(APIView): class UpdatePatchPolicy(APIView):
# create new patch policy # create new patch policy
@@ -438,22 +439,26 @@ class UpdatePatchPolicy(APIView):
serializer.save() serializer.save()
return Response("ok") return Response("ok")
# update patch policy # update patch policy
def put(self, request, patchpolicy): def put(self, request, patchpolicy):
policy = get_object_or_404(WinUpdatePolicy, pk=patchpolicy) policy = get_object_or_404(WinUpdatePolicy, pk=patchpolicy)
serializer = WinUpdatePolicySerializer(instance=policy, data=request.data, partial=True) serializer = WinUpdatePolicySerializer(
instance=policy, data=request.data, partial=True
)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
serializer.save() serializer.save()
return Response("ok") return Response("ok")
def patch(self, request): def patch(self, request):
agents = None agents = None
if "client" in request.data and "site" in request.data: if "client" in request.data and "site" in request.data:
agents = Agent.objects.filter(client=request.data["client"], site=request.data["site"]) agents = Agent.objects.filter(
client=request.data["client"], site=request.data["site"]
)
elif "client" in request.data: elif "client" in request.data:
agents = Agent.objects.filter(client=request.data["client"]) agents = Agent.objects.filter(client=request.data["client"])
else: else:
@@ -473,7 +478,6 @@ class UpdatePatchPolicy(APIView):
return Response("ok") return Response("ok")
# delete patch policy # delete patch policy
def delete(self, request, patchpolicy): def delete(self, request, patchpolicy):
get_object_or_404(WinUpdatePolicy, pk=patchpolicy).delete() get_object_or_404(WinUpdatePolicy, pk=patchpolicy).delete()

View File

@@ -7,13 +7,19 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('autotasks', '0002_auto_20200701_1615'), ("autotasks", "0002_auto_20200701_1615"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='automatedtask', model_name="automatedtask",
name='script_args', name="script_args",
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(blank=True, max_length=255, null=True), blank=True, default=list, null=True, size=None), field=django.contrib.postgres.fields.ArrayField(
base_field=models.CharField(blank=True, max_length=255, null=True),
blank=True,
default=list,
null=True,
size=None,
),
), ),
] ]

View File

@@ -6,13 +6,21 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('autotasks', '0003_automatedtask_script_args'), ("autotasks", "0003_automatedtask_script_args"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='automatedtask', model_name="automatedtask",
name='sync_status', name="sync_status",
field=models.CharField(choices=[('synced', 'Synced With Agent'), ('notsynced', 'Waiting On Agent Checkin'), ('pendingdeletion', 'Pending Deletion on Agent')], default='notsynced', max_length=100), field=models.CharField(
choices=[
("synced", "Synced With Agent"),
("notsynced", "Waiting On Agent Checkin"),
("pendingdeletion", "Pending Deletion on Agent"),
],
default="notsynced",
max_length=100,
),
), ),
] ]

View File

@@ -6,13 +6,21 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('autotasks', '0004_automatedtask_sync_status'), ("autotasks", "0004_automatedtask_sync_status"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='automatedtask', model_name="automatedtask",
name='sync_status', name="sync_status",
field=models.CharField(choices=[('synced', 'Synced With Agent'), ('notsynced', 'Waiting On Agent Checkin'), ('pendingdeletion', 'Pending Deletion on Agent')], default='synced', max_length=100), field=models.CharField(
choices=[
("synced", "Synced With Agent"),
("notsynced", "Waiting On Agent Checkin"),
("pendingdeletion", "Pending Deletion on Agent"),
],
default="synced",
max_length=100,
),
), ),
] ]

View File

@@ -88,7 +88,9 @@ class AutomatedTask(models.Model):
execution_time = models.CharField(max_length=100, default="0.0000") execution_time = models.CharField(max_length=100, default="0.0000")
last_run = models.DateTimeField(null=True, blank=True) last_run = models.DateTimeField(null=True, blank=True)
enabled = models.BooleanField(default=True) enabled = models.BooleanField(default=True)
sync_status = models.CharField(max_length=100, choices=SYNC_STATUS_CHOICES, default="synced") sync_status = models.CharField(
max_length=100, choices=SYNC_STATUS_CHOICES, default="synced"
)
def __str__(self): def __str__(self):
return self.name return self.name

View File

@@ -63,7 +63,11 @@ def create_win_task_schedule(pk, pending_action=False):
if r == "timeout" or r == "error" or (isinstance(r, bool) and not r): if r == "timeout" or r == "error" or (isinstance(r, bool) and not r):
# don't create pending action if this task was initiated by a pending action # don't create pending action if this task was initiated by a pending action
if not pending_action: if not pending_action:
PendingAction(agent = task.agent, action_type="taskaction", details={"action": "createtask", "task_id": task.id}).save() PendingAction(
agent=task.agent,
action_type="taskaction",
details={"action": "createtask", "task_id": task.id},
).save()
task.sync_status = "notsynced" task.sync_status = "notsynced"
task.save(update_fields=["sync_status"]) task.save(update_fields=["sync_status"])
@@ -71,17 +75,16 @@ def create_win_task_schedule(pk, pending_action=False):
f"Unable to create scheduled task {task.win_task_name} on {task.agent.hostname}. It will be created when the agent checks in." f"Unable to create scheduled task {task.win_task_name} on {task.agent.hostname}. It will be created when the agent checks in."
) )
return return
# clear pending action since it was successful # clear pending action since it was successful
if pending_action: if pending_action:
pendingaction = PendingAction.objects.get(pk=pending_action) pendingaction = PendingAction.objects.get(pk=pending_action)
pendingaction.status = "completed" pendingaction.status = "completed"
pendingaction.save(update_fields=["status"]) pendingaction.save(update_fields=["status"])
task.sync_status = "synced" task.sync_status = "synced"
task.save(update_fields=["sync_status"]) task.save(update_fields=["sync_status"])
logger.info(f"{task.agent.hostname} task {task.name} was successfully created") logger.info(f"{task.agent.hostname} task {task.name} was successfully created")
return "ok" return "ok"
@@ -92,13 +95,23 @@ def enable_or_disable_win_task(pk, action, pending_action=False):
task = AutomatedTask.objects.get(pk=pk) task = AutomatedTask.objects.get(pk=pk)
r = task.agent.salt_api_cmd( r = task.agent.salt_api_cmd(
timeout=20, func="task.edit_task", arg=[f"name={task.win_task_name}", f"enabled={action}"] timeout=20,
func="task.edit_task",
arg=[f"name={task.win_task_name}", f"enabled={action}"],
) )
if r == "timeout" or r == "error" or (isinstance(r, bool) and not r): if r == "timeout" or r == "error" or (isinstance(r, bool) and not r):
# don't create pending action if this task was initiated by a pending action # don't create pending action if this task was initiated by a pending action
if not pending_action: if not pending_action:
PendingAction(agent = task.agent, action_type="taskaction", details={"action": "tasktoggle", "value":task.enabled, "task_id": task.id}).save() PendingAction(
agent=task.agent,
action_type="taskaction",
details={
"action": "tasktoggle",
"value": task.enabled,
"task_id": task.id,
},
).save()
task.sync_status = "notsynced" task.sync_status = "notsynced"
task.save(update_fields=["sync_status"]) task.save(update_fields=["sync_status"])
@@ -124,13 +137,19 @@ def delete_win_task_schedule(pk, pending_action=False):
task = AutomatedTask.objects.get(pk=pk) task = AutomatedTask.objects.get(pk=pk)
r = task.agent.salt_api_cmd( r = task.agent.salt_api_cmd(
timeout=20, func="task.delete_task", arg=[f"name={task.win_task_name}"], timeout=20,
func="task.delete_task",
arg=[f"name={task.win_task_name}"],
) )
if r == "timeout" or r == "error" or (isinstance(r, bool) and not r): if r == "timeout" or r == "error" or (isinstance(r, bool) and not r):
# don't create pending action if this task was initiated by a pending action # don't create pending action if this task was initiated by a pending action
if not pending_action: if not pending_action:
PendingAction(agent = task.agent, action_type="taskaction", details={"action": "taskdelete", "task_id": task.id}).save() PendingAction(
agent=task.agent,
action_type="taskaction",
details={"action": "taskdelete", "task_id": task.id},
).save()
task.sync_status = "pendingdeletion" task.sync_status = "pendingdeletion"
task.save(update_fields=["sync_status"]) task.save(update_fields=["sync_status"])

View File

@@ -6,18 +6,18 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('checks', '0004_check_parent_check'), ("checks", "0004_check_parent_check"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='check', model_name="check",
name='extra_details', name="extra_details",
field=models.JSONField(blank=True, null=True), field=models.JSONField(blank=True, null=True),
), ),
migrations.AlterField( migrations.AlterField(
model_name='check', model_name="check",
name='outage_history', name="outage_history",
field=models.JSONField(blank=True, null=True), field=models.JSONField(blank=True, null=True),
), ),
] ]

View File

@@ -6,13 +6,13 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('checks', '0005_auto_20200810_0544'), ("checks", "0005_auto_20200810_0544"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='check', model_name="check",
name='event_id_is_wildcard', name="event_id_is_wildcard",
field=models.BooleanField(default=False), field=models.BooleanField(default=False),
), ),
] ]

View File

@@ -7,13 +7,19 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('checks', '0006_check_event_id_is_wildcard'), ("checks", "0006_check_event_id_is_wildcard"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='check', model_name="check",
name='script_args', name="script_args",
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(blank=True, max_length=255, null=True), blank=True, default=list, null=True, size=None), field=django.contrib.postgres.fields.ArrayField(
base_field=models.CharField(blank=True, max_length=255, null=True),
blank=True,
default=list,
null=True,
size=None,
),
), ),
] ]

View File

@@ -112,4 +112,3 @@ class TestCheckViews(BaseTestCase):
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.check_not_authenticated("patch", url_a) self.check_not_authenticated("patch", url_a)

View File

@@ -7,37 +7,61 @@ import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('automation', '0004_auto_20200617_0332'), ("automation", "0004_auto_20200617_0332"),
('clients', '0003_auto_20200609_1607'), ("clients", "0003_auto_20200609_1607"),
] ]
operations = [ operations = [
migrations.RemoveField( migrations.RemoveField(
model_name='client', model_name="client",
name='policy', name="policy",
), ),
migrations.RemoveField( migrations.RemoveField(
model_name='site', model_name="site",
name='policy', name="policy",
), ),
migrations.AddField( migrations.AddField(
model_name='client', model_name="client",
name='server_policy', name="server_policy",
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='server_clients', to='automation.policy'), field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="server_clients",
to="automation.policy",
),
), ),
migrations.AddField( migrations.AddField(
model_name='client', model_name="client",
name='workstation_policy', name="workstation_policy",
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='workstation_clients', to='automation.policy'), field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="workstation_clients",
to="automation.policy",
),
), ),
migrations.AddField( migrations.AddField(
model_name='site', model_name="site",
name='server_policy', name="server_policy",
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='server_sites', to='automation.policy'), field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="server_sites",
to="automation.policy",
),
), ),
migrations.AddField( migrations.AddField(
model_name='site', model_name="site",
name='workstation_policy', name="workstation_policy",
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='workstation_sites', to='automation.policy'), field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="workstation_sites",
to="automation.policy",
),
), ),
] ]

View File

@@ -105,4 +105,3 @@ class Command(BaseCommand):
# load community scripts into the db # load community scripts into the db
Script.load_community_scripts() Script.load_community_scripts()

View File

@@ -10,7 +10,10 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.RemoveField(model_name="coresettings", name="smtp_use_tls",), migrations.RemoveField(
model_name="coresettings",
name="smtp_use_tls",
),
migrations.AddField( migrations.AddField(
model_name="coresettings", model_name="coresettings",
name="smtp_from_email", name="smtp_from_email",

View File

@@ -6,13 +6,15 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('core', '0005_auto_20200712_0454'), ("core", "0005_auto_20200712_0454"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='coresettings', model_name="coresettings",
name='smtp_host_user', name="smtp_host_user",
field=models.CharField(blank=True, default='admin@example.com', max_length=255, null=True), field=models.CharField(
blank=True, default="admin@example.com", max_length=255, null=True
),
), ),
] ]

View File

@@ -6,13 +6,13 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('core', '0006_auto_20200812_0223'), ("core", "0006_auto_20200812_0223"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='coresettings', model_name="coresettings",
name='smtp_requires_auth', name="smtp_requires_auth",
field=models.BooleanField(default=True), field=models.BooleanField(default=True),
), ),
] ]

View File

@@ -7,19 +7,31 @@ import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('automation', '0004_auto_20200617_0332'), ("automation", "0004_auto_20200617_0332"),
('core', '0007_coresettings_smtp_requires_auth'), ("core", "0007_coresettings_smtp_requires_auth"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='coresettings', model_name="coresettings",
name='server_policy', name="server_policy",
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_server_policy', to='automation.policy'), field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="default_server_policy",
to="automation.policy",
),
), ),
migrations.AddField( migrations.AddField(
model_name='coresettings', model_name="coresettings",
name='workstation_policy', name="workstation_policy",
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_workstation_policy', to='automation.policy'), field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="default_workstation_policy",
to="automation.policy",
),
), ),
] ]

View File

@@ -17,7 +17,10 @@ TZ_CHOICES = [(_, _) for _ in pytz.all_timezones]
class CoreSettings(models.Model): class CoreSettings(models.Model):
email_alert_recipients = ArrayField( email_alert_recipients = ArrayField(
models.EmailField(null=True, blank=True), null=True, blank=True, default=list, models.EmailField(null=True, blank=True),
null=True,
blank=True,
default=list,
) )
smtp_from_email = models.CharField( smtp_from_email = models.CharField(
max_length=255, null=True, blank=True, default="from@example.com" max_length=255, null=True, blank=True, default="from@example.com"

View File

@@ -44,13 +44,17 @@ def edit_settings(request):
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
new_settings = serializer.save() new_settings = serializer.save()
#check if default policies changed # check if default policies changed
if settings.server_policy != new_settings.server_policy: if settings.server_policy != new_settings.server_policy:
generate_all_agent_checks_task.delay(mon_type="server", clear=True, create_tasks=True) generate_all_agent_checks_task.delay(
mon_type="server", clear=True, create_tasks=True
)
if settings.workstation_policy != new_settings.workstation_policy: if settings.workstation_policy != new_settings.workstation_policy:
generate_all_agent_checks_task.delay(mon_type="workstation", clear=True, create_tasks=True) generate_all_agent_checks_task.delay(
mon_type="workstation", clear=True, create_tasks=True
)
return Response("ok") return Response("ok")

View File

@@ -1,2 +1 @@
default_app_config = "logs.apps.LogsConfig" default_app_config = "logs.apps.LogsConfig"

View File

@@ -6,13 +6,13 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('logs', '0001_initial'), ("logs", "0001_initial"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='pendingaction', model_name="pendingaction",
name='details', name="details",
field=models.JSONField(blank=True, null=True), field=models.JSONField(blank=True, null=True),
), ),
] ]

View File

@@ -6,13 +6,21 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('logs', '0002_auto_20200810_0544'), ("logs", "0002_auto_20200810_0544"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='pendingaction', model_name="pendingaction",
name='action_type', name="action_type",
field=models.CharField(blank=True, choices=[('schedreboot', 'Scheduled Reboot'), ('taskaction', 'Scheduled Task Action')], max_length=255, null=True), field=models.CharField(
blank=True,
choices=[
("schedreboot", "Scheduled Reboot"),
("taskaction", "Scheduled Task Action"),
],
max_length=255,
null=True,
),
), ),
] ]

View File

@@ -25,14 +25,18 @@ STATUS_CHOICES = [
class PendingAction(models.Model): class PendingAction(models.Model):
agent = models.ForeignKey( agent = models.ForeignKey(
Agent, related_name="pendingactions", on_delete=models.CASCADE, Agent,
related_name="pendingactions",
on_delete=models.CASCADE,
) )
entry_time = models.DateTimeField(auto_now_add=True) entry_time = models.DateTimeField(auto_now_add=True)
action_type = models.CharField( action_type = models.CharField(
max_length=255, choices=ACTION_TYPE_CHOICES, null=True, blank=True max_length=255, choices=ACTION_TYPE_CHOICES, null=True, blank=True
) )
status = models.CharField( status = models.CharField(
max_length=255, choices=STATUS_CHOICES, default="pending", max_length=255,
choices=STATUS_CHOICES,
default="pending",
) )
celery_id = models.CharField(null=True, blank=True, max_length=255) celery_id = models.CharField(null=True, blank=True, max_length=255)
details = models.JSONField(null=True, blank=True) details = models.JSONField(null=True, blank=True)
@@ -50,7 +54,7 @@ class PendingAction(models.Model):
def description(self): def description(self):
if self.action_type == "schedreboot": if self.action_type == "schedreboot":
return "Device pending reboot" return "Device pending reboot"
elif self.action_type == "taskaction": elif self.action_type == "taskaction":
if self.details.action == "taskdelete": if self.details.action == "taskdelete":
return "Device pending task deletion" return "Device pending task deletion"
@@ -58,4 +62,3 @@ class PendingAction(models.Model):
return "Device pending task creation" return "Device pending task creation"
elif self.details.action == "tasktoggle": elif self.details.action == "tasktoggle":
return f"Device pending task {self.details.value}" return f"Device pending task {self.details.value}"

View File

@@ -6,13 +6,17 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('scripts', '0001_initial'), ("scripts", "0001_initial"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='script', model_name="script",
name='script_type', name="script_type",
field=models.CharField(choices=[('userdefined', 'User Defined'), ('builtin', 'Built In')], default='userdefined', max_length=100), field=models.CharField(
choices=[("userdefined", "User Defined"), ("builtin", "Built In")],
default="userdefined",
max_length=100,
),
), ),
] ]

View File

@@ -56,7 +56,9 @@ def service_action(request):
service_action = data["sv_action"] service_action = data["sv_action"]
agent = get_object_or_404(Agent, pk=pk) agent = get_object_or_404(Agent, pk=pk)
r = agent.salt_api_cmd( r = agent.salt_api_cmd(
timeout=45, func=f"service.{service_action}", arg=service_name, timeout=45,
func=f"service.{service_action}",
arg=service_name,
) )
if r == "timeout": if r == "timeout":
@@ -97,7 +99,10 @@ def edit_service(request):
kwargs = {"start_type": edit_action} kwargs = {"start_type": edit_action}
r = agent.salt_api_cmd( r = agent.salt_api_cmd(
timeout=20, func="service.modify", arg=service_name, kwargs=kwargs, timeout=20,
func="service.modify",
arg=service_name,
kwargs=kwargs,
) )
if r == "timeout": if r == "timeout":

View File

@@ -6,18 +6,18 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('software', '0001_initial'), ("software", "0001_initial"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='chocosoftware', model_name="chocosoftware",
name='chocos', name="chocos",
field=models.JSONField(), field=models.JSONField(),
), ),
migrations.AlterField( migrations.AlterField(
model_name='installedsoftware', model_name="installedsoftware",
name='software', name="software",
field=models.JSONField(), field=models.JSONField(),
), ),
] ]

View File

@@ -113,7 +113,9 @@ def install_program(pk, name, version):
agent = Agent.objects.get(pk=pk) agent = Agent.objects.get(pk=pk)
r = agent.salt_api_cmd( r = agent.salt_api_cmd(
timeout=900, func="chocolatey.install", arg=[name, f"version={version}"], timeout=900,
func="chocolatey.install",
arg=[name, f"version={version}"],
) )
if r == "timeout" or r == "error": if r == "timeout" or r == "error":

View File

@@ -38,7 +38,9 @@ class BaseTestCase(TestCase):
Site.objects.create(client=facebook, site="NY Office") Site.objects.create(client=facebook, site="NY Office")
self.policy = Policy.objects.create( self.policy = Policy.objects.create(
name="testpolicy", desc="my awesome policy", active=True, name="testpolicy",
desc="my awesome policy",
active=True,
) )
self.policy.server_clients.add(google) self.policy.server_clients.add(google)
self.policy.workstation_clients.add(facebook) self.policy.workstation_clients.add(facebook)

View File

@@ -6,13 +6,21 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('winupdate', '0001_initial'), ("winupdate", "0001_initial"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='reboot_after_install', name="reboot_after_install",
field=models.CharField(choices=[('never', 'Never'), ('required', 'When Required'), ('always', 'Always')], default='never', max_length=50), field=models.CharField(
choices=[
("never", "Never"),
("required", "When Required"),
("always", "Always"),
],
default="never",
max_length=50,
),
), ),
] ]

View File

@@ -7,20 +7,32 @@ import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('automation', '0004_auto_20200617_0332'), ("automation", "0004_auto_20200617_0332"),
('agents', '0012_auto_20200810_0544'), ("agents", "0012_auto_20200810_0544"),
('winupdate', '0002_auto_20200715_0445'), ("winupdate", "0002_auto_20200715_0445"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='policy', name="policy",
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='winupdatepolicy', to='automation.policy'), field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="winupdatepolicy",
to="automation.policy",
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='agent', name="agent",
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='winupdatepolicy', to='agents.agent'), field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="winupdatepolicy",
to="agents.agent",
),
), ),
] ]

View File

@@ -6,33 +6,78 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('winupdate', '0003_auto_20200828_0134'), ("winupdate", "0003_auto_20200828_0134"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='critical', name="critical",
field=models.CharField(choices=[('manual', 'Manual'), ('approve', 'Approve'), ('ignore', 'Ignore'), ('inherit', 'Inherit')], default='manual', max_length=100), field=models.CharField(
choices=[
("manual", "Manual"),
("approve", "Approve"),
("ignore", "Ignore"),
("inherit", "Inherit"),
],
default="manual",
max_length=100,
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='important', name="important",
field=models.CharField(choices=[('manual', 'Manual'), ('approve', 'Approve'), ('ignore', 'Ignore'), ('inherit', 'Inherit')], default='manual', max_length=100), field=models.CharField(
choices=[
("manual", "Manual"),
("approve", "Approve"),
("ignore", "Ignore"),
("inherit", "Inherit"),
],
default="manual",
max_length=100,
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='low', name="low",
field=models.CharField(choices=[('manual', 'Manual'), ('approve', 'Approve'), ('ignore', 'Ignore'), ('inherit', 'Inherit')], default='manual', max_length=100), field=models.CharField(
choices=[
("manual", "Manual"),
("approve", "Approve"),
("ignore", "Ignore"),
("inherit", "Inherit"),
],
default="manual",
max_length=100,
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='moderate', name="moderate",
field=models.CharField(choices=[('manual', 'Manual'), ('approve', 'Approve'), ('ignore', 'Ignore'), ('inherit', 'Inherit')], default='manual', max_length=100), field=models.CharField(
choices=[
("manual", "Manual"),
("approve", "Approve"),
("ignore", "Ignore"),
("inherit", "Inherit"),
],
default="manual",
max_length=100,
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='other', name="other",
field=models.CharField(choices=[('manual', 'Manual'), ('approve', 'Approve'), ('ignore', 'Ignore'), ('inherit', 'Inherit')], default='manual', max_length=100), field=models.CharField(
choices=[
("manual", "Manual"),
("approve", "Approve"),
("ignore", "Ignore"),
("inherit", "Inherit"),
],
default="manual",
max_length=100,
),
), ),
] ]

View File

@@ -6,33 +6,78 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('winupdate', '0004_auto_20200904_0103'), ("winupdate", "0004_auto_20200904_0103"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='critical', name="critical",
field=models.CharField(choices=[('manual', 'Manual'), ('approve', 'Approve'), ('ignore', 'Ignore'), ('inherit', 'Inherit')], default='inherit', max_length=100), field=models.CharField(
choices=[
("manual", "Manual"),
("approve", "Approve"),
("ignore", "Ignore"),
("inherit", "Inherit"),
],
default="inherit",
max_length=100,
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='important', name="important",
field=models.CharField(choices=[('manual', 'Manual'), ('approve', 'Approve'), ('ignore', 'Ignore'), ('inherit', 'Inherit')], default='inherit', max_length=100), field=models.CharField(
choices=[
("manual", "Manual"),
("approve", "Approve"),
("ignore", "Ignore"),
("inherit", "Inherit"),
],
default="inherit",
max_length=100,
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='low', name="low",
field=models.CharField(choices=[('manual', 'Manual'), ('approve', 'Approve'), ('ignore', 'Ignore'), ('inherit', 'Inherit')], default='inherit', max_length=100), field=models.CharField(
choices=[
("manual", "Manual"),
("approve", "Approve"),
("ignore", "Ignore"),
("inherit", "Inherit"),
],
default="inherit",
max_length=100,
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='moderate', name="moderate",
field=models.CharField(choices=[('manual', 'Manual'), ('approve', 'Approve'), ('ignore', 'Ignore'), ('inherit', 'Inherit')], default='inherit', max_length=100), field=models.CharField(
choices=[
("manual", "Manual"),
("approve", "Approve"),
("ignore", "Ignore"),
("inherit", "Inherit"),
],
default="inherit",
max_length=100,
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='other', name="other",
field=models.CharField(choices=[('manual', 'Manual'), ('approve', 'Approve'), ('ignore', 'Ignore'), ('inherit', 'Inherit')], default='inherit', max_length=100), field=models.CharField(
choices=[
("manual", "Manual"),
("approve", "Approve"),
("ignore", "Ignore"),
("inherit", "Inherit"),
],
default="inherit",
max_length=100,
),
), ),
] ]

View File

@@ -6,23 +6,40 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('winupdate', '0005_auto_20200905_2114'), ("winupdate", "0005_auto_20200905_2114"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='reprocess_failed_inherit', name="reprocess_failed_inherit",
field=models.BooleanField(default=True), field=models.BooleanField(default=True),
), ),
migrations.AddField( migrations.AddField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='run_time_frequency', name="run_time_frequency",
field=models.CharField(choices=[('daily', 'Daily/Weekly'), ('monthly', 'Monthly'), ('inherit', 'Inherit')], default='inherit', max_length=100), field=models.CharField(
choices=[
("daily", "Daily/Weekly"),
("monthly", "Monthly"),
("inherit", "Inherit"),
],
default="inherit",
max_length=100,
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='reboot_after_install', name="reboot_after_install",
field=models.CharField(choices=[('never', 'Never'), ('required', 'When Required'), ('always', 'Always'), ('inherit', 'Inherit')], default='inherit', max_length=50), field=models.CharField(
choices=[
("never", "Never"),
("required", "When Required"),
("always", "Always"),
("inherit", "Inherit"),
],
default="inherit",
max_length=50,
),
), ),
] ]

View File

@@ -6,13 +6,48 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('winupdate', '0006_auto_20200910_1909'), ("winupdate", "0006_auto_20200910_1909"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='winupdatepolicy', model_name="winupdatepolicy",
name='run_time_day', name="run_time_day",
field=models.IntegerField(choices=[(0, '1'), (1, '1'), (2, '1'), (3, '1'), (4, '1'), (5, '1'), (6, '1'), (7, '1'), (8, '1'), (9, '1'), (10, '1'), (11, '1'), (12, '1'), (13, '1'), (14, '1'), (15, '1'), (16, '1'), (17, '1'), (18, '1'), (19, '1'), (20, '1'), (21, '1'), (22, '1'), (23, '1'), (24, '1'), (25, '1'), (26, '1'), (27, '1'), (28, '1'), (29, '1'), (30, '1')], default=1), field=models.IntegerField(
choices=[
(0, "1"),
(1, "1"),
(2, "1"),
(3, "1"),
(4, "1"),
(5, "1"),
(6, "1"),
(7, "1"),
(8, "1"),
(9, "1"),
(10, "1"),
(11, "1"),
(12, "1"),
(13, "1"),
(14, "1"),
(15, "1"),
(16, "1"),
(17, "1"),
(18, "1"),
(19, "1"),
(20, "1"),
(21, "1"),
(22, "1"),
(23, "1"),
(24, "1"),
(25, "1"),
(26, "1"),
(27, "1"),
(28, "1"),
(29, "1"),
(30, "1"),
],
default=1,
),
), ),
] ]

View File

@@ -21,7 +21,7 @@ AUTO_APPROVAL_CHOICES = [
RUN_TIME_HOUR_CHOICES = [(i, dt.time(i).strftime("%I %p")) for i in range(24)] RUN_TIME_HOUR_CHOICES = [(i, dt.time(i).strftime("%I %p")) for i in range(24)]
RUN_TIME_DAY_CHOICES = [(i, dt.date(1970,1,1).strftime("%-d")) for i in range(31)] RUN_TIME_DAY_CHOICES = [(i, dt.date(1970, 1, 1).strftime("%-d")) for i in range(31)]
REBOOT_AFTER_INSTALL_CHOICES = [ REBOOT_AFTER_INSTALL_CHOICES = [
("never", "Never"), ("never", "Never"),
@@ -94,8 +94,10 @@ class WinUpdatePolicy(models.Model):
) )
run_time_hour = models.IntegerField(choices=RUN_TIME_HOUR_CHOICES, default=3) run_time_hour = models.IntegerField(choices=RUN_TIME_HOUR_CHOICES, default=3)
run_time_frequency = models.CharField(max_length=100, choices=SCHEDULE_FREQUENCY_CHOICES, default="inherit") run_time_frequency = models.CharField(
max_length=100, choices=SCHEDULE_FREQUENCY_CHOICES, default="inherit"
)
# 0 to 6 = Monday to Sunday # 0 to 6 = Monday to Sunday
run_time_days = ArrayField( run_time_days = ArrayField(

View File

@@ -64,10 +64,9 @@ def check_agent_update_schedule_task():
last_installed = agent.patches_last_installed.astimezone(timezone) last_installed = agent.patches_last_installed.astimezone(timezone)
# check if patches were already run for this cycle and exit if so # check if patches were already run for this cycle and exit if so
if ( if last_installed and last_installed.strftime(
last_installed "%d/%m/%Y"
and last_installed.strftime("%d/%m/%Y") == agent_localtime_now.strftime("%d/%m/%Y") ) == agent_localtime_now.strftime("%d/%m/%Y"):
):
return return
# check if schedule is set to daily/weekly # check if schedule is set to daily/weekly
@@ -83,7 +82,7 @@ def check_agent_update_schedule_task():
elif patch_policy.run_time_frequency == "monthly": elif patch_policy.run_time_frequency == "monthly":
if patch_policy.run_time_day > 28: if patch_policy.run_time_day > 28:
months_with_30_days = [3,6,9,11] months_with_30_days = [3, 6, 9, 11]
current_month = agent_localtime_now.strftime("%-m") current_month = agent_localtime_now.strftime("%-m")
if current_month == 2: if current_month == 2:
@@ -96,7 +95,7 @@ def check_agent_update_schedule_task():
# check if patches are past due # check if patches are past due
if patch_policy.run_time_hour < hour: if patch_policy.run_time_hour < hour:
install = True install = True
if install: if install:
# initiate update on agent asynchronously and don't worry about ret code # initiate update on agent asynchronously and don't worry about ret code
logger.info(f"Installing windows updates on {agent.salt_id}") logger.info(f"Installing windows updates on {agent.salt_id}")

View File

@@ -8,7 +8,11 @@
<q-item-section> <q-item-section>
<q-item-label overline>{{ alert.client }} - {{ alert.site }} - {{ alert.hostname }}</q-item-label> <q-item-label overline>{{ alert.client }} - {{ alert.site }} - {{ alert.hostname }}</q-item-label>
<q-item-label> <q-item-label>
<q-icon size="xs" :class="`text-${alertColor(alert.severity)}`" :name="alert.severity"></q-icon> <q-icon
size="xs"
:class="`text-${alertColor(alert.severity)}`"
:name="alert.severity"
></q-icon>
{{ alert.message }} {{ alert.message }}
</q-item-label> </q-item-label>
</q-item-section> </q-item-section>
@@ -17,14 +21,10 @@
<q-item-label caption>{{ alertTime(alert.alert_time) }}</q-item-label> <q-item-label caption>{{ alertTime(alert.alert_time) }}</q-item-label>
<q-item-label> <q-item-label>
<q-icon name="snooze" size="xs"> <q-icon name="snooze" size="xs">
<q-tooltip> <q-tooltip>Snooze the alert for 24 hours</q-tooltip>
Snooze the alert for 24 hours
</q-tooltip>
</q-icon> </q-icon>
<q-icon name="alarm_off" size="xs"> <q-icon name="alarm_off" size="xs">
<q-tooltip> <q-tooltip>Dismiss alert</q-tooltip>
Dismiss alert
</q-tooltip>
</q-icon> </q-icon>
</q-item-label> </q-item-label>
</q-item-section> </q-item-section>
@@ -46,7 +46,7 @@
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import mixins from "@/mixins/mixins" import mixins from "@/mixins/mixins";
import AlertsOverview from "@/components/modals/alerts/AlertsOverview"; import AlertsOverview from "@/components/modals/alerts/AlertsOverview";
export default { export default {
@@ -60,11 +60,9 @@ export default {
}, },
methods: { methods: {
getAlerts() { getAlerts() {
this.$store this.$store.dispatch("alerts/getAlerts").catch(error => {
.dispatch("alerts/getAlerts") console.error(error);
.catch(error => { });
console.error(error)
});
}, },
alertColor(type) { alertColor(type) {
if (type === "error") { if (type === "error") {
@@ -80,16 +78,16 @@ export default {
} else { } else {
return this.alerts.length; return this.alerts.length;
} }
} },
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
newAlerts: "alerts/getNewAlerts", newAlerts: "alerts/getNewAlerts",
alerts: "alerts/getAlerts" alerts: "alerts/getAlerts",
}) }),
}, },
mounted() { mounted() {
this.getAlerts() this.getAlerts();
} },
}; };
</script> </script>

View File

@@ -81,7 +81,7 @@ export default {
components: { WmiDetail }, components: { WmiDetail },
data() { data() {
return { return {
tab: "os" tab: "os",
}; };
}, },
computed: { computed: {
@@ -124,8 +124,8 @@ export default {
}, },
network_adapter() { network_adapter() {
return this.assets.network_adapter; return this.assets.network_adapter;
} },
} },
}; };
</script> </script>

View File

@@ -71,7 +71,7 @@ export default {
pagination: { pagination: {
rowsPerPage: 99999, rowsPerPage: 99999,
sortBy: "cpu_percent", sortBy: "cpu_percent",
descending: true descending: true,
}, },
columns: [ columns: [
{ {
@@ -79,44 +79,44 @@ export default {
label: "Name", label: "Name",
field: "name", field: "name",
align: "left", align: "left",
sortable: true sortable: true,
}, },
{ {
name: "cpu_percent", name: "cpu_percent",
label: "CPU", label: "CPU",
field: "cpu_percent", field: "cpu_percent",
align: "left", align: "left",
sortable: true sortable: true,
}, },
{ {
name: "memory_percent", name: "memory_percent",
label: "Memory", label: "Memory",
field: "memory_percent", field: "memory_percent",
align: "left", align: "left",
sortable: true sortable: true,
}, },
{ {
name: "username", name: "username",
label: "User", label: "User",
field: "username", field: "username",
align: "left", align: "left",
sortable: true sortable: true,
}, },
{ {
name: "pid", name: "pid",
label: "PID", label: "PID",
field: "pid", field: "pid",
align: "left", align: "left",
sortable: true sortable: true,
}, },
{ {
name: "status", name: "status",
label: "Status", label: "Status",
field: "status", field: "status",
align: "left", align: "left",
sortable: true sortable: true,
} },
] ],
}; };
}, },
methods: { methods: {
@@ -170,7 +170,7 @@ export default {
convert(percent) { convert(percent) {
const mb = this.mem * 1024; const mb = this.mem * 1024;
return Math.ceil((percent * mb) / 100).toLocaleString(); return Math.ceil((percent * mb) / 100).toLocaleString();
} },
}, },
beforeDestroy() { beforeDestroy() {
clearInterval(this.polling); clearInterval(this.polling);
@@ -184,6 +184,6 @@ export default {
}, },
mounted() { mounted() {
this.refreshProcs(); this.refreshProcs();
} },
}; };
</script> </script>

View File

@@ -57,13 +57,13 @@ export default {
AutomatedTasksTab, AutomatedTasksTab,
WindowsUpdates, WindowsUpdates,
SoftwareTab, SoftwareTab,
AssetsTab AssetsTab,
}, },
data() { data() {
return { return {
subtab: "summary" subtab: "summary",
}; };
} },
}; };
</script> </script>

View File

@@ -100,7 +100,7 @@ export default {
methods: { methods: {
awaitingSync(total, passing, failing) { awaitingSync(total, passing, failing) {
return total !== 0 && passing === 0 && failing === 0 ? true : false; return total !== 0 && passing === 0 && failing === 0 ? true : false;
} },
}, },
computed: { computed: {
summary() { summary() {
@@ -117,8 +117,8 @@ export default {
ret.push(v); ret.push(v);
} }
return ret; return ret;
} },
} },
}; };
</script> </script>

View File

@@ -79,11 +79,11 @@ export default {
}; };
this.$axios this.$axios
.post("/agents/recover/", data) .post("/agents/recover/", data)
.then((r) => { .then(r => {
this.$emit("close"); this.$emit("close");
this.notifySuccess(r.data, 5000); this.notifySuccess(r.data, 5000);
}) })
.catch((e) => { .catch(e => {
this.notifyError(e.response.data, 5000); this.notifyError(e.response.data, 5000);
}); });
}, },

View File

@@ -43,7 +43,7 @@ export default {
mixins: [mixins], mixins: [mixins],
data() { data() {
return { return {
datetime: null datetime: null,
}; };
}, },
methods: { methods: {
@@ -72,15 +72,15 @@ export default {
style: "width: 40vw", style: "width: 40vw",
message: `A reboot has been scheduled for <strong>${data.time}</strong> on ${data.agent}. message: `A reboot has been scheduled for <strong>${data.time}</strong> on ${data.agent}.
<br />It can be cancelled from the Pending Actions menu until the scheduled time.`, <br />It can be cancelled from the Pending Actions menu until the scheduled time.`,
html: true html: true,
}); });
} },
}, },
computed: { computed: {
...mapGetters(["selectedAgentPk"]) ...mapGetters(["selectedAgentPk"]),
}, },
created() { created() {
this.getCurrentDate(); this.getCurrentDate();
} },
}; };
</script> </script>

View File

@@ -59,7 +59,7 @@ export default {
name: "SendCommand", name: "SendCommand",
mixins: [mixins], mixins: [mixins],
props: { props: {
pk: Number pk: Number,
}, },
data() { data() {
return { return {
@@ -67,7 +67,7 @@ export default {
shell: "cmd", shell: "cmd",
cmd: null, cmd: null,
timeout: 30, timeout: 30,
ret: null ret: null,
}; };
}, },
computed: { computed: {
@@ -76,7 +76,7 @@ export default {
}, },
width() { width() {
return this.ret === null ? "40vw" : "70vw"; return this.ret === null ? "40vw" : "70vw";
} },
}, },
methods: { methods: {
send() { send() {
@@ -86,7 +86,7 @@ export default {
pk: this.pk, pk: this.pk,
cmd: this.cmd, cmd: this.cmd,
shell: this.shell, shell: this.shell,
timeout: this.timeout timeout: this.timeout,
}; };
this.$axios this.$axios
.post("/agents/sendrawcmd/", data) .post("/agents/sendrawcmd/", data)
@@ -98,7 +98,7 @@ export default {
this.loading = false; this.loading = false;
this.notifyError(e.response.data); this.notifyError(e.response.data);
}); });
} },
} },
}; };
</script> </script>

View File

@@ -10,24 +10,22 @@
<q-separator /> <q-separator />
<q-card-section class="row"> <q-card-section class="row">
<div class="col-3"> <div class="col-3">
<q-input outlined dense v-model="search"> <q-input outlined dense v-model="search">
<template v-slot:append> <template v-slot:append>
<q-icon v-if="search !== ''" name="close" @click="search = ''" class="cursor-pointer" /> <q-icon v-if="search !== ''" name="close" @click="search = ''" class="cursor-pointer" />
<q-icon name="search" /> <q-icon name="search" />
</template> </template>
<template v-slot:hint> <template v-slot:hint>Type in client, site, or agent name</template>
Type in client, site, or agent name </q-input>
</template> </div>
</q-input>
</div>
<div class="col-3"> <div class="col-3">
<q-checkbox outlined dense v-model="includeDismissed" label="Include dismissed alerts?"/> <q-checkbox outlined dense v-model="includeDismissed" label="Include dismissed alerts?" />
</div> </div>
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
@@ -46,14 +44,10 @@
<q-item-label caption>{{ alertTime(alert.alert_time) }}</q-item-label> <q-item-label caption>{{ alertTime(alert.alert_time) }}</q-item-label>
<q-item-label> <q-item-label>
<q-icon name="snooze" size="sm"> <q-icon name="snooze" size="sm">
<q-tooltip> <q-tooltip>Snooze the alert for 24 hours</q-tooltip>
Snooze the alert for 24 hours
</q-tooltip>
</q-icon> </q-icon>
<q-icon name="alarm_off" size="sm"> <q-icon name="alarm_off" size="sm">
<q-tooltip> <q-tooltip>Dismiss alert</q-tooltip>
Dismiss alert
</q-tooltip>
</q-icon> </q-icon>
</q-item-label> </q-item-label>
</q-item-section> </q-item-section>
@@ -72,7 +66,7 @@ export default {
data() { data() {
return { return {
search: "", search: "",
includeDismissed: false includeDismissed: false,
}; };
}, },
methods: { methods: {
@@ -103,11 +97,11 @@ export default {
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
alerts: "alerts/getAlerts" alerts: "alerts/getAlerts",
}) }),
}, },
mounted() { mounted() {
this.getAlerts() this.getAlerts();
} },
}; };
</script> </script>

View File

@@ -33,19 +33,19 @@ export default {
pagination: { pagination: {
rowsPerPage: 0, rowsPerPage: 0,
sortBy: "time", sortBy: "time",
descending: true descending: true,
}, },
columns: [ columns: [
{ name: "eventType", label: "Type", field: "eventType", align: "left", sortable: true }, { name: "eventType", label: "Type", field: "eventType", align: "left", sortable: true },
{ name: "source", label: "Source", field: "source", align: "left", sortable: true }, { name: "source", label: "Source", field: "source", align: "left", sortable: true },
{ name: "eventID", label: "Event ID", field: "eventID", align: "left", sortable: true }, { name: "eventID", label: "Event ID", field: "eventID", align: "left", sortable: true },
{ name: "time", label: "Time", field: "time", align: "left", sortable: true }, { name: "time", label: "Time", field: "time", align: "left", sortable: true },
{ name: "message", label: "Message", field: "message", align: "left", sortable: true } { name: "message", label: "Message", field: "message", align: "left", sortable: true },
] ],
}; };
}, },
beforeDestroy() { beforeDestroy() {
this.$emit("close"); this.$emit("close");
} },
}; };
</script> </script>

View File

@@ -39,6 +39,6 @@ export default {
props: ["scriptInfo"], props: ["scriptInfo"],
beforeDestroy() { beforeDestroy() {
this.$emit("close"); this.$emit("close");
} },
}; };
</script> </script>

View File

@@ -46,8 +46,8 @@ export default {
return { return {
client: { client: {
client: null, client: null,
site: null site: null,
} },
}; };
}, },
methods: { methods: {
@@ -67,7 +67,7 @@ export default {
this.notifyError(e.response.data.non_field_errors); this.notifyError(e.response.data.non_field_errors);
} }
}); });
} },
} },
}; };
</script> </script>

View File

@@ -37,7 +37,7 @@ export default {
mixins: [mixins], mixins: [mixins],
data() { data() {
return { return {
meshagent: null meshagent: null,
}; };
}, },
methods: { methods: {
@@ -56,7 +56,7 @@ export default {
this.$q.loading.hide(); this.$q.loading.hide();
this.notifyError("Unable to upload"); this.notifyError("Unable to upload");
}); });
} },
} },
}; };
</script> </script>

View File

@@ -82,6 +82,7 @@ export default {
this.$emit("close"); this.$emit("close");
}) })
.catch(e => { .catch(e => {
this.$q.loading.hide();
this.$q.notify(notifyErrorConfig("There was an error reseting policies")); this.$q.notify(notifyErrorConfig("There was an error reseting policies"));
}); });
}, },

View File

@@ -95,7 +95,7 @@ export default {
pagination: { pagination: {
rowsPerPage: 0, rowsPerPage: 0,
sortBy: "due", sortBy: "due",
descending: true descending: true,
}, },
all_columns: [ all_columns: [
{ name: "id", field: "id" }, { name: "id", field: "id" },
@@ -105,7 +105,7 @@ export default {
{ name: "desc", label: "Description", align: "left", sortable: true }, { name: "desc", label: "Description", align: "left", sortable: true },
{ name: "agent", label: "Agent", align: "left", sortable: true }, { name: "agent", label: "Agent", align: "left", sortable: true },
{ name: "client", label: "Client", align: "left", sortable: true }, { name: "client", label: "Client", align: "left", sortable: true },
{ name: "site", label: "Site", align: "left", sortable: true } { name: "site", label: "Site", align: "left", sortable: true },
], ],
all_visibleColumns: ["type", "due", "desc", "agent", "client", "site"], all_visibleColumns: ["type", "due", "desc", "agent", "client", "site"],
agent_columns: [ agent_columns: [
@@ -113,9 +113,9 @@ export default {
{ name: "status", field: "status" }, { name: "status", field: "status" },
{ name: "type", label: "Type", align: "left", sortable: true }, { name: "type", label: "Type", align: "left", sortable: true },
{ name: "due", label: "Due", field: "due", align: "left", sortable: true }, { name: "due", label: "Due", field: "due", align: "left", sortable: true },
{ name: "desc", label: "Description", align: "left", sortable: true } { name: "desc", label: "Description", align: "left", sortable: true },
], ],
agent_visibleColumns: ["type", "due", "desc"] agent_visibleColumns: ["type", "due", "desc"],
}; };
}, },
methods: { methods: {
@@ -128,7 +128,7 @@ export default {
.dialog({ .dialog({
title: "Delete this pending action?", title: "Delete this pending action?",
cancel: true, cancel: true,
ok: { label: "Delete", color: "negative" } ok: { label: "Delete", color: "negative" },
}) })
.onOk(() => { .onOk(() => {
this.$q.loading.show(); this.$q.loading.show();
@@ -164,7 +164,7 @@ export default {
} else if (status === "completed") { } else if (status === "completed") {
return "action-completed"; return "action-completed";
} }
} },
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
@@ -172,7 +172,7 @@ export default {
togglePendingActions: "logs/togglePendingActions", togglePendingActions: "logs/togglePendingActions",
actions: "logs/allPendingActions", actions: "logs/allPendingActions",
agentpk: "logs/actionsAgentPk", agentpk: "logs/actionsAgentPk",
actionsLoading: "logs/pendingActionsLoading" actionsLoading: "logs/pendingActionsLoading",
}), }),
filter() { filter() {
return this.showCompleted ? this.actions : this.actions.filter(k => k.status === "pending"); return this.showCompleted ? this.actions : this.actions.filter(k => k.status === "pending");
@@ -188,7 +188,7 @@ export default {
}, },
completedCount() { completedCount() {
return this.actions.filter(k => k.status === "completed").length; return this.actions.filter(k => k.status === "completed").length;
} },
} },
}; };
</script> </script>

View File

@@ -62,7 +62,7 @@ export default {
pagination: { pagination: {
rowsPerPage: 0, rowsPerPage: 0,
sortBy: "name", sortBy: "name",
descending: false descending: false,
}, },
columns: [ columns: [
{ name: "install", align: "left", label: "Install", sortable: false }, { name: "install", align: "left", label: "Install", sortable: false },
@@ -71,16 +71,16 @@ export default {
align: "left", align: "left",
label: "Name", label: "Name",
field: "name", field: "name",
sortable: true sortable: true,
}, },
{ {
name: "version", name: "version",
align: "left", align: "left",
label: "Version", label: "Version",
field: "version", field: "version",
sortable: false sortable: false,
} },
] ],
}; };
}, },
methods: { methods: {
@@ -100,7 +100,7 @@ export default {
message: `Install ${name} on ${this.agentHostname}?`, message: `Install ${name} on ${this.agentHostname}?`,
persistent: true, persistent: true,
ok: { label: "Install" }, ok: { label: "Install" },
cancel: { color: "negative" } cancel: { color: "negative" },
}) })
.onOk(() => { .onOk(() => {
axios axios
@@ -113,13 +113,13 @@ export default {
this.notifyError("Something went wrong"); this.notifyError("Something went wrong");
}); });
}); });
} },
}, },
computed: { computed: {
...mapGetters(["agentHostname"]) ...mapGetters(["agentHostname"]),
}, },
created() { created() {
this.getChocos(); this.getChocos();
} },
}; };
</script> </script>

View File

@@ -10,6 +10,6 @@
<script> <script>
export default { export default {
name: "NotFound" name: "NotFound",
}; };
</script> </script>

View File

@@ -60,14 +60,14 @@ export default {
components: { components: {
Services, Services,
EventLog, EventLog,
ProcessManager ProcessManager,
}, },
data() { data() {
return { return {
terminal: "", terminal: "",
file: "", file: "",
tab: "terminal", tab: "terminal",
title: "" title: "",
}; };
}, },
methods: { methods: {
@@ -77,20 +77,20 @@ export default {
this.file = r.data.file; this.file = r.data.file;
this.title = `${r.data.hostname} | Remote Background`; this.title = `${r.data.hostname} | Remote Background`;
}); });
} },
}, },
meta() { meta() {
return { return {
title: this.title title: this.title,
}; };
}, },
computed: { computed: {
pk() { pk() {
return this.$route.params.pk; return this.$route.params.pk;
} },
}, },
created() { created() {
this.genURLS(); this.genURLS();
} },
}; };
</script> </script>

View File

@@ -10,6 +10,6 @@ export default {
name: "SessionExpired", name: "SessionExpired",
created() { created() {
this.$store.dispatch("destroyToken"); this.$store.dispatch("destroyToken");
} },
}; };
</script> </script>

View File

@@ -8,12 +8,14 @@
<div class="text-h6">Setup 2-Factor</div> <div class="text-h6">Setup 2-Factor</div>
</q-card-section> </q-card-section>
<q-card-section> <q-card-section>
<p> Scan the QR Code with your authenticator app and then click <p>
Finish to be redirected back to the signin page.</p> Scan the QR Code with your authenticator app and then click
Finish to be redirected back to the signin page.
</p>
<qrcode-vue :value="qr_url" size="200" level="H" /> <qrcode-vue :value="qr_url" size="200" level="H" />
</q-card-section> </q-card-section>
<q-card-section> <q-card-section>
<p> You can also use the below code to configure the authenticator manually.</p> <p>You can also use the below code to configure the authenticator manually.</p>
<p>{{ totp_key }}</p> <p>{{ totp_key }}</p>
</q-card-section> </q-card-section>
<q-card-actions align="center"> <q-card-actions align="center">
@@ -27,7 +29,7 @@
</template> </template>
<script> <script>
import QrcodeVue from 'qrcode.vue'; import QrcodeVue from "qrcode.vue";
export default { export default {
name: "TOTPSetup", name: "TOTPSetup",
@@ -35,7 +37,7 @@ export default {
data() { data() {
return { return {
totp_key: "", totp_key: "",
qr_url: "" qr_url: "",
}; };
}, },
methods: { methods: {
@@ -43,7 +45,7 @@ export default {
this.$q.loading = true; this.$q.loading = true;
const data = { const data = {
username: this.$route.params.username username: this.$route.params.username,
}; };
this.$store this.$store
@@ -61,16 +63,15 @@ export default {
.catch(e => { .catch(e => {
this.$q.loading = false; this.$q.loading = false;
console.log(e.response); console.log(e.response);
}); });
}, },
finish() { finish() {
this.$router.push({ name: "Login" }); this.$router.push({ name: "Login" });
} },
}, },
created() { created() {
this.$q.dark.set(false); this.$q.dark.set(false);
this.getQRCodeData(); this.getQRCodeData();
} },
}; };
</script> </script>

View File

@@ -15,17 +15,17 @@ export default {
name: "TakeControl", name: "TakeControl",
data() { data() {
return { return {
control: "" control: "",
}; };
}, },
methods: { methods: {
genURL() { genURL() {
const pk = this.$route.params.pk; const pk = this.$route.params.pk;
axios.get(`/agents/${pk}/meshcentral/`).then(r => (this.control = r.data.control)); axios.get(`/agents/${pk}/meshcentral/`).then(r => (this.control = r.data.control));
} },
}, },
created() { created() {
this.genURL(); this.genURL();
} },
}; };
</script> </script>