auto format everything
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -28,4 +28,6 @@ meshagent.exe
|
||||
app.ini
|
||||
.env.dev
|
||||
.env
|
||||
*.pem
|
||||
*.pem
|
||||
create_services.py
|
||||
gen_random.py
|
@@ -4,6 +4,7 @@ import os
|
||||
|
||||
PROGRAM_DIR = "C:\\Program Files\\TacticalAgent"
|
||||
|
||||
|
||||
def get_services():
|
||||
return [svc.as_dict() for svc in psutil.win_service_iter()]
|
||||
|
||||
@@ -30,6 +31,7 @@ def update_salt():
|
||||
__salt__["cmd.run_bg"]([tacrmm, "-m", "updatesalt"])
|
||||
return "ok"
|
||||
|
||||
|
||||
def run_manual_checks():
|
||||
tacrmm = os.path.join(PROGRAM_DIR, "tacticalrmm.exe")
|
||||
__salt__["cmd.run_bg"]([tacrmm, "-m", "runchecks"])
|
||||
|
@@ -6,4 +6,3 @@ from .models import User
|
||||
|
||||
admin.site.register(User)
|
||||
TokenAdmin.raw_id_fields = ("user",)
|
||||
|
||||
|
@@ -266,32 +266,3 @@ class Agent(models.Model):
|
||||
versions[i] = release["name"]
|
||||
|
||||
return {"versions": versions, "data": r.json()}
|
||||
|
||||
""" @staticmethod
|
||||
def salt_cmd(tgt, fun, arg=[], timeout=60, kwargs={}):
|
||||
return local.cmd(
|
||||
tgt,
|
||||
fun,
|
||||
arg,
|
||||
timeout=timeout,
|
||||
tgt_type="glob",
|
||||
ret="",
|
||||
jid="",
|
||||
full_return=False,
|
||||
kwarg=kwargs,
|
||||
username=settings.SALT_USERNAME,
|
||||
password=settings.SALT_PASSWORD,
|
||||
eauth="pam"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def salt_wheel_cmd(hostname, func):
|
||||
resp = wheel.cmd_sync({
|
||||
"fun": func,
|
||||
"match": hostname,
|
||||
"username": settings.SALT_USERNAME,
|
||||
"password": settings.SALT_PASSWORD,
|
||||
"eauth": "pam"
|
||||
}, timeout=100)
|
||||
|
||||
return resp """
|
||||
|
@@ -98,7 +98,7 @@ class TestAgentViews(BaseTestCase):
|
||||
|
||||
# TODO
|
||||
# decode the cookie
|
||||
|
||||
|
||||
self.assertIn("&hide=31", r.data)
|
||||
self.assertIn("&viewmode=11", r.data)
|
||||
self.assertIsInstance(r.data, str)
|
||||
|
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
||||
|
||||
|
||||
class AutomationConfig(AppConfig):
|
||||
name = 'automation'
|
||||
name = "automation"
|
||||
|
@@ -37,6 +37,7 @@ TASK_TYPE_CHOICES = [
|
||||
("manual", "Manual"),
|
||||
]
|
||||
|
||||
|
||||
class AutomatedTask(models.Model):
|
||||
agent = models.ForeignKey(Agent, related_name="autotasks", on_delete=models.CASCADE)
|
||||
name = models.CharField(max_length=255)
|
||||
@@ -89,7 +90,9 @@ class AutomatedTask(models.Model):
|
||||
if i in j:
|
||||
ret.append(j[1][0:3])
|
||||
|
||||
run_time_nice = dt.datetime.strptime(self.run_time_minute, "%H:%M").strftime("%I:%M %p")
|
||||
run_time_nice = dt.datetime.strptime(
|
||||
self.run_time_minute, "%H:%M"
|
||||
).strftime("%I:%M %p")
|
||||
|
||||
if len(ret) == 7:
|
||||
return f"Every day at {run_time_nice}"
|
||||
@@ -133,7 +136,7 @@ class AutomatedTask(models.Model):
|
||||
def generate_task_name():
|
||||
chars = string.ascii_letters
|
||||
return "TacticalRMM_" + "".join(random.choice(chars) for i in range(35))
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_related_check(data):
|
||||
from checks.models import (
|
||||
|
@@ -4,14 +4,14 @@ from .models import Policy, AutomatedTask
|
||||
from agents.models import Agent
|
||||
from checks.serializers import ScriptSerializer
|
||||
|
||||
class PolicySerializer(serializers.ModelSerializer):
|
||||
|
||||
class PolicySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Policy
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class PolicyRelationSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Policy
|
||||
fields = "__all__"
|
||||
@@ -28,13 +28,18 @@ class TaskSerializer(serializers.ModelSerializer):
|
||||
fields = "__all__"
|
||||
depth = 1
|
||||
|
||||
|
||||
class AgentTaskSerializer(serializers.ModelSerializer):
|
||||
|
||||
script = ScriptSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = AutomatedTask
|
||||
fields = ("timeout", "script",)
|
||||
fields = (
|
||||
"timeout",
|
||||
"script",
|
||||
)
|
||||
|
||||
|
||||
class AutoTaskSerializer(serializers.ModelSerializer):
|
||||
|
||||
@@ -48,6 +53,7 @@ class AutoTaskSerializer(serializers.ModelSerializer):
|
||||
"autotasks",
|
||||
)
|
||||
|
||||
|
||||
class AutoTaskPolicySerializer(serializers.ModelSerializer):
|
||||
|
||||
autotasks = TaskSerializer(many=True, read_only=True)
|
||||
|
@@ -17,11 +17,11 @@ from checks.models import Script
|
||||
from clients.models import Client, Site
|
||||
|
||||
from .serializers import (
|
||||
PolicySerializer,
|
||||
PolicySerializer,
|
||||
PolicyRelationSerializer,
|
||||
AutoTaskPolicySerializer,
|
||||
AutoTaskSerializer,
|
||||
AgentTaskSerializer
|
||||
AutoTaskSerializer,
|
||||
AgentTaskSerializer,
|
||||
)
|
||||
|
||||
from checks.serializers import ScriptSerializer
|
||||
@@ -32,6 +32,7 @@ from .tasks import (
|
||||
enable_or_disable_win_task,
|
||||
)
|
||||
|
||||
|
||||
class GetAddPolicies(APIView):
|
||||
def get(self, request):
|
||||
|
||||
@@ -53,20 +54,21 @@ class GetAddPolicies(APIView):
|
||||
except DataError:
|
||||
content = {"error": "Policy name too long (max 255 chars)"}
|
||||
return Response(content, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
# Add Clients, Sites, and Agents to Policy
|
||||
if (len(request.data["clients"]) > 0):
|
||||
if len(request.data["clients"]) > 0:
|
||||
policy.clients.set(request.data["clients"])
|
||||
|
||||
if (len(request.data["sites"]) > 0):
|
||||
if len(request.data["sites"]) > 0:
|
||||
policy.sites.set(request.data["sites"])
|
||||
|
||||
if (len(request.data["agents"]) > 0):
|
||||
if len(request.data["agents"]) > 0:
|
||||
policy.agents.set(request.data["agents"])
|
||||
|
||||
return Response("ok")
|
||||
|
||||
class GetUpdateDeletePolicy(APIView):
|
||||
|
||||
class GetUpdateDeletePolicy(APIView):
|
||||
def get(self, request, pk):
|
||||
|
||||
policy = get_object_or_404(Policy, pk=pk)
|
||||
@@ -88,21 +90,21 @@ class GetUpdateDeletePolicy(APIView):
|
||||
return Response(content, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Update Clients, Sites, and Agents to Policy
|
||||
if (len(request.data["clients"]) > 0):
|
||||
if len(request.data["clients"]) > 0:
|
||||
policy.clients.set(request.data["clients"])
|
||||
else:
|
||||
policy.clients.clear()
|
||||
|
||||
if (len(request.data["sites"]) > 0):
|
||||
|
||||
if len(request.data["sites"]) > 0:
|
||||
policy.sites.set(request.data["sites"])
|
||||
else:
|
||||
policy.sites.clear()
|
||||
|
||||
if (len(request.data["agents"]) > 0):
|
||||
if len(request.data["agents"]) > 0:
|
||||
policy.agents.set(request.data["agents"])
|
||||
else:
|
||||
policy.agents.clear()
|
||||
|
||||
|
||||
return Response("ok")
|
||||
|
||||
def delete(self, request, pk):
|
||||
@@ -196,6 +198,7 @@ class PolicyAutoTask(APIView):
|
||||
policy = Policy.objects.only("pk").get(pk=pk)
|
||||
return Response(AutoTaskPolicySerializer(policy).data)
|
||||
|
||||
|
||||
@api_view()
|
||||
def run_task(request, pk):
|
||||
task = get_object_or_404(AutomatedTask, pk=pk)
|
||||
@@ -226,8 +229,7 @@ class TaskRunner(APIView):
|
||||
return Response("ok")
|
||||
|
||||
|
||||
class OverviewPolicy(APIView):
|
||||
|
||||
class OverviewPolicy(APIView):
|
||||
def get(self, request):
|
||||
|
||||
clients = Client.objects.all()
|
||||
@@ -244,14 +246,15 @@ class OverviewPolicy(APIView):
|
||||
sites = Site.objects.filter(client=client)
|
||||
|
||||
for site in sites:
|
||||
|
||||
|
||||
client_sites["sites"][site.site] = {}
|
||||
|
||||
policies = Policy.objects.filter(sites__id=site.id)
|
||||
|
||||
client_sites["sites"][site.site]["policies"] = list(PolicySerializer(policies, many=True).data)
|
||||
|
||||
client_sites["sites"][site.site]["policies"] = list(
|
||||
PolicySerializer(policies, many=True).data
|
||||
)
|
||||
|
||||
response[client.client] = client_sites
|
||||
|
||||
return Response(response)
|
||||
|
||||
|
@@ -5,10 +5,7 @@ from .models import Client, Site
|
||||
class ClientSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Client
|
||||
fields = (
|
||||
"id",
|
||||
"client"
|
||||
)
|
||||
fields = ("id", "client")
|
||||
|
||||
|
||||
class SiteSerializer(serializers.ModelSerializer):
|
||||
@@ -27,4 +24,3 @@ class TreeSerializer(serializers.ModelSerializer):
|
||||
"site",
|
||||
"client_name",
|
||||
)
|
||||
|
||||
|
@@ -1,3 +1 @@
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
|
@@ -11,4 +11,3 @@ class ServicesSerializer(serializers.ModelSerializer):
|
||||
"pk",
|
||||
"services",
|
||||
)
|
||||
|
||||
|
@@ -19,7 +19,7 @@ class ChocoSoftware(models.Model):
|
||||
]
|
||||
biggest = max(range(len(sizes)), key=lambda index: sizes[index]["size"])
|
||||
return int(sizes[biggest]["pk"])
|
||||
|
||||
|
||||
@classmethod
|
||||
def combine_all(cls):
|
||||
from .serializers import ChocoSoftwareSerializer
|
||||
@@ -28,17 +28,16 @@ class ChocoSoftware(models.Model):
|
||||
combined = []
|
||||
for i in chocos:
|
||||
combined.extend(ChocoSoftwareSerializer(i).data["chocos"])
|
||||
|
||||
|
||||
# remove duplicates
|
||||
return [dict(t) for t in {tuple(d.items()) for d in combined}]
|
||||
|
||||
|
||||
def __str__(self):
|
||||
from .serializers import ChocoSoftwareSerializer
|
||||
|
||||
return str(len(ChocoSoftwareSerializer(self).data["chocos"])) + f" - {self.added}"
|
||||
|
||||
|
||||
|
||||
return (
|
||||
str(len(ChocoSoftwareSerializer(self).data["chocos"])) + f" - {self.added}"
|
||||
)
|
||||
|
||||
|
||||
class ChocoLog(models.Model):
|
||||
|
@@ -62,7 +62,7 @@ def update_chocos():
|
||||
continue
|
||||
else:
|
||||
if data:
|
||||
|
||||
|
||||
resp = agent.salt_api_cmd(
|
||||
hostname=agent.salt_id, timeout=200, func="chocolatey.list"
|
||||
)
|
||||
|
@@ -2,4 +2,4 @@ from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from .celery import app as celery_app
|
||||
|
||||
__all__ = ('celery_app',)
|
||||
__all__ = ("celery_app",)
|
||||
|
@@ -11,6 +11,6 @@ import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tacticalrmm.settings')
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tacticalrmm.settings")
|
||||
|
||||
application = get_wsgi_application()
|
||||
|
@@ -74,7 +74,9 @@ class WinUpdatePolicy(models.Model):
|
||||
run_time_hour = models.IntegerField(choices=RUN_TIME_HOUR_CHOICES, default=3)
|
||||
|
||||
# 0 to 6 = Monday to Sunday
|
||||
run_time_days = ArrayField(models.IntegerField(blank=True), null=True, blank=True, default=list)
|
||||
run_time_days = ArrayField(
|
||||
models.IntegerField(blank=True), null=True, blank=True, default=list
|
||||
)
|
||||
|
||||
reboot_after_install = models.CharField(
|
||||
max_length=50, choices=REBOOT_AFTER_INSTALL_CHOICES, default="required"
|
||||
@@ -86,4 +88,3 @@ class WinUpdatePolicy(models.Model):
|
||||
|
||||
def __str__(self):
|
||||
return self.agent.hostname
|
||||
|
||||
|
@@ -47,4 +47,3 @@ class ApprovedUpdateSerializer(serializers.ModelSerializer):
|
||||
"winupdates",
|
||||
"patch_policy",
|
||||
)
|
||||
|
||||
|
@@ -7,7 +7,7 @@ from tacticalrmm.celery import app
|
||||
|
||||
@app.task
|
||||
def check_for_updates_task(pk, wait=False):
|
||||
|
||||
|
||||
if wait:
|
||||
sleep(70)
|
||||
|
||||
|
@@ -1,48 +1,44 @@
|
||||
<template>
|
||||
<q-btn dense flat icon="notifications">
|
||||
<q-badge color="red" floating transparent>
|
||||
{{ test_alerts.length }}
|
||||
</q-badge>
|
||||
<q-badge color="red" floating transparent>{{ test_alerts.length }}</q-badge>
|
||||
<q-menu>
|
||||
<q-list separator>
|
||||
<q-item v-for="alert in test_alerts" :key="alert.id">
|
||||
<q-item-section>
|
||||
<q-item-label>{{ alert.client }} - {{ alert.hostname }}</q-item-label>
|
||||
<q-item-label caption>
|
||||
<q-icon :class="`text-${alertColor(alert.type)}`" :name="alert.type"></q-icon>
|
||||
{{ alert.message }}</q-item-label>
|
||||
<q-icon :class="`text-${alertColor(alert.type)}`" :name="alert.type"></q-icon>
|
||||
{{ alert.message }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section side top>
|
||||
<q-item-label caption>{{ alert.timestamp }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable @click="showAlertsModal = true">
|
||||
View All Alerts ({{test_alerts.length}})
|
||||
</q-item>
|
||||
<q-item clickable @click="showAlertsModal = true">View All Alerts ({{test_alerts.length}})</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
|
||||
<q-dialog
|
||||
v-model="showAlertsModal"
|
||||
maximized
|
||||
transition-show="slide-up"
|
||||
transition-hide="slide-down"
|
||||
>
|
||||
<AlertsOverview @close="showAlertsModal = false" />
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog
|
||||
v-model="showAlertsModal"
|
||||
maximized
|
||||
transition-show="slide-up"
|
||||
transition-hide="slide-down"
|
||||
>
|
||||
<AlertsOverview @close="showAlertsModal = false" />
|
||||
</q-dialog>
|
||||
</q-btn>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import AlertsOverview from '@/components/modals/alerts/AlertsOverview'
|
||||
import { mapState } from "vuex";
|
||||
import AlertsOverview from "@/components/modals/alerts/AlertsOverview";
|
||||
|
||||
export default {
|
||||
name: "AlertsIcon",
|
||||
components: {AlertsOverview},
|
||||
data () {
|
||||
components: { AlertsOverview },
|
||||
data() {
|
||||
return {
|
||||
showAlertsModal: false,
|
||||
test_alerts: [
|
||||
@@ -65,22 +61,22 @@ export default {
|
||||
timestamp: "5 hours ago"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
alertColor (type) {
|
||||
if (type === "error"){
|
||||
alertColor(type) {
|
||||
if (type === "error") {
|
||||
return "red";
|
||||
}
|
||||
if (type === "warning"){
|
||||
return "orange"
|
||||
}
|
||||
if (type === "warning") {
|
||||
return "orange";
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState('alerts/', {
|
||||
...mapState("alerts/", {
|
||||
alerts: state => state.alerts
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -3,7 +3,14 @@
|
||||
<div v-else-if="Object.keys(automatedTasks).length === 0">No Tasks</div>
|
||||
<div class="row" v-else>
|
||||
<div class="col-12">
|
||||
<q-btn size="sm" color="grey-5" icon="fas fa-plus" label="Add Task" text-color="black" @click="showAddAutomatedTask = true" />
|
||||
<q-btn
|
||||
size="sm"
|
||||
color="grey-5"
|
||||
icon="fas fa-plus"
|
||||
label="Add Task"
|
||||
text-color="black"
|
||||
@click="showAddAutomatedTask = true"
|
||||
/>
|
||||
<q-btn dense flat push @click="refreshTasks(automatedTasks.pk)" icon="refresh" />
|
||||
<template v-if="tasks === undefined || tasks.length === 0">
|
||||
<p>No Tasks</p>
|
||||
@@ -184,10 +191,7 @@ export default {
|
||||
axios
|
||||
.delete(`/automation/${pk}/automatedtasks/`)
|
||||
.then(r => {
|
||||
this.$store.dispatch(
|
||||
"loadAutomatedTasks",
|
||||
this.automatedTasks.pk
|
||||
);
|
||||
this.$store.dispatch("loadAutomatedTasks", this.automatedTasks.pk);
|
||||
this.$store.dispatch("loadChecks", this.automatedTasks.pk);
|
||||
this.notifySuccess(r.data);
|
||||
})
|
||||
|
@@ -313,7 +313,7 @@ export default {
|
||||
field: "last_run",
|
||||
align: "left"
|
||||
},
|
||||
{ name: "assignedtasks", label: "Assigned Tasks", field: "assigned_task", align: "left" },
|
||||
{ name: "assignedtasks", label: "Assigned Tasks", field: "assigned_task", align: "left" }
|
||||
],
|
||||
pagination: {
|
||||
rowsPerPage: 9999
|
||||
|
@@ -161,15 +161,11 @@ export default {
|
||||
},
|
||||
startPoll() {
|
||||
this.poll = true;
|
||||
axios
|
||||
.get(`/agents/${this.pk}/getprocs/`)
|
||||
.then(r => (this.procs = r.data));
|
||||
axios.get(`/agents/${this.pk}/getprocs/`).then(r => (this.procs = r.data));
|
||||
this.refreshProcs();
|
||||
},
|
||||
getAgent() {
|
||||
axios
|
||||
.get(`/agents/${this.pk}/agentdetail/`)
|
||||
.then(r => (this.mem = r.data.total_ram));
|
||||
axios.get(`/agents/${this.pk}/agentdetail/`).then(r => (this.mem = r.data.total_ram));
|
||||
},
|
||||
convert(percent) {
|
||||
const mb = this.mem * 1024;
|
||||
|
@@ -207,15 +207,16 @@ export default {
|
||||
});
|
||||
},
|
||||
downloadScript() {
|
||||
axios.get(`/checks/downloadscript/${this.selectedRow}/`, { responseType: 'blob' })
|
||||
axios
|
||||
.get(`/checks/downloadscript/${this.selectedRow}/`, { responseType: "blob" })
|
||||
.then(({ data }) => {
|
||||
const blob = new Blob([data], { type: 'text/plain' })
|
||||
let link = document.createElement('a')
|
||||
link.href = window.URL.createObjectURL(blob)
|
||||
link.download = this.filename
|
||||
link.click()
|
||||
const blob = new Blob([data], { type: "text/plain" });
|
||||
let link = document.createElement("a");
|
||||
link.href = window.URL.createObjectURL(blob);
|
||||
link.download = this.filename;
|
||||
link.click();
|
||||
})
|
||||
.catch(error => console.error(error))
|
||||
.catch(error => console.error(error));
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@@ -12,37 +12,18 @@
|
||||
hide-bottom
|
||||
>
|
||||
<template v-slot:top>
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
push
|
||||
@click="refreshServices"
|
||||
icon="refresh"
|
||||
/>
|
||||
<q-btn dense flat push @click="refreshServices" icon="refresh" />
|
||||
<q-space />
|
||||
<q-input
|
||||
v-model="filter"
|
||||
outlined
|
||||
label="Search"
|
||||
dense
|
||||
clearable
|
||||
>
|
||||
<q-input v-model="filter" outlined label="Search" dense clearable>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="search" />
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
<template
|
||||
slot="body"
|
||||
slot-scope="props"
|
||||
:props="props"
|
||||
>
|
||||
<template slot="body" slot-scope="props" :props="props">
|
||||
<q-tr :props="props">
|
||||
<q-menu context-menu>
|
||||
<q-list
|
||||
dense
|
||||
style="min-width: 200px"
|
||||
>
|
||||
<q-list dense style="min-width: 200px">
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
@@ -65,38 +46,19 @@
|
||||
<q-item-section>Restart</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="editService(props.row.name)"
|
||||
>
|
||||
<q-item clickable v-close-popup @click="editService(props.row.name)">
|
||||
<q-item-section>Service Details</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
<q-td
|
||||
key="display_name"
|
||||
:props="props"
|
||||
>
|
||||
<q-td key="display_name" :props="props">
|
||||
<q-icon name="fas fa-cogs" />
|
||||
{{ props.row.display_name }}
|
||||
</q-td>
|
||||
<q-td
|
||||
key="start_type"
|
||||
:props="props"
|
||||
>{{ props.row.start_type }}</q-td>
|
||||
<q-td
|
||||
key="pid"
|
||||
:props="props"
|
||||
>{{ props.row.pid }}</q-td>
|
||||
<q-td
|
||||
key="status"
|
||||
:props="props"
|
||||
>{{ props.row.status }}</q-td>
|
||||
<q-td
|
||||
key="username"
|
||||
:props="props"
|
||||
>{{ props.row.username }}</q-td>
|
||||
<q-td key="start_type" :props="props">{{ props.row.start_type }}</q-td>
|
||||
<q-td key="pid" :props="props">{{ props.row.pid }}</q-td>
|
||||
<q-td key="status" :props="props">{{ props.row.status }}</q-td>
|
||||
<q-td key="username" :props="props">{{ props.row.username }}</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
@@ -121,10 +83,7 @@
|
||||
<div class="row">
|
||||
<div class="col-3">Description:</div>
|
||||
<div class="col-9">
|
||||
<q-field
|
||||
outlined
|
||||
color="black"
|
||||
>{{ serviceData.Description }}</q-field>
|
||||
<q-field outlined color="black">{{ serviceData.Description }}</q-field>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
@@ -186,10 +145,7 @@
|
||||
</div>
|
||||
</q-card-section>
|
||||
<hr />
|
||||
<q-card-actions
|
||||
align="left"
|
||||
class="bg-white text-teal"
|
||||
>
|
||||
<q-card-actions align="left" class="bg-white text-teal">
|
||||
<q-btn
|
||||
:disable="saveServiceDetailButton"
|
||||
dense
|
||||
@@ -197,12 +153,7 @@
|
||||
color="positive"
|
||||
@click="changeStartupType(startupType, serviceData.svc_name)"
|
||||
/>
|
||||
<q-btn
|
||||
dense
|
||||
label="Cancel"
|
||||
color="grey"
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn dense label="Cancel" color="grey" v-close-popup />
|
||||
</q-card-actions>
|
||||
<q-inner-loading :showing="serviceDetailVisible" />
|
||||
</q-card>
|
||||
@@ -218,7 +169,7 @@ export default {
|
||||
name: "Services",
|
||||
props: ["pk"],
|
||||
mixins: [mixins],
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
servicesData: [],
|
||||
serviceDetailsModal: false,
|
||||
@@ -226,12 +177,7 @@ export default {
|
||||
saveServiceDetailButton: true,
|
||||
serviceData: {},
|
||||
startupType: "",
|
||||
startupOptions: [
|
||||
"Automatic (Delayed Start)",
|
||||
"Automatic",
|
||||
"Manual",
|
||||
"Disabled"
|
||||
],
|
||||
startupOptions: ["Automatic (Delayed Start)", "Automatic", "Manual", "Disabled"],
|
||||
filter: "",
|
||||
pagination: {
|
||||
rowsPerPage: 9999,
|
||||
@@ -278,7 +224,7 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
changeStartupType (startuptype, name) {
|
||||
changeStartupType(startuptype, name) {
|
||||
let changed;
|
||||
switch (startuptype) {
|
||||
case "Automatic (Delayed Start)":
|
||||
@@ -315,10 +261,10 @@ export default {
|
||||
this.notifyError(err.response.data.error);
|
||||
});
|
||||
},
|
||||
startupTypeChanged () {
|
||||
startupTypeChanged() {
|
||||
this.saveServiceDetailButton = false;
|
||||
},
|
||||
editService (name) {
|
||||
editService(name) {
|
||||
this.saveServiceDetailButton = true;
|
||||
this.serviceDetailsModal = true;
|
||||
this.serviceDetailVisible = true;
|
||||
@@ -328,15 +274,9 @@ export default {
|
||||
this.serviceData = r.data;
|
||||
this.serviceData.svc_name = name;
|
||||
this.startupType = this.serviceData.StartType;
|
||||
if (
|
||||
this.serviceData.StartType === "Auto" &&
|
||||
this.serviceData.StartTypeDelayed === true
|
||||
) {
|
||||
if (this.serviceData.StartType === "Auto" && this.serviceData.StartTypeDelayed === true) {
|
||||
this.startupType = "Automatic (Delayed Start)";
|
||||
} else if (
|
||||
this.serviceData.StartType === "Auto" &&
|
||||
this.serviceData.StartTypeDelayed === false
|
||||
) {
|
||||
} else if (this.serviceData.StartType === "Auto" && this.serviceData.StartTypeDelayed === false) {
|
||||
this.startupType = "Automatic";
|
||||
}
|
||||
this.serviceDetailVisible = false;
|
||||
@@ -347,7 +287,7 @@ export default {
|
||||
this.notifyError(err.response.data.error);
|
||||
});
|
||||
},
|
||||
serviceAction (name, action, fullname) {
|
||||
serviceAction(name, action, fullname) {
|
||||
let msg, status;
|
||||
switch (action) {
|
||||
case "start":
|
||||
@@ -383,15 +323,15 @@ export default {
|
||||
this.notifyError(err.response.data.error);
|
||||
});
|
||||
},
|
||||
async getServices () {
|
||||
async getServices() {
|
||||
try {
|
||||
let r = await axios.get(`/services/${this.pk}/services/`);
|
||||
this.servicesData = [r.data][0].services;
|
||||
} catch (e) {
|
||||
console.log(`ERROR!: ${e}`)
|
||||
console.log(`ERROR!: ${e}`);
|
||||
}
|
||||
},
|
||||
refreshServices () {
|
||||
refreshServices() {
|
||||
this.$q.loading.show({ message: "Reloading services..." });
|
||||
axios
|
||||
.get(`/services/${this.pk}/refreshedservices/`)
|
||||
@@ -405,7 +345,7 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
created () {
|
||||
created() {
|
||||
this.getServices();
|
||||
}
|
||||
};
|
||||
|
@@ -1,62 +1,62 @@
|
||||
<template>
|
||||
<div class="q-pa-md">
|
||||
<q-tabs
|
||||
v-model="subtab"
|
||||
dense
|
||||
inline-label
|
||||
class="text-grey"
|
||||
active-color="primary"
|
||||
indicator-color="primary"
|
||||
align="left"
|
||||
narrow-indicator
|
||||
no-caps
|
||||
>
|
||||
<q-tab name="summary" icon="fas fa-info-circle" size="xs" label="Summary" />
|
||||
<q-tab name="checks" icon="fas fa-check-double" label="Checks" />
|
||||
<q-tab name="tasks" icon="fas fa-tasks" label="Tasks" />
|
||||
<q-tab name="patches" icon="system_update" label="Patches" />
|
||||
<q-tab name="software" icon="fab fa-windows" label="Software" />
|
||||
</q-tabs>
|
||||
<q-separator />
|
||||
<q-tab-panels v-model="subtab" :animated="false">
|
||||
<q-tab-panel name="summary">
|
||||
<SummaryTab />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="checks">
|
||||
<ChecksTab />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="tasks">
|
||||
<AutomatedTasksTab />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="patches">
|
||||
<WindowsUpdates />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="software">
|
||||
<SoftwareTab />
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</div>
|
||||
<div class="q-pa-md">
|
||||
<q-tabs
|
||||
v-model="subtab"
|
||||
dense
|
||||
inline-label
|
||||
class="text-grey"
|
||||
active-color="primary"
|
||||
indicator-color="primary"
|
||||
align="left"
|
||||
narrow-indicator
|
||||
no-caps
|
||||
>
|
||||
<q-tab name="summary" icon="fas fa-info-circle" size="xs" label="Summary" />
|
||||
<q-tab name="checks" icon="fas fa-check-double" label="Checks" />
|
||||
<q-tab name="tasks" icon="fas fa-tasks" label="Tasks" />
|
||||
<q-tab name="patches" icon="system_update" label="Patches" />
|
||||
<q-tab name="software" icon="fab fa-windows" label="Software" />
|
||||
</q-tabs>
|
||||
<q-separator />
|
||||
<q-tab-panels v-model="subtab" :animated="false">
|
||||
<q-tab-panel name="summary">
|
||||
<SummaryTab />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="checks">
|
||||
<ChecksTab />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="tasks">
|
||||
<AutomatedTasksTab />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="patches">
|
||||
<WindowsUpdates />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="software">
|
||||
<SoftwareTab />
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SummaryTab from '@/components/SummaryTab';
|
||||
import ChecksTab from '@/components/ChecksTab';
|
||||
import AutomatedTasksTab from '@/components/AutomatedTasksTab';
|
||||
import WindowsUpdates from '@/components/WindowsUpdates';
|
||||
import SoftwareTab from '@/components/SoftwareTab';
|
||||
import SummaryTab from "@/components/SummaryTab";
|
||||
import ChecksTab from "@/components/ChecksTab";
|
||||
import AutomatedTasksTab from "@/components/AutomatedTasksTab";
|
||||
import WindowsUpdates from "@/components/WindowsUpdates";
|
||||
import SoftwareTab from "@/components/SoftwareTab";
|
||||
export default {
|
||||
name: "SubTableTabs",
|
||||
components: {
|
||||
SummaryTab,
|
||||
ChecksTab,
|
||||
AutomatedTasksTab,
|
||||
WindowsUpdates,
|
||||
SoftwareTab,
|
||||
SummaryTab,
|
||||
ChecksTab,
|
||||
AutomatedTasksTab,
|
||||
WindowsUpdates,
|
||||
SoftwareTab
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
subtab: 'summary'
|
||||
}
|
||||
return {
|
||||
subtab: "summary"
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@@ -30,10 +30,7 @@
|
||||
</q-item>
|
||||
|
||||
<!-- physical disks -->
|
||||
<q-item
|
||||
v-for="disk in summary.physical_disks"
|
||||
:key="disk.model"
|
||||
>
|
||||
<q-item v-for="disk in summary.physical_disks" :key="disk.model">
|
||||
<q-item-section avatar>
|
||||
<q-icon name="far fa-hdd" />
|
||||
</q-item-section>
|
||||
@@ -57,10 +54,7 @@
|
||||
<!-- right -->
|
||||
<div class="col-3">
|
||||
<span class="text-subtitle2 text-bold">Disks</span>
|
||||
<div
|
||||
v-for="disk in disks"
|
||||
:key="disk.device"
|
||||
>
|
||||
<div v-for="disk in disks" :key="disk.device">
|
||||
<span>{{ disk.device }} ({{ disk.fstype }})</span>
|
||||
<q-linear-progress
|
||||
rounded
|
||||
@@ -80,16 +74,15 @@
|
||||
<script>
|
||||
export default {
|
||||
name: "SummaryTab",
|
||||
data () {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
methods: {},
|
||||
computed: {
|
||||
summary () {
|
||||
summary() {
|
||||
return this.$store.state.agentSummary;
|
||||
},
|
||||
disks () {
|
||||
disks() {
|
||||
const entries = Object.entries(this.summary.disks);
|
||||
const ret = [];
|
||||
for (let [k, v] of entries) {
|
||||
|
@@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<div v-if="!selectedAgentPk">No agent selected</div>
|
||||
<div v-else-if="managedByWsus">Patch management is not available for this agent because it is managed by WSUS</div>
|
||||
<div
|
||||
v-else-if="managedByWsus"
|
||||
>Patch management is not available for this agent because it is managed by WSUS</div>
|
||||
<div v-else-if="Object.keys(sortedUpdates).length === 0">No Patches</div>
|
||||
<div v-else class="q-pa-xs">
|
||||
<q-btn label="Refresh" dense flat push @click="refreshUpdates(updates.pk)" icon="refresh" />
|
||||
@@ -22,16 +24,36 @@
|
||||
<q-tr :props="props">
|
||||
<q-menu context-menu>
|
||||
<q-list dense style="min-width: 100px">
|
||||
<q-item v-if="!props.row.installed" clickable v-close-popup @click="editPolicy(props.row.id, 'inherit')">
|
||||
<q-item
|
||||
v-if="!props.row.installed"
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="editPolicy(props.row.id, 'inherit')"
|
||||
>
|
||||
<q-item-section>Inherit</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="!props.row.installed" clickable v-close-popup @click="editPolicy(props.row.id, 'approve')">
|
||||
<q-item
|
||||
v-if="!props.row.installed"
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="editPolicy(props.row.id, 'approve')"
|
||||
>
|
||||
<q-item-section>Approve</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="!props.row.installed" clickable v-close-popup @click="editPolicy(props.row.id, 'ignore')">
|
||||
<q-item
|
||||
v-if="!props.row.installed"
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="editPolicy(props.row.id, 'ignore')"
|
||||
>
|
||||
<q-item-section>Ignore</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="!props.row.installed" clickable v-close-popup @click="editPolicy(props.row.id, 'nothing')">
|
||||
<q-item
|
||||
v-if="!props.row.installed"
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="editPolicy(props.row.id, 'nothing')"
|
||||
>
|
||||
<q-item-section>Do Nothing</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
@@ -47,15 +69,27 @@
|
||||
<q-icon v-else-if="props.row.action === 'ignore'" name="fas fa-check" color="negative">
|
||||
<q-tooltip>Ignore</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon v-else-if="props.row.action === 'inherit'" name="fiber_manual_record" color="accent">
|
||||
<q-icon
|
||||
v-else-if="props.row.action === 'inherit'"
|
||||
name="fiber_manual_record"
|
||||
color="accent"
|
||||
>
|
||||
<q-tooltip>Inherit</q-tooltip>
|
||||
</q-icon>
|
||||
</q-td>
|
||||
<q-td>
|
||||
<q-icon v-if="props.row.installed" name="fas fa-check" color="positive"><q-tooltip>Installed</q-tooltip></q-icon>
|
||||
<q-icon v-else-if="props.row.action == 'approve'" name="fas fa-tasks" color="primary"><q-tooltip>Pending</q-tooltip></q-icon>
|
||||
<q-icon v-else-if="props.row.action == 'ignore'" name="fas fa-ban" color="negative"><q-tooltip>Ignored</q-tooltip></q-icon>
|
||||
<q-icon v-else name="fas fa-exclamation" color="warning"><q-tooltip>Missing</q-tooltip></q-icon>
|
||||
<q-icon v-if="props.row.installed" name="fas fa-check" color="positive">
|
||||
<q-tooltip>Installed</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon v-else-if="props.row.action == 'approve'" name="fas fa-tasks" color="primary">
|
||||
<q-tooltip>Pending</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon v-else-if="props.row.action == 'ignore'" name="fas fa-ban" color="negative">
|
||||
<q-tooltip>Ignored</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon v-else name="fas fa-exclamation" color="warning">
|
||||
<q-tooltip>Missing</q-tooltip>
|
||||
</q-icon>
|
||||
</q-td>
|
||||
<q-td>{{ props.row.severity }}</q-td>
|
||||
<q-td>{{ formatMessage(props.row.title) }}</q-td>
|
||||
@@ -129,14 +163,7 @@ export default {
|
||||
sortable: true
|
||||
}
|
||||
],
|
||||
visibleColumns: [
|
||||
"action",
|
||||
"installed",
|
||||
"severity",
|
||||
"title",
|
||||
"description",
|
||||
"date_installed",
|
||||
]
|
||||
visibleColumns: ["action", "installed", "severity", "title", "description", "date_installed"]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@@ -2,7 +2,15 @@
|
||||
<div style="width: 900px; max-width: 90vw;">
|
||||
<q-card>
|
||||
<q-bar>
|
||||
<q-btn ref="refresh" @click="getPolicies; clearRow()" class="q-mr-sm" dense flat push icon="refresh" />Automation Manager
|
||||
<q-btn
|
||||
ref="refresh"
|
||||
@click="getPolicies; clearRow()"
|
||||
class="q-mr-sm"
|
||||
dense
|
||||
flat
|
||||
push
|
||||
icon="refresh"
|
||||
/>Automation Manager
|
||||
<q-space />
|
||||
<q-btn dense flat icon="close" v-close-popup>
|
||||
<q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
|
||||
@@ -74,17 +82,11 @@
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||
{{ col.label }}
|
||||
</q-th>
|
||||
<q-th v-for="col in props.cols" :key="col.name" :props="props">{{ col.label }}</q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props">
|
||||
<q-tr
|
||||
:props="props"
|
||||
class="cursor-pointer"
|
||||
@click="props.selected = true"
|
||||
>
|
||||
<q-tr :props="props" class="cursor-pointer" @click="props.selected = true">
|
||||
<q-td>{{ props.row.name }}</q-td>
|
||||
<q-td>{{ props.row.desc }}</q-td>
|
||||
<q-td>{{ props.row.active }}</q-td>
|
||||
@@ -111,16 +113,16 @@
|
||||
|
||||
<script>
|
||||
import mixins from "@/mixins/mixins";
|
||||
import { mapState } from 'vuex';
|
||||
import { mapState } from "vuex";
|
||||
import PolicyForm from "@/components/automation/modals/PolicyForm";
|
||||
import PolicyOverview from "@/components/automation/PolicyOverview";
|
||||
import PolicySubTableTabs from "@/components/automation/PolicySubTableTabs"
|
||||
import PolicySubTableTabs from "@/components/automation/PolicySubTableTabs";
|
||||
|
||||
export default {
|
||||
name: "AutomationManager",
|
||||
components: { PolicyForm, PolicyOverview, PolicySubTableTabs },
|
||||
mixins: [mixins],
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
showPolicyFormModal: false,
|
||||
showPolicyOverviewModal: false,
|
||||
@@ -179,30 +181,30 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getPolicies () {
|
||||
this.$store.dispatch('automation/loadPolicies');
|
||||
getPolicies() {
|
||||
this.$store.dispatch("automation/loadPolicies");
|
||||
},
|
||||
policyRowSelected ({added, keys, rows}) {
|
||||
|
||||
policyRowSelected({ added, keys, rows }) {
|
||||
// First key of the array is the selected row pk
|
||||
this.$store.commit('automation/setSelectedPolicy', keys[0]);
|
||||
this.$store.dispatch('automation/loadPolicyChecks', keys[0]);
|
||||
this.$store.dispatch('automation/loadPolicyAutomatedTasks', keys[0]);
|
||||
this.$store.commit("automation/setSelectedPolicy", keys[0]);
|
||||
this.$store.dispatch("automation/loadPolicyChecks", keys[0]);
|
||||
this.$store.dispatch("automation/loadPolicyAutomatedTasks", keys[0]);
|
||||
},
|
||||
clearRow () {
|
||||
this.$store.commit('automation/setSelectedPolicy', null);
|
||||
this.$store.commit('automation/setPolicyChecks', {});
|
||||
this.$store.commit('automation/setPolicyAutomatedTasks', {});
|
||||
clearRow() {
|
||||
this.$store.commit("automation/setSelectedPolicy", null);
|
||||
this.$store.commit("automation/setPolicyChecks", {});
|
||||
this.$store.commit("automation/setPolicyAutomatedTasks", {});
|
||||
},
|
||||
deletePolicy () {
|
||||
this.$q.dialog({
|
||||
deletePolicy() {
|
||||
this.$q
|
||||
.dialog({
|
||||
title: "Delete policy?",
|
||||
cancel: true,
|
||||
ok: { label: "Delete", color: "negative" }
|
||||
})
|
||||
.onOk(() => {
|
||||
|
||||
this.$store.dispatch('automation/deletePolicy', this.selectedRow)
|
||||
this.$store
|
||||
.dispatch("automation/deletePolicy", this.selectedRow)
|
||||
.then(response => {
|
||||
this.notifySuccess(`Policy was deleted!`);
|
||||
})
|
||||
@@ -210,15 +212,15 @@ export default {
|
||||
this.notifyError(`An Error occured while deleting policy`);
|
||||
});
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
policies: state => state.automation.policies,
|
||||
selectedRow: state => state.automation.selectedPolicy
|
||||
}),
|
||||
})
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
this.getPolicies();
|
||||
}
|
||||
};
|
||||
|
@@ -26,17 +26,11 @@
|
||||
<q-tr>
|
||||
<!-- tds -->
|
||||
<q-td>
|
||||
<q-checkbox
|
||||
disabled
|
||||
dense
|
||||
v-model="props.row.enabled"
|
||||
/>
|
||||
<q-checkbox disabled dense v-model="props.row.enabled" />
|
||||
</q-td>
|
||||
<q-td>{{ props.row.name }}</q-td>
|
||||
<q-td v-if="props.row.retcode || props.row.stdout || props.row.stderr">
|
||||
<span
|
||||
style="cursor:pointer;color:blue;text-decoration:underline"
|
||||
>output</span>
|
||||
<span style="cursor:pointer;color:blue;text-decoration:underline">output</span>
|
||||
</q-td>
|
||||
<q-td v-else>Awaiting output</q-td>
|
||||
<q-td v-if="props.row.last_run">{{ props.row.last_run }}</q-td>
|
||||
@@ -59,7 +53,7 @@ export default {
|
||||
name: "OverviewAutomatedTasksTab",
|
||||
props: ["policypk"],
|
||||
mixins: [mixins],
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
automatedTasks: {},
|
||||
columns: [
|
||||
@@ -95,27 +89,29 @@ export default {
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
this.getPolicyTasks();
|
||||
},
|
||||
watch: {
|
||||
'policypk': function () {
|
||||
policypk: function() {
|
||||
this.getPolicyTasks();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPolicyTasks () {
|
||||
axios.get(`/automation/${this.policypk}/policyautomatedtasks/`).then(r => {
|
||||
this.automatedTasks = r.data;
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
getPolicyTasks() {
|
||||
axios
|
||||
.get(`/automation/${this.policypk}/policyautomatedtasks/`)
|
||||
.then(r => {
|
||||
this.automatedTasks = r.data;
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tasks () {
|
||||
tasks() {
|
||||
return this.automatedTasks.autotasks;
|
||||
}
|
||||
}
|
||||
|
@@ -38,18 +38,10 @@
|
||||
<q-tr>
|
||||
<!-- tds -->
|
||||
<q-td>
|
||||
<q-checkbox
|
||||
disabled
|
||||
dense
|
||||
v-model="props.row.text_alert"
|
||||
/>
|
||||
<q-checkbox disabled dense v-model="props.row.text_alert" />
|
||||
</q-td>
|
||||
<q-td>
|
||||
<q-checkbox
|
||||
disabled
|
||||
dense
|
||||
v-model="props.row.email_alert"
|
||||
/>
|
||||
<q-checkbox disabled dense v-model="props.row.email_alert" />
|
||||
</q-td>
|
||||
<q-td v-if="props.row.status === 'pending'"></q-td>
|
||||
<q-td v-else-if="props.row.status === 'passing'">
|
||||
@@ -84,14 +76,10 @@
|
||||
<q-badge color="negative">Failing</q-badge>
|
||||
</q-td>
|
||||
<q-td v-if="props.row.check_type === 'ping'">
|
||||
<span
|
||||
style="cursor:pointer;color:blue;text-decoration:underline"
|
||||
>output</span>
|
||||
<span style="cursor:pointer;color:blue;text-decoration:underline">output</span>
|
||||
</q-td>
|
||||
<q-td v-else-if="props.row.check_type === 'script'">
|
||||
<span
|
||||
style="cursor:pointer;color:blue;text-decoration:underline"
|
||||
>output</span>
|
||||
<span style="cursor:pointer;color:blue;text-decoration:underline">output</span>
|
||||
</q-td>
|
||||
<q-td v-else>{{ props.row.more_info }}</q-td>
|
||||
<q-td>{{ props.row.last_run }}</q-td>
|
||||
@@ -104,8 +92,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import mixins from '@/mixins/mixins'
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
|
||||
export default {
|
||||
name: "OverviewChecksTab",
|
||||
@@ -138,23 +126,25 @@ export default {
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
this.getPolicyChecks();
|
||||
},
|
||||
watch: {
|
||||
'policypk': function () {
|
||||
policypk: function() {
|
||||
this.getPolicyChecks();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPolicyChecks () {
|
||||
axios.get(`/checks/${this.policypk}/loadpolicychecks/`).then(r => {
|
||||
this.checks = r.data;
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
getPolicyChecks() {
|
||||
axios
|
||||
.get(`/checks/${this.policypk}/loadpolicychecks/`)
|
||||
.then(r => {
|
||||
this.checks = r.data;
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@@ -2,7 +2,14 @@
|
||||
<div v-if="Object.keys(automatedTasks).length === 0">No Policy Selected</div>
|
||||
<div class="row" v-else>
|
||||
<div class="col-12">
|
||||
<q-btn size="sm" color="grey-5" icon="fas fa-plus" label="Add Task" text-color="black" @click="showAddAutomatedTask = true" />
|
||||
<q-btn
|
||||
size="sm"
|
||||
color="grey-5"
|
||||
icon="fas fa-plus"
|
||||
label="Add Task"
|
||||
text-color="black"
|
||||
@click="showAddAutomatedTask = true"
|
||||
/>
|
||||
<q-btn dense flat push @click="refreshTasks(automatedTasks.pk)" icon="refresh" />
|
||||
<template v-if="tasks === undefined || tasks.length === 0">
|
||||
<p>No Tasks</p>
|
||||
@@ -143,7 +150,7 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
taskEnableorDisable (pk, action) {
|
||||
taskEnableorDisable(pk, action) {
|
||||
const data = { enableordisable: action };
|
||||
axios
|
||||
.patch(`/automation/${pk}/automatedtasks/`, data)
|
||||
@@ -153,14 +160,14 @@ export default {
|
||||
})
|
||||
.catch(e => this.notifyError("Something went wrong"));
|
||||
},
|
||||
refreshTasks (id) {
|
||||
refreshTasks(id) {
|
||||
this.$store.dispatch("automation/loadPolicyAutomatedTasks", id);
|
||||
},
|
||||
scriptMoreInfo (props) {
|
||||
scriptMoreInfo(props) {
|
||||
this.scriptInfo = props;
|
||||
this.showScriptOutput = true;
|
||||
},
|
||||
runTask (pk, enabled) {
|
||||
runTask(pk, enabled) {
|
||||
if (!enabled) {
|
||||
this.notifyError("Task cannot be run when it's disabled. Enable it first.");
|
||||
return;
|
||||
@@ -170,7 +177,7 @@ export default {
|
||||
.then(r => this.notifySuccess(r.data))
|
||||
.catch(() => this.notifyError("Something went wrong"));
|
||||
},
|
||||
deleteTask (name, pk) {
|
||||
deleteTask(name, pk) {
|
||||
this.$q
|
||||
.dialog({
|
||||
title: "Are you sure?",
|
||||
|
@@ -7,10 +7,7 @@
|
||||
<q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
|
||||
</q-btn>
|
||||
</q-bar>
|
||||
<q-splitter
|
||||
v-model="splitterModel"
|
||||
style="height: 600px"
|
||||
>
|
||||
<q-splitter v-model="splitterModel" style="height: 600px">
|
||||
<template v-slot:before>
|
||||
<div class="q-pa-md">
|
||||
<q-tree
|
||||
@@ -21,9 +18,7 @@
|
||||
selected-color="primary"
|
||||
@update:selected="loadPolicyDetails"
|
||||
default-expand-all
|
||||
>
|
||||
|
||||
</q-tree>
|
||||
></q-tree>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -69,41 +64,44 @@
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
import OverviewChecksTab from "@/components/automation/OverviewChecksTab"
|
||||
import OverviewAutomatedTasksTab from "@/components/automation/OverviewAutomatedTasksTab"
|
||||
import OverviewChecksTab from "@/components/automation/OverviewChecksTab";
|
||||
import OverviewAutomatedTasksTab from "@/components/automation/OverviewAutomatedTasksTab";
|
||||
|
||||
export default {
|
||||
name: "PolicyOverview",
|
||||
components: {
|
||||
OverviewChecksTab,
|
||||
OverviewAutomatedTasksTab,
|
||||
OverviewAutomatedTasksTab
|
||||
},
|
||||
mixins: [mixins],
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
splitterModel: 25,
|
||||
selected: "",
|
||||
selectedPolicy: {},
|
||||
selectedTab: "checks",
|
||||
clientSiteTree: [],
|
||||
}
|
||||
clientSiteTree: []
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
this.getPolicyTree();
|
||||
},
|
||||
methods: {
|
||||
getPolicyTree () {
|
||||
axios.get(`/automation/policies/overview/`).then(r => {
|
||||
this.processTreeDataFromApi(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
|
||||
getPolicyTree() {
|
||||
axios
|
||||
.get(`/automation/policies/overview/`)
|
||||
.then(r => {
|
||||
this.processTreeDataFromApi(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
loadPolicyDetails (key) {
|
||||
if (key === undefined) {return;}
|
||||
loadPolicyDetails(key) {
|
||||
if (key === undefined) {
|
||||
return;
|
||||
}
|
||||
this.selectedPolicy = this.$refs.Tree.getNodeByKey(key);
|
||||
},
|
||||
processTreeDataFromApi(data) {
|
||||
@@ -121,12 +119,11 @@ export default {
|
||||
* }
|
||||
* }
|
||||
* }]
|
||||
*/
|
||||
*/
|
||||
|
||||
var result = [];
|
||||
|
||||
for (let client in data) {
|
||||
|
||||
var client_temp = {};
|
||||
|
||||
client_temp["label"] = client;
|
||||
@@ -139,27 +136,26 @@ export default {
|
||||
for (let policy in data[client].policies)
|
||||
client_temp["children"].push({
|
||||
label: data[client].policies[policy].name,
|
||||
icon: 'policy',
|
||||
icon: "policy",
|
||||
id: data[client].policies[policy].id
|
||||
});
|
||||
}
|
||||
|
||||
// Iterate through Sites
|
||||
for (let site in data[client].sites) {
|
||||
var site_temp = {}
|
||||
var site_temp = {};
|
||||
site_temp["label"] = site;
|
||||
site_temp["icon"] = "apartment";
|
||||
site_temp["selectable"] = false;
|
||||
|
||||
|
||||
// Add any policies assigned to site
|
||||
if (data[client].sites[site].policies.length > 0) {
|
||||
|
||||
site_temp["children"] = [];
|
||||
|
||||
for (let policy in data[client].sites[site].policies) {
|
||||
site_temp["children"].push({
|
||||
label: data[client].sites[site].policies[policy].name,
|
||||
icon: 'policy',
|
||||
icon: "policy",
|
||||
id: data[client].sites[site].policies[policy].id
|
||||
});
|
||||
}
|
||||
@@ -167,19 +163,17 @@ export default {
|
||||
|
||||
// Add Site to Client children array
|
||||
client_temp.children.push(site_temp);
|
||||
|
||||
}
|
||||
|
||||
// Add Client and it's Sites to result array
|
||||
result.push(client_temp);
|
||||
|
||||
}
|
||||
|
||||
this.clientSiteTree = result;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
policypk () {
|
||||
policypk() {
|
||||
return this.selectedPolicy.id;
|
||||
}
|
||||
}
|
||||
|
@@ -27,20 +27,20 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PolicyChecksTab from '@/components/automation/PolicyChecksTab';
|
||||
import PolicyAutomatedTasksTab from '@/components/automation/PolicyAutomatedTasksTab';
|
||||
import PolicyChecksTab from "@/components/automation/PolicyChecksTab";
|
||||
import PolicyAutomatedTasksTab from "@/components/automation/PolicyAutomatedTasksTab";
|
||||
|
||||
export default {
|
||||
name: "PolicySubTableTabs",
|
||||
props: ["policypk"],
|
||||
components: {
|
||||
PolicyChecksTab,
|
||||
PolicyAutomatedTasksTab,
|
||||
PolicyAutomatedTasksTab
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
subtab: 'checks'
|
||||
}
|
||||
subtab: "checks"
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@@ -27,18 +27,10 @@
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Clients:</div>
|
||||
<div class="col-10">
|
||||
<q-select
|
||||
v-model="selectedClients"
|
||||
:options="clientOptions"
|
||||
filled
|
||||
multiple
|
||||
use-chips
|
||||
>
|
||||
<q-select v-model="selectedClients" :options="clientOptions" filled multiple use-chips>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
<q-item-section class="text-grey">No Results</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
@@ -47,18 +39,10 @@
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Sites:</div>
|
||||
<div class="col-10">
|
||||
<q-select
|
||||
v-model="selectedSites"
|
||||
:options="siteOptions"
|
||||
filled
|
||||
multiple
|
||||
use-chips
|
||||
>
|
||||
<q-select v-model="selectedSites" :options="siteOptions" filled multiple use-chips>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
<q-item-section class="text-grey">No Results</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
@@ -67,18 +51,10 @@
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Agents:</div>
|
||||
<div class="col-10">
|
||||
<q-select
|
||||
v-model="selectedAgents"
|
||||
:options="agentOptions"
|
||||
filled
|
||||
multiple
|
||||
use-chips
|
||||
>
|
||||
<q-select v-model="selectedAgents" :options="agentOptions" filled multiple use-chips>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
<q-item-section class="text-grey">No Results</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
@@ -98,8 +74,8 @@ import dropdown_formatter from "@/mixins/dropdown_formatter";
|
||||
export default {
|
||||
name: "PolicyForm",
|
||||
mixins: [mixins, dropdown_formatter],
|
||||
props: {"pk": Number},
|
||||
data () {
|
||||
props: { pk: Number },
|
||||
data() {
|
||||
return {
|
||||
name: "",
|
||||
desc: "",
|
||||
@@ -109,18 +85,17 @@ export default {
|
||||
selectedClients: [],
|
||||
clientOptions: [],
|
||||
siteOptions: [],
|
||||
agentOptions: [],
|
||||
agentOptions: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title () {
|
||||
return (this.pk) ? "Edit Policy" : "Add Policy";
|
||||
title() {
|
||||
return this.pk ? "Edit Policy" : "Add Policy";
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPolicy () {
|
||||
getPolicy() {
|
||||
this.$store.dispatch("automation/loadPolicy", this.pk).then(r => {
|
||||
|
||||
this.name = r.data.name;
|
||||
this.desc = r.data.desc;
|
||||
this.active = r.data.active;
|
||||
@@ -144,7 +119,7 @@ export default {
|
||||
});
|
||||
});
|
||||
},
|
||||
submit () {
|
||||
submit() {
|
||||
if (!this.name) {
|
||||
this.notifyError("Name is required!");
|
||||
return false;
|
||||
@@ -160,9 +135,10 @@ export default {
|
||||
sites: this.selectedSites.map(site => site.value),
|
||||
clients: this.selectedClients.map(client => client.value)
|
||||
};
|
||||
|
||||
|
||||
if (this.pk) {
|
||||
this.$store.dispatch("automation/editPolicy", this.pk, formData)
|
||||
this.$store
|
||||
.dispatch("automation/editPolicy", this.pk, formData)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
@@ -173,10 +149,9 @@ export default {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
this.$store.dispatch("automation/addPolicy", formData)
|
||||
this.$store
|
||||
.dispatch("automation/addPolicy", formData)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
@@ -187,11 +162,11 @@ export default {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
getClients () {
|
||||
this.$store.dispatch("loadClients")
|
||||
getClients() {
|
||||
this.$store
|
||||
.dispatch("loadClients")
|
||||
.then(r => {
|
||||
this.clientOptions = this.formatClient(r.data);
|
||||
})
|
||||
@@ -200,8 +175,9 @@ export default {
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getSites () {
|
||||
this.$store.dispatch("loadSites")
|
||||
getSites() {
|
||||
this.$store
|
||||
.dispatch("loadSites")
|
||||
.then(r => {
|
||||
this.siteOptions = this.formatSites(r.data);
|
||||
})
|
||||
@@ -210,18 +186,19 @@ export default {
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getAgents () {
|
||||
this.$store.dispatch("loadAgents")
|
||||
getAgents() {
|
||||
this.$store
|
||||
.dispatch("loadAgents")
|
||||
.then(r => {
|
||||
this.agentOptions = this.formatAgents(r.data)
|
||||
this.agentOptions = this.formatAgents(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
//If pk prop is set that means we are editting
|
||||
if (this.pk) {
|
||||
this.getPolicy();
|
||||
|
@@ -1,24 +1,10 @@
|
||||
<template>
|
||||
<q-card
|
||||
style="min-width: 800px"
|
||||
v-if="agentLoaded && clientsLoaded"
|
||||
>
|
||||
<q-card style="min-width: 800px" v-if="agentLoaded && clientsLoaded">
|
||||
<q-splitter v-model="splitterModel">
|
||||
<template v-slot:before>
|
||||
<q-tabs
|
||||
dense
|
||||
v-model="tab"
|
||||
vertical
|
||||
class="text-primary"
|
||||
>
|
||||
<q-tab
|
||||
name="general"
|
||||
label="General"
|
||||
/>
|
||||
<q-tab
|
||||
name="patch"
|
||||
label="Patches"
|
||||
/>
|
||||
<q-tabs dense v-model="tab" vertical class="text-primary">
|
||||
<q-tab name="general" label="General" />
|
||||
<q-tab name="patch" label="Patches" />
|
||||
</q-tabs>
|
||||
</template>
|
||||
<template v-slot:after>
|
||||
@@ -26,18 +12,9 @@
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">Edit {{ agent.hostname }}</div>
|
||||
<q-space />
|
||||
<q-btn
|
||||
icon="close"
|
||||
flat
|
||||
round
|
||||
dense
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-scroll-area
|
||||
:thumb-style="thumbStyle"
|
||||
style="height: 500px;"
|
||||
>
|
||||
<q-scroll-area :thumb-style="thumbStyle" style="height: 500px;">
|
||||
<q-tab-panels
|
||||
v-model="tab"
|
||||
animated
|
||||
@@ -61,13 +38,7 @@
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Site:</div>
|
||||
<div class="col-2"></div>
|
||||
<q-select
|
||||
class="col-8"
|
||||
dense
|
||||
outlined
|
||||
v-model="agent.site"
|
||||
:options="sites"
|
||||
/>
|
||||
<q-select class="col-8" dense outlined v-model="agent.site" :options="sites" />
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Type:</div>
|
||||
@@ -124,14 +95,8 @@
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<q-checkbox
|
||||
v-model="agent.overdue_email_alert"
|
||||
label="Get overdue email alerts"
|
||||
/>
|
||||
<q-checkbox
|
||||
v-model="agent.overdue_text_alert"
|
||||
label="Get overdue sms alerts"
|
||||
/>
|
||||
<q-checkbox v-model="agent.overdue_email_alert" label="Get overdue email alerts" />
|
||||
<q-checkbox v-model="agent.overdue_text_alert" label="Get overdue sms alerts" />
|
||||
</q-card-section>
|
||||
</q-tab-panel>
|
||||
<!-- patch -->
|
||||
@@ -317,15 +282,8 @@
|
||||
</q-tab-panels>
|
||||
</q-scroll-area>
|
||||
<q-card-section class="row items-center">
|
||||
<q-btn
|
||||
label="Save"
|
||||
color="primary"
|
||||
type="submit"
|
||||
/>
|
||||
<q-btn
|
||||
label="Cancel"
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn label="Save" color="primary" type="submit" />
|
||||
<q-btn label="Cancel" v-close-popup />
|
||||
</q-card-section>
|
||||
</q-form>
|
||||
</template>
|
||||
@@ -341,7 +299,7 @@ import { scheduledTimes } from "@/mixins/data";
|
||||
export default {
|
||||
name: "EditAgent",
|
||||
mixins: [mixins],
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
agentLoaded: false,
|
||||
clientsLoaded: false,
|
||||
@@ -366,19 +324,19 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getAgentInfo () {
|
||||
getAgentInfo() {
|
||||
axios.get(`/agents/${this.selectedAgentPk}/agentdetail/`).then(r => {
|
||||
this.agent = r.data;
|
||||
this.agentLoaded = true;
|
||||
});
|
||||
},
|
||||
getClientsSites () {
|
||||
getClientsSites() {
|
||||
axios.get("/clients/loadclients/").then(r => {
|
||||
this.tree = r.data;
|
||||
this.clientsLoaded = true;
|
||||
});
|
||||
},
|
||||
editAgent () {
|
||||
editAgent() {
|
||||
let data = this.agent;
|
||||
delete data.services;
|
||||
delete data.disks;
|
||||
@@ -396,13 +354,13 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["selectedAgentPk"]),
|
||||
sites () {
|
||||
sites() {
|
||||
if (this.agentLoaded && this.clientsLoaded) {
|
||||
return this.tree[this.agent.client];
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
created() {
|
||||
this.getAgentInfo();
|
||||
this.getClientsSites();
|
||||
}
|
||||
|
@@ -10,37 +10,18 @@
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
Select Version
|
||||
<q-select
|
||||
square
|
||||
outlined
|
||||
v-model="version"
|
||||
:options="Object.values(versions)"
|
||||
/>
|
||||
<q-select square outlined v-model="version" :options="Object.values(versions)" />
|
||||
</q-card-section>
|
||||
<q-card-section v-show="version !== null">
|
||||
Select Agent
|
||||
<br />
|
||||
<hr />
|
||||
<q-checkbox
|
||||
v-model="selectAll"
|
||||
label="Select All"
|
||||
@input="selectAllAction"
|
||||
/>
|
||||
<q-checkbox v-model="selectAll" label="Select All" @input="selectAllAction" />
|
||||
<hr />
|
||||
<q-option-group
|
||||
v-model="group"
|
||||
:options="agentOptions"
|
||||
color="green"
|
||||
type="checkbox"
|
||||
/>
|
||||
<q-option-group v-model="group" :options="agentOptions" color="green" type="checkbox" />
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-btn
|
||||
v-show="group.length !== 0"
|
||||
label="Update"
|
||||
color="primary"
|
||||
@click="update"
|
||||
/>
|
||||
<q-btn v-show="group.length !== 0" label="Update" color="primary" @click="update" />
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
@@ -8,14 +8,9 @@
|
||||
</q-btn>
|
||||
</q-bar>
|
||||
<q-separator />
|
||||
<q-card-section>All Alerts</q-card-section>
|
||||
<q-card-section>
|
||||
All Alerts
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-btn
|
||||
label="Update"
|
||||
color="primary"
|
||||
/>
|
||||
<q-btn label="Update" color="primary" />
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
@@ -29,7 +24,7 @@ export default {
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
alerts: [],
|
||||
alerts: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -38,17 +33,15 @@ export default {
|
||||
axios
|
||||
.get("/alerts/")
|
||||
.then(r => {
|
||||
this.alerts = r.data.alerts
|
||||
this.alerts = r.data.alerts;
|
||||
})
|
||||
.catch(() => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError("Something went wrong");
|
||||
});
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
created() {
|
||||
this.getAlerts();
|
||||
}
|
||||
|
@@ -185,21 +185,13 @@ export default {
|
||||
return r;
|
||||
},
|
||||
step1Done() {
|
||||
return this.step > 1 && this.scriptPk !== null && this.taskName !== null
|
||||
? true
|
||||
: false;
|
||||
return this.step > 1 && this.scriptPk !== null && this.taskName !== null ? true : false;
|
||||
},
|
||||
step2Done() {
|
||||
if (this.trigger === "daily") {
|
||||
return this.days !== null &&
|
||||
this.days.length !== 0 &&
|
||||
this.time !== null
|
||||
? true
|
||||
: false;
|
||||
return this.days !== null && this.days.length !== 0 && this.time !== null ? true : false;
|
||||
} else if (this.trigger === "checkfailure") {
|
||||
return this.assignedCheck !== null && this.assignedCheck.length !== 0
|
||||
? true
|
||||
: false;
|
||||
return this.assignedCheck !== null && this.assignedCheck.length !== 0 ? true : false;
|
||||
} else if (this.trigger === "manual") {
|
||||
return true;
|
||||
} else {
|
||||
|
@@ -53,7 +53,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
addCheck() {
|
||||
const pk = (this.policypk) ? {policy: this.policypk} : {pk: this.agentpk}
|
||||
const pk = this.policypk ? { policy: this.policypk } : { pk: this.agentpk };
|
||||
|
||||
const data = {
|
||||
...pk,
|
||||
|
@@ -3,23 +3,12 @@
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">Add Disk Space Check</div>
|
||||
<q-space />
|
||||
<q-btn
|
||||
icon="close"
|
||||
flat
|
||||
round
|
||||
dense
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
|
||||
<q-form @submit.prevent="addCheck">
|
||||
<q-card-section>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="firstdisk"
|
||||
:options="disks"
|
||||
label="Disk"
|
||||
/>
|
||||
<q-select outlined v-model="firstdisk" :options="disks" label="Disk" />
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-input
|
||||
@@ -43,15 +32,8 @@
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
label="Add"
|
||||
color="primary"
|
||||
type="submit"
|
||||
/>
|
||||
<q-btn
|
||||
label="Cancel"
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn label="Add" color="primary" type="submit" />
|
||||
<q-btn label="Cancel" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
@@ -87,10 +69,9 @@ export default {
|
||||
this.firstdisk = Object.keys(r.data)[0];
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
addCheck() {
|
||||
const pk = (this.policypk) ? { policy: this.policypk } : { pk: this.agentpk }
|
||||
const pk = this.policypk ? { policy: this.policypk } : { pk: this.agentpk };
|
||||
const data = {
|
||||
...pk,
|
||||
check_type: "diskspace",
|
||||
|
@@ -53,7 +53,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
addCheck() {
|
||||
const pk = (this.policypk) ? {policy: this.policypk} : {pk: this.agentpk}
|
||||
const pk = this.policypk ? { policy: this.policypk } : { pk: this.agentpk };
|
||||
|
||||
const data = {
|
||||
...pk,
|
||||
|
@@ -57,17 +57,18 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
addCheck() {
|
||||
let pk = (this.policypk) ? {policy: this.policypk} : {pk: this.agentpk}
|
||||
let pk = this.policypk ? { policy: this.policypk } : { pk: this.agentpk };
|
||||
|
||||
const data = {
|
||||
...pk,
|
||||
check_type: "ping",
|
||||
failures: this.failure,
|
||||
name: this.pingname,
|
||||
ip: this.pingip,
|
||||
ip: this.pingip
|
||||
};
|
||||
|
||||
axios.post("/checks/addstandardcheck/", data)
|
||||
axios
|
||||
.post("/checks/addstandardcheck/", data)
|
||||
.then(r => {
|
||||
this.$emit("close");
|
||||
|
||||
|
@@ -80,7 +80,7 @@ export default {
|
||||
this.$store.dispatch("getScripts");
|
||||
},
|
||||
addScriptCheck() {
|
||||
const pk = (this.policypk) ? {policy: this.policypk} : {pk: this.agentpk}
|
||||
const pk = this.policypk ? { policy: this.policypk } : { pk: this.agentpk };
|
||||
|
||||
const data = {
|
||||
...pk,
|
||||
@@ -99,7 +99,7 @@ export default {
|
||||
} else {
|
||||
this.$store.dispatch("loadChecks", this.agentpk);
|
||||
}
|
||||
|
||||
|
||||
this.notifySuccess(r.data);
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data));
|
||||
|
@@ -3,13 +3,7 @@
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">Add Windows Service Check</div>
|
||||
<q-space />
|
||||
<q-btn
|
||||
icon="close"
|
||||
flat
|
||||
round
|
||||
dense
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
|
||||
<q-form @submit.prevent="addCheck">
|
||||
@@ -67,10 +61,7 @@
|
||||
v-model="passIfStartPending"
|
||||
label="PASS if service is in 'Start Pending' mode"
|
||||
/>
|
||||
<q-checkbox
|
||||
v-model="restartIfStopped"
|
||||
label="RESTART service if it's stopped"
|
||||
/>
|
||||
<q-checkbox v-model="restartIfStopped" label="RESTART service if it's stopped" />
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-select
|
||||
@@ -82,15 +73,8 @@
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
label="Add"
|
||||
color="primary"
|
||||
type="submit"
|
||||
/>
|
||||
<q-btn
|
||||
label="Cancel"
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn label="Add" color="primary" type="submit" />
|
||||
<q-btn label="Cancel" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
@@ -136,31 +120,35 @@ export default {
|
||||
}
|
||||
},
|
||||
getRawName() {
|
||||
let svc = this.servicesData.find(
|
||||
k => k.display_name === this.displayName
|
||||
);
|
||||
let svc = this.servicesData.find(k => k.display_name === this.displayName);
|
||||
this.rawName = [svc].map(j => j.name);
|
||||
},
|
||||
addCheck() {
|
||||
const pk = (this.policypk) ? { policy: this.policypk } : { pk: this.agentpk }
|
||||
const pk = this.policypk ? { policy: this.policypk } : { pk: this.agentpk };
|
||||
|
||||
let rawname, displayname;
|
||||
|
||||
if (this.policypk) {
|
||||
// policy
|
||||
if (this.serviceType === 'svcdefault') {
|
||||
rawname = { rawname: this.rawName[0] }
|
||||
displayname = { displayname: this.displayName }
|
||||
if (this.rawName.length === 0) { this.notifyError("Please select a service"); return; }
|
||||
} else if (this.serviceType === 'svcmanual') {
|
||||
rawname = { rawname: this.manualServiceName }
|
||||
displayname = { displayname: this.manualSvcDisplayName }
|
||||
if (!this.manualServiceName || !this.manualSvcDisplayName) { this.notifyError("All fields required"); return; }
|
||||
if (this.serviceType === "svcdefault") {
|
||||
rawname = { rawname: this.rawName[0] };
|
||||
displayname = { displayname: this.displayName };
|
||||
if (this.rawName.length === 0) {
|
||||
this.notifyError("Please select a service");
|
||||
return;
|
||||
}
|
||||
} else if (this.serviceType === "svcmanual") {
|
||||
rawname = { rawname: this.manualServiceName };
|
||||
displayname = { displayname: this.manualSvcDisplayName };
|
||||
if (!this.manualServiceName || !this.manualSvcDisplayName) {
|
||||
this.notifyError("All fields required");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// agent
|
||||
rawname = { rawname: this.rawName[0] }
|
||||
displayname = { displayname: this.displayName }
|
||||
rawname = { rawname: this.rawName[0] };
|
||||
displayname = { displayname: this.displayName };
|
||||
}
|
||||
|
||||
const data = {
|
||||
|
@@ -53,12 +53,10 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getCheck() {
|
||||
axios
|
||||
.get(`/checks/getstandardcheck/cpuload/${this.editCheckPK}/`)
|
||||
.then(r => {
|
||||
this.threshold = r.data.cpuload;
|
||||
this.failure = r.data.failures;
|
||||
});
|
||||
axios.get(`/checks/getstandardcheck/cpuload/${this.editCheckPK}/`).then(r => {
|
||||
this.threshold = r.data.cpuload;
|
||||
this.failure = r.data.failures;
|
||||
});
|
||||
},
|
||||
editCheck() {
|
||||
const data = {
|
||||
@@ -77,7 +75,7 @@ export default {
|
||||
} else {
|
||||
this.$store.dispatch("loadChecks", this.agentpk);
|
||||
}
|
||||
|
||||
|
||||
this.notifySuccess("CPU load check was edited!");
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data.error));
|
||||
|
@@ -57,14 +57,12 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getCheck() {
|
||||
axios
|
||||
.get(`/checks/getstandardcheck/diskspace/${this.editCheckPK}/`)
|
||||
.then(r => {
|
||||
this.disks = [r.data.disk];
|
||||
this.diskToEdit = r.data.disk;
|
||||
this.threshold = r.data.threshold;
|
||||
this.failure = r.data.failures;
|
||||
});
|
||||
axios.get(`/checks/getstandardcheck/diskspace/${this.editCheckPK}/`).then(r => {
|
||||
this.disks = [r.data.disk];
|
||||
this.diskToEdit = r.data.disk;
|
||||
this.threshold = r.data.threshold;
|
||||
this.failure = r.data.failures;
|
||||
});
|
||||
},
|
||||
editCheck() {
|
||||
const data = {
|
||||
|
@@ -75,7 +75,7 @@ export default {
|
||||
} else {
|
||||
this.$store.dispatch("loadChecks", this.agentpk);
|
||||
}
|
||||
|
||||
|
||||
this.notifySuccess("Memory check was edited!");
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data.error));
|
||||
|
@@ -57,13 +57,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getCheck() {
|
||||
axios
|
||||
.get(`/checks/getstandardcheck/ping/${this.editCheckPK}/`)
|
||||
.then(r => {
|
||||
this.failure = r.data.failures;
|
||||
this.pingname = r.data.name;
|
||||
this.pingip = r.data.ip;
|
||||
});
|
||||
axios.get(`/checks/getstandardcheck/ping/${this.editCheckPK}/`).then(r => {
|
||||
this.failure = r.data.failures;
|
||||
this.pingname = r.data.name;
|
||||
this.pingip = r.data.ip;
|
||||
});
|
||||
},
|
||||
editCheck() {
|
||||
const data = {
|
||||
@@ -83,7 +81,7 @@ export default {
|
||||
} else {
|
||||
this.$store.dispatch("loadChecks", this.agentpk);
|
||||
}
|
||||
|
||||
|
||||
this.notifySuccess("Ping check was edited!");
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data.error));
|
||||
|
@@ -57,13 +57,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getScriptCheck() {
|
||||
axios
|
||||
.get(`/checks/getstandardcheck/script/${this.editCheckPK}/`)
|
||||
.then(r => {
|
||||
this.failure = r.data.failures;
|
||||
this.timeout = r.data.timeout;
|
||||
this.scriptName = r.data.script.name;
|
||||
});
|
||||
axios.get(`/checks/getstandardcheck/script/${this.editCheckPK}/`).then(r => {
|
||||
this.failure = r.data.failures;
|
||||
this.timeout = r.data.timeout;
|
||||
this.scriptName = r.data.script.name;
|
||||
});
|
||||
},
|
||||
editScriptCheck() {
|
||||
const data = {
|
||||
@@ -82,7 +80,7 @@ export default {
|
||||
} else {
|
||||
this.$store.dispatch("loadChecks", this.agentpk);
|
||||
}
|
||||
|
||||
|
||||
this.notifySuccess(r.data);
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data.error));
|
||||
|
@@ -7,13 +7,21 @@
|
||||
</q-card-section>
|
||||
|
||||
<q-form @submit.prevent="editCheck">
|
||||
|
||||
<q-card-section>
|
||||
<q-select disable dense outlined v-model="displayName" :options="svcDisplayNames" label="Service" />
|
||||
|
||||
<q-select
|
||||
disable
|
||||
dense
|
||||
outlined
|
||||
v-model="displayName"
|
||||
:options="svcDisplayNames"
|
||||
label="Service"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-checkbox v-model="passIfStartPending" label="PASS if service is in 'Start Pending' mode" />
|
||||
<q-checkbox
|
||||
v-model="passIfStartPending"
|
||||
label="PASS if service is in 'Start Pending' mode"
|
||||
/>
|
||||
<q-checkbox v-model="restartIfStopped" label="RESTART service if it's stopped" />
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
@@ -82,7 +90,7 @@ export default {
|
||||
} else {
|
||||
this.$store.dispatch("loadChecks", this.agentpk);
|
||||
}
|
||||
|
||||
|
||||
this.notifySuccess("Windows service check was edited!");
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data.error));
|
||||
@@ -90,6 +98,6 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.getService();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -10,49 +10,40 @@
|
||||
>
|
||||
<q-card class="bg-grey-10 text-white">
|
||||
<q-bar>
|
||||
<q-btn @click="getLog" class="q-mr-sm" dense flat push icon="refresh" label="Refresh" />
|
||||
Debug Log
|
||||
<q-btn @click="getLog" class="q-mr-sm" dense flat push icon="refresh" label="Refresh" />Debug Log
|
||||
<q-space />
|
||||
<q-btn color="primary" text-color="white" label="Download log" @click="downloadLog" />
|
||||
<q-space />
|
||||
<q-space />
|
||||
<q-btn dense flat icon="close" v-close-popup>
|
||||
<q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
|
||||
</q-btn>
|
||||
</q-bar>
|
||||
<div class="q-pa-md row">
|
||||
|
||||
<div class="col-2">
|
||||
<q-select
|
||||
dark
|
||||
dense
|
||||
outlined
|
||||
v-model="agent"
|
||||
:options="agents"
|
||||
label="Filter Agent"
|
||||
@input="getLog"
|
||||
/>
|
||||
<q-select
|
||||
dark
|
||||
dense
|
||||
outlined
|
||||
v-model="agent"
|
||||
:options="agents"
|
||||
label="Filter Agent"
|
||||
@input="getLog"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<q-select
|
||||
dark
|
||||
dense
|
||||
outlined
|
||||
v-model="order"
|
||||
:options="orders"
|
||||
label="Order"
|
||||
@input="getLog"
|
||||
/>
|
||||
<q-select
|
||||
dark
|
||||
dense
|
||||
outlined
|
||||
v-model="order"
|
||||
:options="orders"
|
||||
label="Order"
|
||||
@input="getLog"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<q-card-section>
|
||||
<q-radio
|
||||
dark
|
||||
v-model="loglevel"
|
||||
color="cyan"
|
||||
val="info"
|
||||
label="Info"
|
||||
@input="getLog"
|
||||
/>
|
||||
<q-radio dark v-model="loglevel" color="cyan" val="info" label="Info" @input="getLog" />
|
||||
<q-radio
|
||||
dark
|
||||
v-model="loglevel"
|
||||
@@ -61,14 +52,7 @@
|
||||
label="Critical"
|
||||
@input="getLog"
|
||||
/>
|
||||
<q-radio
|
||||
dark
|
||||
v-model="loglevel"
|
||||
color="red"
|
||||
val="error"
|
||||
label="Error"
|
||||
@input="getLog"
|
||||
/>
|
||||
<q-radio dark v-model="loglevel" color="red" val="error" label="Error" @input="getLog" />
|
||||
<q-radio
|
||||
dark
|
||||
v-model="loglevel"
|
||||
@@ -80,12 +64,12 @@
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<q-scroll-area
|
||||
<q-scroll-area
|
||||
:thumb-style="{ right: '4px', borderRadius: '5px', background: 'red', width: '10px', opacity: 1 }"
|
||||
style="height: 60vh;"
|
||||
>
|
||||
<pre>{{ logContent }}</pre>
|
||||
</q-scroll-area>
|
||||
>
|
||||
<pre>{{ logContent }}</pre>
|
||||
</q-scroll-area>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
@@ -94,7 +78,7 @@
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import { mapState } from 'vuex';
|
||||
import { mapState } from "vuex";
|
||||
export default {
|
||||
name: "LogModal",
|
||||
data() {
|
||||
@@ -109,15 +93,16 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
downloadLog() {
|
||||
axios.get("/api/v1/downloadrmmlog/", { responseType: 'blob' })
|
||||
axios
|
||||
.get("/api/v1/downloadrmmlog/", { responseType: "blob" })
|
||||
.then(({ data }) => {
|
||||
const blob = new Blob([data], { type: 'text/plain' })
|
||||
let link = document.createElement('a')
|
||||
link.href = window.URL.createObjectURL(blob)
|
||||
link.download = 'debug.log'
|
||||
link.click()
|
||||
const blob = new Blob([data], { type: "text/plain" });
|
||||
let link = document.createElement("a");
|
||||
link.href = window.URL.createObjectURL(blob);
|
||||
link.download = "debug.log";
|
||||
link.click();
|
||||
})
|
||||
.catch(error => console.error(error))
|
||||
.catch(error => console.error(error));
|
||||
},
|
||||
getLog() {
|
||||
axios.get(`/api/v1/getrmmlog/${this.loglevel}/${this.agent}/${this.order}/`).then(r => {
|
||||
|
@@ -80,7 +80,7 @@ export default {
|
||||
this.name = r.data.name;
|
||||
this.desc = r.data.description;
|
||||
this.shell = r.data.shell;
|
||||
})
|
||||
});
|
||||
},
|
||||
editScript() {
|
||||
if (!this.name || !this.shell) {
|
||||
|
@@ -35,7 +35,7 @@ router.beforeEach((to, from, next) => {
|
||||
});
|
||||
|
||||
axios.interceptors.request.use(
|
||||
function(config) {
|
||||
function (config) {
|
||||
const token = store.state.token;
|
||||
|
||||
if (token != null) {
|
||||
@@ -44,19 +44,19 @@ axios.interceptors.request.use(
|
||||
|
||||
return config;
|
||||
},
|
||||
function(err) {
|
||||
function (err) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
);
|
||||
|
||||
axios.interceptors.response.use(
|
||||
function(response) {
|
||||
function (response) {
|
||||
if (response.status === 400) {
|
||||
return Promise.reject(response);
|
||||
}
|
||||
return response;
|
||||
},
|
||||
function(error) {
|
||||
function (error) {
|
||||
if (error.response.status === 401) {
|
||||
router.push({ path: "/expired" });
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
export default {
|
||||
methods: {
|
||||
formatClients (clients) {
|
||||
formatClients(clients) {
|
||||
return clients.map(client => {
|
||||
return {
|
||||
label: client.client,
|
||||
@@ -8,7 +8,7 @@ export default {
|
||||
};
|
||||
});
|
||||
},
|
||||
formatSites (sites) {
|
||||
formatSites(sites) {
|
||||
return sites.map(site => {
|
||||
return {
|
||||
label: `${site.client_name}\\${site.site}`,
|
||||
@@ -16,7 +16,7 @@ export default {
|
||||
};
|
||||
});
|
||||
},
|
||||
formatAgents (agents) {
|
||||
formatAgents(agents) {
|
||||
return agents.map(agent => {
|
||||
return {
|
||||
label: `${agent.client}\\${agent.site}\\${agent.hostname}`,
|
||||
|
@@ -6,7 +6,7 @@ export default {
|
||||
alerts: [],
|
||||
},
|
||||
|
||||
getters:{
|
||||
getters: {
|
||||
getAlerts(state) {
|
||||
return state.alerts;
|
||||
},
|
||||
|
@@ -9,56 +9,56 @@ export default {
|
||||
policies: [],
|
||||
},
|
||||
|
||||
getters:{
|
||||
selectedPolicyPk (state) {
|
||||
getters: {
|
||||
selectedPolicyPk(state) {
|
||||
return state.selectedPolicy;
|
||||
},
|
||||
policies (state) {
|
||||
policies(state) {
|
||||
return state.policies;
|
||||
}
|
||||
},
|
||||
|
||||
mutations: {
|
||||
SET_POLICIES (state, policies) {
|
||||
SET_POLICIES(state, policies) {
|
||||
state.policies = policies;
|
||||
},
|
||||
setSelectedPolicy (state, pk) {
|
||||
setSelectedPolicy(state, pk) {
|
||||
state.selectedPolicy = pk;
|
||||
},
|
||||
setPolicyChecks (state, checks) {
|
||||
setPolicyChecks(state, checks) {
|
||||
state.checks = checks;
|
||||
},
|
||||
setPolicyAutomatedTasks (state, tasks) {
|
||||
setPolicyAutomatedTasks(state, tasks) {
|
||||
state.automatedTasks = tasks;
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
loadPolicies (context) {
|
||||
loadPolicies(context) {
|
||||
axios.get("/automation/policies/").then(r => {
|
||||
context.commit("SET_POLICIES", r.data);
|
||||
})
|
||||
},
|
||||
loadPolicyAutomatedTasks (context, pk) {
|
||||
loadPolicyAutomatedTasks(context, pk) {
|
||||
axios.get(`/automation/${pk}/policyautomatedtasks/`).then(r => {
|
||||
context.commit("setPolicyAutomatedTasks", r.data);
|
||||
});
|
||||
},
|
||||
loadPolicyChecks (context, pk) {
|
||||
loadPolicyChecks(context, pk) {
|
||||
axios.get(`/checks/${pk}/loadpolicychecks/`).then(r => {
|
||||
context.commit("setPolicyChecks", r.data);
|
||||
});
|
||||
},
|
||||
loadPolicy (context, pk) {
|
||||
loadPolicy(context, pk) {
|
||||
return axios.get(`/automation/policies/${pk}/`);
|
||||
},
|
||||
addPolicy (context, data) {
|
||||
addPolicy(context, data) {
|
||||
return axios.post("/automation/policies/", data);
|
||||
},
|
||||
editpolicy (context, data) {
|
||||
editpolicy(context, data) {
|
||||
return axios.put(`/automation/policies/${this.pk}/`, formData)
|
||||
},
|
||||
deletePolicy (context, pk) {
|
||||
deletePolicy(context, pk) {
|
||||
return axios.delete(`/automation/policies/${pk}`).then(r => {
|
||||
context.dispatch("getPolicies");
|
||||
});
|
||||
|
@@ -6,6 +6,6 @@ export default {
|
||||
mutations: {
|
||||
TOGGLE_LOG_MODAL(state, action) {
|
||||
state.toggleLogModal = action;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -63,7 +63,7 @@ export const store = new Vuex.Store({
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
TOGGLE_SCRIPT_MANAGER (state, action) {
|
||||
TOGGLE_SCRIPT_MANAGER(state, action) {
|
||||
state.toggleScriptManager = action;
|
||||
},
|
||||
AGENT_TABLE_LOADING(state, visible) {
|
||||
@@ -149,13 +149,13 @@ export const store = new Vuex.Store({
|
||||
context.commit("getUpdatedSites", r.data);
|
||||
});
|
||||
},
|
||||
loadClients (context) {
|
||||
loadClients(context) {
|
||||
return axios.get("/clients/listclients/");
|
||||
},
|
||||
loadSites (context) {
|
||||
loadSites(context) {
|
||||
return axios.get("/clients/listsites/");
|
||||
},
|
||||
loadAgents (context) {
|
||||
loadAgents(context) {
|
||||
return axios.get("/agents/listagents/");
|
||||
},
|
||||
loadTree({ commit }) {
|
||||
|
@@ -67,24 +67,27 @@ export default {
|
||||
this.notifyError("Please upload your meshagent.exe");
|
||||
} else {
|
||||
this.$q.loading.show();
|
||||
const data = {client: this.firstclient, site: this.firstsite};
|
||||
axios.post("/clients/initialsetup/", data).then(r => {
|
||||
let formData = new FormData();
|
||||
formData.append("meshagent", this.meshagent);
|
||||
axios.put("/api/v1/uploadmeshagent/", formData).then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$router.push({ name: "Dashboard" });
|
||||
const data = { client: this.firstclient, site: this.firstsite };
|
||||
axios
|
||||
.post("/clients/initialsetup/", data)
|
||||
.then(r => {
|
||||
let formData = new FormData();
|
||||
formData.append("meshagent", this.meshagent);
|
||||
axios
|
||||
.put("/api/v1/uploadmeshagent/", formData)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$router.push({ name: "Dashboard" });
|
||||
})
|
||||
.catch(e => {
|
||||
this.notifyError("error uploading");
|
||||
this.$q.loading.hide();
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.notifyError('error uploading');
|
||||
.catch(err => {
|
||||
this.notifyError(err.response.data.error);
|
||||
this.$q.loading.hide();
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
this.notifyError(err.response.data.error);
|
||||
this.$q.loading.hide();
|
||||
})
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,10 +9,7 @@
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-form
|
||||
@submit.prevent="checkCreds"
|
||||
class="q-gutter-md"
|
||||
>
|
||||
<q-form @submit.prevent="checkCreds" class="q-gutter-md">
|
||||
<q-input
|
||||
filled
|
||||
v-model="credentials.username"
|
||||
@@ -31,11 +28,7 @@
|
||||
/>
|
||||
|
||||
<div>
|
||||
<q-btn
|
||||
label="Login"
|
||||
type="submit"
|
||||
color="primary"
|
||||
/>
|
||||
<q-btn label="Login" type="submit" color="primary" />
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
@@ -55,20 +48,9 @@
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions
|
||||
align="right"
|
||||
class="text-primary"
|
||||
>
|
||||
<q-btn
|
||||
flat
|
||||
label="Cancel"
|
||||
v-close-popup
|
||||
/>
|
||||
<q-btn
|
||||
flat
|
||||
label="Submit"
|
||||
type="submit"
|
||||
/>
|
||||
<q-card-actions align="right" class="text-primary">
|
||||
<q-btn flat label="Cancel" v-close-popup />
|
||||
<q-btn flat label="Submit" type="submit" />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
@@ -94,13 +76,14 @@ export default {
|
||||
|
||||
methods: {
|
||||
checkCreds() {
|
||||
axios.post("/checkcreds/", this.credentials)
|
||||
axios
|
||||
.post("/checkcreds/", this.credentials)
|
||||
.then(r => {
|
||||
this.prompt = true;
|
||||
})
|
||||
.catch(() => {
|
||||
this.notifyError('Bad credentials')
|
||||
})
|
||||
this.notifyError("Bad credentials");
|
||||
});
|
||||
},
|
||||
onSubmit() {
|
||||
this.$store
|
||||
@@ -124,11 +107,6 @@ export default {
|
||||
|
||||
<style>
|
||||
.bg-image {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(20, 20, 29, 1) 0%,
|
||||
rgba(38, 42, 56, 1) 49%,
|
||||
rgba(15, 18, 20, 1) 100%
|
||||
);
|
||||
background-image: linear-gradient(90deg, rgba(20, 20, 29, 1) 0%, rgba(38, 42, 56, 1) 49%, rgba(15, 18, 20, 1) 100%);
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,16 +1,15 @@
|
||||
<template>
|
||||
<div class="fixed-center text-center">
|
||||
<p class="text-faded">Sorry, nothing here...<strong>(404)</strong></p>
|
||||
<q-btn
|
||||
color="secondary"
|
||||
style="width:200px;"
|
||||
@click="$router.push('/')"
|
||||
>Go back</q-btn>
|
||||
<p class="text-faded">
|
||||
Sorry, nothing here...
|
||||
<strong>(404)</strong>
|
||||
</p>
|
||||
<q-btn color="secondary" style="width:200px;" @click="$router.push('/')">Go back</q-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "NotFound"
|
||||
}
|
||||
name: "NotFound"
|
||||
};
|
||||
</script>
|
@@ -21,9 +21,11 @@
|
||||
<q-tab-panel name="terminal">
|
||||
<iframe
|
||||
style="overflow:hidden;height:715px;"
|
||||
:src="terminalurl" width="100%" height="100%" scrolling="no"
|
||||
>
|
||||
</iframe>
|
||||
:src="terminalurl"
|
||||
width="100%"
|
||||
height="100%"
|
||||
scrolling="no"
|
||||
></iframe>
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="processes">
|
||||
<ProcessManager :pk="pk" />
|
||||
@@ -37,9 +39,11 @@
|
||||
<q-tab-panel name="filebrowser">
|
||||
<iframe
|
||||
style="overflow:hidden;height:715px;"
|
||||
:src="fileurl" width="100%" height="100%" scrolling="no"
|
||||
>
|
||||
</iframe>
|
||||
:src="fileurl"
|
||||
width="100%"
|
||||
height="100%"
|
||||
scrolling="no"
|
||||
></iframe>
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</div>
|
||||
@@ -63,7 +67,7 @@ export default {
|
||||
terminalurl: "",
|
||||
fileurl: "",
|
||||
tab: "terminal",
|
||||
title: ''
|
||||
title: ""
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -78,7 +82,7 @@ export default {
|
||||
meta() {
|
||||
return {
|
||||
title: this.title
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
pk() {
|
||||
|
@@ -1,29 +1,31 @@
|
||||
<template>
|
||||
<iframe
|
||||
style="overflow:hidden;height:900px;"
|
||||
:src="takeControlUrl" width="100%" height="100%" scrolling="no"
|
||||
>
|
||||
</iframe>
|
||||
:src="takeControlUrl"
|
||||
width="100%"
|
||||
height="100%"
|
||||
scrolling="no"
|
||||
></iframe>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
name: "TakeControl",
|
||||
data() {
|
||||
return {
|
||||
takeControlUrl: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
genURL() {
|
||||
const pk = this.$route.params.pk
|
||||
axios.get(`/agents/${pk}/takecontrol/`).then(r => this.takeControlUrl = r.data)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.genURL()
|
||||
name: "TakeControl",
|
||||
data() {
|
||||
return {
|
||||
takeControlUrl: ""
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
genURL() {
|
||||
const pk = this.$route.params.pk;
|
||||
axios.get(`/agents/${pk}/takecontrol/`).then(r => (this.takeControlUrl = r.data));
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.genURL();
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -15,7 +15,7 @@ describe('AutomationManager.vue', () => {
|
||||
desc: "Description",
|
||||
active: true,
|
||||
clients: [],
|
||||
sites: [{},{}],
|
||||
sites: [{}, {}],
|
||||
agents: [{}]
|
||||
},
|
||||
{
|
||||
@@ -24,7 +24,7 @@ describe('AutomationManager.vue', () => {
|
||||
desc: "Description 2",
|
||||
active: false,
|
||||
clients: [],
|
||||
sites: [{},{}],
|
||||
sites: [{}, {}],
|
||||
agents: [{}]
|
||||
}
|
||||
];
|
||||
@@ -45,7 +45,7 @@ describe('AutomationManager.vue', () => {
|
||||
};
|
||||
|
||||
mutations = {
|
||||
setSelectedPolicy: jest.fn((state, key) => {state.selectedPolicy = key}),
|
||||
setSelectedPolicy: jest.fn((state, key) => { state.selectedPolicy = key }),
|
||||
setPolicyChecks: jest.fn(),
|
||||
setPolicyAutomatedTasks: jest.fn(),
|
||||
|
||||
@@ -74,14 +74,14 @@ describe('AutomationManager.vue', () => {
|
||||
store,
|
||||
localVue,
|
||||
stubs: [
|
||||
"PolicySubTableTabs",
|
||||
"PolicySubTableTabs",
|
||||
"PolicyForm"
|
||||
],
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Runs after every test
|
||||
// This is needed to remove q-dialogs since body doesn't rerender
|
||||
afterEach(() => {
|
||||
@@ -107,7 +107,7 @@ describe('AutomationManager.vue', () => {
|
||||
it("sends vuex mutations and actions when policy is selected", () => {
|
||||
|
||||
const row = wrapper.findAll("tbody > tr.q-tr").wrappers[1];
|
||||
|
||||
|
||||
row.trigger('click');
|
||||
|
||||
expect(mutations.setSelectedPolicy).toHaveBeenCalledWith(expect.anything(), 2);
|
||||
@@ -118,7 +118,7 @@ describe('AutomationManager.vue', () => {
|
||||
|
||||
it("shows edit policy modal on edit button press", async () => {
|
||||
|
||||
const button = wrapper.find({ref: "edit"});
|
||||
const button = wrapper.find({ ref: "edit" });
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
await button.trigger("click")
|
||||
@@ -133,7 +133,7 @@ describe('AutomationManager.vue', () => {
|
||||
|
||||
it('shows add policy modal on button press', async () => {
|
||||
|
||||
const button = wrapper.find({ref: "new"});
|
||||
const button = wrapper.find({ ref: "new" });
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
await button.trigger("click");
|
||||
@@ -143,7 +143,7 @@ describe('AutomationManager.vue', () => {
|
||||
|
||||
it('deletes selected policy', async () => {
|
||||
|
||||
const button = wrapper.find({ref: "delete"});
|
||||
const button = wrapper.find({ ref: "delete" });
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
// Select Row
|
||||
@@ -160,7 +160,7 @@ describe('AutomationManager.vue', () => {
|
||||
|
||||
it('shows overview modal when button clicked', async () => {
|
||||
|
||||
const button = wrapper.find({ref: "overview"});
|
||||
const button = wrapper.find({ ref: "overview" });
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
await button.trigger("click");
|
||||
@@ -169,7 +169,7 @@ describe('AutomationManager.vue', () => {
|
||||
|
||||
it('calls vuex loadPolicies action when refresh button clicked and clears selected', () => {
|
||||
|
||||
const button = wrapper.find({ref: "refresh"});
|
||||
const button = wrapper.find({ ref: "refresh" });
|
||||
|
||||
button.trigger("click");
|
||||
expect(actions.loadPolicies).toHaveBeenCalled();
|
||||
@@ -180,4 +180,3 @@ describe('AutomationManager.vue', () => {
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -20,13 +20,13 @@ describe('PolicyForm.vue', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
rootActions = {
|
||||
loadClients: jest.fn( () => clients ),
|
||||
loadSites: jest.fn( () => sites ),
|
||||
loadAgents: jest.fn( () => agents ),
|
||||
loadClients: jest.fn(() => clients),
|
||||
loadSites: jest.fn(() => sites),
|
||||
loadAgents: jest.fn(() => agents),
|
||||
};
|
||||
|
||||
actions = {
|
||||
loadPolicy: jest.fn( () => policy ),
|
||||
loadPolicy: jest.fn(() => policy),
|
||||
addPolicy: jest.fn(),
|
||||
editPolicy: jest.fn(),
|
||||
};
|
||||
@@ -82,4 +82,3 @@ describe('PolicyForm.vue', () => {
|
||||
})*/
|
||||
|
||||
})
|
||||
|
Reference in New Issue
Block a user