From a23d9e8de8316a4403104adda2500d11493d5a14 Mon Sep 17 00:00:00 2001 From: admingit Date: Sun, 25 Jan 2026 21:54:59 +0100 Subject: [PATCH] del --- apps/pusher_app_prem/.DS_Store | Bin 6148 -> 0 bytes .../appserver/static/git_pusher.js | 557 ------------------ apps/pusher_app_prem/bin/README | 1 - apps/pusher_app_prem/bin/git_pusher.pid | 1 - apps/pusher_app_prem/bin/git_pusher.py | 340 ----------- apps/pusher_app_prem/bin/start_git_pusher.sh | 5 - apps/pusher_app_prem/certs/server.crt | 19 - apps/pusher_app_prem/certs/server.key | 28 - apps/pusher_app_prem/default/app.conf | 16 - .../default/data/ui/nav/default.xml | 8 - .../default/data/ui/views/README | 1 - apps/pusher_app_prem/local/app.conf | 3 - .../git_pusher_-_deploy_applications.xml | 484 --------------- .../git_pusher_-_push_applications_to_git.xml | 256 -------- .../git_pusher_-_push_dashboards_to_git.xml | 254 -------- apps/pusher_app_prem/metadata/default.meta | 35 -- apps/pusher_app_prem/metadata/local.meta | 26 - 17 files changed, 2034 deletions(-) delete mode 100644 apps/pusher_app_prem/.DS_Store delete mode 100755 apps/pusher_app_prem/appserver/static/git_pusher.js delete mode 100755 apps/pusher_app_prem/bin/README delete mode 100755 apps/pusher_app_prem/bin/git_pusher.pid delete mode 100755 apps/pusher_app_prem/bin/git_pusher.py delete mode 100755 apps/pusher_app_prem/bin/start_git_pusher.sh delete mode 100755 apps/pusher_app_prem/certs/server.crt delete mode 100755 apps/pusher_app_prem/certs/server.key delete mode 100755 apps/pusher_app_prem/default/app.conf delete mode 100755 apps/pusher_app_prem/default/data/ui/nav/default.xml delete mode 100755 apps/pusher_app_prem/default/data/ui/views/README delete mode 100755 apps/pusher_app_prem/local/app.conf delete mode 100644 apps/pusher_app_prem/local/data/ui/views/git_pusher_-_deploy_applications.xml delete mode 100644 apps/pusher_app_prem/local/data/ui/views/git_pusher_-_push_applications_to_git.xml delete mode 100644 apps/pusher_app_prem/local/data/ui/views/git_pusher_-_push_dashboards_to_git.xml delete mode 100755 apps/pusher_app_prem/metadata/default.meta delete mode 100644 apps/pusher_app_prem/metadata/local.meta diff --git a/apps/pusher_app_prem/.DS_Store b/apps/pusher_app_prem/.DS_Store deleted file mode 100644 index 7e30b28c5e2e9622c3d9fd5633d61c1f123fe0ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHLJxc>Y5S=xN#@GaGEbk{6uoOIF?1dDzCOM7bofq;U+Q_x31Z^$+6@nllSfmnv zfWJlb&F-4)dKa-0m7TErHajyr?_P4Z*$|Pa4uT3%nTU#LjQJ9}3}ZjHl+EawC7_UN z>{6GG34Pd3MY{>7fK%YNDZuycJT<6;SC8-9kNdY$Z^cnZ(cL)9j*8-1tr^Bmc#E^$ z#l!oH(fYK=;G2=1eY5fw6Ub4M4(KRso1WFviO1xT4A)*B6c3#j#gp1;uU$`GaDiG< zi9Yr0nx!|?G`wcrr{Vbet%ynO>0O-GnKZqCO%KCNTw zFg?oVv&?)7U=c%;28A}4!K3Xpc|2c@c^LU7hwKQu{x#PxQUpEvs2`vKZ5Fw^tQeEa z==Ee}`%->4Q)`)wzKXMXdCcpt8}@9r;(|igI|ZBqPJyuk{Cx1x7=4Y2Liy-GCyxNY zJf@{#T;>7L)97nV6v6`&Dix?wg+5{km5zB&$N3r)g({tdK70sWS?CjrkkzriC&Nkj z3SI9Ma0=K88z3j8YtM7~z9RdGprZ%ths@3kJ<4jLQBB?@H< kI=vms0dK|pzk)RQJRSgjjfq0cz}yc3DTC{r0zaz2JEC^YvH$=8 diff --git a/apps/pusher_app_prem/appserver/static/git_pusher.js b/apps/pusher_app_prem/appserver/static/git_pusher.js deleted file mode 100755 index a8533d92..00000000 --- a/apps/pusher_app_prem/appserver/static/git_pusher.js +++ /dev/null @@ -1,557 +0,0 @@ -// ============================================ -// 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 = '
'; - html += 'Select Applications'; - html += ''; - html += '
'; - - apps.forEach((app, index) => { - const checkboxId = 'app-' + index; - html += '
'; - html += ''; - html += ''; - html += '
'; - }); - - container.innerHTML = html; - console.log('Successfully populated ' + apps.length + ' apps'); - - // Ajouter les event listeners - addCheckboxListeners(); -} - -function addCheckboxListeners() { - console.log("addCheckboxListeners called"); - - const selectAllCheckbox = document.getElementById('select-all'); - if (selectAllCheckbox) { - selectAllCheckbox.addEventListener('change', function() { - toggleSelectAll(this); - }); - } - - const appCheckboxes = document.querySelectorAll('#dashboard-list input[type="checkbox"][data-app]'); - appCheckboxes.forEach(checkbox => { - checkbox.addEventListener('change', function() { - console.log("App checkbox changed"); - }); - }); -} - -function showAppsEmpty() { - const container = document.getElementById('dashboard-list'); - if (container) { - container.innerHTML = '
No apps found
'; - } - 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 = '
'; - html += ''; - html += ''; - html += '
'; - - apps.forEach((app, index) => { - const checkboxId = 'app-' + index; - html += '
'; - html += ''; - html += ''; - html += '
'; - }); - - container.innerHTML = html; - console.log('Successfully populated ' + apps.length + ' apps'); -} - -function showAppsEmpty() { - const container = document.getElementById('dashboard-list'); - if (container) { - container.innerHTML = '
No apps found
'; - } - console.log("Displayed empty state"); -} - -function toggleSelectAll(checkbox) { - const checkboxes = document.querySelectorAll('#dashboard-list input[type="checkbox"][data-app]'); - 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(showConfirm = false) { - 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 - // SEULEMENT si showConfirm = true (c'est-à-dire si l'utilisateur a cliqué sur Reset) - if (showConfirm && document.getElementById('save-credentials').checked) { - const confirmClear = confirm('Do you want to clear saved credentials?'); - if (confirmClear) { - clearSavedCredentials(); - document.getElementById('save-credentials').checked = false; - } - } -} \ No newline at end of file diff --git a/apps/pusher_app_prem/bin/README b/apps/pusher_app_prem/bin/README deleted file mode 100755 index 9a70db09..00000000 --- a/apps/pusher_app_prem/bin/README +++ /dev/null @@ -1 +0,0 @@ -This is where you put any scripts you want to add to this app. diff --git a/apps/pusher_app_prem/bin/git_pusher.pid b/apps/pusher_app_prem/bin/git_pusher.pid deleted file mode 100755 index 81d2a971..00000000 --- a/apps/pusher_app_prem/bin/git_pusher.pid +++ /dev/null @@ -1 +0,0 @@ -919562 diff --git a/apps/pusher_app_prem/bin/git_pusher.py b/apps/pusher_app_prem/bin/git_pusher.py deleted file mode 100755 index 6f0c0ceb..00000000 --- a/apps/pusher_app_prem/bin/git_pusher.py +++ /dev/null @@ -1,340 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import sys -import os -import json -import logging -import tempfile -import shutil -import subprocess -from datetime import datetime -from http.server import HTTPServer, BaseHTTPRequestHandler -from urllib.parse import parse_qs, urlparse - -# Configuration du logging -log_dir = '/opt/splunk/var/log/splunk' -os.makedirs(log_dir, exist_ok=True) - -logging.basicConfig( - level=logging.INFO, - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - handlers=[ - logging.FileHandler(os.path.join(log_dir, 'git_pusher.log')), - logging.StreamHandler() - ] -) -logger = logging.getLogger('git_pusher') - - -class GitPusherRequestHandler(BaseHTTPRequestHandler): - """Handler pour les requêtes HTTP""" - - def do_OPTIONS(self): - """Traiter les requêtes OPTIONS (CORS preflight)""" - self.send_response(200) - self.send_header('Access-Control-Allow-Origin', '*') - self.send_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS') - self.send_header('Access-Control-Allow-Headers', 'Content-Type') - self.end_headers() - - def do_POST(self): - """Traiter les requêtes POST""" - # Envoyer les headers CORS EN PREMIER - self.send_response(200) - self.send_header('Content-type', 'application/json') - self.send_header('Access-Control-Allow-Origin', '*') - self.send_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS') - self.send_header('Access-Control-Allow-Headers', 'Content-Type') - self.end_headers() - - try: - logger.info(f"POST request to {self.path}") - - # Parser l'URL et les paramètres - parsed_url = urlparse(self.path) - query_params = parse_qs(parsed_url.query) - - logger.info(f"Query params keys: {list(query_params.keys())}") - - # Extraire les paramètres - git_url = query_params.get('git_url', [''])[0] - git_branch = query_params.get('git_branch', ['main'])[0] - git_token = query_params.get('git_token', [''])[0] - commit_message = query_params.get('commit_message', [''])[0] - - # Accepter soit 'apps' soit 'dashboards' - apps_json = query_params.get('apps', query_params.get('dashboards', ['[]']))[0] - user = query_params.get('user', ['unknown'])[0] - - logger.info(f"Parameters received: git_url={git_url}, branch={git_branch}, user={user}") - logger.info(f"Raw apps_json: '{apps_json}'") - - # Parser les apps - try: - # parse_qs décode déjà, mais au cas où - if isinstance(apps_json, str): - apps = json.loads(apps_json) - else: - apps = apps_json - except (json.JSONDecodeError, TypeError) as e: - logger.error(f"JSON parse error: {e} - trying to parse: {apps_json}") - apps = [] - - logger.info(f"Parsed apps: {len(apps)} items - {apps}") - - # Valider - if not git_url or not git_token or not commit_message or not apps: - logger.warning(f"Validation failed: git_url={bool(git_url)}, git_token={bool(git_token)}, commit_message={bool(commit_message)}, apps={len(apps)}") - response = { - 'status': 'error', - 'message': 'Missing required parameters' - } - self.wfile.write(json.dumps(response).encode()) - return - - # Créer un répertoire temporaire - temp_dir = tempfile.mkdtemp(prefix='splunk_git_') - logger.info(f"Created temp directory: {temp_dir}") - - try: - # Préparer l'URL Git avec le token - git_url_with_token = self.prepare_git_url(git_url, git_token) - - logger.info(f"Git URL prepared (token inserted)") - logger.debug(f"Git URL with token: {git_url_with_token}") - logger.info("Cloning repository...") - self.clone_repository(temp_dir, git_url_with_token, git_branch) - - # Récupérer TOUTES les applications (dossiers complets) - logger.info("Fetching applications from Splunk...") - dashboard_contents = self.fetch_apps_directories(apps) - - # Créer le dossier apps - apps_dir = os.path.join(temp_dir, 'apps') - os.makedirs(apps_dir, exist_ok=True) - - # Copier les applications - logger.info("Copying applications to repository...") - for app_data in dashboard_contents: - app_name = app_data['name'] - app_path = app_data['path'] - dest_path = os.path.join(apps_dir, app_name) - - if os.path.exists(app_path): - logger.info(f"Copying app {app_name} from {app_path}") - # Supprimer le dossier s'il existe déjà - if os.path.exists(dest_path): - logger.info(f"Removing existing app directory: {dest_path}") - shutil.rmtree(dest_path) - # Copier le dossier - shutil.copytree(app_path, dest_path) - logger.info(f"Copied app: {app_name}") - else: - logger.warning(f"App path not found: {app_path}") - - # Configurer git - logger.info("Configuring git...") - subprocess.run(['git', 'config', 'user.email', 'splunk@splunk.local'], - cwd=temp_dir, capture_output=True) - subprocess.run(['git', 'config', 'user.name', 'Splunk Git Pusher'], - cwd=temp_dir, capture_output=True) - - # Commit et push - logger.info("Adding files...") - subprocess.run(['git', 'add', '-A'], cwd=temp_dir, capture_output=True) - - full_message = f"{commit_message}\n\nPushed by: {user}\nTimestamp: {datetime.now().isoformat()}" - logger.info("Committing...") - result = subprocess.run(['git', 'commit', '-m', full_message], - cwd=temp_dir, capture_output=True, text=True) - - if result.returncode != 0: - logger.warning(f"Commit may have failed or had no changes: {result.stderr}") - - logger.info("Pushing...") - result = subprocess.run(['git', 'push', 'origin', git_branch], - cwd=temp_dir, capture_output=True, text=True, timeout=60) - - if result.returncode != 0: - raise Exception(f"Push failed: {result.stderr}") - - logger.info("Push successful!") - response = { - 'status': 'success', - 'message': f'Successfully pushed {len(dashboard_contents)} dashboards from {len(apps)} application(s) to Git', - 'dashboards_pushed': len(dashboard_contents) - } - self.wfile.write(json.dumps(response).encode()) - - finally: - logger.info(f"Cleaning up {temp_dir}") - shutil.rmtree(temp_dir, ignore_errors=True) - - except Exception as e: - logger.error(f"Error: {str(e)}", exc_info=True) - response = { - 'status': 'error', - 'message': f'Error: {str(e)}' - } - self.wfile.write(json.dumps(response).encode()) - - def log_message(self, format, *args): - """Éviter les logs HTTP par défaut""" - logger.debug(format % args) - - @staticmethod - def prepare_git_url(git_url, token): - """Préparer l'URL Git avec le token inséré""" - logger.info(f"Preparing git URL with token") - - # Si l'URL contient déjà un token (format: https://user:token@host/repo) - # on le remplace - if '@' in git_url: - # Extraire la partie sans le token - protocol = git_url.split('://')[0] - rest = git_url.split('://', 1)[1] - host_and_path = rest.split('@', 1)[1] if '@' in rest else rest - return f"{protocol}://{token}@{host_and_path}" - - # Si l'URL est juste https://host/repo (sans credentials) - if git_url.startswith('https://') or git_url.startswith('http://'): - protocol = git_url.split('://')[0] - host_and_path = git_url.split('://', 1)[1] - # Insérer le token au format user:token@host ou juste token@host - return f"{protocol}://{token}@{host_and_path}" - - return git_url - - @staticmethod - def clone_repository(dest_dir, git_url, branch): - """Cloner le repository""" - try: - cmd = ['git', 'clone', '--depth', '1', '--branch', branch, git_url, dest_dir] - result = subprocess.run(cmd, capture_output=True, text=True, timeout=60) - - if result.returncode != 0: - raise Exception(f"Clone failed: {result.stderr}") - - logger.info("Repository cloned successfully") - except subprocess.TimeoutExpired: - raise Exception("Git clone operation timed out") - except FileNotFoundError: - raise Exception("Git is not installed on this system") - - @staticmethod - def fetch_apps_directories(apps): - """Récupérer les dossiers complets des applications""" - logger.info(f"Fetching directories for {len(apps)} applications") - - splunk_home = '/opt/splunk' - apps_base_path = os.path.join(splunk_home, 'etc', 'apps') - - app_directories = [] - - for app in apps: - app_id = app.get('id') or app.get('app_id') - app_path = os.path.join(apps_base_path, app_id) - - logger.info(f"Checking app directory: {app_path}") - - if os.path.isdir(app_path): - app_directories.append({ - 'name': app_id, - 'path': app_path, - 'size': sum(os.path.getsize(os.path.join(dirpath, filename)) - for dirpath, dirnames, filenames in os.walk(app_path) - for filename in filenames) - }) - logger.info(f"Found app: {app_id} at {app_path}") - else: - logger.warning(f"App directory not found: {app_path}") - - logger.info(f"Successfully found {len(app_directories)} application directories") - return app_directories - """Récupérer TOUS les dashboards de chaque application""" - logger.info(f"Fetching dashboards from {len(apps)} applications") - - import urllib.request - import urllib.error - import ssl - import base64 - - # Ignorer les certificats SSL auto-signés - ssl_context = ssl.create_default_context() - ssl_context.check_hostname = False - ssl_context.verify_mode = ssl.CERT_NONE - - dashboard_contents = [] - - # Lire le fichier de configuration Splunk pour obtenir les credentials - # Ou utiliser des credentials par défaut - splunk_username = os.environ.get('SPLUNK_USERNAME', 'admin') - splunk_password = os.environ.get('SPLUNK_PASSWORD', 'changeme') - - # Créer l'authentification Basic - credentials = base64.b64encode(f"{splunk_username}:{splunk_password}".encode()).decode() - - for app in apps: - app_id = app.get('id') or app.get('app_id') - logger.info(f"Fetching all dashboards from app: {app_id}") - - try: - # Récupérer la liste de TOUS les dashboards de cette app - api_url = f"https://127.0.0.1:8089/servicesNS/-/{app_id}/data/ui/views?output_mode=json&count=0" - - logger.debug(f"API URL: {api_url}") - - req = urllib.request.Request(api_url) - req.add_header('Authorization', f'Basic {credentials}') - - with urllib.request.urlopen(req, timeout=15, context=ssl_context) as response: - api_data = json.loads(response.read().decode('utf-8')) - - if 'entry' in api_data and len(api_data['entry']) > 0: - for entry in api_data['entry']: - try: - dashboard_id = entry.get('name') - content = entry.get('content', {}) - - # eai:data contient le XML complet du dashboard - dashboard_xml = content.get('eai:data', '') - - if dashboard_xml: - dashboard_contents.append({ - 'id': f"{app_id}_{dashboard_id}", - 'app': app_id, - 'content': dashboard_xml, - 'name': dashboard_id - }) - logger.debug(f"Fetched: {dashboard_id} from {app_id}") - except Exception as e: - logger.error(f"Error processing dashboard entry: {str(e)}") - - logger.info(f"Found {len([d for d in dashboard_contents if d['app'] == app_id])} dashboards in {app_id}") - else: - logger.warning(f"No dashboards found in app {app_id}") - - except urllib.error.HTTPError as e: - logger.error(f"HTTP {e.code} when fetching app {app_id}: {e.reason}") - except urllib.error.URLError as e: - logger.error(f"Cannot reach Splunk API for app {app_id}: {e.reason}") - except Exception as e: - logger.error(f"Error fetching dashboards from {app_id}: {str(e)}") - - logger.info(f"Successfully fetched {len(dashboard_contents)} dashboards total") - return dashboard_contents - - -def start_server(port=9999): - """Démarrer le serveur HTTP""" - server = HTTPServer(('0.0.0.0', port), GitPusherRequestHandler) - logger.info(f"Git Pusher server listening on 0.0.0.0:{port} (HTTP)") - server.serve_forever() - - -if __name__ == '__main__': - # Démarrer le serveur en background - port = 9999 - logger.info(f"Starting Git Pusher on port {port}") - start_server(port) \ No newline at end of file diff --git a/apps/pusher_app_prem/bin/start_git_pusher.sh b/apps/pusher_app_prem/bin/start_git_pusher.sh deleted file mode 100755 index 951e1a0e..00000000 --- a/apps/pusher_app_prem/bin/start_git_pusher.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -export SPLUNK_USERNAME=admin -export SPLUNK_PASSWORD='2312Jocpam!?' -python3 /opt/splunk/etc/apps/pusher_app/bin/git_pusher.py > /opt/splunk/var/log/splunk/git_pusher_startup.log 2>&1 & -echo $! > /opt/splunk/etc/apps/pusher_app/bin/git_pusher.pid \ No newline at end of file diff --git a/apps/pusher_app_prem/certs/server.crt b/apps/pusher_app_prem/certs/server.crt deleted file mode 100755 index 11fa39a7..00000000 --- a/apps/pusher_app_prem/certs/server.crt +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDCTCCAfGgAwIBAgIUCuKo8SLloS5cjBOR04+X6ayZ40cwDQYJKoZIhvcNAQEL -BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDEyMzIyMTIxOFoXDTI3MDEy -MzIyMTIxOFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAs0vF6sFTseKgZC1nZ6CVZdw45yk1Ni0W9Mc24KZ9NKCJ -rP0tHy0hs6mME/sq8DV1fh0YtqIvBCxcKEE84/cVXmUfZF9JRXO95734+JGPmo07 -zpiu7p3r4WyIWmCXX5VB0UkMEXsPQmonqG1Kwtz+R1cfgis2lUk+xsC2zSjER8l4 -2UODjHvtD25usgxKjpwPrCuZt43miArnVnwfB8OLbAqpwQeYIf18bPt/TrnQsdgd -ZZiQdE6UTaJ5xhqztwpYJO9pvZA24Bi3bGNfBciITds5RCGY2wQo8yxbeJsidTuW -7Z64DK9t33oVnB2PqlP6hVGD5Agthsv9ehRPxdd3MwIDAQABo1MwUTAdBgNVHQ4E -FgQUy0dni+ogqC7YuvfD/Pn0AuebsXQwHwYDVR0jBBgwFoAUy0dni+ogqC7YuvfD -/Pn0AuebsXQwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAlyxg -vR15lsYp4TxJPi1WPzLZl1e6ewTl8GhyE1saxS8LRtyTyr8sa9EFRLQ0OIsqYrUw -zZi7FIDoDPZDKpd0/+U94UKlhUuPUyufQwl5vNu0A+SEpwKeznUMaj4Y98tHvVGd -1SCndZBWn/v2U4nXqHoTd6Y0xEOga0jUEsUMBckNC236BTo88Zk65/oa9Gncyb27 -9vGVCbmPyzE70H4KFoVtxkoZrKywn+0ajHhgH5gqZNRPWpe6i8xTbMAeIXkCjmWL -LmOA7MkjeQBBEWewu4vMOXsvf+gCtxUj5owsAcOQlZ3g72Sng4MeMjuVx4ZRVxX9 -fj+vCP9EFI8rX48tjQ== ------END CERTIFICATE----- diff --git a/apps/pusher_app_prem/certs/server.key b/apps/pusher_app_prem/certs/server.key deleted file mode 100755 index 8b790585..00000000 --- a/apps/pusher_app_prem/certs/server.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQCzS8XqwVOx4qBk -LWdnoJVl3DjnKTU2LRb0xzbgpn00oIms/S0fLSGzqYwT+yrwNXV+HRi2oi8ELFwo -QTzj9xVeZR9kX0lFc73nvfj4kY+ajTvOmK7unevhbIhaYJdflUHRSQwRew9Caieo -bUrC3P5HVx+CKzaVST7GwLbNKMRHyXjZQ4OMe+0Pbm6yDEqOnA+sK5m3jeaICudW -fB8Hw4tsCqnBB5gh/Xxs+39OudCx2B1lmJB0TpRNonnGGrO3Clgk72m9kDbgGLds -Y18FyIhN2zlEIZjbBCjzLFt4myJ1O5btnrgMr23fehWcHY+qU/qFUYPkCC2Gy/16 -FE/F13czAgMBAAECggEAMrEMrvej0xpQ4KHZp3nGY3sk9242JjAPWntsb42CvrtY -0XjvJe5bpfEcspWDqVBj/Jj7YL9v7Y0hLRxsu8Mi3oJWoskx7RnxKjES0CxPXpHp -w9p1Mu+hPiWyU2MVySdo6WPuro6NXOiod70WswtKNR9TwDi5gPGpdwYLaOvKusSp -Rncm0m0H3IBhgVA691X0AUIomAW3Wmh+5If1XHfjrNHTB8cjcNf6koPMkCqHCEZ9 -wtINxOJior+gGkjMXaDszqzNlicVBXFEFjaXWcp38xAif1uimpqKsRzZEF6RAUzi -H7cI3aF2dXG3C9l6Byi7OSgd8X4JUnE0dlCpC7qweQKBgQDgvoavo8G0kYruCUIQ -6vcSs1YBByOkl6yZBCZWk10NgRpU1wyu9zmlvEwNVlUfALs5eoLxnhe8Wklq0ckQ -r/Rl+r/lj/MZUFn49TgUCsUOIi/G7nWQG0bPo4bCB2QXsAiKdY+KZeC56620uyom -1VY+nS3y8O4EP0YHX0qHFfmIZwKBgQDMOywO0DSrZMDyvmbwL0ISzHRcNpRn0jk7 -pEtzM/VOx+v0O93E+5OygzmXlBKjF0MwMXBidf8IZu4xO8qWqAM4EP2DD0cpoS1Z -WiHHkc5NZhjgeG6C4XaCXR++7CuY25VKKe01yz/+j51linDD8OAibKUspkjVufEN -R/AT0GFLVQKBgBxMYTEkcXOHD/NA/yyaKVoVcrLWb0p+PqFVwG4OSB03MFWWbmZp -gry3pOvY/wbUVL68CljaCysQQ0ZL/AE55pAgrqD9KyL41xtd5R3A7WcGLvXheLQY -eyYR9RnhTF0fMTQd8WD/yvgeENU86+XP3vgrWmnIpG+sd+jdusifn7fpAn9QkwfO -0FX3SMjW/EegewSWZhOCTgY+77Gk1izuRpGBg16T/QqBrL+Yri0KoGC593OKj/bG -4ca8id9vjSdgSOj8NbfO/TgWNICvv9+T3PKHlsA5z0nKWSloRVVA/ew1YmyD1gbA -MnAM/pwac4QJyf6jljmUZAZYTAPOOZN+PbglAoGBAJ9cOGDgT+BCOoNc0T1GJDAk -xOR8d+tD+j4JH5IVxB51DXjJOZxw9U3XhNH1OcE0x3fRzKJOtlQLxP6fHYVtMVFq -VpeekmTtJ9OfMg68ELOlf7ykA3GhMJ3FarM6e8+X+KliGf6ND4HBMb112FlMgIi6 -yYi7sfSL53Dzp1Q2DxXV ------END PRIVATE KEY----- diff --git a/apps/pusher_app_prem/default/app.conf b/apps/pusher_app_prem/default/app.conf deleted file mode 100755 index a01a048d..00000000 --- a/apps/pusher_app_prem/default/app.conf +++ /dev/null @@ -1,16 +0,0 @@ -# -# Splunk app configuration file -# - -[install] -is_configured = 0 - -[ui] -is_visible = true -label = Pusher Premium - -[launcher] -author = -description = -version = 1.0.0 - diff --git a/apps/pusher_app_prem/default/data/ui/nav/default.xml b/apps/pusher_app_prem/default/data/ui/nav/default.xml deleted file mode 100755 index 8e98eadb..00000000 --- a/apps/pusher_app_prem/default/data/ui/nav/default.xml +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/apps/pusher_app_prem/default/data/ui/views/README b/apps/pusher_app_prem/default/data/ui/views/README deleted file mode 100755 index 6cf74f0b..00000000 --- a/apps/pusher_app_prem/default/data/ui/views/README +++ /dev/null @@ -1 +0,0 @@ -Add all the views that your app needs in this directory diff --git a/apps/pusher_app_prem/local/app.conf b/apps/pusher_app_prem/local/app.conf deleted file mode 100755 index 78666a91..00000000 --- a/apps/pusher_app_prem/local/app.conf +++ /dev/null @@ -1,3 +0,0 @@ -[ui] - -[launcher] diff --git a/apps/pusher_app_prem/local/data/ui/views/git_pusher_-_deploy_applications.xml b/apps/pusher_app_prem/local/data/ui/views/git_pusher_-_deploy_applications.xml deleted file mode 100644 index 15b0b86d..00000000 --- a/apps/pusher_app_prem/local/data/ui/views/git_pusher_-_deploy_applications.xml +++ /dev/null @@ -1,484 +0,0 @@ - - - - Modern interface to push Splunk applications to Git repository - - - | rest /services/apps/local | search disabled=0 | fields name, label, description | sort label - -4h@h - now - - - - - - - -
-

🚀 Git Pusher

-

Deploy your Splunk applications to Git with confidence

-
- -
-
- ✨ Configure your Git settings below and select the applications you want to deploy to your repository -
- -
- -
-
⚙️ Configuration
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
-
- - -
-
📦 Applications
- -
-
-
-

Loading applications...

-
-
-
-
- -
-
-
Deploying applications to Git... Please wait
-
- -
- ✅ Applications successfully deployed to Git! -
- -
- ❌ Error occurred while deploying applications -
- - -
- -
-
- -
\ No newline at end of file diff --git a/apps/pusher_app_prem/local/data/ui/views/git_pusher_-_push_applications_to_git.xml b/apps/pusher_app_prem/local/data/ui/views/git_pusher_-_push_applications_to_git.xml deleted file mode 100644 index eca8b17e..00000000 --- a/apps/pusher_app_prem/local/data/ui/views/git_pusher_-_push_applications_to_git.xml +++ /dev/null @@ -1,256 +0,0 @@ - - - - Push Splunk applications to Git repository - - - | rest /services/apps/local | search disabled=0 | fields name, label, description | sort label - -4h@h - now - - - - Configuration & Application Selection - - - -
-
- ℹ️ Configure your Git settings and select the applications you want to push to your repository. -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- -
-
-
- Loading applications... -
-
- Select one or more applications to push -
- -
- - -
- -
- - -
- -
-
- Pushing dashboards to Git... -
- -
- ✓ Dashboards successfully pushed to Git! -
- -
- ✗ Error occurred while pushing dashboards -
-
- - - - - - - Push History - - - index=_internal source=*git_pusher* action=push_attempt | table _time, user, dashboards, commit_message, status, error_msg | reverse | rename _time as "Timestamp", user as "User", dashboards as "Dashboards", commit_message as "Message", status as "Status", error_msg as "Error" | head 20 - -30d@d - now - - - - {"success": "#28a745", "error": "#dc3545", "pending": "#ffc107"} - -
-
-
- - \ No newline at end of file diff --git a/apps/pusher_app_prem/metadata/default.meta b/apps/pusher_app_prem/metadata/default.meta deleted file mode 100755 index b77b8cb9..00000000 --- a/apps/pusher_app_prem/metadata/default.meta +++ /dev/null @@ -1,35 +0,0 @@ - -# Application-level permissions - -[] -access = read : [ * ], write : [ admin, power ] - -### EVENT TYPES - -[eventtypes] -export = system - - -### PROPS - -[props] -export = system - - -### TRANSFORMS - -[transforms] -export = system - - -### LOOKUPS - -[lookups] -export = system - - -### VIEWSTATES: even normal users should be able to create shared viewstates - -[viewstates] -access = read : [ * ], write : [ * ] -export = system diff --git a/apps/pusher_app_prem/metadata/local.meta b/apps/pusher_app_prem/metadata/local.meta deleted file mode 100644 index a2a6d1a5..00000000 --- a/apps/pusher_app_prem/metadata/local.meta +++ /dev/null @@ -1,26 +0,0 @@ -[app/ui] -version = 10.0.2 -modtime = 1769115948.043388000 - -[app/launcher] -version = 10.0.2 -modtime = 1769115948.046389000 - -[views/git_pusher_-_push_dashboards_to_git] -access = read : [ admin ], write : [ admin ] -export = system -owner = admin -version = 10.0.2 -modtime = 1769276443.812957000 - -[views/git_pusher_-_push_applications_to_git] -owner = admin -version = 10.0.2 -modtime = 1769361925.808816000 - -[views/git_pusher_-_deploy_applications] -access = read : [ * ], write : [ * ] -export = none -owner = admin -version = 10.0.2 -modtime = 1769368785.414181000