Show services discovered by site agents as suggested targets
Stores the sanitised list per site, serves it at /sites/{id}/discovered and adds
it to the target picker. Needs a Reef release containing model.DiscoveredService.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
39659f0144
commit
7e429a7be0
6 files changed
+90
-7
No files matched your search
+5
-4
@@ -788,21 +788,22 @@ function portForm(existing) {
|
||||
const th = h('input', {value:t.host, oninput:e => t.host = e.target.value, placeholder:'127.0.0.1 or 192.168.1.20'});
|
||||
const tp = h('input', {type:'number', value:t.port, placeholder:'port', oninput:e => t.port = +e.target.value});
|
||||
return h('div', {class:'tgt'}, field(i ? 'Target ' + (i + 1) : 'Target site', site), field('Host', th), field('Port', tp),
|
||||
h('button', {class:'ghost', type:'button', title:'Pick a Docker container on that site', onclick:() => discover(t, th, tp)}, 'Containers'),
|
||||
h('button', {class:'ghost', type:'button', title:'Pick a Docker container or discovered service on that site', onclick:() => discover(t, th, tp)}, 'Containers'),
|
||||
targets.length > 1 ? h('button', {class:'ghost danger', type:'button', 'aria-label':'Remove target', onclick:() => { targets.splice(i, 1); drawTargets(); }}, icon('close', 16)) : h('span'));
|
||||
}), many ? h('button', {class:'ghost', type:'button', style:'align-self:flex-start', title:'Spread visitors across targets, or fail over when one is down', onclick:() => { targets.push({siteId:targets[0] ? targets[0].siteId : '', host:'127.0.0.1', port:''}); drawTargets(); }}, icon('add', 16), 'Add another target') : null);
|
||||
};
|
||||
const discover = act(async (t, th, tp) => {
|
||||
if (!t.siteId) throw new Error('Choose a site first');
|
||||
const list = await api('GET', O(`/sites/${t.siteId}/containers`));
|
||||
if (!list.length) throw new Error('No containers reported. Run the agent with --docker (and make sure Docker is running).');
|
||||
const [list, found] = await Promise.all([api('GET', O(`/sites/${t.siteId}/containers`)), api('GET', O(`/sites/${t.siteId}/discovered`))]);
|
||||
if (!list.length && !found.length) throw new Error('Nothing reported. Run the agent with --docker for containers, or --discover (optionally --discover-subnets) for services on the network.');
|
||||
const opts = [];
|
||||
for (const d of found) opts.push({label:`${d.service || 'tcp'} ${d.host}:${d.port}${d.detail ? ' ' + d.detail : ''} (${d.source === 'local' ? 'listening here' : 'found by scan'})`, host:d.host, port:d.port});
|
||||
for (const c of list) for (const p of c.ports) {
|
||||
if (p.public) opts.push({label:`${c.name} 127.0.0.1:${p.public} (published)`, host:'127.0.0.1', port:p.public});
|
||||
for (const [n, ip] of Object.entries(c.networks)) opts.push({label:`${c.name} ${ip}:${p.private} (${n} network)`, host:ip, port:p.private});
|
||||
}
|
||||
const sel = h('select', {size:Math.min(12, opts.length + 1)}, opts.map((o, i) => h('option', {value:i}, o.label)));
|
||||
const close = modal('Pick a container', h('div', {class:'stack'}, sel, h('button', {class:'btn', onclick:() => { const o = opts[sel.value]; if (!o) return; t.host = th.value = o.host; t.port = o.port; tp.value = o.port; close(); }}, 'Use this')));
|
||||
const close = modal('Pick a container or discovered service', h('div', {class:'stack'}, sel, h('button', {class:'btn', onclick:() => { const o = opts[sel.value]; if (!o) return; t.host = th.value = o.host; t.port = o.port; tp.value = o.port; close(); }}, 'Use this')));
|
||||
});
|
||||
const drawRules = () => ruleBox.replaceChildren(...rules.map((r, i) => h('div', {class:'grid', style:'grid-template-columns:110px 110px 1fr auto'},
|
||||
h('select', {onchange:e => r.action = e.target.value}, ['allow', 'deny'].map(v => h('option', {value:v, selected:r.action === v}, v === 'allow' ? 'Skip login' : 'Block'))),
|
||||
|
||||
Reference in new issue
Block a user