migrate napalm/device config to typescript

This commit is contained in:
checktheroads 2021-04-20 01:43:36 -07:00
parent 98829b209a
commit 0aa8fc2fc2
15 changed files with 97 additions and 56 deletions

BIN
netbox/project-static/dist/config.js vendored Normal file

Binary file not shown.

BIN
netbox/project-static/dist/config.js.map vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -5,7 +5,7 @@
"license": "Apache2", "license": "Apache2",
"scripts": { "scripts": {
"bundle:css": "parcel build --public-url /static -o netbox.css main.scss && parcel build --public-url /static -o rack_elevation.css rack_elevation.scss", "bundle:css": "parcel build --public-url /static -o netbox.css main.scss && parcel build --public-url /static -o rack_elevation.css rack_elevation.scss",
"bundle:js": "parcel build --public-url /static -o netbox.js src/index.ts && parcel build --public-url /static -o jobs.js src/jobs.ts && parcel build --public-url /static -o lldp.js src/lldp.ts", "bundle:js": "parcel build --public-url /static -o netbox.js src/index.ts && parcel build --public-url /static -o jobs.js src/jobs.ts && parcel build --public-url /static -o lldp.js src/device/lldp.ts && parcel build --public-url /static -o config.js src/device/config.ts",
"bundle": "yarn bundle:css && yarn bundle:js" "bundle": "yarn bundle:css && yarn bundle:js"
}, },
"dependencies": { "dependencies": {

View File

@ -0,0 +1,41 @@
import { createToast } from '../toast';
import { apiGetBase, getNetboxData, hasError, toggleLoader } from '../util';
/**
* Initialize device config elements.
*/
function initConfig() {
toggleLoader('show');
const url = getNetboxData('data-object-url');
if (url !== null) {
apiGetBase<DeviceConfig>(url)
.then(data => {
if (hasError(data)) {
createToast('danger', 'Error Fetching Device Config', data.error).show();
} else {
const configTypes = [
'running',
'startup',
'candidate',
] as (keyof DeviceConfig['get_config'])[];
for (const configType of configTypes) {
const element = document.getElementById(`${configType}_config`);
if (element !== null) {
element.innerHTML = data.get_config[configType];
}
}
}
})
.finally(() => {
toggleLoader('hide');
});
}
}
if (document.readyState !== 'loading') {
initConfig();
} else {
document.addEventListener('DOMContentLoaded', initConfig);
}

View File

@ -1,19 +1,5 @@
import { createToast } from './toast'; import { createToast } from '../toast';
import { getNetboxData, apiGetBase, hasError, isTruthy } from './util'; import { getNetboxData, apiGetBase, hasError, isTruthy, toggleLoader } from '../util';
/**
* Toggle visibility of card loader.
*/
function toggleLoader(action: 'show' | 'hide') {
const spinnerContainer = document.querySelector('div.card-overlay');
if (spinnerContainer !== null) {
if (action === 'show') {
spinnerContainer.classList.remove('d-none');
} else {
spinnerContainer.classList.add('d-none');
}
}
}
/** /**
* Get an attribute from a row's cell. * Get an attribute from a row's cell.

View File

@ -113,6 +113,14 @@ type LLDPNeighborDetail = {
get_lldp_neighbors_detail: { [interface: string]: LLDPInterface[] }; get_lldp_neighbors_detail: { [interface: string]: LLDPInterface[] };
}; };
type DeviceConfig = {
get_config: {
candidate: string;
running: string;
startup: string;
};
};
interface ObjectWithGroup extends APIObjectBase { interface ObjectWithGroup extends APIObjectBase {
group: Nullable<APIReference>; group: Nullable<APIReference>;
} }

View File

@ -172,3 +172,17 @@ export function getNetboxData(key: string): string | null {
} }
return null; return null;
} }
/**
* Toggle visibility of card loader.
*/
export function toggleLoader(action: 'show' | 'hide') {
const spinnerContainer = document.querySelector('div.card-overlay');
if (spinnerContainer !== null) {
if (action === 'show') {
spinnerContainer.classList.remove('d-none');
} else {
spinnerContainer.classList.add('d-none');
}
}
}

View File

@ -3,50 +3,43 @@
{% block title %}{{ object }} - Config{% endblock %} {% block title %}{{ object }} - Config{% endblock %}
{% block head %}
<script type="text/javascript" src="{% static 'config.js' %}" onerror="window.location='{% url 'media_failure' %}?filename=config.js'"></script>
{% endblock %}
{% block content %} {% block content %}
{% include 'inc/ajax_loader.html' %} <div class="row">
<div class="row"> <div class="col-md-10 col-md-offset-1">
<div class="col-md-10 col-md-offset-1"> <div class="card">
<div class="card"> <div class="card-overlay">
<h5 class="card-header">Device Configuration</h5> <div class="spinner-border" role="status">
<div class="card-body"> <span class="visually-hidden">Loading...</span>
<ul class="nav nav-tabs" role="tablist"> </div>
<li role="presentation" class="active"><a href="#running" aria-controls="running" role="tab" data-toggle="tab">Running</a></li> </div>
<li role="presentation"><a href="#startup" aria-controls="startup" role="tab" data-toggle="tab">Startup</a></li> <h5 class="card-header">Device Configuration</h5>
<li role="presentation"><a href="#candidate" aria-controls="candidate" role="tab" data-toggle="tab">Candidate</a></li> <div class="card-body">
</ul> <ul class="nav nav-tabs" role="tablist">
<div class="tab-content"> <li role="presentation"><a class="nav-link active" href="#running" aria-controls="running" role="tab" data-bs-toggle="tab">Running</a></li>
<div role="tabpanel" class="tab-pane active" id="running"> <li role="presentation"><a class="nav-link" href="#startup" aria-controls="startup" role="tab" data-bs-toggle="tab">Startup</a></li>
<pre id="running_config"></pre> <li role="presentation"><a class="nav-link" href="#candidate" aria-controls="candidate" role="tab" data-bs-toggle="tab">Candidate</a></li>
</div> </ul>
<div role="tabpanel" class="tab-pane" id="startup"> <div class="tab-content pt-3">
<pre id="startup_config"></pre> <div role="tabpanel" class="tab-pane active" id="running">
</div> <pre id="running_config"></pre>
<div role="tabpanel" class="tab-pane" id="candidate"> </div>
<pre id="candidate_config"></pre> <div role="tabpanel" class="tab-pane" id="startup">
</div> <pre id="startup_config"></pre>
</div>
<div role="tabpanel" class="tab-pane" id="candidate">
<pre id="candidate_config"></pre>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
{% endblock %} {% endblock %}
{% block javascript %} {% block data %}
<script type="text/javascript"> <span data-object-url="{% url 'dcim-api:device-napalm' pk=object.pk %}?method=get_config"></span>
$(document).ready(function() {
$.ajax({
url: "{% url 'dcim-api:device-napalm' pk=object.pk %}?method=get_config",
dataType: 'json',
success: function(json) {
$('#running_config').html($.trim(json['get_config']['running']));
$('#startup_config').html($.trim(json['get_config']['startup']));
$('#candidate_config').html($.trim(json['get_config']['candidate']));
},
error: function(xhr) {
alert(xhr.responseText);
}
});
});
</script>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="card-header"> <div class="card-header">
<h5 class="d-inline">LLDP Neighbors</h5> <h5 class="d-inline">LLDP Neighbors</h5>
{% comment %} <div id="spinner-container" class="float-end"></div> {% endcomment %}
</div> </div>
<div class="card-body"> <div class="card-body">
<table class="table table-hover"> <table class="table table-hover">