Commit 1a6efc8b authored by Janis Streib's avatar Janis Streib 🦉

ADD: macfinder (closes #172)

parent 80f85ee9
Pipeline #130076 passed with stages
in 5 minutes and 58 seconds
......@@ -35,6 +35,7 @@
"vue": "^2.6.12",
"vue-awesome": "^4.1.0",
"vue-axios": "^3.2.2",
"vue-bootstrap-typeahead": "^0.2.6",
"vue-router": "^3.4.9",
"vue-virtual-scroller": "^1.0.10",
"vue2-leaflet": "^2.6.0",
......@@ -16518,6 +16519,11 @@
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz",
"integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA=="
},
"node_modules/resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"node_modules/resolve": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
......@@ -19260,6 +19266,15 @@
"vue": "^ 3.0.0 || ^ 2.0.0"
}
},
"node_modules/vue-bootstrap-typeahead": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/vue-bootstrap-typeahead/-/vue-bootstrap-typeahead-0.2.6.tgz",
"integrity": "sha512-BcUAnvfN+PS0StL6E3endd37P7HUt9otk+8m7tsa2gkt2I2KY8O2Dma49oR8ie8iletvJAlAqpN+klF6ktPULQ==",
"dependencies": {
"resize-observer-polyfill": "^1.5.0",
"vue": "^2.5.17"
}
},
"node_modules/vue-eslint-parser": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.4.1.tgz",
......@@ -34026,6 +34041,11 @@
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz",
"integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA=="
},
"resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"resolve": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
......@@ -36267,6 +36287,15 @@
"integrity": "sha512-kRhbZOOp9p+iEB46mtC7tfwYlvmycLUsdNUjC+24So6PkhK9VathdEP0d5OcR2QDb/Z+JNTs4i8DzJEGbx9zOg==",
"requires": {}
},
"vue-bootstrap-typeahead": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/vue-bootstrap-typeahead/-/vue-bootstrap-typeahead-0.2.6.tgz",
"integrity": "sha512-BcUAnvfN+PS0StL6E3endd37P7HUt9otk+8m7tsa2gkt2I2KY8O2Dma49oR8ie8iletvJAlAqpN+klF6ktPULQ==",
"requires": {
"resize-observer-polyfill": "^1.5.0",
"vue": "^2.5.17"
}
},
"vue-eslint-parser": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.4.1.tgz",
......@@ -35,6 +35,7 @@
"vue": "^2.6.12",
"vue-awesome": "^4.1.0",
"vue-axios": "^3.2.2",
"vue-bootstrap-typeahead": "^0.2.6",
"vue-router": "^3.4.9",
"vue-virtual-scroller": "^1.0.10",
"vue2-leaflet": "^2.6.0",
......
import Axios from 'axios'
export default {
getJobs() {
return Axios.get('/api/macfinder/jobs')
},
createJob(bcd, mac) {
return Axios.post('/api/macfinder/create_job', { bcd: bcd, mac: mac })
}
}
......@@ -115,6 +115,10 @@ export default {
name: 'Orgranisationseinheiten (OE/OU)',
url: '/cntl/ou'
},
{
name: 'Macfinder',
url: '/tools/macfinder'
},
{
name: 'Gruppen & Untergruppen',
url: '/cntl/groups'
......
......@@ -45,6 +45,17 @@
Geplante Aktionen
<b-badge variant="primary">{{ $store.state.ta_list ? $store.state.ta_list.length : 0 }}</b-badge>
</b-nav-item>
<b-nav-item-dropdown v-if="$store.state.user" right
:toggle-class="$route.path.startsWith('/tools/')?'active':''">
<template slot="button-content">
<font-awesome-icon icon="tools"/>
Werkzeuge
</template>
<b-dropdown-item to="/tools/macfinder" :active="$route.path === '/tools/macfinder'">
<font-awesome-icon fixed-width icon="ethernet"/>
Macfinder
</b-dropdown-item>
</b-nav-item-dropdown>
<b-nav-item-dropdown v-if="$store.state.user" right
:toggle-class="$route.path.startsWith('/cntl/')?'active':''">
<template slot="button-content">
......
......@@ -48,7 +48,9 @@ import {
faNetworkWired,
faHistory,
faEthernet,
faPooStorm
faPooStorm,
faTools,
faSync
} from '@fortawesome/free-solid-svg-icons'
import {
......@@ -117,5 +119,7 @@ library.add(
faNetworkWired,
faHistory,
faEthernet,
faPooStorm
faPooStorm,
faTools,
faSync
)
......@@ -17,6 +17,7 @@ import APIUtil from './util/apiutil'
import WAPITransactionSerice from './api-services/transaction.service'
import LoginService from '@/api-services/login.service'
import {EventBus} from '@/eventbus'
import VueBootstrapTypeahead from 'vue-bootstrap-typeahead'
Vue.use(Vuex)
Vue.mixin(titleMixin)
......@@ -24,6 +25,8 @@ Vue.mixin(isMobileMixin)
Vue.use(BootstrapVue)
Vue.use(vuexUndoRedo, { emptyStateMutation: 'emptyState' })
Vue.component('vue-bootstrap-typeahead', VueBootstrapTypeahead)
async function init() {
let session_info = null
let stored_token = null
......
......@@ -112,6 +112,16 @@ export default new Router({
}
}
},
{
path: '/tools/macfinder',
name: 'macfinder',
component: () => import('./views/tools/Macfinder'),
meta: {
resolveName: function () {
return 'Macfinder'
}
}
},
{
path: '/dnsvs',
component: () => import('./views/dnsvs/Main.vue'),
......
<template>
<div class="macfinder">
<h1>Macfinder</h1>
<b-form @submit="createJob">
<b-form-group label="Broadcastdomain">
<vue-bootstrap-typeahead
:data="bcds"
v-model="bcd_query"
:serializer="serializeBCD"
placeholder="BCD"
@hit="search_bcd = $event"
></vue-bootstrap-typeahead>
</b-form-group>
<b-form-group label="MAC-Adresse" description="Beliebiges Format möglich">
<b-input v-model="search_mac" placeholder="MAC-Adresse"></b-input>
</b-form-group>
<b-button type="submit" class="float-right" variant="outline-success">
<font-awesome-icon icon="search"></font-awesome-icon>
Suchen
</b-button>
</b-form>
<div class="clearfix"></div>
<hr>
<h2>Ergebnisse</h2>
<b-table :sort-by.sync="sortBy" :sort-desc.sync="sortDesc" :items="jobs" :busy="jobs === null" :fields="res_fields">
<template v-slot:cell(mac)="data">
<code>{{ data.item.mac }}</code> ({{ data.item.vendor }})
</template>
<template v-slot:cell(status)="data">
<template v-if="data.item.finished">
<template v-if="data.item.status.result.length == 0">
<i>Keine Geräte gefunden.</i>
</template>
<template v-else>
<ul>
<li v-for="res in data.item.status.result" v-bind:key="res.host + res.port">
Switch <code>{{ res.host }}</code>, Port <code>{{ res.port }}</code>
<p>{{ res.nd_p_port.module.root_module.building.name }}
({{ res.nd_p_port.module.root_module.building.nr }}),
{{ res.nd_p_port.module.root_module.floor.nr }},
{{ res.nd_p_port.module.root_module.room.name }} ({{ res.nd_p_port.module.root_module.room.nr }})
</p>
<p>Root-Modul: <code>{{ res.nd_p_port.module.root_module.name }}</code> ({{ res.nd_p_port.module.root_module.module_type.name }})</p>
</li>
</ul>
</template>
</template>
<template v-else-if="data.item.failed">
Suche fehlgeschlagen.
</template>
<template v-else>
Suche läuft...
<b-spinner></b-spinner>
</template>
</template>
<template v-slot:cell(actions)="data">
<b-button variant="outline-primary" @click="refire(data.item.bcd, data.item.mac)"><font-awesome-icon icon="sync"></font-awesome-icon></b-button>
</template>
<template v-slot:cell(started)="data">
{{ (new Date(data.item.started)).toLocaleDateString()}}
{{ (new Date(data.item.started)).toLocaleTimeString()}}
</template>
</b-table>
</div>
</template>
<script>
import MacfinderService from '@/api-services/macfinder.service'
import SearchService from '@/api-services/search.service'
export default {
name: 'Macfinder',
data() {
return {
bcds: [],
search_bcd: null,
search_mac: null,
bcd_query: '',
jobs: null,
poller: null,
sortBy: 'started',
sortDesc: true,
res_fields: [
{
key: 'mac',
label: 'MAC-Adresse'
},
{
key: 'started',
label: 'Zeit',
sortable: true
},
{
key: 'status',
label: 'Status'
},
{
key: 'bcd',
label: 'Broadcastdomain'
},
{
key: 'vlan',
label: 'VLAN-ID'
},
{
key: 'actions',
label: 'Aktionen'
}
]
}
},
methods: {
serializeBCD(i) {
window.console.debug('serialize' + i)
return i.name
},
async refresh() {
const jobs = await MacfinderService.getJobs()
this.jobs = []
for (const job in jobs.data.jobs) {
this.jobs.push(jobs.data.jobs[job])
}
},
async createJob(ev) {
ev.preventDefault()
await MacfinderService.createJob(this.search_bcd.name, this.search_mac)
await this.refresh()
},
async refire(bcd, mac) {
await MacfinderService.createJob(bcd, mac)
await this.refresh()
},
async getBCDs(bcd) {
const res = await SearchService.searchBCDRegex(this.$store.state.netdb_axios_config, bcd, null)
this.bcds = res.data[0]
},
pollData() {
this.poller = setInterval(() => {
this.refresh()
}, 3000)
}
},
watch: {
bcd_query(new_q) {
this.getBCDs(new_q)
}
},
beforeDestroy() {
clearInterval(this.poller)
},
async mounted() {
await this.refresh()
this.pollData()
}
}
</script>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment