<?php if (!defined('DASHBOARD_ROOT')) { http_response_code(403); exit; } $nodes = Database::fetchAll("SELECT id,node_id,hostname,wg_ip,role_code,ssh_port,status_code FROM nodes ORDER BY hostname"); ?> <div id="fleet-provision" class="editor-form"> <span class="section-label">Node Provisioning</span> <div id="provision-new" class="panel"> <span class="section-label">Register New Node</span> <div class="form-group"><span>Node ID</span><input id="prov-nodeid" class="form-group input" type="text" placeholder="e.g. backup-01"></div> <div class="form-group"><span>Hostname</span><input id="prov-hostname" class="form-group input" type="text" placeholder="e.g. backup"></div> <div class="form-group"><span>WireGuard IP</span><input id="prov-wgip" class="form-group input" type="text" placeholder="e.g. 10.69.0.8"></div> <div class="form-group"><span>Role</span> <select id="prov-role" class="form-group input"> <option value="5050">Shield</option><option value="5051">Proxy</option> <option value="5052">Filter</option><option value="5053">DNS</option> <option value="5054">Origin</option><option value="5055">Payment</option> <option value="5056">Email</option> </select> </div> <div class="form-group"><span>SSH Port</span><input id="prov-ssh" class="form-group input" type="number" value="33022"></div> <div class="form-actions"><a id="prov-submit" class="btn btn-primary" href="javascript:void(0)"><span>Provision Node</span></a></div> </div> <div id="provision-existing" class="panel"> <span class="section-label">Existing Nodes</span><?php foreach ($nodes as $n): ?> <div class="event-row"> <span><?= UI::e($n['hostname']) ?> (<?= UI::e($n['wg_ip']) ?> )</span> <span><?= StatusCode::render((int)$n['status_code']) ?> </span><?php if ((int)$n['status_code'] !== 5004): ?> <a class="btn btn-danger btn-sm decom-btn" href="javascript:void(0)" data-id="<?= (int)$n['id'] ?> "><span>Decommission</span></a><?php endif; ?> </div><?php endforeach; ?> </div> </div> <script nonce="<?= $cspNonce ?? '' ?> "> document.getElementById('prov-submit').addEventListener('click',function(){ window.dashFetch('license',{action:'provision','data[node_id]':document.getElementById('prov-nodeid').value,'data[hostname]':document.getElementById('prov-hostname').value,'data[wg_ip]':document.getElementById('prov-wgip').value,'data[role_code]':document.getElementById('prov-role').value,'data[ssh_port]':document.getElementById('prov-ssh').value},function(r){if(r.ok){alert('Provisioned.');location.reload();}else{alert(r.error||'Failed');}}); }); document.querySelectorAll('.decom-btn').forEach(function(b){b.addEventListener('click',function(){if(!confirm('Decommission this node?'))return;window.dashFetch('license',{action:'decommission',node_id:b.dataset.id},function(r){if(r.ok)location.reload();else alert(r.error);});});}); </script>