Skip to content

Commit

Permalink
Release 0.4.10
Browse files Browse the repository at this point in the history
  • Loading branch information
wh1te909 committed Feb 17, 2021
2 parents 4a202c5 + bb65108 commit 31257bd
Show file tree
Hide file tree
Showing 17 changed files with 534 additions and 220 deletions.
21 changes: 13 additions & 8 deletions api/tacticalrmm/agents/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,17 +542,22 @@ def get_alert_template(self) -> Union[AlertTemplate, None]:
for template in templates:
# check if client, site, or agent has been excluded from template
if (
client.pk in template.excluded_clients.all()
or site.pk in template.excluded_sites.all()
or self.pk in template.excluded_agents.all()
client.pk
in template.excluded_clients.all().values_list("pk", flat=True)
or site.pk in template.excluded_sites.all().values_list("pk", flat=True)
or self.pk
in template.excluded_agents.all()
.only("pk")
.values_list("pk", flat=True)
):
continue

# see if template is excluding desktops
if (
self.monitoring_type == "workstation"
and not template.agent_include_desktops
):
# check if template is excluding desktops
if self.monitoring_type == "workstation" and template.exclude_desktops:
continue

# check if template is excluding servers
elif self.monitoring_type == "server" and template.exclude_servers:
continue
else:
return template
Expand Down
15 changes: 15 additions & 0 deletions api/tacticalrmm/agents/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ class AgentTableSerializer(serializers.ModelSerializer):
logged_username = serializers.SerializerMethodField()
italic = serializers.SerializerMethodField()
policy = serializers.ReadOnlyField(source="policy.id")
alert_template = serializers.SerializerMethodField()

def get_alert_template(self, obj):
alert_template = obj.get_alert_template()

if not alert_template:
return None
else:
return {
"name": alert_template.name,
"always_email": alert_template.agent_always_email,
"always_text": alert_template.agent_always_text,
"always_alert": alert_template.agent_always_alert,
}

def get_pending_actions(self, obj):
return obj.pendingactions.filter(status="pending").count()
Expand Down Expand Up @@ -83,6 +97,7 @@ class Meta:
model = Agent
fields = [
"id",
"alert_template",
"hostname",
"agent_id",
"site_name",
Expand Down
72 changes: 72 additions & 0 deletions api/tacticalrmm/alerts/migrations/0006_auto_20210217_1736.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Generated by Django 3.1.6 on 2021-02-17 17:36

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('alerts', '0005_auto_20210212_1745'),
]

operations = [
migrations.RemoveField(
model_name='alerttemplate',
name='agent_include_desktops',
),
migrations.AddField(
model_name='alerttemplate',
name='exclude_servers',
field=models.BooleanField(blank=True, default=False, null=True),
),
migrations.AddField(
model_name='alerttemplate',
name='exclude_workstations',
field=models.BooleanField(blank=True, default=False, null=True),
),
migrations.AlterField(
model_name='alerttemplate',
name='agent_always_alert',
field=models.BooleanField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='alerttemplate',
name='agent_always_email',
field=models.BooleanField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='alerttemplate',
name='agent_always_text',
field=models.BooleanField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='alerttemplate',
name='check_always_alert',
field=models.BooleanField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='alerttemplate',
name='check_always_email',
field=models.BooleanField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='alerttemplate',
name='check_always_text',
field=models.BooleanField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='alerttemplate',
name='task_always_alert',
field=models.BooleanField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='alerttemplate',
name='task_always_email',
field=models.BooleanField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name='alerttemplate',
name='task_always_text',
field=models.BooleanField(blank=True, default=None, null=True),
),
]
23 changes: 13 additions & 10 deletions api/tacticalrmm/alerts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,9 @@ class AlertTemplate(models.Model):
# agent alert settings
agent_email_on_resolved = BooleanField(null=True, blank=True, default=False)
agent_text_on_resolved = BooleanField(null=True, blank=True, default=False)
agent_include_desktops = BooleanField(null=True, blank=True, default=False)
agent_always_email = BooleanField(null=True, blank=True, default=False)
agent_always_text = BooleanField(null=True, blank=True, default=False)
agent_always_alert = BooleanField(null=True, blank=True, default=False)
agent_always_email = BooleanField(null=True, blank=True, default=None)
agent_always_text = BooleanField(null=True, blank=True, default=None)
agent_always_alert = BooleanField(null=True, blank=True, default=None)
agent_periodic_alert_days = PositiveIntegerField(blank=True, null=True, default=0)

# check alert settings
Expand All @@ -194,9 +193,9 @@ class AlertTemplate(models.Model):
)
check_email_on_resolved = BooleanField(null=True, blank=True, default=False)
check_text_on_resolved = BooleanField(null=True, blank=True, default=False)
check_always_email = BooleanField(null=True, blank=True, default=False)
check_always_text = BooleanField(null=True, blank=True, default=False)
check_always_alert = BooleanField(null=True, blank=True, default=False)
check_always_email = BooleanField(null=True, blank=True, default=None)
check_always_text = BooleanField(null=True, blank=True, default=None)
check_always_alert = BooleanField(null=True, blank=True, default=None)
check_periodic_alert_days = PositiveIntegerField(blank=True, null=True, default=0)

# task alert settings
Expand All @@ -217,11 +216,15 @@ class AlertTemplate(models.Model):
)
task_email_on_resolved = BooleanField(null=True, blank=True, default=False)
task_text_on_resolved = BooleanField(null=True, blank=True, default=False)
task_always_email = BooleanField(null=True, blank=True, default=False)
task_always_text = BooleanField(null=True, blank=True, default=False)
task_always_alert = BooleanField(null=True, blank=True, default=False)
task_always_email = BooleanField(null=True, blank=True, default=None)
task_always_text = BooleanField(null=True, blank=True, default=None)
task_always_alert = BooleanField(null=True, blank=True, default=None)
task_periodic_alert_days = PositiveIntegerField(blank=True, null=True, default=0)

# exclusion settings
exclude_workstations = BooleanField(null=True, blank=True, default=False)
exclude_servers = BooleanField(null=True, blank=True, default=False)

excluded_sites = models.ManyToManyField(
"clients.Site", related_name="alert_exclusions", blank=True
)
Expand Down
18 changes: 18 additions & 0 deletions api/tacticalrmm/autotasks/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ class TaskSerializer(serializers.ModelSerializer):
assigned_check = CheckSerializer(read_only=True)
schedule = serializers.ReadOnlyField()
last_run = serializers.ReadOnlyField(source="last_run_as_timezone")
alert_template = serializers.SerializerMethodField()

def get_alert_template(self, obj):

if obj.agent:
alert_template = obj.agent.get_alert_template()
else:
alert_template = None

if not alert_template:
return None
else:
return {
"name": alert_template.name,
"always_email": alert_template.task_always_email,
"always_text": alert_template.task_always_text,
"always_alert": alert_template.task_always_alert,
}

class Meta:
model = AutomatedTask
Expand Down
17 changes: 17 additions & 0 deletions api/tacticalrmm/checks/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,23 @@ class CheckSerializer(serializers.ModelSerializer):
assigned_task = serializers.SerializerMethodField()
last_run = serializers.ReadOnlyField(source="last_run_as_timezone")
history_info = serializers.ReadOnlyField()
alert_template = serializers.SerializerMethodField()

def get_alert_template(self, obj):
if obj.agent:
alert_template = obj.agent.get_alert_template()
else:
alert_template = None

if not alert_template:
return None
else:
return {
"name": alert_template.name,
"always_email": alert_template.check_always_email,
"always_text": alert_template.check_always_text,
"always_alert": alert_template.check_always_alert,
}

## Change to return only array of tasks after 9/25/2020
def get_assigned_task(self, obj):
Expand Down
4 changes: 2 additions & 2 deletions api/tacticalrmm/tacticalrmm/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
AUTH_USER_MODEL = "accounts.User"

# latest release
TRMM_VERSION = "0.4.9"
TRMM_VERSION = "0.4.10"

# bump this version everytime vue code is changed
# to alert user they need to manually refresh their browser
APP_VER = "0.0.112"
APP_VER = "0.0.113"

# https://github.com/wh1te909/rmmagent
LATEST_AGENT_VER = "1.4.5"
Expand Down
69 changes: 69 additions & 0 deletions docs/docs/alerting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Alerting Overview

## Notification Types

* *Email Alerts* - Sends email
* *SMS Alerts* - Sends text message
* *Dashboard Alerts* - Adds a notification in the dashboard alert icon


## Alert Severities

* Informational
* Warning
* Error

#### Agents
Agent offline alerts always have an error severity.

#### Checks
Checks can be configured to create alerts with different severities

* Memory and Cpuload checks can be configured with a warning and error threshold. To disable one of them put in a 0.
* Script checks allow for information and warning return codes. Everything else, besides a 0 will result in an error severity.
* Event Log, service, and ping checks require you to set the severity to information, warning, or error.

#### Automated Tasks
For automated tasks, you set the what the alert severity should be directly on the task.


## Configure Alert Templates
Alert template allow you to setup alerting and notifications on many agents at once. Alert templates can be applied to Sites, Client, Automation Policies, and in the Global Settings.

To create an alert template, go to Settings > Alerts Manager. Then click New

In the form, give the alert template a name and make sure it is enabled.

Optionally setup any of the below settings:
* *Failure Action* - Runs the selected script once on any agent. This is useful for running one-time tasks like sending an http request to an external system to create a ticket.
* *Failure action args* - Optionally pass in arguments to the failure script.
* *Failure action timeout* - Sets the timeout for the script.
* *Resolved action* - Runs the selected script once on any agent if the alert is resolved. This is useful for running onetime tasks like sending an http request to an external system to close the ticket that was created.
* *Resolved action args* - Optionally pass in arguments to the resolved script.
* *Resolved action timeout* - Sets the timeout for the script.
* *Email Recipients* - Overrides the default email recipients in Global Settings.
* *From Email* - Overrides the From email address in Global Settings.
* *SMS Recipients* - Overrides the SMS recipients in Global Settings.
* *Include desktops* - Will apply to desktops
#### agent/check/task settings
* *Email on resolved* - Sends a email when the alert clears
* *Text on resolved* - Sends a text when the alert clears
* *Always email* - This enables the email notification setting on the agent/check/task
* *Always sms* - This enables the text notification setting on the agent/check/task
* *Always dashboard alert* - This enables the dashboard alert notification setting on the agent/check/task
* *Periodic notification* - This sets up a periodic notification on for the agent/check/task alert
* *Alert on severity* - When configured, will only send a notification through the corresponding channel if the alert is of the specified severity

## Applying Alert Templates

Alerts are applied in the following over. The agent picks the closest matching alert template.

* Right-click on any Client or Site and go to Assign Alert Template
* In Automation Manager, click on Assign Alert Template for the policy you want to apply it to
* In Global Settings, select the default alert template

1. Policy w/ Alert Template applied to Site
2. Site
3. Policy w/ Alert Template applied to Client
4. Client
5. Default Alert Template
31 changes: 30 additions & 1 deletion web/src/components/AgentTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -253,20 +253,50 @@
</q-menu>
<q-td>
<q-checkbox
v-if="props.row.alert_template && props.row.alert_template.always_text !== null"
:value="props.row.alert_template.always_text"
disable
dense
>
<q-tooltip> Setting is overidden by alert template: {{ props.row.alert_template.name }} </q-tooltip>
</q-checkbox>

<q-checkbox
v-else
dense
@input="overdueAlert('text', props.row.id, props.row.overdue_text_alert)"
v-model="props.row.overdue_text_alert"
/>
</q-td>
<q-td>
<q-checkbox
v-if="props.row.alert_template && props.row.alert_template.always_email !== null"
:value="props.row.alert_template.always_email"
disable
dense
>
<q-tooltip> Setting is overidden by alert template: {{ props.row.alert_template.name }} </q-tooltip>
</q-checkbox>

<q-checkbox
v-else
dense
@input="overdueAlert('email', props.row.id, props.row.overdue_email_alert)"
v-model="props.row.overdue_email_alert"
/>
</q-td>
<q-td>
<q-checkbox
v-if="props.row.alert_template && props.row.alert_template.always_alert !== null"
:value="props.row.alert_template.always_alert"
disable
dense
>
<q-tooltip> Setting is overidden by alert template: {{ props.row.alert_template.name }} </q-tooltip>
</q-checkbox>

<q-checkbox
v-else
dense
@input="overdueAlert('dashboard', props.row.id, props.row.overdue_dashboard_alert)"
v-model="props.row.overdue_dashboard_alert"
Expand Down Expand Up @@ -369,7 +399,6 @@
</template>

<script>
import axios from "axios";
import { notifySuccessConfig, notifyErrorConfig } from "@/mixins/mixins";
import mixins from "@/mixins/mixins";
import { mapGetters } from "vuex";
Expand Down
Loading

0 comments on commit 31257bd

Please sign in to comment.