229 lines
5.6 KiB
JavaScript
229 lines
5.6 KiB
JavaScript
//////////////////////////////////////////////////////////////////////////
|
|
// DN42 Realtime GRC
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
const ExplorerURL='https://explorer.burble.com/#'
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// smaller display components
|
|
|
|
Vue.component('reg-asn', {
|
|
template: '#reg-asn',
|
|
props: [ 'asn' ],
|
|
data() {
|
|
return { }
|
|
},
|
|
computed: {
|
|
normal: function() {
|
|
if (this.asn.startsWith("AS")) {
|
|
return this.asn;
|
|
} else {
|
|
return "AS" + this.asn;
|
|
}
|
|
},
|
|
url: function() {
|
|
return ExplorerURL + "/aut-num/" + this.normal;
|
|
}
|
|
}
|
|
})
|
|
|
|
Vue.component('reg-path', {
|
|
template: '#reg-path',
|
|
props: [ 'path' ],
|
|
data() {
|
|
return { }
|
|
},
|
|
computed: {
|
|
list: function() {
|
|
return this.path.split(" ");
|
|
}
|
|
}
|
|
})
|
|
|
|
Vue.component('reg-prefix', {
|
|
template: '#reg-prefix',
|
|
props: [ 'prefix' ],
|
|
data() {
|
|
return { }
|
|
},
|
|
computed: {
|
|
isIPv6: function() {
|
|
return this.prefix.includes(":")
|
|
},
|
|
forced: function() { return this.prefix },
|
|
url: function() {
|
|
var prefix = this.prefix.replace("/", "_")
|
|
if (this.isIPv6) {
|
|
return ExplorerURL + "/inet6num/" + prefix;
|
|
}
|
|
else {
|
|
return ExplorerURL + "/inetnum/" + prefix;
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// flap list component
|
|
|
|
Vue.component('app-flaps', {
|
|
template: '#app-flaps-template',
|
|
data() {
|
|
return {
|
|
filter: '',
|
|
currentPage: 1,
|
|
total: 0,
|
|
fields: [
|
|
{
|
|
key: 'prefix',
|
|
label: 'Prefix',
|
|
sortable: true
|
|
},
|
|
{
|
|
key: 'path',
|
|
label: 'Path',
|
|
sortable: true
|
|
},
|
|
{
|
|
key: 'count',
|
|
label: 'Updates',
|
|
sortable: true,
|
|
sortDirection: 'desc'
|
|
}
|
|
],
|
|
flaps: [ ]
|
|
}
|
|
},
|
|
computed: {
|
|
rows: function() {
|
|
return this.flaps.length;
|
|
}
|
|
},
|
|
methods: {
|
|
update: function(data) {
|
|
this.flaps.splice(0);
|
|
|
|
this.total = data.total;
|
|
this.flaps = data.list.map((update) => {
|
|
var tmp = update.path.split(" ");
|
|
update.path = tmp.map((asn) => {
|
|
return "AS" + asn;
|
|
}).join(" ")
|
|
return update;
|
|
})
|
|
}
|
|
},
|
|
mounted() {
|
|
this.$root.$on('flaps-update', data => {
|
|
this.update(data)
|
|
})
|
|
}
|
|
})
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// roa list component
|
|
|
|
Vue.component('app-roa', {
|
|
template: '#app-roa-template',
|
|
data() {
|
|
return {
|
|
filter4: '',
|
|
filter6: '',
|
|
roaFields: [
|
|
{
|
|
key: 'prefix',
|
|
label: 'Prefix',
|
|
sortable: true
|
|
},
|
|
{
|
|
key: 'origin',
|
|
label: 'Origin',
|
|
sortable: true
|
|
}
|
|
],
|
|
roa4: [ ],
|
|
roa6: [ ]
|
|
}
|
|
},
|
|
methods: {
|
|
update: function(data) {
|
|
this.roa4.splice(0);
|
|
this.roa6.splice(0);
|
|
|
|
data.list.forEach((roa) => {
|
|
var nroa = {
|
|
origin: "AS" + roa.origin,
|
|
prefix: roa.prefix
|
|
};
|
|
if (roa.prefix.includes(":")) { this.roa6.push(nroa) }
|
|
else { this.roa4.push(nroa) }
|
|
})
|
|
}
|
|
},
|
|
mounted() {
|
|
this.$root.$on('roa-update', data => {
|
|
this.update(data)
|
|
});
|
|
}
|
|
})
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// timer to update every minute
|
|
|
|
Vue.component('app-timer', {
|
|
template: '#app-timer',
|
|
data() {
|
|
return {
|
|
seconds: 0,
|
|
timer: 0
|
|
}
|
|
},
|
|
methods: {
|
|
trigger: function() {
|
|
if (this.seconds <= 0) {
|
|
this.seconds = 61;
|
|
|
|
axios.get('/api/flaps').then(response => {
|
|
this.$root.$emit('flaps-update', response.data)
|
|
});
|
|
|
|
axios.get('/api/roa').then(response => {
|
|
this.$root.$emit('roa-update', response.data)
|
|
});
|
|
|
|
}
|
|
this.seconds -= 1;
|
|
this.timer = setTimeout(() => this.trigger(), 1000);
|
|
}
|
|
},
|
|
mounted() {
|
|
this.trigger()
|
|
}
|
|
})
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// main vue application starts here
|
|
|
|
// initialise the Vue Router
|
|
const router = new VueRouter({
|
|
routes: [
|
|
{ path: '/', component: Vue.component('app-flaps') },
|
|
{ path: '/flaps', component: Vue.component('app-flaps') },
|
|
{ path: '/roa', component: Vue.component('app-roa') }
|
|
]
|
|
})
|
|
|
|
// and the main app instance
|
|
const vm = new Vue({
|
|
el: '#grc_realtime',
|
|
data: { },
|
|
router
|
|
})
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// end of code
|