Files
luci-app-dockerman/htdocs/luci-static/resources/view/dockerman/network.js
T
2026-02-21 22:33:23 +08:00

166 lines
5.1 KiB
JavaScript

'use strict';
'require form';
'require fs';
'require ui';
'require dockerman.common as dm2';
/*
Copyright 2026
Docker manager JS for Luci by Paul Donald <newtwen+github@gmail.com>
Based on Docker Lua by lisaac <https://github.com/lisaac/luci-app-dockerman>
LICENSE: GPLv2.0
*/
return dm2.dv.extend({
load() {
const requestPath = L.env.requestpath;
const netId = requestPath[requestPath.length-1] || '';
this.networkId = netId;
return Promise.all([
dm2.network_inspect({ id: netId }),
dm2.container_list({query: {all: true}}),
]);
},
render([network, containers]) {
if (network?.code !== 200) {
window.location.href = `${this.dockerman_url}/networks`;
return;
}
const view = this;
const this_network = network.body || {};
const container_list = Array.isArray(containers.body) ? containers.body : [];
const m = new form.JSONMap({
network: this_network,
Driver: this_network?.IPAM?.Driver,
Config: this_network?.IPAM?.Config,
Containers: Object.entries(this_network?.Containers || {}).map(([id, info]) => ({ id, ...info })),
_inspect: {},
},
_('Docker - Networks'),
_('This page displays all docker networks that have been created on the connected docker host.'));
m.submit = false;
m.reset = false;
let s = m.section(form.NamedSection, 'network', _('Networks overview'));
s.anonymous = true;
s.addremove = false;
s.nodescriptions = true;
let o, ss;
// INFO TAB
s.tab('info', _('Info'));
o = s.taboption('info', form.DummyValue, 'Name', _('Network Name'));
o = s.taboption('info', form.DummyValue, 'Id', _('ID'));
o = s.taboption('info', form.DummyValue, 'Created', _('Created'));
o = s.taboption('info', form.DummyValue, 'Scope', _('Scope'));
o = s.taboption('info', form.DummyValue, 'Driver', _('Driver'));
o = s.taboption('info', form.Flag, 'EnableIPv6', _('IPv6'));
o.readonly = true;
o = s.taboption('info', form.Flag, 'Internal', _('Internal'));
o.readonly = true;
o = s.taboption('info', form.Flag, 'Attachable', _('Attachable'));
o.readonly = true;
o = s.taboption('info', form.Flag, 'Ingress', _('Ingress'));
o.readonly = true;
o = s.taboption('info', form.DummyValue, 'ConfigFrom', _('ConfigFrom'));
o.cfgvalue = view.objectCfgValueTT;
o = s.taboption('info', form.Flag, 'ConfigOnly', _('Config Only'));
o.readonly = true;
o.cfgvalue = view.objectCfgValueTT;
o = s.taboption('info', form.DummyValue, 'Containers', _('Containers'));
o.load = function(sid) {
return view.parseContainerLinksForNetwork(this_network, container_list);
};
o = s.taboption('info', form.DummyValue, 'Options', _('Options'));
o.cfgvalue = view.objectCfgValueTT;
o = s.taboption('info', form.DummyValue, 'Labels', _('Labels'));
o.cfgvalue = view.objectCfgValueTT;
// CONFIGS TAB
s.tab('detail', _('Detail'));
o = s.taboption('detail', form.DummyValue, 'Driver', _('IPAM Driver'));
o = s.taboption('detail', form.SectionValue, '_conf_', form.TableSection, 'Config', _('Network Configurations'));
ss = o.subsection;
ss.anonymous = true;
ss.option(form.DummyValue, 'Subnet', _('Subnet'));
ss.option(form.DummyValue, 'Gateway', _('Gateway'));
o = s.taboption('detail', form.SectionValue, '_cont_', form.TableSection, 'Containers', _('Containers'));
ss = o.subsection;
ss.anonymous = true;
o = ss.option(form.DummyValue, 'Name', _('Name'));
o.cfgvalue = function(sid) {
const val = this.data?.[sid] ?? this.map.data.get(this.map.config, sid, this.option);
const containerId = container_list.find(c => c.Names.find(e => e.substring(1) === val)).Id;
return E('a', {
href: `${view.dockerman_url}/container/${containerId}`,
title: containerId,
style: 'white-space: nowrap;'
}, [val]);
};
ss.option(form.DummyValue, 'MacAddress', _('Mac Address'));
ss.option(form.DummyValue, 'IPv4Address', _('IPv4 Address'));
// Show IPv6 column when at least one entry contains a non-empty IPv6Address
const _networkContainers = Object.values(this_network?.Containers || {});
const _hasIPv6 = _networkContainers.some(c => c?.IPv6Address && String(c.IPv6Address).trim() !== '');
if (_hasIPv6) {
ss.option(form.DummyValue, 'IPv6Address', _('IPv6 Address'));
}
// INSPECT TAB
s.tab('inspect', _('Inspect'));
o = s.taboption('inspect', form.SectionValue, '__ins__', form.NamedSection, '_inspect', null);
ss = o.subsection;
ss.anonymous = true;
ss.nodescriptions = true;
o = ss.option(form.Button, '_inspect_button', null);
o.inputtitle = `${dm2.ActionTypes['inspect'].i18n} ${dm2.ActionTypes['inspect'].e}`;
o.inputstyle = 'neutral';
o.onclick = L.bind(function(section_id, ev) {
return dm2.network_inspect({ id: this_network.Id }).then((response) => {
const inspectField = document.getElementById('inspect-output-text');
if (inspectField && response?.body) {
inspectField.textContent = JSON.stringify(response.body, null, 2);
}
});
}, this);
o = s.taboption('inspect', form.SectionValue, '__insoutput__', form.NamedSection, null, null);
o.render = L.bind(() => {
return this.insertOutputFrame(null, null);
}, this);
return m.render();
},
handleSave: null,
handleSaveApply: null,
handleReset: null,
});