start prepping for go agent
This commit is contained in:
parent
75cca4e75f
commit
055b5241be
|
@ -146,26 +146,30 @@ class Agent(BaseAuditModel):
|
|||
|
||||
@property
|
||||
def local_ips(self):
|
||||
ret = []
|
||||
try:
|
||||
ips = self.wmi_detail["network_config"]
|
||||
ret = []
|
||||
for _ in ips:
|
||||
try:
|
||||
addr = [x["IPAddress"] for x in _ if "IPAddress" in x][0]
|
||||
except:
|
||||
continue
|
||||
else:
|
||||
for ip in addr:
|
||||
if validators.ipv4(ip):
|
||||
ret.append(ip)
|
||||
|
||||
if len(ret) == 1:
|
||||
return ret[0]
|
||||
else:
|
||||
return ", ".join(ret)
|
||||
except:
|
||||
except KeyError:
|
||||
return "error getting local ips"
|
||||
|
||||
for i in ips:
|
||||
try:
|
||||
addr = [x["IPAddress"] for x in i if "IPAddress" in x][0]
|
||||
except:
|
||||
continue
|
||||
|
||||
if addr is None:
|
||||
continue
|
||||
|
||||
for ip in addr:
|
||||
if validators.ipv4(ip):
|
||||
ret.append(ip)
|
||||
|
||||
if len(ret) == 1:
|
||||
return ret[0]
|
||||
else:
|
||||
return ", ".join(ret) if ret else "error getting local ips"
|
||||
|
||||
@property
|
||||
def make_model(self):
|
||||
try:
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class Apiv3Config(AppConfig):
|
||||
name = "apiv3"
|
|
@ -0,0 +1,16 @@
|
|||
from tacticalrmm.test import BaseTestCase
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
class TestAPIv3(BaseTestCase):
|
||||
def test_get_checks(self):
|
||||
url = f"/api/v3/{self.agent.agent_id}/checkrunner/"
|
||||
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
url = "/api/v3/Maj34ACb324j234asdj2n34kASDjh34-DESKTOPTEST123/checkrunner/"
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 404)
|
||||
|
||||
self.check_not_authenticated("get", url)
|
|
@ -0,0 +1,7 @@
|
|||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path("checkrunner/", views.CheckRunner.as_view()),
|
||||
path("<str:agentid>/checkrunner/", views.CheckRunner.as_view()),
|
||||
]
|
|
@ -0,0 +1,41 @@
|
|||
from django.shortcuts import get_object_or_404
|
||||
from django.utils import timezone as djangotime
|
||||
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.authentication import TokenAuthentication
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
|
||||
from agents.models import Agent
|
||||
from checks.models import Check
|
||||
from checks.serializers import (
|
||||
CheckResultsSerializer,
|
||||
CheckRunnerGetSerializerV3,
|
||||
)
|
||||
|
||||
|
||||
class CheckRunner(APIView):
|
||||
"""
|
||||
For the windows golang agent
|
||||
"""
|
||||
|
||||
authentication_classes = [TokenAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, agentid):
|
||||
agent = get_object_or_404(Agent, agent_id=agentid)
|
||||
checks = Check.objects.filter(agent__pk=agent.pk, overriden_by_policy=False)
|
||||
|
||||
ret = {
|
||||
"agent": agent.pk,
|
||||
"check_interval": agent.check_interval,
|
||||
"checks": CheckRunnerGetSerializerV3(checks, many=True).data,
|
||||
}
|
||||
return Response(ret)
|
||||
|
||||
def patch(self, request):
|
||||
check = get_object_or_404(Check, pk=request.data["id"])
|
||||
check.last_run = djangotime.now()
|
||||
check.save(update_fields=["last_run"])
|
||||
status = check.handle_checkv2(request.data)
|
||||
return Response(status)
|
|
@ -246,7 +246,12 @@ class Check(BaseAuditModel):
|
|||
self.stdout = data["stdout"]
|
||||
self.stderr = data["stderr"]
|
||||
self.retcode = data["retcode"]
|
||||
self.execution_time = "{:.4f}".format(data["stop"] - data["start"])
|
||||
try:
|
||||
# python agent
|
||||
self.execution_time = "{:.4f}".format(data["stop"] - data["start"])
|
||||
except:
|
||||
# golang agent
|
||||
self.execution_time = "{:.4f}".format(data["runtime"])
|
||||
|
||||
if data["retcode"] != 0:
|
||||
self.status = "failing"
|
||||
|
|
|
@ -4,7 +4,7 @@ from rest_framework import serializers
|
|||
|
||||
from .models import Check
|
||||
from autotasks.models import AutomatedTask
|
||||
from scripts.serializers import ScriptSerializer
|
||||
from scripts.serializers import ScriptSerializer, ScriptCheckSerializer
|
||||
|
||||
|
||||
class AssignedTaskField(serializers.ModelSerializer):
|
||||
|
@ -88,23 +88,13 @@ class CheckRunnerGetSerializer(serializers.ModelSerializer):
|
|||
task = obj.assignedtask.first()
|
||||
return AssignedTaskCheckRunnerField(task).data
|
||||
|
||||
|
||||
class CheckRunnerGetSerializerV2(serializers.ModelSerializer):
|
||||
# for the windows agent
|
||||
# only send data needed for agent to run a check
|
||||
|
||||
assigned_tasks = serializers.SerializerMethodField()
|
||||
script = ScriptSerializer(read_only=True)
|
||||
|
||||
def get_assigned_tasks(self, obj):
|
||||
if obj.assignedtask.exists():
|
||||
tasks = obj.assignedtask.all()
|
||||
return AssignedTaskCheckRunnerField(tasks, many=True).data
|
||||
|
||||
class Meta:
|
||||
model = Check
|
||||
exclude = [
|
||||
"policy",
|
||||
"managed_by_policy",
|
||||
"overriden_by_policy",
|
||||
"parent_check",
|
||||
"name",
|
||||
"more_info",
|
||||
"last_run",
|
||||
|
@ -122,6 +112,101 @@ class CheckRunnerGetSerializerV2(serializers.ModelSerializer):
|
|||
"execution_time",
|
||||
"svc_display_name",
|
||||
"svc_policy_mode",
|
||||
"created_by",
|
||||
"created_time",
|
||||
"modified_by",
|
||||
"modified_time",
|
||||
"history",
|
||||
]
|
||||
|
||||
|
||||
class CheckRunnerGetSerializerV2(serializers.ModelSerializer):
|
||||
# for the windows __python__ agent
|
||||
# only send data needed for agent to run a check
|
||||
|
||||
assigned_tasks = serializers.SerializerMethodField()
|
||||
script = ScriptSerializer(read_only=True)
|
||||
|
||||
def get_assigned_tasks(self, obj):
|
||||
if obj.assignedtask.exists():
|
||||
tasks = obj.assignedtask.all()
|
||||
return AssignedTaskCheckRunnerField(tasks, many=True).data
|
||||
|
||||
class Meta:
|
||||
model = Check
|
||||
exclude = [
|
||||
"policy",
|
||||
"managed_by_policy",
|
||||
"overriden_by_policy",
|
||||
"parent_check",
|
||||
"name",
|
||||
"more_info",
|
||||
"last_run",
|
||||
"email_alert",
|
||||
"text_alert",
|
||||
"fails_b4_alert",
|
||||
"fail_count",
|
||||
"email_sent",
|
||||
"text_sent",
|
||||
"outage_history",
|
||||
"extra_details",
|
||||
"stdout",
|
||||
"stderr",
|
||||
"retcode",
|
||||
"execution_time",
|
||||
"svc_display_name",
|
||||
"svc_policy_mode",
|
||||
"created_by",
|
||||
"created_time",
|
||||
"modified_by",
|
||||
"modified_time",
|
||||
"history",
|
||||
]
|
||||
|
||||
|
||||
class CheckRunnerGetSerializerV3(serializers.ModelSerializer):
|
||||
# for the windows __golang__ agent
|
||||
# only send data needed for agent to run a check
|
||||
# the difference here is in the script serializer
|
||||
# script checks no longer rely on salt and are executed directly by the go agent
|
||||
|
||||
assigned_tasks = serializers.SerializerMethodField()
|
||||
script = ScriptCheckSerializer(read_only=True)
|
||||
|
||||
def get_assigned_tasks(self, obj):
|
||||
if obj.assignedtask.exists():
|
||||
tasks = obj.assignedtask.all()
|
||||
return AssignedTaskCheckRunnerField(tasks, many=True).data
|
||||
|
||||
class Meta:
|
||||
model = Check
|
||||
exclude = [
|
||||
"policy",
|
||||
"managed_by_policy",
|
||||
"overriden_by_policy",
|
||||
"parent_check",
|
||||
"name",
|
||||
"more_info",
|
||||
"last_run",
|
||||
"email_alert",
|
||||
"text_alert",
|
||||
"fails_b4_alert",
|
||||
"fail_count",
|
||||
"email_sent",
|
||||
"text_sent",
|
||||
"outage_history",
|
||||
"extra_details",
|
||||
"stdout",
|
||||
"stderr",
|
||||
"retcode",
|
||||
"execution_time",
|
||||
"svc_display_name",
|
||||
"svc_policy_mode",
|
||||
"created_by",
|
||||
"created_time",
|
||||
"modified_by",
|
||||
"modified_time",
|
||||
"history",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -35,3 +35,11 @@ class ScriptSerializer(ModelSerializer):
|
|||
)
|
||||
|
||||
return val
|
||||
|
||||
|
||||
class ScriptCheckSerializer(ModelSerializer):
|
||||
code = ReadOnlyField()
|
||||
|
||||
class Meta:
|
||||
model = Script
|
||||
fields = ["code", "shell"]
|
||||
|
|
|
@ -40,6 +40,7 @@ INSTALLED_APPS = [
|
|||
"accounts",
|
||||
"api",
|
||||
"apiv2",
|
||||
"apiv3",
|
||||
"clients",
|
||||
"agents",
|
||||
"checks",
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import json
|
||||
import os
|
||||
import random
|
||||
import string
|
||||
|
||||
from django.test import TestCase, override_settings
|
||||
from django.utils import timezone as djangotime
|
||||
from django.conf import settings
|
||||
|
||||
from rest_framework.test import APIClient
|
||||
from rest_framework.test import force_authenticate
|
||||
|
@ -30,7 +33,9 @@ class TacticalTestCase(TestCase):
|
|||
self.client = APIClient()
|
||||
|
||||
# fixes tests waiting 2 minutes for mesh token to appear
|
||||
@override_settings(MESH_TOKEN_KEY="41410834b8bb4481446027f87d88ec6f119eb9aa97860366440b778540c7399613f7cabfef4f1aa5c0bd9beae03757e17b2e990e5876b0d9924da59bdf24d3437b3ed1a8593b78d65a72a76c794160d9")
|
||||
@override_settings(
|
||||
MESH_TOKEN_KEY="41410834b8bb4481446027f87d88ec6f119eb9aa97860366440b778540c7399613f7cabfef4f1aa5c0bd9beae03757e17b2e990e5876b0d9924da59bdf24d3437b3ed1a8593b78d65a72a76c794160d9"
|
||||
)
|
||||
def setup_coresettings(self):
|
||||
self.coresettings = CoreSettings.objects.create()
|
||||
|
||||
|
@ -168,6 +173,13 @@ class BaseTestCase(TestCase):
|
|||
self.assertEqual(r.status_code, 401)
|
||||
|
||||
def create_agent(self, hostname, client, site, monitoring_type="server"):
|
||||
with open(
|
||||
os.path.join(
|
||||
settings.BASE_DIR, "tacticalrmm/test_data/wmi_python_agent.json"
|
||||
)
|
||||
) as f:
|
||||
wmi_py = json.load(f)
|
||||
|
||||
return Agent.objects.create(
|
||||
operating_system="Windows 10",
|
||||
plat="windows",
|
||||
|
@ -219,6 +231,7 @@ class BaseTestCase(TestCase):
|
|||
description="Test PC",
|
||||
mesh_node_id="abcdefghijklmnopAABBCCDD77443355##!!AI%@#$%#*",
|
||||
last_seen=djangotime.now(),
|
||||
wmi_detail=wmi_py,
|
||||
)
|
||||
|
||||
def generate_agent_id(self, hostname):
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,6 +12,7 @@ urlpatterns = [
|
|||
path("logoutall/", knox_views.LogoutAllView.as_view()),
|
||||
path("api/v1/", include("api.urls")),
|
||||
path("api/v2/", include("apiv2.urls")),
|
||||
path("api/v3/", include("apiv3.urls")),
|
||||
path("clients/", include("clients.urls")),
|
||||
path("agents/", include("agents.urls")),
|
||||
path("checks/", include("checks.urls")),
|
||||
|
|
Loading…
Reference in New Issue