mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-08-25 00:15:06 +03:00
Implement Admin API integration in WebUI for enhanced node management
This commit is contained in:
parent
3187114780
commit
675e2e71a5
10 changed files with 1055 additions and 47 deletions
181
src/webui/static/api.js
Normal file
181
src/webui/static/api.js
Normal file
|
@ -0,0 +1,181 @@
|
|||
/**
|
||||
* Yggdrasil Admin API Client
|
||||
* Provides JavaScript interface for accessing Yggdrasil admin functions
|
||||
*/
|
||||
class YggdrasilAPI {
|
||||
constructor() {
|
||||
this.baseURL = '/api/admin';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method to call admin API endpoints
|
||||
* @param {string} command - Admin command name
|
||||
* @param {Object} args - Command arguments
|
||||
* @returns {Promise<Object>} - API response
|
||||
*/
|
||||
async callAdmin(command, args = {}) {
|
||||
const url = command ? `${this.baseURL}/${command}` : this.baseURL;
|
||||
const options = {
|
||||
method: Object.keys(args).length > 0 ? 'POST' : 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'same-origin' // Include session cookies
|
||||
};
|
||||
|
||||
if (Object.keys(args).length > 0) {
|
||||
options.body = JSON.stringify(args);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(url, options);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === 'error') {
|
||||
throw new Error(data.error || 'Unknown API error');
|
||||
}
|
||||
|
||||
return data.response || data.commands;
|
||||
} catch (error) {
|
||||
console.error(`API call failed for ${command}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of available admin commands
|
||||
* @returns {Promise<Array>} - List of available commands
|
||||
*/
|
||||
async getCommands() {
|
||||
return await this.callAdmin('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about this node
|
||||
* @returns {Promise<Object>} - Node information
|
||||
*/
|
||||
async getSelf() {
|
||||
return await this.callAdmin('getSelf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of connected peers
|
||||
* @returns {Promise<Object>} - Peers information
|
||||
*/
|
||||
async getPeers() {
|
||||
return await this.callAdmin('getPeers');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tree routing information
|
||||
* @returns {Promise<Object>} - Tree information
|
||||
*/
|
||||
async getTree() {
|
||||
return await this.callAdmin('getTree');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get established paths through this node
|
||||
* @returns {Promise<Object>} - Paths information
|
||||
*/
|
||||
async getPaths() {
|
||||
return await this.callAdmin('getPaths');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get established traffic sessions with remote nodes
|
||||
* @returns {Promise<Object>} - Sessions information
|
||||
*/
|
||||
async getSessions() {
|
||||
return await this.callAdmin('getSessions');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a peer to the peer list
|
||||
* @param {string} uri - Peer URI (e.g., "tls://example.com:12345")
|
||||
* @param {string} int - Network interface (optional)
|
||||
* @returns {Promise<Object>} - Add peer response
|
||||
*/
|
||||
async addPeer(uri, int = '') {
|
||||
return await this.callAdmin('addPeer', { uri, int });
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a peer from the peer list
|
||||
* @param {string} uri - Peer URI to remove
|
||||
* @param {string} int - Network interface (optional)
|
||||
* @returns {Promise<Object>} - Remove peer response
|
||||
*/
|
||||
async removePeer(uri, int = '') {
|
||||
return await this.callAdmin('removePeer', { uri, int });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data formatting utilities
|
||||
*/
|
||||
class YggdrasilUtils {
|
||||
/**
|
||||
* Format bytes to human readable format
|
||||
* @param {number} bytes - Bytes count
|
||||
* @returns {string} - Formatted string (e.g., "1.5 MB")
|
||||
*/
|
||||
static formatBytes(bytes) {
|
||||
if (bytes === 0) return '0 B';
|
||||
|
||||
const k = 1024;
|
||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Format duration to human readable format
|
||||
* @param {number} seconds - Duration in seconds
|
||||
* @returns {string} - Formatted duration
|
||||
*/
|
||||
static formatDuration(seconds) {
|
||||
if (seconds < 60) return `${Math.round(seconds)}s`;
|
||||
if (seconds < 3600) return `${Math.round(seconds / 60)}m`;
|
||||
if (seconds < 86400) return `${Math.round(seconds / 3600)}h`;
|
||||
return `${Math.round(seconds / 86400)}d`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format public key for display (show first 8 and last 8 chars)
|
||||
* @param {string} key - Full public key
|
||||
* @returns {string} - Shortened key
|
||||
*/
|
||||
static formatPublicKey(key) {
|
||||
if (!key || key.length < 16) return key;
|
||||
return `${key.substring(0, 8)}...${key.substring(key.length - 8)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status color class based on peer state
|
||||
* @param {boolean} up - Whether peer is up
|
||||
* @returns {string} - CSS class name
|
||||
*/
|
||||
static getPeerStatusClass(up) {
|
||||
return up ? 'status-online' : 'status-offline';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status text based on peer state
|
||||
* @param {boolean} up - Whether peer is up
|
||||
* @returns {string} - Status text
|
||||
*/
|
||||
static getPeerStatusText(up) {
|
||||
return up ? 'Online' : 'Offline';
|
||||
}
|
||||
}
|
||||
|
||||
// Create global API instance
|
||||
window.yggAPI = new YggdrasilAPI();
|
||||
window.yggUtils = YggdrasilUtils;
|
Loading…
Add table
Add a link
Reference in a new issue