Initial commit of AthonetTools
This commit is contained in:
189
templates/pages/network_config.html
Normal file
189
templates/pages/network_config.html
Normal file
@@ -0,0 +1,189 @@
|
||||
{% extends "layout.html" %}
|
||||
{% set active_page = 'network_config' %}
|
||||
{% block title %}Network Config - {{ super() }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2 id="page-title" class="mb-0">Network Configuration</h2>
|
||||
</div>
|
||||
<div class="row align-items-end">
|
||||
<div class="col-md-4" id="dashboard-select-wrapper">
|
||||
<label for="dashboard-select" class="form-label">HPE P5G Dashboard</label>
|
||||
<select class="form-select" id="dashboard-select">
|
||||
<option selected>Triton</option>
|
||||
<option>Star</option>
|
||||
<option>Bluebonnet</option>
|
||||
<option>Lonestar</option>
|
||||
<option>Production</option>
|
||||
<option>Test (future)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div id="netconfig-view">
|
||||
<p>Retrieve a summary of network nodes from the selected dashboard. Click on any node to view its full configuration.</p>
|
||||
<button class="btn btn-primary" id="getConfigBtn">Get Network Config</button>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<h4>Results</h4>
|
||||
<div id="spinner" class="d-none spinner-border text-primary" role="status"><span class="visually-hidden">Loading...</span></div>
|
||||
<div id="results-output" class="p-3"></div>
|
||||
</div>
|
||||
|
||||
<div id="details-pane" class="d-none">
|
||||
<hr>
|
||||
<h4>Selected Network Details</h4>
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6">
|
||||
<h5>General Info</h5>
|
||||
<dl class="row">
|
||||
<dt class="col-sm-4">Name</dt>
|
||||
<dd class="col-sm-8" id="detail-name"></dd>
|
||||
<dt class="col-sm-4">Tenant</dt>
|
||||
<dd class="col-sm-8" id="detail-tenant"></dd>
|
||||
<dt class="col-sm-4">Status</dt>
|
||||
<dd class="col-sm-8" id="detail-status"></dd>
|
||||
<dt class="col-sm-4">Reachable</dt>
|
||||
<dd class="col-sm-8" id="detail-reachable"></dd>
|
||||
<dt class="col-sm-4">Serials</dt>
|
||||
<dd class="col-sm-8" id="detail-serials"></dd>
|
||||
<dt class="col-sm-4">Radios</dt>
|
||||
<dd class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" id="detail-radios-input" min="0">
|
||||
<button class="btn btn-success" id="updateRadiosBtn">Update</button>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h5>RAN Addressing</h5>
|
||||
<dl class="row">
|
||||
<dt class="col-sm-4">Gateway</dt>
|
||||
<dd class="col-sm-8" id="detail-ran-gateway"></dd>
|
||||
<dt class="col-sm-4">Subnet</dt>
|
||||
<dd class="col-sm-8" id="detail-ran-subnet"></dd>
|
||||
<dt class="col-sm-4">Radio Subnets</dt>
|
||||
<dd class="col-sm-8" id="detail-ran-radiosubnets"></dd>
|
||||
<dt class="col-sm-4">VLAN</dt>
|
||||
<dd class="col-sm-8" id="detail-ran-vlan"></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h5>Data Network (DNN) List</h5>
|
||||
<div id="detail-dnn-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script defer>
|
||||
const detailsPane = document.getElementById('details-pane');
|
||||
let fullNodeConfig = []; // Store the full config data
|
||||
|
||||
function populateDetailsPane(node) {
|
||||
detailsPane.dataset.networkId = node.id;
|
||||
document.getElementById('detail-name').textContent = node.name || 'N/A';
|
||||
document.getElementById('detail-tenant').textContent = node.tenant?.name || 'N/A';
|
||||
document.getElementById('detail-status').innerHTML = `<span class="badge ${getStatusClass(node.status)}">${node.status}</span>`;
|
||||
document.getElementById('detail-reachable').innerHTML = `<span class="badge ${node.network_reachable ? 'bg-success' : 'bg-danger'}">${node.network_reachable ? 'Reachable' : 'Unreachable'}</span>`;
|
||||
document.getElementById('detail-serials').textContent = node.info?.hardware?.map(hw => hw.serial).join(', ') || 'N/A';
|
||||
document.getElementById('detail-radios-input').value = node.info?.radio_pool?.[0]?.num_of_radios ?? 0;
|
||||
const ran = node.addressing?.ran;
|
||||
document.getElementById('detail-ran-gateway').textContent = ran?.gateway || 'N/A';
|
||||
document.getElementById('detail-ran-subnet').textContent = ran?.subnet || 'N/A';
|
||||
document.getElementById('detail-ran-radiosubnets').textContent = ran?.radio_subnets?.join(', ') || 'N/A';
|
||||
document.getElementById('detail-ran-vlan').textContent = ran?.vlan || 'N/A';
|
||||
const dnnListContainer = document.getElementById('detail-dnn-list');
|
||||
dnnListContainer.innerHTML = '';
|
||||
const dnnList = node.addressing?.dn_list || [];
|
||||
if (dnnList.length > 0) {
|
||||
dnnList.forEach((dnn, index) => {
|
||||
const dnnHtml = `
|
||||
<div class="mb-3">
|
||||
<h6>DNN #${index + 1}: ${dnn.dnn}</h6>
|
||||
<dl class="row">
|
||||
<dt class="col-sm-4">Gateway</dt><dd class="col-sm-8">${dnn.gateway || 'N/A'}</dd>
|
||||
<dt class="col-sm-4">Subnet</dt><dd class="col-sm-8">${dnn.subnet || 'N/A'}</dd>
|
||||
<dt class="col-sm-4">IP Pools</dt><dd class="col-sm-8">${dnn.ip_pools?.join(', ') || 'N/A'}</dd>
|
||||
<dt class="col-sm-4">DNS</dt><dd class="col-sm-8">${dnn.dns?.join(', ') || 'N/A'}</dd>
|
||||
<dt class="col-sm-4">VLAN</dt><dd class="col-sm-8">${dnn.vlan || 'N/A'}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
`;
|
||||
dnnListContainer.innerHTML += dnnHtml;
|
||||
});
|
||||
} else {
|
||||
dnnListContainer.textContent = 'No Data Networks configured.';
|
||||
}
|
||||
detailsPane.classList.remove('d-none');
|
||||
}
|
||||
|
||||
document.getElementById('getConfigBtn').addEventListener('click', async () => {
|
||||
detailsPane.classList.add('d-none');
|
||||
const dashboard = document.getElementById('dashboard-select').value;
|
||||
const configData = await apiCall('/api/network/get-config', { dashboard });
|
||||
if (configData && Array.isArray(configData.items)) {
|
||||
fullNodeConfig = configData.items; // Store the full data
|
||||
let cardsHtml = '<div class="row g-3">';
|
||||
fullNodeConfig.forEach((node, index) => {
|
||||
const name = node.name || 'Unnamed Node';
|
||||
cardsHtml += `
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="card h-100 network-card" data-node-index="${index}">
|
||||
<div class="card-header"><strong>${name}</strong></div>
|
||||
<div class="card-body">
|
||||
<p class="card-text mb-1"><small>Tenant: ${node.tenant?.name || 'N/A'}</small></p>
|
||||
<p class="card-text mb-1"><small>Serials: ${node.info?.hardware?.map(hw => hw.serial).join(', ') || 'N/A'}</small></p>
|
||||
<p class="card-text"><small>Radios: ${node.info?.radio_pool?.[0]?.num_of_radios ?? 'N/A'}</small></p>
|
||||
</div>
|
||||
<div class="card-footer d-flex justify-content-between align-items-center">
|
||||
<span class="badge ${getStatusClass(node.status)}">${node.status}</span>
|
||||
<span class="badge ${node.network_reachable ? 'bg-success' : 'bg-danger'}">
|
||||
${node.network_reachable ? 'Reachable' : 'Unreachable'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
cardsHtml += '</div>';
|
||||
resultsOutput.innerHTML = cardsHtml;
|
||||
} else {
|
||||
resultsOutput.innerHTML = `<div class="alert alert-info">Could not find network items in the response.</div>`;
|
||||
}
|
||||
});
|
||||
|
||||
resultsOutput.addEventListener('click', (event) => {
|
||||
const card = event.target.closest('.network-card');
|
||||
if (card) {
|
||||
document.querySelectorAll('.network-card.active').forEach(c => c.classList.remove('active'));
|
||||
card.classList.add('active');
|
||||
const nodeIndex = card.dataset.nodeIndex;
|
||||
const selectedNode = fullNodeConfig[nodeIndex];
|
||||
if (selectedNode) {
|
||||
populateDetailsPane(selectedNode);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('updateRadiosBtn').addEventListener('click', async () => {
|
||||
const networkId = detailsPane.dataset.networkId;
|
||||
const newCount = document.getElementById('detail-radios-input').value;
|
||||
const dashboard = document.getElementById('dashboard-select').value;
|
||||
|
||||
if (!networkId) {
|
||||
alert('No network selected.');
|
||||
return;
|
||||
}
|
||||
const node = fullNodeConfig.find(n => n.id === networkId);
|
||||
const operation = (node && node.info && node.info.radio_pool && node.info.radio_pool.length > 0) ? 'replace' : 'add';
|
||||
|
||||
const result = await apiCall('/api/network/update-radios', { dashboard, network_id: networkId, new_count: newCount, operation });
|
||||
if (result) {
|
||||
document.getElementById('getConfigBtn').click();
|
||||
detailsPane.classList.add('d-none');
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user