Add live Disable Telnet action to Web Access Control

Adds a standalone DISABLE TELNET button (no enable counterpart, per
requirement) alongside the existing HTTPS enable/disable toggle. Reuses
the same target/concurrency controls and SSH push flow, backed by a new
"disable_telnet" action mapped to "no ip telnet" on the switch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CLfUJoQTaUePx1m1d2v2j9
This commit is contained in:
2026-08-18 11:28:23 -05:00
parent 7233386d36
commit ac13c913e3
2 changed files with 21 additions and 6 deletions
+9 -3
View File
@@ -89,16 +89,22 @@ def api_web_access():
ip = data.get("ip", "").strip() ip = data.get("ip", "").strip()
username = data.get("username", "").strip() username = data.get("username", "").strip()
password = data.get("password", "").strip() password = data.get("password", "").strip()
action = data.get("action", "") # "enable" or "disable" action = data.get("action", "") # "enable", "disable", or "disable_telnet"
commands = {
"enable": "ip http secure-server",
"disable": "no ip http secure-server",
"disable_telnet": "no ip telnet",
}
if not ip or not username or not password: if not ip or not username or not password:
return jsonify({"ok": False, "error": "Missing IP or credentials"}), 400 return jsonify({"ok": False, "error": "Missing IP or credentials"}), 400
if action not in ("enable", "disable"): if action not in commands:
return jsonify({"ok": False, "error": "Invalid action"}), 400 return jsonify({"ok": False, "error": "Invalid action"}), 400
print(f"[web-access] {action} {ip} user={username!r} pass_len={len(password)}", flush=True) print(f"[web-access] {action} {ip} user={username!r} pass_len={len(password)}", flush=True)
cmd = "ip http secure-server" if action == "enable" else "no ip http secure-server" cmd = commands[action]
try: try:
sock = socket.create_connection((ip, 22), timeout=10) sock = socket.create_connection((ip, 22), timeout=10)
+12 -3
View File
@@ -646,6 +646,11 @@
<button class="btn-wa btn-wa-enable" id="btn-wa-enable" disabled>ENABLE</button> <button class="btn-wa btn-wa-enable" id="btn-wa-enable" disabled>ENABLE</button>
<button class="btn-wa btn-wa-disable" id="btn-wa-disable" disabled>DISABLE</button> <button class="btn-wa btn-wa-disable" id="btn-wa-disable" disabled>DISABLE</button>
</div> </div>
<div class="setting-label" style="margin:14px 0 5px">Telnet Access</div>
<div class="wa-btn-row" style="grid-template-columns: 1fr">
<button class="btn-wa btn-wa-disable" id="btn-wa-disable-telnet" disabled>DISABLE TELNET</button>
</div>
</div> </div>
<!-- Settings accordion --> <!-- Settings accordion -->
@@ -1253,6 +1258,7 @@ const waConcurrency = document.getElementById('wa-concurrency');
const waConcurVal = document.getElementById('wa-concurrency-val'); const waConcurVal = document.getElementById('wa-concurrency-val');
const btnWaEnable = document.getElementById('btn-wa-enable'); const btnWaEnable = document.getElementById('btn-wa-enable');
const btnWaDisable = document.getElementById('btn-wa-disable'); const btnWaDisable = document.getElementById('btn-wa-disable');
const btnWaDisableTelnet = document.getElementById('btn-wa-disable-telnet');
waConcurrency.addEventListener('input', () => { waConcurrency.addEventListener('input', () => {
waConcurVal.textContent = waConcurrency.value; waConcurVal.textContent = waConcurrency.value;
@@ -1267,6 +1273,7 @@ function updateWaButtons() {
const enabled = (target === 'selected') ? hasSelected : hasAny; const enabled = (target === 'selected') ? hasSelected : hasAny;
btnWaEnable.disabled = !enabled; btnWaEnable.disabled = !enabled;
btnWaDisable.disabled = !enabled; btnWaDisable.disabled = !enabled;
btnWaDisableTelnet.disabled = !enabled;
} }
function getWaTargetSwitches() { function getWaTargetSwitches() {
@@ -1332,8 +1339,8 @@ function showWaResults(action, targetList) {
document.getElementById('wa-results-panel').classList.add('active'); document.getElementById('wa-results-panel').classList.add('active');
const badge = document.getElementById('wa-action-badge'); const badge = document.getElementById('wa-action-badge');
badge.textContent = action.toUpperCase(); badge.textContent = action.replace('_', ' ').toUpperCase();
badge.className = 'wa-action-badge ' + action; badge.className = 'wa-action-badge ' + (action === 'enable' ? 'enable' : 'disable');
const body = document.getElementById('wa-results-body'); const body = document.getElementById('wa-results-body');
body.innerHTML = ''; body.innerHTML = '';
@@ -1366,6 +1373,7 @@ async function runWaOperation(action) {
btnWaEnable.disabled = true; btnWaEnable.disabled = true;
btnWaDisable.disabled = true; btnWaDisable.disabled = true;
btnWaDisableTelnet.disabled = true;
const rows = showWaResults(action, targetList); const rows = showWaResults(action, targetList);
let done = 0; let done = 0;
@@ -1400,12 +1408,13 @@ async function runWaOperation(action) {
} }
); );
showToast(`Web access ${action} complete — ${targetList.length} switches`, 'ok'); showToast(`Web access ${action.replace('_', ' ')} complete — ${targetList.length} switches`, 'ok');
updateWaButtons(); updateWaButtons();
} }
btnWaEnable.addEventListener('click', () => runWaOperation('enable')); btnWaEnable.addEventListener('click', () => runWaOperation('enable'));
btnWaDisable.addEventListener('click', () => runWaOperation('disable')); btnWaDisable.addEventListener('click', () => runWaOperation('disable'));
btnWaDisableTelnet.addEventListener('click', () => runWaOperation('disable_telnet'));
</script> </script>
</body> </body>
</html> </html>