Newer
Older
EnvoyControlPlane / static / index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Envoy Configuration Dashboard</title>
    <link rel="stylesheet" href="style.css">
    <script src="https://cdn.jsdelivr.net/npm/js-yaml@4.1.0/dist/js-yaml.min.js"></script>
</head>
<body>

    <div class="container">
        <h1>Envoy Configuration Dashboard ⚙️</h1>

        <div id="consistency-status-container">
            <button id="consistency-button" 
                    class="status-indicator-button" 
                    title="System Consistency Status"
                    onclick="showConsistencyModal()"
                    disabled>
                Loading...
            </button>
        </div>

        <div class="toolbar">
            <button onclick="listClusters()">🔁 Reload Clusters</button>
            <button onclick="listListeners()">🔁 Reload Listeners</button>
            <button onclick="loadAllData()">Refresh All Data 🌐</button>
            <button onclick="window.showAddListenerModal()">Add New Listener</button> 
            </div>

        <h2>Existing Clusters (Click a row for full JSON)</h2>
        <table id="clusterTable" class="config-table">
            <thead>
                <tr>
                    <th>Cluster Name</th>
                    <th>Status</th>
                    <th>Primary Endpoint</th>
                    <th>Connect Timeout</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody id="cluster-table-body">
                <tr><td colspan="4" style="text-align: center;">Loading cluster data...</td></tr> 
            </tbody>
        </table>

        <h2>Existing Listeners (Click a domain/filter for details)</h2>
        <table id="listenerTable" class="config-table">
            <thead>
                <tr>
                    <th>Listener Name</th>
                    <th>Status</th>
                    <th>Address:Port</th>
                    <th>Domains / Filters</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody id="listener-table-body">
                <tr><td colspan="4" style="text-align: center;">Loading listener data...</td></tr>
            </tbody>
        </table>
    </div>

<div id="configModal" class="modal">
    <div class="modal-content">
    <span class="close" onclick="hideModal()">&times;</span>
    <h2 id="modal-title"></h2>

    <div class="tab-controls">
        <button class="tab-button active" data-tab="json">JSON</button>
        <button class="tab-button" data-tab="yaml">YAML</button>
        <button id="download-yaml-btn" class="tab-button download-button" onclick="downloadYaml()">
            ⬇️ Download YAML
        </button>
    </div>

    <div class="tab-content">
        <pre id="modal-json-content" class="code-block"></pre>
        <pre id="modal-yaml-content" class="code-block" style="display: none;"></pre>
    </div>
</div>
</div>

    <div id="consistencyModal" class="modal" onclick="hideConsistencyModal()">
        <div class="modal-content" onclick="event.stopPropagation()">
            <div class="modal-header">
                <h3>⚠️ Consistency Conflict Detected</h3>
                <span class="close-btn" onclick="hideConsistencyModal()">&times;</span>
            </div>
            
            <p>The in-memory cache and the persistent database are out of sync. Please choose a resolution strategy.</p>

            <h4>Inconsistency Details:</h4>
            <div id="inconsistency-details-content">
                <p><strong>Cache-Only Resources (DB Missing):</strong> <span id="cache-only-count">0</span></p>
                <pre id="cache-only-data" class="conflict-list"></pre>
                
                <p><strong>DB-Only Resources (Cache Missing):</strong> <span id="db-only-count">0</span></p>
                <pre id="db-only-data" class="conflict-list"></pre>
            </div>

            <div class="modal-actions">
                <button class="action-button enable" onclick="resolveConsistency('flush')">
                    Flush (Cache &rarr; DB)
                    <br> <small>Override DB with Cache (Risk of DB data loss)</small>
                </button>
                <button class="action-button disable" onclick="resolveConsistency('rollback')">
                    Rollback (DB &rarr; Cache)
                    <br> <small>Override Cache with DB (Risk of in-memory data loss)</small>
                </button>
            </div>
        </div>
    </div>

  <div id="addFilterChainModal" class="modal">
        <div class="modal-content">
            <div class="modal-header">
                <h3 id="add-fc-modal-title">Add New Filter Chain</h3>
                <span class="close-btn" onclick="hideAddFilterChainModal()">&times;</span>
            </div>

            <p>Paste the YAML configuration for the new filter chain below and submit.</p>

            <form id="add-filter-chain-form">
                <input type="hidden" id="add-fc-listener-name" value="">
                
                <label for="add-fc-yaml-input">Filter Chain YAML:</label>
                <textarea id="add-fc-yaml-input" rows="15" placeholder="Paste YAML here..."></textarea>
                
                <div class="modal-actions">
                    <button type="button" class="action-button add" onclick="submitNewFilterChain()">
                        Submit Filter Chain
                    </button>
                    <button type="button" class="action-button disable" onclick="hideAddFilterChainModal()">
                        Cancel
                    </button>
                </div>
            </form>
        </div>
    </div>

    <div id="addListenerModal" class="modal">
        <div class="modal-content">
            <div class="modal-header">
                <h3>Add New Listener</h3>
                <span class="close-btn" onclick="hideAddListenerModal()">&times;</span>
            </div>

            <p>Paste the full YAML configuration for the new listener below and submit.</p>

            <form id="add-listener-form">
                <label for="add-listener-yaml-input">Listener YAML:</label>
                <textarea id="add-listener-yaml-input" rows="20" placeholder="Paste full listener YAML here..."></textarea>
                
                <div class="modal-actions">
                    <button type="button" class="action-button add" onclick="submitNewListener()">
                        Submit Listener
                    </button>
                    <button type="button" class="action-button disable" onclick="hideAddListenerModal()">
                        Cancel
                    </button>
                </div>
            </form>
        </div>
    </div>

    <script type="module" src="global.js"></script> 
    <script type="module" src="modals.js"></script>
    <script type="module" src="data_fetchers.js"></script>
    <script type="module" src="clusters.js"></script>
    <script type="module" src="listeners.js"></script>
    <script type="module" src="consistency.js"></script>
    <script type="module" src="data_loader.js"></script>
</body>
</html>