mirror of
https://github.com/jpros/tacticalrmm-web.git
synced 2026-03-02 08:12:12 +00:00
Policy Overview Add/Edit
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<q-card style="width: 40vw">
|
||||
<q-card style="width: 60vw">
|
||||
<q-form @submit.prevent="addPolicy">
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">Add Policy</div>
|
||||
@@ -15,7 +15,73 @@
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Description:</div>
|
||||
<div class="col-10">
|
||||
<q-input outlined dense v-model="desc" type="textarea" />
|
||||
<q-input outlined dense v-model="desc" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Active:</div>
|
||||
<div class="col-10">
|
||||
<q-toggle v-model="active" color="green" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<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
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<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
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<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
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row items-center">
|
||||
@@ -34,7 +100,14 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
name: "",
|
||||
desc: ""
|
||||
desc: "",
|
||||
active: false,
|
||||
selectedAgents: [],
|
||||
selectedSites: [],
|
||||
selectedClients: [],
|
||||
clientOptions: [],
|
||||
siteOptions: [],
|
||||
agentOptions: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -45,22 +118,78 @@ export default {
|
||||
}
|
||||
|
||||
this.$q.loading.show();
|
||||
let formData = new FormData();
|
||||
formData.append("name", this.name);
|
||||
formData.append("desc", this.desc);
|
||||
axios
|
||||
.post("/automation/policies/", formData)
|
||||
|
||||
let formData = {
|
||||
name: this.name,
|
||||
desc: this.desc,
|
||||
active: this.active,
|
||||
agents: this.selectedAgents.map(agent => agent.value),
|
||||
sites: this.selectedSites.map(site => site.value),
|
||||
clients: this.selectedClients.map(client => client.value)
|
||||
};
|
||||
|
||||
axios.post("/automation/policies/", formData)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
this.$emit("added");
|
||||
this.notifySuccess("Policy added! Edit the policy to add Checks!");
|
||||
this.notifySuccess("Policy added! Now you can add Tasks and Checks!");
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
}
|
||||
},
|
||||
getClients() {
|
||||
|
||||
axios.get(`/clients/listclients/`).then(r => {
|
||||
this.clientOptions = r.data.map(client => {
|
||||
return {
|
||||
label: client.client,
|
||||
value: client.id
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getSites() {
|
||||
|
||||
axios.get(`/clients/listsites/`).then(r => {
|
||||
this.siteOptions = r.data.map(site => {
|
||||
return {
|
||||
label: `${site.client_name}\\${site.site}`,
|
||||
value: site.id
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getAgents() {
|
||||
|
||||
axios.get(`/agents/listagents/`).then(r => {
|
||||
this.agentOptions = r.data.map(agent => {
|
||||
return {
|
||||
label: `${agent.client}\\${agent.site}\\${agent.hostname}`,
|
||||
value: agent.pk
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getClients();
|
||||
this.getSites();
|
||||
this.getAgents();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<q-card style="width: 40vw">
|
||||
<q-card style="width: 60vw">
|
||||
<q-form @submit.prevent="editPolicy">
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">Edit Policy</div>
|
||||
@@ -15,7 +15,73 @@
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Description:</div>
|
||||
<div class="col-10">
|
||||
<q-input outlined dense v-model="desc" type="textarea" />
|
||||
<q-input outlined dense v-model="desc" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Active:</div>
|
||||
<div class="col-10">
|
||||
<q-toggle v-model="active" color="green" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<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
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<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
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<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
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row items-center">
|
||||
@@ -37,15 +103,41 @@ export default {
|
||||
return {
|
||||
name: "",
|
||||
desc: "",
|
||||
associations: []
|
||||
active: false,
|
||||
selectedAgents: [],
|
||||
selectedSites: [],
|
||||
selectedClients: [],
|
||||
clientOptions: [],
|
||||
siteOptions: [],
|
||||
agentOptions: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getPolicy() {
|
||||
axios.get(`/automation/policies/${this.pk}/`).then(r => {
|
||||
|
||||
this.name = r.data.name;
|
||||
this.desc = r.data.desc;
|
||||
})
|
||||
this.active = r.data.active;
|
||||
this.selectedAgents = r.data.agents.map(agent => {
|
||||
return {
|
||||
label: agent.hostname,
|
||||
value: agent.pk
|
||||
}
|
||||
});
|
||||
this.selectedSites = r.data.sites.map(site => {
|
||||
return {
|
||||
label: site.site,
|
||||
value: site.id
|
||||
}
|
||||
});
|
||||
this.selectedClients = r.data.clients.map(client => {
|
||||
return {
|
||||
label: client.client,
|
||||
value: client.id
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
editPolicy() {
|
||||
if (!this.name) {
|
||||
@@ -54,10 +146,15 @@ export default {
|
||||
}
|
||||
|
||||
this.$q.loading.show();
|
||||
let formData = new FormData();
|
||||
|
||||
formData.append("name", this.name);
|
||||
formData.append("desc", this.desc);
|
||||
let formData = {
|
||||
name: this.name,
|
||||
desc: this.desc,
|
||||
active: this.active,
|
||||
agents: this.selectedAgents.map(agent => agent.value),
|
||||
sites: this.selectedSites.map(site => site.value),
|
||||
clients: this.selectedClients.map(client => client.value)
|
||||
}
|
||||
|
||||
axios.put(`/automation/policies/${this.pk}/`, formData)
|
||||
.then(r => {
|
||||
@@ -70,10 +167,58 @@ export default {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
}
|
||||
},
|
||||
getClients() {
|
||||
|
||||
axios.get(`/clients/listclients/`).then(r => {
|
||||
this.clientOptions = r.data.map(client => {
|
||||
return {
|
||||
label: client.client,
|
||||
value: client.id
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getSites() {
|
||||
|
||||
axios.get(`/clients/listsites/`).then(r => {
|
||||
this.siteOptions = r.data.map(site => {
|
||||
return {
|
||||
label: `${site.client_name}\\${site.site}`,
|
||||
value: site.id
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getAgents() {
|
||||
|
||||
axios.get(`/agents/listagents/`).then(r => {
|
||||
this.agentOptions = r.data.map(agent => {
|
||||
return {
|
||||
label: `${agent.client}\\${agent.site}\\${agent.hostname}`,
|
||||
value: agent.pk
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getPolicy();
|
||||
this.getClients();
|
||||
this.getSites();
|
||||
this.getAgents();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,7 +1,166 @@
|
||||
<template>
|
||||
<div>Policy Overview</div>
|
||||
<q-card style="width: 600px; max-width: 60vw">
|
||||
<q-bar>
|
||||
<q-btn @click="getPolicyTree" class="q-mr-sm" dense flat push icon="refresh" />Policy Overview
|
||||
<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>
|
||||
<q-splitter
|
||||
v-model="splitterModel"
|
||||
style="height: 400px"
|
||||
>
|
||||
<template v-slot:before>
|
||||
<div class="q-pa-md">
|
||||
<q-tree
|
||||
ref="Tree"
|
||||
:nodes="clientSiteTree"
|
||||
node-key="label"
|
||||
:selected.sync="selected"
|
||||
selected-color="primary"
|
||||
@update:selected="loadPolicyDetails"
|
||||
default-expand-all
|
||||
>
|
||||
|
||||
</q-tree>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:after>
|
||||
<q-tab-panels
|
||||
v-model="selectedTab"
|
||||
animated
|
||||
transition-prev="jump-up"
|
||||
transition-next="jump-up"
|
||||
>
|
||||
<q-tab-panel name="Checks">
|
||||
<p>List Checks</p>
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="Tasks">
|
||||
<p>List Tasks</p>
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</template>
|
||||
</q-splitter>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
|
||||
export default {
|
||||
name: "PolicyOverview",
|
||||
mixins: [mixins],
|
||||
data () {
|
||||
return {
|
||||
splitterModel: 50,
|
||||
selected: "",
|
||||
selectedPolicy: {},
|
||||
selectedTab: "Checks",
|
||||
clientSiteTree: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
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);
|
||||
});
|
||||
|
||||
},
|
||||
loadPolicyDetails(key) {
|
||||
|
||||
if (key === undefined) {return}
|
||||
|
||||
let node = this.$refs.Tree.getNodeByKey(key);
|
||||
|
||||
axios.get(`/automation/policies/${node.id}/`).then(r => {
|
||||
this.selectedPolicy = r.data
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
processTreeDataFromApi(data) {
|
||||
/* Structure
|
||||
* [{
|
||||
* "client_name_1": {
|
||||
* "policies": [
|
||||
* {
|
||||
* id: 1
|
||||
* name: "Policy Name 1"
|
||||
* }
|
||||
* ]
|
||||
* "site_name_1": {
|
||||
* "policies": []
|
||||
* }
|
||||
* }
|
||||
* }]
|
||||
*/
|
||||
|
||||
var result = [];
|
||||
|
||||
for (let client in data) {
|
||||
|
||||
var client_temp = {};
|
||||
|
||||
client_temp["label"] = client;
|
||||
client_temp["icon"] = "business";
|
||||
client_temp["selectable"] = false;
|
||||
client_temp["children"] = [];
|
||||
|
||||
// Add any policies assigned to client
|
||||
if (data[client].policies.length > 0) {
|
||||
for (let policy in data[client].policies)
|
||||
client_temp["children"].push({
|
||||
label: data[client].policies[policy].name,
|
||||
icon: 'policy',
|
||||
id: data[client].policies[policy].id
|
||||
});
|
||||
}
|
||||
|
||||
// Iterate through Sites
|
||||
for (let site in data[client].sites) {
|
||||
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',
|
||||
id: data[client].sites[site].policies[policy].id
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -42,7 +42,7 @@ import { mapState } from "vuex";
|
||||
import mixins from "@/mixins/mixins";
|
||||
export default {
|
||||
name: "AddCpuLoadCheck",
|
||||
props: ["agentpk"],
|
||||
props: ["agentpk", "policypk"],
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
@@ -53,8 +53,10 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
addCheck() {
|
||||
pk = (this.policypk) ? {policy: policypk} : {pk: agentpk}
|
||||
|
||||
const data = {
|
||||
pk: this.agentpk,
|
||||
pk,
|
||||
check_type: "cpuload",
|
||||
threshold: this.threshold,
|
||||
failure: this.failure
|
||||
@@ -63,7 +65,13 @@ export default {
|
||||
.post("/checks/addstandardcheck/", data)
|
||||
.then(r => {
|
||||
this.$emit("close");
|
||||
this.$store.dispatch("loadChecks", this.agentpk);
|
||||
|
||||
if (this.policypk) {
|
||||
this.$store.dispatch("loadPolicyChecks", this.policypk);
|
||||
} else {
|
||||
this.$store.dispatch("loadChecks", this.agentpk);
|
||||
}
|
||||
|
||||
this.notifySuccess("CPU load check was added!");
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data.error));
|
||||
|
||||
@@ -45,7 +45,7 @@ import { mapState } from "vuex";
|
||||
import mixins from "@/mixins/mixins";
|
||||
export default {
|
||||
name: "AddPingCheck",
|
||||
props: ["agentpk"],
|
||||
props: ["agentpk", "policypk"],
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
@@ -57,21 +57,32 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
addCheck() {
|
||||
let pk = (this.policypk) ? {policy: this.policypk} : {pk: this.agentpk}
|
||||
|
||||
const data = {
|
||||
pk: this.agentpk,
|
||||
...pk,
|
||||
check_type: "ping",
|
||||
failures: this.failure,
|
||||
name: this.pingname,
|
||||
ip: this.pingip,
|
||||
};
|
||||
axios
|
||||
.post("/checks/addstandardcheck/", data)
|
||||
|
||||
axios.post("/checks/addstandardcheck/", data)
|
||||
.then(r => {
|
||||
this.$emit("close");
|
||||
this.$store.dispatch("loadChecks", this.agentpk);
|
||||
|
||||
if (this.policypk) {
|
||||
this.$store.dispatch("loadPolicyChecks", this.policypk);
|
||||
} else {
|
||||
this.$store.dispatch("loadChecks", this.agentpk);
|
||||
}
|
||||
|
||||
this.notifySuccess("Ping check was added!");
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data.error));
|
||||
.catch(e => {
|
||||
this.notifyError(e.response.data);
|
||||
console.log(e.response.data)
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user