You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
535 lines
16 KiB
535 lines
16 KiB
// ============================================
|
|
// CHARGER LES DASHBOARDS DYNAMIQUEMENT
|
|
// ============================================
|
|
|
|
// Charger les applications
|
|
function loadAvailableApps() {
|
|
console.log("loadAvailableApps called");
|
|
|
|
const apiUrl = '/en-US/splunkd/__raw/services/apps/local?output_mode=json&count=0';
|
|
|
|
fetch(apiUrl)
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('HTTP ' + response.status);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log("Apps Response: Found " + (data.entry ? data.entry.length : 0) + " apps");
|
|
|
|
if (data.entry && data.entry.length > 0) {
|
|
const apps = data.entry
|
|
.filter(item => {
|
|
// Filtrer les apps système
|
|
const isHidden = item.content && item.content.is_visible === 0;
|
|
const appName = item.name;
|
|
// Exclure les apps système
|
|
const systemApps = ['launcher', 'splunk_monitoring_console', 'introspection'];
|
|
return !isHidden && !systemApps.includes(appName);
|
|
})
|
|
.map(item => ({
|
|
id: item.name,
|
|
name: item.content.label || item.name,
|
|
description: item.content.description || ''
|
|
}))
|
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
|
|
console.log("Filtered apps: " + apps.length);
|
|
populateAppsList(apps);
|
|
} else {
|
|
console.warn("No apps found");
|
|
showAppsEmpty();
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error("API Error:", error);
|
|
showAppsEmpty();
|
|
});
|
|
}
|
|
|
|
function populateAppsList(apps) {
|
|
console.log("populateAppsList called with", apps.length, "apps");
|
|
|
|
const container = document.getElementById('dashboard-list');
|
|
|
|
if (!container) {
|
|
console.error("dashboard-list container not found");
|
|
return;
|
|
}
|
|
|
|
if (!apps || apps.length === 0) {
|
|
showAppsEmpty();
|
|
return;
|
|
}
|
|
|
|
let html = '<div class="select-all-group">';
|
|
html += '<input type="checkbox" id="select-all" onchange="toggleSelectAll(this)">';
|
|
html += '<label for="select-all">Select All (' + apps.length + ' apps)</label>';
|
|
html += '</div>';
|
|
|
|
apps.forEach((app, index) => {
|
|
const checkboxId = 'app-' + index;
|
|
html += '<div class="dashboard-item">';
|
|
html += '<input type="checkbox" id="' + checkboxId + '" value="' + app.id + '" data-app="' + app.id + '" data-name="' + app.name + '">';
|
|
html += '<label for="' + checkboxId + '"><strong>' + app.name + '</strong> <span class="app-badge">' + app.id + '</span>';
|
|
if (app.description) {
|
|
html += '<div style="font-size: 11px; color: #666; margin-top: 3px;">' + app.description + '</div>';
|
|
}
|
|
html += '</label>';
|
|
html += '</div>';
|
|
});
|
|
|
|
container.innerHTML = html;
|
|
console.log('Successfully populated ' + apps.length + ' apps');
|
|
}
|
|
|
|
function showAppsEmpty() {
|
|
const container = document.getElementById('dashboard-list');
|
|
if (container) {
|
|
container.innerHTML = '<div class="dashboard-empty">No apps found</div>';
|
|
}
|
|
console.log("Displayed empty state");
|
|
}
|
|
|
|
// Attendre que le DOM soit chargé
|
|
function initScript() {
|
|
console.log("initScript called");
|
|
|
|
// Charger les applications
|
|
loadAvailableApps();
|
|
|
|
// Charger les credentials sauvegardés
|
|
loadSavedCredentials();
|
|
|
|
// Attacher les event listeners au bouton
|
|
const pushBtn = document.getElementById('push-btn');
|
|
if (pushBtn) {
|
|
console.log("Push button found, attaching listener");
|
|
pushBtn.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
console.log("Push button clicked!");
|
|
pushDashboards();
|
|
});
|
|
} else {
|
|
console.warn("Push button not found");
|
|
}
|
|
|
|
// Attacher l'event listener pour sauvegarder les credentials
|
|
const saveCheckbox = document.getElementById('save-credentials');
|
|
if (saveCheckbox) {
|
|
saveCheckbox.addEventListener('change', function() {
|
|
if (this.checked) {
|
|
saveCredentials();
|
|
} else {
|
|
clearSavedCredentials();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function loadSavedCredentials() {
|
|
console.log("Loading saved credentials...");
|
|
|
|
try {
|
|
const savedUrl = getCookie('git_pusher_url');
|
|
const savedToken = getCookie('git_pusher_token');
|
|
const savedBranch = getCookie('git_pusher_branch');
|
|
|
|
if (savedUrl) {
|
|
document.getElementById('git-url').value = decodeURIComponent(savedUrl);
|
|
console.log("Loaded saved URL from cookie");
|
|
}
|
|
|
|
if (savedToken) {
|
|
document.getElementById('git-token').value = decodeURIComponent(savedToken);
|
|
console.log("Loaded saved token from cookie");
|
|
}
|
|
|
|
if (savedBranch) {
|
|
document.getElementById('git-branch').value = decodeURIComponent(savedBranch);
|
|
}
|
|
|
|
if (savedUrl && savedToken) {
|
|
document.getElementById('save-credentials').checked = true;
|
|
}
|
|
} catch (e) {
|
|
console.warn("Could not load saved credentials:", e);
|
|
}
|
|
}
|
|
|
|
function saveCredentials() {
|
|
console.log("Saving credentials...");
|
|
|
|
try {
|
|
const gitUrl = document.getElementById('git-url').value;
|
|
const gitToken = document.getElementById('git-token').value;
|
|
const gitBranch = document.getElementById('git-branch').value;
|
|
|
|
if (gitUrl && gitToken) {
|
|
setCookie('git_pusher_url', gitUrl, 30);
|
|
setCookie('git_pusher_token', gitToken, 30);
|
|
setCookie('git_pusher_branch', gitBranch, 30);
|
|
console.log("Credentials saved to cookies");
|
|
showSuccess("Credentials saved locally");
|
|
} else {
|
|
showError("Please fill in URL and Token before saving");
|
|
}
|
|
} catch (e) {
|
|
console.error("Error saving credentials:", e);
|
|
showError("Could not save credentials");
|
|
}
|
|
}
|
|
|
|
function clearSavedCredentials() {
|
|
console.log("Clearing saved credentials...");
|
|
|
|
try {
|
|
deleteCookie('git_pusher_url');
|
|
deleteCookie('git_pusher_token');
|
|
deleteCookie('git_pusher_branch');
|
|
console.log("Credentials cleared from cookies");
|
|
showSuccess("Credentials cleared");
|
|
} catch (e) {
|
|
console.error("Error clearing credentials:", e);
|
|
}
|
|
}
|
|
|
|
// Fonctions utilitaires pour les cookies
|
|
function setCookie(name, value, days) {
|
|
const d = new Date();
|
|
d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
|
|
const expires = "expires=" + d.toUTCString();
|
|
document.cookie = name + "=" + encodeURIComponent(value) + ";" + expires + ";path=/";
|
|
console.log("Cookie set: " + name);
|
|
}
|
|
|
|
function getCookie(name) {
|
|
const nameEQ = name + "=";
|
|
const ca = document.cookie.split(';');
|
|
for (let i = 0; i < ca.length; i++) {
|
|
let c = ca[i].trim();
|
|
if (c.indexOf(nameEQ) === 0) {
|
|
return c.substring(nameEQ.length);
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function deleteCookie(name) {
|
|
setCookie(name, "", -1);
|
|
console.log("Cookie deleted: " + name);
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
console.log("DOM Ready - Initializing script...");
|
|
setTimeout(function() {
|
|
initScript();
|
|
}, 1000);
|
|
});
|
|
} else {
|
|
console.log("DOM already ready - Initializing script...");
|
|
setTimeout(function() {
|
|
initScript();
|
|
}, 1000);
|
|
}
|
|
|
|
function getFormKeyValue() {
|
|
try {
|
|
// Chercher dans les meta tags du DOM
|
|
const metaTag = document.querySelector('meta[name="splunk_form_key"]');
|
|
if (metaTag) {
|
|
return metaTag.getAttribute('content');
|
|
}
|
|
|
|
// Chercher dans les cookies
|
|
const cookies = document.cookie.split(';');
|
|
for (let cookie of cookies) {
|
|
const [name, value] = cookie.trim().split('=');
|
|
if (name === 'splunk_form_key') {
|
|
return decodeURIComponent(value);
|
|
}
|
|
}
|
|
|
|
console.warn("Could not find form key, proceeding without it");
|
|
return '';
|
|
} catch (e) {
|
|
console.error("Error getting form key:", e);
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function loadAvailableApps() {
|
|
console.log("loadAvailableApps called");
|
|
|
|
const apiUrl = '/en-US/splunkd/__raw/services/apps/local?output_mode=json&count=0';
|
|
|
|
fetch(apiUrl)
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('HTTP ' + response.status);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log("Apps Response: Found " + (data.entry ? data.entry.length : 0) + " apps");
|
|
|
|
if (data.entry && data.entry.length > 0) {
|
|
const apps = data.entry
|
|
.filter(item => {
|
|
// Filtrer les apps système
|
|
const isHidden = item.content && item.content.is_visible === 0;
|
|
const appName = item.name;
|
|
// Exclure les apps système
|
|
const systemApps = ['launcher', 'splunk_monitoring_console', 'introspection'];
|
|
return !isHidden && !systemApps.includes(appName);
|
|
})
|
|
.map(item => ({
|
|
id: item.name,
|
|
name: item.content.label || item.name,
|
|
description: item.content.description || ''
|
|
}))
|
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
|
|
console.log("Filtered apps: " + apps.length);
|
|
populateAppsList(apps);
|
|
} else {
|
|
console.warn("No apps found");
|
|
showAppsEmpty();
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error("API Error:", error);
|
|
showAppsEmpty();
|
|
});
|
|
}
|
|
|
|
function populateAppsList(apps) {
|
|
console.log("populateAppsList called with", apps.length, "apps");
|
|
|
|
const container = document.getElementById('dashboard-list');
|
|
|
|
if (!container) {
|
|
console.error("dashboard-list container not found");
|
|
return;
|
|
}
|
|
|
|
if (!apps || apps.length === 0) {
|
|
showAppsEmpty();
|
|
return;
|
|
}
|
|
|
|
let html = '<div class="select-all-group">';
|
|
html += '<input type="checkbox" id="select-all" onchange="toggleSelectAll(this)">';
|
|
html += '<label for="select-all">Select All (' + apps.length + ' apps)</label>';
|
|
html += '</div>';
|
|
|
|
apps.forEach((app, index) => {
|
|
const checkboxId = 'app-' + index;
|
|
html += '<div class="dashboard-item">';
|
|
html += '<input type="checkbox" id="' + checkboxId + '" value="' + app.id + '" data-app="' + app.id + '" data-name="' + app.name + '">';
|
|
html += '<label for="' + checkboxId + '"><strong>' + app.name + '</strong> <span class="app-badge">' + app.id + '</span>';
|
|
if (app.description) {
|
|
html += '<div style="font-size: 11px; color: #666; margin-top: 3px;">' + app.description + '</div>';
|
|
}
|
|
html += '</label>';
|
|
html += '</div>';
|
|
});
|
|
|
|
container.innerHTML = html;
|
|
console.log('Successfully populated ' + apps.length + ' apps');
|
|
}
|
|
|
|
function showAppsEmpty() {
|
|
const container = document.getElementById('dashboard-list');
|
|
if (container) {
|
|
container.innerHTML = '<div class="dashboard-empty">No apps found</div>';
|
|
}
|
|
console.log("Displayed empty state");
|
|
}
|
|
|
|
function toggleSelectAll(checkbox) {
|
|
const checkboxes = document.querySelectorAll('#dashboard-list input[type="checkbox"]:not(#select-all)');
|
|
checkboxes.forEach(cb => cb.checked = checkbox.checked);
|
|
}
|
|
|
|
// ============================================
|
|
// POUSSER LES DASHBOARDS VERS GIT
|
|
// ============================================
|
|
|
|
function pushDashboards() {
|
|
console.log("pushDashboards called");
|
|
|
|
const gitUrl = document.getElementById('git-url').value;
|
|
const gitBranch = document.getElementById('git-branch').value;
|
|
const gitToken = document.getElementById('git-token').value;
|
|
const commitMessage = document.getElementById('commit-message').value;
|
|
|
|
console.log("Git URL:", gitUrl);
|
|
console.log("Git Branch:", gitBranch);
|
|
console.log("Commit Message:", commitMessage);
|
|
|
|
const checkboxes = document.querySelectorAll('#dashboard-list input[type="checkbox"]:not(#select-all):checked');
|
|
const selectedApps = Array.from(checkboxes).map(cb => ({
|
|
id: cb.value,
|
|
name: cb.getAttribute('data-name')
|
|
}));
|
|
|
|
console.log("Selected apps:", selectedApps);
|
|
|
|
// Validation
|
|
if (!gitUrl.trim()) {
|
|
console.warn("Validation failed: No Git URL");
|
|
showError('Please enter a Git repository URL');
|
|
return;
|
|
}
|
|
|
|
if (!gitToken.trim()) {
|
|
console.warn("Validation failed: No Git token");
|
|
showError('Please enter your Git token or password');
|
|
return;
|
|
}
|
|
|
|
if (!commitMessage.trim()) {
|
|
console.warn("Validation failed: No commit message");
|
|
showError('Please enter a commit message');
|
|
return;
|
|
}
|
|
|
|
if (selectedApps.length === 0) {
|
|
console.warn("Validation failed: No apps selected");
|
|
showError('Please select at least one application');
|
|
return;
|
|
}
|
|
|
|
console.log("Validation passed, showing loading state...");
|
|
|
|
// Afficher le loading
|
|
document.getElementById('loading').style.display = 'block';
|
|
document.getElementById('success-msg').style.display = 'none';
|
|
document.getElementById('error-msg').style.display = 'none';
|
|
document.getElementById('push-btn').disabled = true;
|
|
|
|
// Sauvegarder les credentials si la case est cochée
|
|
if (document.getElementById('save-credentials').checked) {
|
|
try {
|
|
setCookie('git_pusher_url', gitUrl, 30);
|
|
setCookie('git_pusher_token', gitToken, 30);
|
|
setCookie('git_pusher_branch', gitBranch, 30);
|
|
console.log("Credentials auto-saved to cookies");
|
|
} catch (e) {
|
|
console.warn("Could not auto-save credentials:", e);
|
|
}
|
|
}
|
|
|
|
// Préparer les données - passer les apps au lieu des dashboards
|
|
const payload = {
|
|
git_url: gitUrl,
|
|
git_branch: gitBranch,
|
|
git_token: gitToken,
|
|
apps: selectedApps,
|
|
commit_message: commitMessage,
|
|
timestamp: new Date().toISOString(),
|
|
user: getCurrentUser()
|
|
};
|
|
|
|
console.log("Payload prepared:", payload);
|
|
|
|
// Appeler le script Python via serveur
|
|
callPushScript(payload);
|
|
}
|
|
|
|
function callPushScript(payload) {
|
|
console.log("callPushScript called");
|
|
console.log("Payload:", payload);
|
|
|
|
// Construire l'URL vers le serveur Python sur le port 9999 en HTTP
|
|
const hostname = window.location.hostname;
|
|
const baseUrl = `http://${hostname}:9999`;
|
|
|
|
const url = new URL('/push', baseUrl);
|
|
|
|
// Ajouter les paramètres en query string
|
|
url.searchParams.append('git_url', payload.git_url);
|
|
url.searchParams.append('git_branch', payload.git_branch);
|
|
url.searchParams.append('git_token', payload.git_token);
|
|
url.searchParams.append('commit_message', payload.commit_message);
|
|
|
|
// Encoder correctement les apps en JSON
|
|
const appsJson = JSON.stringify(payload.apps);
|
|
console.log("Apps JSON:", appsJson);
|
|
url.searchParams.append('apps', appsJson);
|
|
|
|
url.searchParams.append('user', payload.user);
|
|
|
|
console.log("Calling:", url.toString());
|
|
|
|
fetch(url.toString(), {
|
|
method: 'POST',
|
|
mode: 'no-cors'
|
|
})
|
|
.then(response => {
|
|
// Avec no-cors, on ne peut pas lire response.json()
|
|
// Donc on suppose que si la requête arrive au serveur, c'est bon
|
|
console.log("Request sent successfully");
|
|
document.getElementById('loading').style.display = 'none';
|
|
document.getElementById('push-btn').disabled = false;
|
|
showSuccess('Push request sent! Check server logs for details.');
|
|
resetForm();
|
|
return;
|
|
})
|
|
.catch(error => {
|
|
console.error('Fetch error:', error);
|
|
document.getElementById('loading').style.display = 'none';
|
|
document.getElementById('push-btn').disabled = false;
|
|
showError('Network error: ' + error.message);
|
|
});
|
|
}
|
|
|
|
function getCurrentUser() {
|
|
try {
|
|
// Essayer plusieurs méthodes
|
|
if (Splunk && Splunk.util && typeof Splunk.util.getCurrentUser === 'function') {
|
|
return Splunk.util.getCurrentUser();
|
|
}
|
|
|
|
// Fallback: chercher dans le DOM ou retourner 'unknown'
|
|
return 'unknown_user';
|
|
} catch (e) {
|
|
console.warn("Could not get current user:", e);
|
|
return 'unknown_user';
|
|
}
|
|
}
|
|
|
|
function showSuccess(message) {
|
|
const successMsg = document.getElementById('success-msg');
|
|
document.getElementById('success-text').textContent = message;
|
|
successMsg.style.display = 'block';
|
|
setTimeout(() => {
|
|
successMsg.style.display = 'none';
|
|
}, 5000);
|
|
}
|
|
|
|
function showError(message) {
|
|
const errorMsg = document.getElementById('error-msg');
|
|
document.getElementById('error-text').textContent = 'X ' + message;
|
|
errorMsg.style.display = 'block';
|
|
}
|
|
|
|
function resetForm() {
|
|
document.getElementById('git-url').value = '';
|
|
document.getElementById('git-branch').value = 'main';
|
|
document.getElementById('git-token').value = '';
|
|
document.getElementById('commit-message').value = '';
|
|
document.querySelectorAll('#dashboard-list input[type="checkbox"]').forEach(cb => cb.checked = false);
|
|
|
|
// Demander si l'utilisateur veut aussi effacer les credentials sauvegardés
|
|
if (document.getElementById('save-credentials').checked) {
|
|
const confirmClear = confirm('Do you want to clear saved credentials?');
|
|
if (confirmClear) {
|
|
clearSavedCredentials();
|
|
document.getElementById('save-credentials').checked = false;
|
|
}
|
|
}
|
|
} |