diff --git a/_modules/process_manager.py b/_modules/process_manager.py new file mode 100644 index 00000000..dc17435e --- /dev/null +++ b/_modules/process_manager.py @@ -0,0 +1,33 @@ +from __future__ import absolute_import +import psutil +from time import sleep +import random +import string + +def get_procs(): + ret = [] + + # setup + for proc in psutil.process_iter(): + with proc.oneshot(): + proc.cpu_percent(interval=None) + + # need time for psutil to record cpu percent + sleep(1) + + for proc in psutil.process_iter(): + x = {} + with proc.oneshot(): + x['name'] = proc.name() + x['cpu_percent'] = proc.cpu_percent(interval=None) / psutil.cpu_count() + x['memory_percent'] = proc.memory_percent() + x['pid'] = proc.pid + x['ppid'] = proc.ppid() + x['status'] = proc.status() + x['username'] = proc.username() + x['id'] = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(10)]) + + if proc.pid != 0: + ret.append(x) + + return ret \ No newline at end of file diff --git a/api/tacticalrmm/agents/urls.py b/api/tacticalrmm/agents/urls.py index 1ddf1b00..9fd82b14 100644 --- a/api/tacticalrmm/agents/urls.py +++ b/api/tacticalrmm/agents/urls.py @@ -16,4 +16,6 @@ urlpatterns = [ path("/geteventlog///", views.get_event_log), path("getagentversions/", views.get_agent_versions), path("updateagents/", views.update_agents), + path("/getprocs/", views.get_processes), + path("//killproc/", views.kill_proc), ] diff --git a/api/tacticalrmm/agents/views.py b/api/tacticalrmm/agents/views.py index 33dc05f5..289e3257 100644 --- a/api/tacticalrmm/agents/views.py +++ b/api/tacticalrmm/agents/views.py @@ -194,6 +194,42 @@ def agent_detail(request, pk): return Response(AgentSerializer(agent).data) +@api_view() +def get_processes(request, pk): + agent = get_object_or_404(Agent, pk=pk) + try: + resp = agent.salt_api_cmd( + hostname=agent.salt_id, + timeout=70, + func="process_manager.get_procs" + ) + data = resp.json() + except Exception: + return Response( + {"error": "unable to contact the agent"}, status=status.HTTP_400_BAD_REQUEST + ) + + return Response(data["return"][0][agent.salt_id]) + +@api_view() +def kill_proc(request, pk, pid): + agent = get_object_or_404(Agent, pk=pk) + resp = agent.salt_api_cmd( + hostname=agent.salt_id, + timeout=60, + func="ps.kill_pid", + arg=int(pid) + ) + data = resp.json() + + if not data["return"][0][agent.salt_id]: + return Response( + {"error": "Unable to kill the process"}, status=status.HTTP_400_BAD_REQUEST + ) + else: + return Response("ok") + + @api_view() def get_event_log(request, pk, logtype, days): agent = get_object_or_404(Agent, pk=pk) diff --git a/web/package.json b/web/package.json index e2fd33c5..e08095ac 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "web", - "version": "0.1.7", + "version": "0.1.8", "private": true, "scripts": { "serve": "vue-cli-service serve", diff --git a/web/src/components/ProcessManager.vue b/web/src/components/ProcessManager.vue new file mode 100644 index 00000000..082f09d7 --- /dev/null +++ b/web/src/components/ProcessManager.vue @@ -0,0 +1,213 @@ + + + + + \ No newline at end of file diff --git a/web/src/views/RemoteBackground.vue b/web/src/views/RemoteBackground.vue index fc99468c..968b757c 100644 --- a/web/src/views/RemoteBackground.vue +++ b/web/src/views/RemoteBackground.vue @@ -13,7 +13,8 @@ - + + @@ -24,6 +25,9 @@ > + + + @@ -43,6 +47,7 @@