diff --git a/dist/CHANGELOG.md b/dist/CHANGELOG.md new file mode 100644 index 0000000..6a5eeb1 --- /dev/null +++ b/dist/CHANGELOG.md @@ -0,0 +1,111 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +## [1.6.1] - 2022-07-21 + +- Query Editor: + - new Filter in addition to the available on the top of the dashboard + - support setting filter values either as a dropdown or as a template variable + - support "OR" operator in addition to "AND" + - support multiple metrics in a panel + - be able to select Site as source + +## [1.6.0] - 2022-02-24 + +- Added support for Grafana version 8 +- Build tooling support for official plugin + +## [1.5.0] - 2021-08-06 + +### Breaking changes + +Plugin ID is changed according to [Grafana convention](https://grafana.com/docs/grafana/v7.5/developers/plugins/legacy/review-guidelines/#pluginjson): `kentik-app` -> `kentik-connect-app`. + +**Please refer to the updated installation instructions before updating.** +It's important to **remove the existing plugin** and **enable the plugin in Grafana again**. + +## [1.4.2] - 2021-05-21 + +### Fixed + +- Filter field "inet_dst_addr" does not support the operator "=" error [#36](https://github.com/kentik/kentik-grafana-app/pull/36) + +### Changed +- Remove old unsupported filters + +## [1.4.1] - 2020-09-25 + +### Fixed + +- 403 error when using non-admin Kentik user [#31](https://github.com/kentik/kentik-grafana-app/issues/31) + +## [1.4.0] - 2019-12-26 + +### Breaking changes + +Fixed "Permission denied" error for Viewers and Editors [#28](https://github.com/kentik/kentik-grafana-app/pull/28). + +Because of [#28](https://github.com/kentik/kentik-grafana-app/pull/28) it's required to do after update: +- restart Grafana +- go to the plugin config (e.g. http://localhost:3000/plugins/kentik-app/) and click "Update" + +## [1.3.6] - 2019-10-02 + +### New Features + +- Resolve IPs in a given view [#5](https://github.com/kentik/kentik-grafana-app/issues/5) + +## [1.3.5] - 2019-09-23 + +Autocomplete for plugin #4 + +## [1.3.4] - 2019-05-24 + +- Added support for custom api endpoints, [#71](https://github.com/grafana/kentik-app/issues/71) + + +## [1.3.3] - 2019-02-01 + +### New Features +- Added support for EU api endpoint, [#64](https://github.com/grafana/kentik-app/issues/64) + +### Fixed +- click-through to device-details page now works correctly + +### Changed +- Updated device-details page to show more data +- device-details page now displays more informative messages when updating fails + +## [1.3.2] - 2018-12-18 + +### New Features +- Added better error messaging for API issues, [#61](https://github.com/grafana/kentik-app/issues/61) + +## [1.3.1] - 2018-11-13 + +### Fixed + +- Filter operators do not match Group By operators, [#37](https://github.com/grafana/kentik-app/issues/37) + +## [1.3.0] - 2018-10-22 + +### New Features + +- Custom dimensions support [#46](https://github.com/grafana/kentik-app/issues/46) +- Direct filter import (using saved filters in Grafana) [#45](https://github.com/grafana/kentik-app/issues/45) + +## [1.2.4] - 2017-05-22 + +### New Features + +- Test for Kentik query builder + +### Changed + +- Enable stacking by default in Kentik top talkers dashboard + +### Fixed + +- Unique Src/Dst IPs metrics (after Kentik API update) +- Table data columns for Unique Src/Dst IPs metrics (now is Avg, p95th, Max, p95th mbps, p95th pps) diff --git a/dist/README.md b/dist/README.md new file mode 100644 index 0000000..9ae6ce5 --- /dev/null +++ b/dist/README.md @@ -0,0 +1,52 @@ +[![CircleCI](https://circleci.com/gh/kentik/kentik-grafana-app.svg?style=svg)](https://circleci.com/gh/kentik/kentik-grafana-app) + +Kentik Connect for Grafana allows you to quickly and easily enhance your visibility into your network traffic. Kentik Connect leverages the power of Kentik Detect, which provides real-time, Internet-scale ingest and querying of network data including flow records (NetFlow, IPFIX, sFlow), BGP, GeoIP, and SNMP. Stored in the Kentik Data Engine (KDE), Kentik Detect’s distributed post-Hadoop Big Data backend, this information is a rich source of actionable insights into network traffic, including anomalies that can affect application or service performance. Kentik Connect provides Grafana with instant access to KDE, enabling you to seamlessly integrate network activity metrics into your Grafana dashboard. + +## Features + +Kentik Connect for Grafana ships with an official Kentik Data Source, the database connector that allows you to read and visualize data directly from KDE. Within the Grafana environment, you can specify the parameters of the traffic that you want Kentik Connect to display: + +- Timespan: set the time range for which you want to see traffic data. +- Devices: view traffic from all devices or individual routers, switches, or hosts. +- Dimensions: group by over 30 source and destination dimensions representing NetFlow, BGP, or GeoIP data. +- Metrics: display data in metrics including bits, packets, or unique IPs. +- Sort: visualizations are accompanied by a sortable table showing Max, 95th percentile, and Average values. + +Kentik Connect also allows you to edit the configuration of devices (which must already be registered with Kentik Detect). And, as with any Grafana dashboard, current settings can be managed (Manage dashboard menu) and dashboards can be saved, shared, and starred. + +## External Dependencies + +- A Kentik account and API key is required to Enable the Kentik app. If you don’t have a Kentik account, [sign up for your Free Trial Now](https://portal.kentik.com/signup.html?ref=signup_2nd&utm_source=grafana&utm_medium=landingpage&utm_term=portal&utm_campaign=grafana-signup). +- To appear in the Kentik Connect device list, devices must first be registered with Kentik Detect. + +## Build +To produce a build of the plugin you will need [Docker](https://www.docker.com/products/docker-desktop). If you want to build locally without +Docker then you can reference the `Dockerfile` for the required dependencies. + +To create a local package, use `make`: + +**Note:** you will need to have a Grafana API Key in order to create a build as the package is signed. + +``` +make GRAFANA_API_KEY=$GRAFANA_API_KEY +``` + +If the builds succeeds, it will produce an archive named `kentik-connect-app-dev.zip`. + +To specify a version, use the `VERSION` environment variable: + +``` +make GRAFANA_API_KEY=$GRAFANA_API_KEY VERSION=1.5.0 +``` + +This will produce an archive named `kentik-connect-app-1.5.0.zip`. + +To add extra signing arguments use the `SIGN_ARGS` environment variable. For example, to specify a private archive +for use on the `https://grafana-test.kentiklabs.com` domain: + +``` +make GRAFANA_API_KEY=$GRAFANA_API_KEY SIGN_ARGS="--rootUrls https://grafana-test.kentiklabs.com" +``` + +#### Useful links +- Grafana docs about Docker installation: https://docs.grafana.org/installation/docker/#installing-plugins-from-other-sources diff --git a/dist/dashboards/kentik-home.json b/dist/dashboards/kentik-home.json new file mode 100644 index 0000000..6930930 --- /dev/null +++ b/dist/dashboards/kentik-home.json @@ -0,0 +1,139 @@ +{ + "uid": "xScUGST71", + "title": "Kentik: Home", + "originalTitle": "Kentik: Home", + "tags": ["kentik"], + "style": "dark", + "timezone": "browser", + "editable": false, + "hideControls": true, + "sharedCrosshair": false, + "rows": [ + { + "collapse": false, + "editable": true, + "height": "330px", + "panels": [ + { + "editable": true, + "error": false, + "id": 5, + "span": 7.5, + "height": "415px", + "title": "", + "type": "kentik-devicelist-panel" + }, + { + "content": "", + "editable": true, + "error": false, + "id": 4, + "links": [], + "mode": "markdown", + "span": 0.5, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + }, + { + "editable": true, + "error": false, + "id": 1, + "span": 4, + "title": "", + "type": "kentik-calltoaction-panel" + }, + { + "content": "", + "editable": true, + "error": false, + "id": 6, + "links": [], + "mode": "markdown", + "span": 0.5, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + }, + { + "editable": true, + "error": false, + "id": 3, + "limit": 10, + "links": [], + "mode": "search", + "query": "", + "span": 4, + "tags": [ + "kentik" + ], + "options": { + "showStarred": false, + "showRecentlyViewed": false, + "showSearch": true, + "showHeadings": false, + "maxItems": 10, + "query": "", + "tags": [ + "kentik" + ] + }, + "title": "Kentik dashboards", + "type": "dashlist" + } + ], + "title": "Row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [], + "title": "Endpoint List Row" + } + ], + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "collapse": false, + "enable": true, + "notice": false, + "now": true, + "refresh_intervals": [ + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "status": "Stable", + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "type": "timepicker" + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "schemaVersion": 7, + "version": 4, + "revision": 2, + "links": [] + } diff --git a/dist/dashboards/kentik-top-talkers.json b/dist/dashboards/kentik-top-talkers.json new file mode 100644 index 0000000..b7b53aa --- /dev/null +++ b/dist/dashboards/kentik-top-talkers.json @@ -0,0 +1,279 @@ +{ + "uid": "NS58GIo71", + "title": "Kentik Top Talkers", + "originalTitle": "Kentik Top Talkers", + "tags": ["kentik"], + "style": "dark", + "timezone": "", + "editable": true, + "hideControls": false, + "sharedCrosshair": false, + "rows": [ + { + "collapse": false, + "editable": true, + "height": 534.4375, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "kentik", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 1, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 12, + "stack": true, + "steppedLine": false, + "targets": [ + { + "device": "$device", + "metric": "$metric", + "mode": "graph", + "refId": "A", + "target": "", + "unit": "$unit", + "hostnameLookup": "$dns_lookup" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Kentik Network Flow Data", + "tooltip": { + "msResolution": false, + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "show": true + }, + "yaxes": [ + { + "format": "bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "Row" + }, + { + "collapse": false, + "editable": true, + "height": 495.015625, + "panels": [ + { + "columns": [], + "datasource": "kentik", + "editable": true, + "error": false, + "fontSize": "100%", + "id": 2, + "isNew": true, + "links": [], + "pageSize": null, + "scroll": true, + "showHeader": true, + "sort": { + "col": 1, + "desc": true + }, + "span": 12, + "styles": [ + { + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/^(Max|95th|p95th|Avg|Average)/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "device": "$device", + "metric": "$metric", + "mode": "table", + "refId": "A", + "target": "", + "unit": "$unit", + "hostnameLookup": "$dns_lookup" + } + ], + "title": "", + "transform": "table", + "type": "table" + } + ], + "title": "New row" + } + ], + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "templating": { + "list": [ + { + "allValue": null, + "current": { + "tags": [], + "text": "disabled", + "value": "disabled" + }, + "hide": 0, + "includeAll": false, + "label": "DNS Lookup", + "multi": false, + "name": "dns_lookup", + "options": [ + { + "selected": false, + "text": "enabled", + "value": "enabled" + }, + { + "selected": true, + "text": "disabled", + "value": "disabled" + } + ], + "query": "enabled,disabled", + "skipUrlSync": false, + "type": "custom" + }, + { + "current": { + "tags": [], + "text": "All", + "value": [ + "$__all" + ] + }, + "datasource": "kentik", + "hide": 0, + "includeAll": true, + "label": "Devices", + "multi": true, + "name": "device", + "options": [], + "query": "devices()", + "refresh": 1, + "type": "query" + }, + { + "current": {"value": "Traffic", "text": "Traffic"}, + "datasource": "kentik", + "hide": 0, + "includeAll": false, + "label": "Group By", + "multi": false, + "name": "metric", + "options": [], + "query": "metrics()", + "refresh": 1, + "type": "query" + }, + { + "current": {}, + "datasource": "kentik", + "hide": 0, + "includeAll": false, + "label": "Metric", + "multi": false, + "name": "unit", + "options": [], + "query": "units()", + "refresh": 1, + "regex": "", + "type": "query" + }, + { + + "datasource": "kentik", + "filters": [], + "hide": 0, + "label": "", + "name": "Filters", + "type": "adhoc" + } + ] + }, + "annotations": { + "list": [] + }, + "refresh": false, + "schemaVersion": 12, + "revision": 4, + "links": [] +} diff --git a/dist/datasource/config.html b/dist/datasource/config.html new file mode 100644 index 0000000..e69de29 diff --git a/dist/datasource/module.js b/dist/datasource/module.js new file mode 100644 index 0000000..410cba6 --- /dev/null +++ b/dist/datasource/module.js @@ -0,0 +1 @@ +define(["lodash","app/core/core","app/plugins/sdk","angular","moment","app/core/table_model"],(function(t,e,n,r,i,o){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=15)}([,function(e,n){e.exports=t},function(t,e,n){"use strict";n.d(e,"a",(function(){return o})),n.d(e,"b",(function(){return s}));var r=n(4),i=n(1);function o(t){var e="";e+=t.status?"(".concat(t.status,") "):"",e+=t.statusText?t.statusText+": ":"",t.data&&t.data.error?e+=t.data.error:t.err?e+=t.err:i.isString(t)&&(e+=t),r.appEvents.emit("alert-error",["Can't connect to Kentik API",e])}function s(t,e,n){var o="";o+=e.status?"(".concat(e.status,") "):"",o+=e.statusText?e.statusText+": ":"",e.data&&e.data.error?o+=e.data.error:e.err?o+=e.err:i.isString(e)&&(o+=e),r.appEvents.emit("alert-".concat(n),[t,o])}},function(t,e,n){"use strict";n.d(e,"a",(function(){return u}));var r=n(2),i=n(6),o=n.n(i),s=function(t,e,n,r){return new(n||(n=Promise))((function(i,o){function s(t){try{u(r.next(t))}catch(t){o(t)}}function a(t){try{u(r.throw(t))}catch(t){o(t)}}function u(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,a)}u((r=r.apply(t,e||[])).next())}))},a=function(t,e){var n,r,i,o,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function a(o){return function(a){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return s.label++,{value:o[1],done:!1};case 5:s.label++,r=o[1],o=[0];continue;case 7:o=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]s.duration(1,"months")?36e5:e>s.duration(1,"day")?9e5:3e5}(e);return!this.cache[n]||r-o>d||this.cache[n]&&(r-f>d||i6e4)},t.prototype.getFieldValues=function(t){return a(this,void 0,void 0,(function(){var e,n;return u(this,(function(r){switch(r.label){case 0:return e=c(),this.cache[t]&&e-this.cache[t].ts"),{filterField:e.field,operator:n,filterValue:t.value}}var _,g={buildTopXdataQuery:function(t){var e=o.find(d,{value:t.unit});if(!e)throw new Error("Query error: Unit field is required");var n,r,i=t.range.from.utc().format("YYYY-MM-DD HH:mm:ss"),s=t.range.to.utc().format("YYYY-MM-DD HH:mm:ss");return{dimension:[t.metric],metric:t.unit,matrixBy:[],cidr:32,cidr6:128,topx:"8",depth:100,fastData:"Auto",lookback_seconds:0,time_format:"UTC",starting_time:i,ending_time:s,device_name:t.deviceNames,outsort:e.outsort,aggregates:h(e),filters_obj:(n=t.kentikFilterGroups,r={connector:"All",filterGroups:[]},n.length&&(r.filterGroups=n),r),saved_filters:t.kentikSavedFilters,hostname_lookup:t.hostnameLookup}},formatAggs:h,convertToKentikFilterGroup:function(t,e,n){var r,i=[],s=[];if(t.length){for(var a=o.concat(v,e),u=0,c=t;u0){var d="All";!t[0].condition||"or"!==t[0].condition.toLowerCase()&&"any"!==t[0].condition.toLowerCase()||(d="Any"),i=[{connector:d,filters:i,not:!1}]}}return{kentikFilters:i,savedFilters:s}}},S=n(11),x=n.n(S),y=function(t,e,n,r){return new(n||(n=Promise))((function(i,o){function s(t){try{u(r.next(t))}catch(t){o(t)}}function a(t){try{u(r.throw(t))}catch(t){o(t)}}function u(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,a)}u((r=r.apply(t,e||[])).next())}))},b=function(t,e){var n,r,i,o,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function a(o){return function(a){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return s.label++,{value:o[1],done:!1};case 5:s.label++,r=o[1],o=[0];continue;case 7:o=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]1&&(this.conjunctionSegment=this.uiSegmentSrv.newCondition("AND"),this.filterList[this.filterList.length-2].conjunctionOperator=null===(t=this.conjunctionSegment)||void 0===t?void 0:t.value),this.target.conjunctionOperator=null===(e=this.conjunctionSegment)||void 0===e?void 0:e.value,this.onFilterListChange()},e.prototype.deleteFilter=function(t){var e,n;this.filterList.splice(t,1),null===(e=o.last(this.filterList))||void 0===e||(e.conjunctionOperator=void 0),this.filterList.length<=1&&(this.conjunctionSegment=void 0),this.target.conjunctionOperator=null===(n=this.conjunctionSegment)||void 0===n?void 0:n.value,this.onFilterListChange()},e.prototype.onPrefixChange=function(){this.panelCtrl.refresh()},e.prototype.getFilterOptionValues=function(t){return F(this,void 0,void 0,(function(){var e,n,r,i;return C(this,(function(s){switch(s.label){case 0:return e=o.map(this.templateSrv.variables,(function(t){return"$".concat(t.name)})),n=o.map(e,(function(t){return{text:t}})),[4,this.datasource.getTagValues({key:this.filterList[t].keySegment.value})];case 1:return r=s.sent(),i=I(I([],n,!0),r,!0),[2,this.uiSegmentSrv.transformToSegments(!1)(i)]}}))}))},e.prototype.getFilterOptionKeys=function(){return F(this,void 0,void 0,(function(){var t,e,n,r;return C(this,(function(i){switch(i.label){case 0:return t=o.map(this.templateSrv.variables,(function(t){return"$".concat(t.name)})),e=o.map(t,(function(t){return{text:t}})),[4,this.datasource.getTagKeys()];case 1:return n=i.sent(),r=I(I([],e,!0),n,!0),[2,this.uiSegmentSrv.transformToSegments(!1)(r)]}}))}))},e.prototype.getOperatorOptionValues=function(){return F(this,void 0,void 0,(function(){var t;return C(this,(function(e){return t=["=","!=","<","<=",">",">="],[2,this.uiSegmentSrv.transformToSegments(!1)(t.map((function(t){return{text:t}})))]}))}))},e.prototype.getConditionsOptionValues=function(){return F(this,void 0,void 0,(function(){var t;return C(this,(function(e){return t=["AND","OR"],[2,this.uiSegmentSrv.transformToSegments(!1)(t.map((function(t){return{text:t}})))]}))}))},e.prototype.getHostnameLookupOptionValues=function(){return F(this,void 0,void 0,(function(){var t;return C(this,(function(e){return t=L,this.templateSrv.variableExists("$dns_lookup")&&(t=I(["$dns_lookup"],t,!0)),[2,this.uiSegmentSrv.transformToSegments(!1)(t.map((function(t){return{text:t}})))]}))}))},e.prototype.onMetricChange=function(){return F(this,void 0,void 0,(function(){var t;return C(this,(function(e){switch(e.label){case 0:return[4,this.datasource.findMetric({text:this.metricSegment.value})];case 1:return t=e.sent(),this.target.metric=null!==t?t.value:this.metricSegment.value,this.panelCtrl.refresh(),[2]}}))}))},e.prototype.onDeviceChange=function(){return F(this,void 0,void 0,(function(){return C(this,(function(t){return this.target.device=this.deviceSegment.value,this.panelCtrl.refresh(),[2]}))}))},e.prototype.onSiteChange=function(){return F(this,void 0,void 0,(function(){return C(this,(function(t){return this.target.site=this.siteSegment.value,this.panelCtrl.refresh(),[2]}))}))},e.prototype.onUnitChange=function(){return F(this,void 0,void 0,(function(){var t;return C(this,(function(e){switch(e.label){case 0:return[4,this.datasource.findUnit({text:this.unitSegment.value})];case 1:return t=e.sent(),this.target.unit=null!==t?t.value:this.unitSegment.value,this.panelCtrl.refresh(),[2]}}))}))},e.prototype.onHostnameLookupChange=function(){return F(this,void 0,void 0,(function(){var t;return C(this,(function(e){return I(["$dns_lookup"],t=L,!0).includes(this.hostnameLookup.value)?(this.target.hostnameLookup=this.hostnameLookup.value,this.panelCtrl.refresh()):t.includes(this.hostnameLookup.value)||Object(D.a)("".concat(this.hostnameLookup.value," isn't valid hostname lookup value. Use one of ").concat(["enable","disable"])),[2]}))}))},e.prototype.onFilterInputChange=function(t,e){return F(this,void 0,void 0,(function(){return C(this,(function(n){return"keySegment"===e&&void 0===this.filterList[t].operatorSegment&&(this.filterList[t].operatorSegment=this.uiSegmentSrv.newOperator("=")),"keySegment"===e&&void 0===this.filterList[t].valueSegment&&(this.filterList[t].valueSegment=this.uiSegmentSrv.newSegment({value:"none"})),this.onFilterListChange(),[2]}))}))},e.prototype.onConjunctionSegmentChange=function(){var t;return F(this,void 0,void 0,(function(){var e=this;return C(this,(function(n){return this.filterList.forEach((function(t){var n;void 0!==t.conjunctionOperator&&(t.conjunctionOperator=null===(n=e.conjunctionSegment)||void 0===n?void 0:n.value)})),this.target.conjunctionOperator=null===(t=this.conjunctionSegment)||void 0===t?void 0:t.value,this.onFilterListChange(),[2]}))}))},e.prototype.onFilterListChange=function(){this.target.customFilters=this.filterList,this.panelCtrl.refresh()},e}(T.QueryCtrl);O.templateUrl="datasource/query_editor.html",n.d(e,"Datasource",(function(){return w})),n.d(e,"ConfigCtrl",(function(){return P})),n.d(e,"QueryCtrl",(function(){return O}))}])})); \ No newline at end of file diff --git a/dist/datasource/plugin.json b/dist/datasource/plugin.json new file mode 100644 index 0000000..64b45d6 --- /dev/null +++ b/dist/datasource/plugin.json @@ -0,0 +1,7 @@ +{ + "type": "datasource", + "name": "Kentik DS", + "id": "kentik-connect-datasource", + + "metrics": true +} diff --git a/dist/datasource/query_editor.html b/dist/datasource/query_editor.html new file mode 100644 index 0000000..88cc8e7 --- /dev/null +++ b/dist/datasource/query_editor.html @@ -0,0 +1,113 @@ + +
+
+ + +
+
+ + +
+
+
+
+
+
+
+ + +
+
+ + +
+
+ +
+ +
+
+
+
+
+
+
+
+ + +
+ +
+ + +
+
+
+
+
+
+
+ +
+ + + +
+ +
+
+
+
+
+
+
+ +
+
+ + + + + + + +
+
+
+
+
+
diff --git a/dist/img/kentik-connect-device-details.png b/dist/img/kentik-connect-device-details.png new file mode 100644 index 0000000..f3411fc Binary files /dev/null and b/dist/img/kentik-connect-device-details.png differ diff --git a/dist/img/kentik-connect-home.png b/dist/img/kentik-connect-home.png new file mode 100644 index 0000000..45664f3 Binary files /dev/null and b/dist/img/kentik-connect-home.png differ diff --git a/dist/img/kentik-connect-top-talkers-2.png b/dist/img/kentik-connect-top-talkers-2.png new file mode 100644 index 0000000..3c216c5 Binary files /dev/null and b/dist/img/kentik-connect-top-talkers-2.png differ diff --git a/dist/img/kentik-connect-top-talkers.png b/dist/img/kentik-connect-top-talkers.png new file mode 100644 index 0000000..ea7ba87 Binary files /dev/null and b/dist/img/kentik-connect-top-talkers.png differ diff --git a/dist/img/kentik_logo.png b/dist/img/kentik_logo.png new file mode 100644 index 0000000..cfda8dc Binary files /dev/null and b/dist/img/kentik_logo.png differ diff --git a/dist/img/loading-pulse.svg b/dist/img/loading-pulse.svg new file mode 100644 index 0000000..4e4ebd3 --- /dev/null +++ b/dist/img/loading-pulse.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dist/img/logo_large.png b/dist/img/logo_large.png new file mode 100644 index 0000000..a170215 Binary files /dev/null and b/dist/img/logo_large.png differ diff --git a/dist/img/logo_small.png b/dist/img/logo_small.png new file mode 100644 index 0000000..996ed36 Binary files /dev/null and b/dist/img/logo_small.png differ diff --git a/dist/module.js b/dist/module.js new file mode 100644 index 0000000..8306c29 --- /dev/null +++ b/dist/module.js @@ -0,0 +1 @@ +define(["react","lodash","app/core/core","app/plugins/sdk","angular","@grafana/runtime","@grafana/data"],(function(e,t,n,a,r,i,o){return function(e){var t={};function n(a){if(t[a])return t[a].exports;var r=t[a]={i:a,l:!1,exports:{}};return e[a].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(a,r,function(t){return e[t]}.bind(null,r));return a},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=14)}([function(t,n){t.exports=e},function(e,n){e.exports=t},function(e,t,n){"use strict";n.d(t,"a",(function(){return i})),n.d(t,"b",(function(){return o}));var a=n(4),r=n(1);function i(e){var t="";t+=e.status?"(".concat(e.status,") "):"",t+=e.statusText?e.statusText+": ":"",e.data&&e.data.error?t+=e.data.error:e.err?t+=e.err:r.isString(e)&&(t+=e),a.appEvents.emit("alert-error",["Can't connect to Kentik API",t])}function o(e,t,n){var i="";i+=t.status?"(".concat(t.status,") "):"",i+=t.statusText?t.statusText+": ":"",t.data&&t.data.error?i+=t.data.error:t.err?i+=t.err:r.isString(t)&&(i+=t),a.appEvents.emit("alert-".concat(n),[e,i])}},function(e,t,n){"use strict";n.d(t,"a",(function(){return l}));var a=n(2),r=n(6),i=n.n(r),o=function(e,t,n,a){return new(n||(n=Promise))((function(r,i){function o(e){try{l(a.next(e))}catch(e){i(e)}}function c(e){try{l(a.throw(e))}catch(e){i(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,c)}l((a=a.apply(e,t||[])).next())}))},c=function(e,t){var n,a,r,i,o={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]};return i={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function c(i){return function(c){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;o;)try{if(n=1,a&&(r=2&i[0]?a.return:i[0]?a.throw||((r=a.return)&&r.call(a),0):a.next)&&!(r=r.call(a,i[1])).done)return r;switch(a=0,r&&(i=[2&i[0],r.value]),i[0]){case 0:case 1:r=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,a=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!(r=o.trys,(r=r.length>0&&r[r.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!r||i[1]>r[0]&&i[1]Enter your Kentik Credentials\n
\n
\n \n Invalid API credentials. This app wont work until the credentials are updated.\n \n
\n
\n \n \x3c!-- Hidden input to stop chrome from autofilling --\x3e\n \n \n
\n\n
\n \n
\n \n
\n
\n\n \x3c!-- custom endpoint should display the url --\x3e\n
\n \n
\n \n
\n
\n\n
\n
\n \n \x3c!-- Hidden input to stop chrome from autofilling --\x3e\n \n \n
\n \n
\n \n
\n
\n
\n
\n \n
\n
\n
\n\n
\n \n Successfully enabled.\n Next up: \n Go to Kentik Home Dashboard\n
\n\n
\n \n The specified Kentik user seems to have Member access level (not Admin),\n Custom Dimensions in the dashboard filters won\'t be available.\n
\n'},,,,function(e,t,n){"use strict";n.r(t);var a=n(9),r=n(3),i=n(7),o=n(0),c=n.n(o),l=function(){return(l=Object.assign||function(e){for(var t,n=1,a=arguments.length;n0&&r[r.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!r||i[1]>r[0]&&i[1]0&&r[r.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!r||i[1]>r[0]&&i[1]0&&c.a.createElement("section",{className:"card-section card-list-layout-list","layout-mode":!0},c.a.createElement("ol",{className:"card-list"},n.devices.map((function(e){return c.a.createElement("li",{className:"card-item-wrapper card-item-wrapper--clickable"},c.a.createElement("div",{className:"card-item pointer",onClick:function(){return function(e){window.location="/d/NS58GIo71/kentik-top-talkers?var-device=".concat(e.device_name)}(e)}},c.a.createElement("div",{className:"card-item-header card-item-header--kentik-icons card-item-header-action"},c.a.createElement("a",{onClick:function(e){return e.stopPropagation()},href:"/d/NS58GIo71/kentik-top-talkers?var-device=".concat(e.device_name)},c.a.createElement("i",{className:"icon icon-gf icon-gf-dashboard","bs-tooltip":"'Go to Top Talkers
dashboard for {{device.device_name}}'"})),c.a.createElement("a",{onClick:function(e){return e.stopPropagation()},href:"/a/kentik-connect-app?tab=device-details&device=".concat(e.id)},c.a.createElement("i",{className:"icon icon-gf icon-gf-settings","bs-tooltip":"'Configure {{device.device_name}}'"}))),c.a.createElement("div",{className:"card-item-body"},c.a.createElement("div",{className:"card-item-details"},c.a.createElement("a",{onClick:function(e){return e.stopPropagation()},href:"/d/NS58GIo71/kentik-top-talkers?var-device=".concat(e.device_name)},c.a.createElement("div",{className:"card-item-name"},e.device_name),c.a.createElement("div",{className:"card-item-sub-name"},c.a.createElement("span",{className:"card-item-sub-name--header"},e.device_type,": ")," ",e.device_description))))))})))))},icon:"file-alt",id:"device-list",text:"Device List"},{component:function(e){e.query,e.path,e.meta;var t=Object(o.useState)({pageReady:!1,device:{},deviceDTO:{},tabIndex:1}),n=t[0],a=t[1],l=Object(i.getBackendSrv)(),s=new r.a(l);function u(e){return m(this,void 0,void 0,(function(){var t,r;return v(this,(function(i){switch(i.label){case 0:return[4,s.getDeviceById(e)];case 1:return t=i.sent(),r={device_id:t.id,device_name:t.device_name,device_type:t.device_type,device_description:t.device_description,device_flow_type:t.device_flow_type,device_sample_rate:parseInt(t.device_sample_rate,10),minimize_snmp:t.minimize_snmp?1:0,device_snmp_ip:t.device_snmp_ip,device_snmp_community:t.device_snmp_community,device_bgp_type:t.device_bgp_type,device_bgp_password:t.device_bgp_password,device_bgp_neighbor_ip:t.device_bgp_neighbor_ip,device_bgp_neighbor_asn:parseInt(t.device_bgp_neighbor_asn,10)},a(f(f({},n),{pageReady:!0,device:t,deviceDTO:r})),[2]}}))}))}function h(e){a(f(f({},n),{tabIndex:e}))}function g(e,t){var r=n.deviceDTO;r[t]=e.target.value,a(f(f({},n),{deviceDTO:r}))}return Object(o.useEffect)((function(){u(new URLSearchParams(window.location.search).get("device"))}),[]),c.a.createElement("div",null,c.a.createElement("div",{className:"page-header"},c.a.createElement("h1",null,n.device.device_name,c.a.createElement("a",{onClick:function(){return e=n.device,void(window.location="/d/NS58GIo71/kentik-top-talkers?var-device=".concat(e.device_name));var e}},c.a.createElement("i",{className:"icon icon-gf icon-gf-dashboard","bs-tooltip":"'Go to Kentik: Summary
dashboard for this Device'"}))),c.a.createElement("div",{className:"page-header-tabs"},c.a.createElement("ul",{className:"gf-tabs"},c.a.createElement("li",{className:"gf-tabs-item"},c.a.createElement("a",{className:"gf-tabs-link ".concat(1===n.tabIndex&&"active"),onClick:function(){return h(1)}},"Configuration")),c.a.createElement("li",{className:"gf-tabs-item"},c.a.createElement("a",{className:"gf-tabs-link ".concat(2===n.tabIndex&&"active"),onClick:function(){return h(2)}},"Help"))))),c.a.createElement("div",{className:"page-body"},1===n.tabIndex&&c.a.createElement("div",{className:"tab-content page-content-with-sidebar"},c.a.createElement("form",{name:"collectorNameForm",onSubmit:function(e){return m(this,void 0,void 0,(function(){var t,a,r,i;return v(this,(function(o){switch(o.label){case 0:e.preventDefault(),(t=d.cloneDeep(n.deviceDTO)).device_snmp_ip||delete t.device_snmp_ip,t.device_snmp_community||delete t.device_snmp_community,t.minimize_snmp=Boolean(t.minimize_snmp),a={device:t},o.label=1;case 1:return o.trys.push([1,3,,4]),[4,s.updateDevice(n.deviceDTO.device_id,a)];case 2:return"err"in(r=o.sent())?(Object(p.b)("Device Update failed.",r.err,"error"),[3,4]):(Object(p.b)("Device Updated.",n.deviceDTO.device_name,"success"),[2,u(n.deviceDTO.device_id)]);case 3:return"error"in(i=o.sent()).data?(Object(p.b)("Device Update failed.",i.data.error,"error"),[2]):(Object(p.b)("Device Update failed.",i,"error"),[2]);case 4:return[2]}}))}))}},c.a.createElement("div",null,c.a.createElement("br",null),c.a.createElement("div",{className:"gf-form-group"},c.a.createElement("h3",{className:"page-headering"},"Update device details")),c.a.createElement("div",{className:"gf-form-group"},c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"Device Name"),c.a.createElement("input",{className:"gf-form-input max-width-21",type:"text",value:n.deviceDTO.device_name,onChange:function(e){return g(e,"device_name")},required:!0})),c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"Device Type"),c.a.createElement("div",{className:"gf-form-select-wrapper"},c.a.createElement("select",{className:"gf-form-input gf-size-auto",value:n.deviceDTO.device_type,onChange:function(e){return g(e,"device_type")}},c.a.createElement("option",{value:"router"},"Router"),c.a.createElement("option",{value:"host-nprobe-basic"},"Host"),c.a.createElement("option",{value:n.device.device_type},"Other (",n.device.device_type,")")))),c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"Device ID"),c.a.createElement("label",{className:"gf-form-label max-width-21"},n.deviceDTO.device_id)),c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"Client ID"),c.a.createElement("label",{className:"gf-form-label max-width-21"},n.device.company_id))),c.a.createElement("div",{className:"gf-form-group"},c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"Description"),c.a.createElement("input",{className:"gf-form-input max-width-21",type:"text",value:n.deviceDTO.device_description,onChange:function(e){return g(e,"device_description")}})),"router"===n.deviceDTO.device_type&&c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"Flow Type"),c.a.createElement("div",{className:"gf-form-select-wrapper"},c.a.createElement("select",{className:"gf-form-input gf-size-auto",value:n.deviceDTO.device_flow_type,onChange:function(e){return g(e,"device_flow_type")}},c.a.createElement("option",{value:"sflow"},"sFlow"),c.a.createElement("option",{value:"netflow.v5"},"NetFlow v5"),c.a.createElement("option",{value:"netflow.v9"},"NetFlow v9"),c.a.createElement("option",{value:"ipfix"},"IPFIX")))),"host-nprobe-basic"===n.deviceDTO.device_type&&c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"Flow Type"),c.a.createElement("div",{className:"gf-form-select-wrapper"},c.a.createElement("select",{className:"gf-form-input gf-size-auto",value:n.deviceDTO.device_flow_type,onChange:function(e){return g(e,"device_flow_type")}},c.a.createElement("option",{value:"ipfix"},"IPFIX")))),c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"Sample Rate"),c.a.createElement("input",{className:"gf-form-input max-width-5",type:"number",value:n.deviceDTO.device_sample_rate,onChange:function(e){return g(e,"device_sample_rate")},required:!0}))),"router"===n.deviceDTO.device_type&&c.a.createElement("div",{className:"gf-form-group"},c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"SNMP Polling"),c.a.createElement("div",{className:"gf-form-select-wrapper"},c.a.createElement("select",{className:"gf-form-input gf-size-auto",value:n.deviceDTO.minimize_snmp,onChange:function(e){return g(e,"minimize_snmp")}},c.a.createElement("option",{value:"1"},"Minimum"),c.a.createElement("option",{value:"0"},"Standard")))),c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"SNMP Community"),c.a.createElement("input",{className:"gf-form-input max-width-15",type:"text",value:n.deviceDTO.device_snmp_community,onChange:function(e){return g(e,"device_snmp_community")}})),c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"Device IP"),c.a.createElement("input",{className:"gf-form-input max-width-15",type:"text",value:n.deviceDTO.device_snmp_ip,onChange:function(e){return g(e,"device_snmp_ip")}}))),c.a.createElement("div",{className:"gf-form-group"},c.a.createElement("div",{className:"gf-form"},c.a.createElement("label",{className:"gf-form-label width-11"},"BGP"),c.a.createElement("div",{className:"gf-form-select-wrapper"},c.a.createElement("select",{className:"gf-form-input max-width-15",disabled:!0},c.a.createElement("option",null,"Available with paid acounts")))))),c.a.createElement("button",{type:"submit",className:"btn btn-success"},"Update Device"),c.a.createElement("a",{className:"btn btn-link",href:"/a/kentik-connect-app?tab=device-list"},"Cancel"))),2===n.tabIndex&&c.a.createElement("div",{className:"tab-content page-content-with-sidebar"},c.a.createElement("div",{className:"plugin-markdown-readme"},c.a.createElement("br",null),c.a.createElement("h2",null,"Router Configuration Overview"),c.a.createElement("p",null,"Setting up a device to use with Kentik Detect involves configuration steps on the device itself and also on the Devices » Add Device page in the Kentik Detect portal. Before you start, you'll need to know whether you'll be exporting flow to the Kentik Detect servers directly or through a local encryptor/redirector running the Kentik software called \"chfagent\" (see NetFlow Proxy Agent)."),c.a.createElement("p",null,'The device configuration process varies depending on device manufacturer, but is typically performed in "configuration mode" or in a "configuration editor." Before you start you\'ll need to know the following information:',c.a.createElement("ul",null,c.a.createElement("li",null,'The destination IP and Port for the router to send flow too (flow collector IP). Depending on your configuration, this will be either the Kentik Detect servers (see the device tab for "flow collector IP" and "flow collector port") or will be the IP and Port you chose on your local encryptor/redirector running chfagent.'),c.a.createElement("li",null,"The sample rate (see Flow Sampling)."),c.a.createElement("li",null,"Whether you will examine ingress or egress (ingress is recommended; see Ingress and Egress)."))),c.a.createElement("p",null,"The following sections cover several configurations that work on some hardware/software combinations."),c.a.createElement("em",null,"Notes: "),c.a.createElement("p",null,"- Routers must be configured to persist SNMP interface IDs across reboots. The example configurations below include, where applicable, the commands to accomplish this."),c.a.createElement("p",null,"- Every vendor changes flow configuration slightly based on hardware and software versions. The configuration information below is provided for reference only. Check your router vendor documentation before configuring your devices for use with Kentik Detect."),c.a.createElement("h2",null,"SNMP OID Polling"),c.a.createElement("p",null,"OIDs are identifiers for SNMP objects that each represent the properties of a network-connected device such as a router. An OID takes the form of a path to the SNMP object it represents. Like a standard HTTP path, each segment represents a successively narrower slice of the entire networked universe, but in the case of an OID each segment is a pre-assigned number. The base OID for MIB-2 defined SNMP variables is 1.3.6.1.2.1."),c.a.createElement("p",null,"Kentik Detect polls 11 SNMP OIDs in two different categories:",c.a.createElement("ul",null,c.a.createElement("li",null,c.a.createElement("strong",null,"Selected counter OIDs"),": polled every two minutes; stored for SNMP-related querying, e.g. comparison to flow (see Compare Flow with SNMP)."),c.a.createElement("li",null,c.a.createElement("strong",null,"Selected info OIDs"),": polled every 30 minutes for interface information."))),c.a.createElement("p",null,"To enable Kentik Detect to properly poll SNMP on a given router:",c.a.createElement("ul",null,c.a.createElement("li",null,"Ensure that SNMP is enabled for the router."),c.a.createElement("li",null,"Permit SNMP polling of the router from the IPs listed in the Device SNMP Polling IPs field of the Device Details page in the portal."),c.a.createElement("li",null,"Set community on the router to match the SNMP Community string indicated on the Device Details page for the router."),c.a.createElement("li",null,"If the router has been configured to block polling of any of the specific OIDs polled by Kentik Detect, re-enable polling of those OIDs."))),c.a.createElement("p",null,"If you've successfully completed the steps above, after about 30 minutes (one complete polling interval) you'll be able to verify in the portal that Kentik Detect is able to poll your router:",c.a.createElement("ul",null,c.a.createElement("li",null,"Go to the portal's Devices page (choose Devices from the drop-down Admin menu)."),c.a.createElement("li",null,"In the Device list, confirm that the SNMP indicator in the column at left is green."),c.a.createElement("li",null,"Click the Interfaces button for the router, which takes you to that router's Interfaces page."),c.a.createElement("li",null,"Verify that names and descriptions for the router's interfaces appear on the Interfaces page."),c.a.createElement("li",null,"Verify that blue bars for SNMP ingress and egress are present in the left-hand columns of the Interfaces list."),c.a.createElement("li",null,"Click the Traffic button to go to the Data Explorer, where you'll see a graph comparing SNMP and flow rates for the router over the preceding hour.")))))))},icon:"file-alt",id:"device-details",text:"Device Details"}],g=function(){return(g=Object.assign||function(e){for(var t,n=1,a=arguments.length;n0&&r[r.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!r||i[1]>r[0]&&i[1]0&&r[r.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!r||i[1]>r[0]&&i[1]