diff --git a/api/tacticalrmm/agents/models.py b/api/tacticalrmm/agents/models.py
index 324edc68..55e9fea1 100644
--- a/api/tacticalrmm/agents/models.py
+++ b/api/tacticalrmm/agents/models.py
@@ -10,6 +10,7 @@ import validators
import random
import string
from loguru import logger
+from packaging import version as pyver
from django.db import models
from django.conf import settings
@@ -423,6 +424,12 @@ class Agent(models.Model):
else:
return "failed"
+ def not_supported(self, version_added):
+ if pyver.parse(self.version) < pyver.parse(version_added):
+ return True
+
+ return False
+
class AgentOutage(models.Model):
agent = models.ForeignKey(
diff --git a/api/tacticalrmm/checks/migrations/0006_check_event_id_is_wildcard.py b/api/tacticalrmm/checks/migrations/0006_check_event_id_is_wildcard.py
new file mode 100644
index 00000000..fbfb71c5
--- /dev/null
+++ b/api/tacticalrmm/checks/migrations/0006_check_event_id_is_wildcard.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1 on 2020-08-24 03:36
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('checks', '0005_auto_20200810_0544'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='check',
+ name='event_id_is_wildcard',
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/api/tacticalrmm/checks/models.py b/api/tacticalrmm/checks/models.py
index 4df35f08..87823c6d 100644
--- a/api/tacticalrmm/checks/models.py
+++ b/api/tacticalrmm/checks/models.py
@@ -130,6 +130,7 @@ class Check(models.Model):
max_length=255, choices=EVT_LOG_NAME_CHOICES, null=True, blank=True
)
event_id = models.IntegerField(null=True, blank=True)
+ event_id_is_wildcard = models.BooleanField(default=False)
event_type = models.CharField(
max_length=255, choices=EVT_LOG_TYPE_CHOICES, null=True, blank=True
)
diff --git a/api/tacticalrmm/checks/views.py b/api/tacticalrmm/checks/views.py
index 85a68434..8503a3b9 100644
--- a/api/tacticalrmm/checks/views.py
+++ b/api/tacticalrmm/checks/views.py
@@ -12,6 +12,7 @@ from rest_framework.decorators import (
permission_classes,
)
+from tacticalrmm.utils import notify_error
from agents.models import Agent
from automation.models import Policy
@@ -52,6 +53,21 @@ class GetAddCheck(APIView):
if "script" in request.data["check"]:
script = get_object_or_404(Script, pk=request.data["check"]["script"])
+ # set event id to 0 if wildcard because it needs to be an integer field for db
+ # will be ignored anyway by the agent when doing wildcard check
+ if (
+ request.data["check"]["check_type"] == "eventlog"
+ and request.data["check"]["event_id_is_wildcard"]
+ ):
+ if agent and agent.not_supported(version_added="0.10.2"):
+ return notify_error(
+ {
+ "non_field_errors": "Wildcard is only available in agent 0.10.2 or greater"
+ }
+ )
+
+ request.data["check"]["event_id"] = 0
+
serializer = CheckSerializer(
data=request.data["check"], partial=True, context=parent
)
@@ -92,6 +108,18 @@ class GetUpdateDeleteCheck(APIView):
if "check_alert" not in request.data.keys():
[request.data.pop(i) for i in check.non_editable_fields]
+ # set event id to 0 if wildcard because it needs to be an integer field for db
+ # will be ignored anyway by the agent when doing wildcard check
+ if check.check_type == "eventlog" and request.data["event_id_is_wildcard"]:
+ if check.agent.not_supported(version_added="0.10.2"):
+ return notify_error(
+ {
+ "non_field_errors": "Wildcard is only available in agent 0.10.2 or greater"
+ }
+ )
+
+ request.data["event_id"] = 0
+
serializer = CheckSerializer(instance=check, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
obj = serializer.save()
diff --git a/api/tacticalrmm/tacticalrmm/settings.py b/api/tacticalrmm/tacticalrmm/settings.py
index a1683811..643c55f6 100644
--- a/api/tacticalrmm/tacticalrmm/settings.py
+++ b/api/tacticalrmm/tacticalrmm/settings.py
@@ -11,7 +11,7 @@ AUTH_USER_MODEL = "accounts.User"
# bump this version everytime vue code is changed
# to alert user they need to manually refresh their browser
-APP_VER = "0.0.26"
+APP_VER = "0.0.27"
# https://github.com/wh1te909/salt
LATEST_SALT_VER = "1.0.3"
diff --git a/web/src/components/modals/checks/EventLogCheck.vue b/web/src/components/modals/checks/EventLogCheck.vue
index da4227e1..60ad2258 100644
--- a/web/src/components/modals/checks/EventLogCheck.vue
+++ b/web/src/components/modals/checks/EventLogCheck.vue
@@ -41,13 +41,9 @@
@@ -110,7 +106,7 @@ export default {
agentpk: Number,
policypk: Number,
mode: String,
- checkpk: Number
+ checkpk: Number,
},
mixins: [mixins],
data() {
@@ -122,25 +118,32 @@ export default {
event_type: "INFO",
fail_when: "contains",
search_last_days: 1,
- fails_b4_alert: 1
+ fails_b4_alert: 1,
+ event_id_is_wildcard: false,
},
logNameOptions: ["Application", "System", "Security"],
failWhenOptions: [
{ label: "Log contains", value: "contains" },
- { label: "Log does not contain", value: "not_contains" }
+ { label: "Log does not contain", value: "not_contains" },
],
- failOptions: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ failOptions: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
};
},
methods: {
getCheck() {
- axios.get(`/checks/${this.checkpk}/check/`).then(r => (this.eventlogcheck = r.data));
+ axios.get(`/checks/${this.checkpk}/check/`).then(r => {
+ this.eventlogcheck = r.data;
+ if (r.data.check_type === "eventlog" && r.data.event_id_is_wildcard) {
+ this.eventlogcheck.event_id = "*";
+ }
+ });
},
addCheck() {
const pk = this.policypk ? { policy: this.policypk } : { pk: this.agentpk };
+ this.eventlogcheck.event_id_is_wildcard = this.eventlogcheck.event_id === "*" ? true : false;
const data = {
...pk,
- check: this.eventlogcheck
+ check: this.eventlogcheck,
};
axios
.post("/checks/checks/", data)
@@ -152,6 +155,7 @@ export default {
.catch(e => this.notifyError(e.response.data.non_field_errors));
},
editCheck() {
+ this.eventlogcheck.event_id_is_wildcard = this.eventlogcheck.event_id === "*" ? true : false;
axios
.patch(`/checks/${this.checkpk}/check/`, this.eventlogcheck)
.then(r => {
@@ -167,12 +171,23 @@ export default {
} else {
this.$store.dispatch("loadChecks", this.agentpk);
}
- }
+ },
+ validateEventID(val) {
+ if (val === null || val.toString().replace(/\s/g, "") === "") {
+ return false;
+ } else if (val === "*") {
+ return true;
+ } else if (!isNaN(val)) {
+ return true;
+ } else {
+ return false;
+ }
+ },
},
mounted() {
if (this.mode === "edit") {
this.getCheck();
}
- }
+ },
};
\ No newline at end of file