diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 48594bd..4e37380 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -2,6 +2,7 @@ project_name: emissary before: hooks: - go mod tidy + - go generate ./... builds: - id: emissary-server env: diff --git a/internal/spec/uci/schema.json b/internal/spec/uci/schema.json index fedb60b..7512dc1 100644 --- a/internal/spec/uci/schema.json +++ b/internal/spec/uci/schema.json @@ -67,13 +67,18 @@ "type": "string" }, "options": { - "type": "array", - "items": { - "$ref": "#/$defs/option" - } + "anyOf": [ + { + "type": ["array"], + "items": { + "$ref": "#/$defs/option" + } + }, + { "type": "null" } + ] } }, - "required": ["name", "section", "options"], + "required": ["name", "options"], "additionalProperties": false }, "option": { diff --git a/internal/spec/uci/testdata/spec-ok.json b/internal/spec/uci/testdata/spec-ok.json index 0b666ed..7128f76 100644 --- a/internal/spec/uci/testdata/spec-ok.json +++ b/internal/spec/uci/testdata/spec-ok.json @@ -3,6 +3,1475 @@ "data": { "config": { "packages": [ + { + "name": "dhcp", + "configs": [ + { + "name": "dnsmasq", + "options": [ + { + "type": "option", + "name": "domainneeded", + "value": "1" + }, + { + "type": "option", + "name": "boguspriv", + "value": "1" + }, + { + "type": "option", + "name": "filterwin2k", + "value": "0" + }, + { + "type": "option", + "name": "localise_queries", + "value": "1" + }, + { + "type": "option", + "name": "rebind_protection", + "value": "1" + }, + { + "type": "option", + "name": "rebind_localhost", + "value": "1" + }, + { + "type": "option", + "name": "local", + "value": "/lan/" + }, + { + "type": "option", + "name": "domain", + "value": "lan" + }, + { + "type": "option", + "name": "expandhosts", + "value": "1" + }, + { + "type": "option", + "name": "nonegcache", + "value": "0" + }, + { + "type": "option", + "name": "authoritative", + "value": "1" + }, + { + "type": "option", + "name": "readethers", + "value": "1" + }, + { + "type": "option", + "name": "leasefile", + "value": "/tmp/dhcp.leases" + }, + { + "type": "option", + "name": "resolvfile", + "value": "/tmp/resolv.conf.d/resolv.conf.auto" + }, + { + "type": "option", + "name": "nonwildcard", + "value": "1" + }, + { + "type": "option", + "name": "localservice", + "value": "1" + }, + { + "type": "option", + "name": "ednspacket_max", + "value": "1232" + } + ] + }, + { + "name": "dhcp", + "section": "lan", + "options": [ + { + "type": "option", + "name": "interface", + "value": "lan" + }, + { + "type": "option", + "name": "start", + "value": "100" + }, + { + "type": "option", + "name": "limit", + "value": "150" + }, + { + "type": "option", + "name": "leasetime", + "value": "12h" + }, + { + "type": "option", + "name": "dhcpv4", + "value": "server" + }, + { + "type": "option", + "name": "dhcpv6", + "value": "server" + }, + { + "type": "option", + "name": "ra", + "value": "server" + }, + { + "type": "option", + "name": "ra_slaac", + "value": "1" + }, + { + "type": "list", + "name": "ra_flags", + "value": "managed-config" + }, + { + "type": "list", + "name": "ra_flags", + "value": "other-config" + } + ] + }, + { + "name": "dhcp", + "section": "wan", + "options": [ + { + "type": "option", + "name": "interface", + "value": "wan" + }, + { + "type": "option", + "name": "ignore", + "value": "1" + } + ] + }, + { + "name": "odhcpd", + "section": "odhcpd", + "options": [ + { + "type": "option", + "name": "maindhcp", + "value": "0" + }, + { + "type": "option", + "name": "leasefile", + "value": "/tmp/hosts/odhcpd" + }, + { + "type": "option", + "name": "leasetrigger", + "value": "/usr/sbin/odhcpd-update" + }, + { + "type": "option", + "name": "loglevel", + "value": "4" + } + ] + } + ] + }, + { + "name": "dropbear", + "configs": [ + { + "name": "dropbear", + "options": [ + { + "type": "option", + "name": "PasswordAuth", + "value": "on" + }, + { + "type": "option", + "name": "RootPasswordAuth", + "value": "on" + }, + { + "type": "option", + "name": "Port", + "value": "22" + } + ] + } + ] + }, + { + "name": "emissary", + "configs": [ + { + "name": "main", + "section": "agent", + "options": [ + { + "type": "option", + "name": "server_url", + "value": "http://192.168.30.15:3000" + }, + { + "type": "option", + "name": "reconciliation_interval", + "value": "30" + } + ] + } + ] + }, + { + "name": "firewall", + "configs": [ + { + "name": "defaults", + "options": [ + { + "type": "option", + "name": "syn_flood", + "value": "1" + }, + { + "type": "option", + "name": "input", + "value": "ACCEPT" + }, + { + "type": "option", + "name": "output", + "value": "ACCEPT" + }, + { + "type": "option", + "name": "forward", + "value": "REJECT" + } + ] + }, + { + "name": "zone", + "options": [ + { + "type": "option", + "name": "name", + "value": "lan" + }, + { + "type": "list", + "name": "network", + "value": "lan" + }, + { + "type": "option", + "name": "input", + "value": "ACCEPT" + }, + { + "type": "option", + "name": "output", + "value": "ACCEPT" + }, + { + "type": "option", + "name": "forward", + "value": "ACCEPT" + } + ] + }, + { + "name": "zone", + "options": [ + { + "type": "option", + "name": "name", + "value": "wan" + }, + { + "type": "list", + "name": "network", + "value": "wan" + }, + { + "type": "list", + "name": "network", + "value": "wan6" + }, + { + "type": "option", + "name": "input", + "value": "REJECT" + }, + { + "type": "option", + "name": "output", + "value": "ACCEPT" + }, + { + "type": "option", + "name": "forward", + "value": "REJECT" + }, + { + "type": "option", + "name": "masq", + "value": "1" + }, + { + "type": "option", + "name": "mtu_fix", + "value": "1" + } + ] + }, + { + "name": "forwarding", + "options": [ + { + "type": "option", + "name": "src", + "value": "lan" + }, + { + "type": "option", + "name": "dest", + "value": "wan" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow-DHCP-Renew" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "udp" + }, + { + "type": "option", + "name": "dest_port", + "value": "68" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + }, + { + "type": "option", + "name": "family", + "value": "ipv4" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow-Ping" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "icmp" + }, + { + "type": "option", + "name": "icmp_type", + "value": "echo-request" + }, + { + "type": "option", + "name": "family", + "value": "ipv4" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow-IGMP" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "igmp" + }, + { + "type": "option", + "name": "family", + "value": "ipv4" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow-DHCPv6" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "udp" + }, + { + "type": "option", + "name": "dest_port", + "value": "546" + }, + { + "type": "option", + "name": "family", + "value": "ipv6" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow-MLD" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "icmp" + }, + { + "type": "option", + "name": "src_ip", + "value": "fe80::/10" + }, + { + "type": "list", + "name": "icmp_type", + "value": "130/0" + }, + { + "type": "list", + "name": "icmp_type", + "value": "131/0" + }, + { + "type": "list", + "name": "icmp_type", + "value": "132/0" + }, + { + "type": "list", + "name": "icmp_type", + "value": "143/0" + }, + { + "type": "option", + "name": "family", + "value": "ipv6" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow-ICMPv6-Input" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "icmp" + }, + { + "type": "list", + "name": "icmp_type", + "value": "echo-request" + }, + { + "type": "list", + "name": "icmp_type", + "value": "echo-reply" + }, + { + "type": "list", + "name": "icmp_type", + "value": "destination-unreachable" + }, + { + "type": "list", + "name": "icmp_type", + "value": "packet-too-big" + }, + { + "type": "list", + "name": "icmp_type", + "value": "time-exceeded" + }, + { + "type": "list", + "name": "icmp_type", + "value": "bad-header" + }, + { + "type": "list", + "name": "icmp_type", + "value": "unknown-header-type" + }, + { + "type": "list", + "name": "icmp_type", + "value": "router-solicitation" + }, + { + "type": "list", + "name": "icmp_type", + "value": "neighbour-solicitation" + }, + { + "type": "list", + "name": "icmp_type", + "value": "router-advertisement" + }, + { + "type": "list", + "name": "icmp_type", + "value": "neighbour-advertisement" + }, + { + "type": "option", + "name": "limit", + "value": "1000/sec" + }, + { + "type": "option", + "name": "family", + "value": "ipv6" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow-ICMPv6-Forward" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "dest", + "value": "*" + }, + { + "type": "option", + "name": "proto", + "value": "icmp" + }, + { + "type": "list", + "name": "icmp_type", + "value": "echo-request" + }, + { + "type": "list", + "name": "icmp_type", + "value": "echo-reply" + }, + { + "type": "list", + "name": "icmp_type", + "value": "destination-unreachable" + }, + { + "type": "list", + "name": "icmp_type", + "value": "packet-too-big" + }, + { + "type": "list", + "name": "icmp_type", + "value": "time-exceeded" + }, + { + "type": "list", + "name": "icmp_type", + "value": "bad-header" + }, + { + "type": "list", + "name": "icmp_type", + "value": "unknown-header-type" + }, + { + "type": "option", + "name": "limit", + "value": "1000/sec" + }, + { + "type": "option", + "name": "family", + "value": "ipv6" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow-IPSec-ESP" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "dest", + "value": "lan" + }, + { + "type": "option", + "name": "proto", + "value": "esp" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow-ISAKMP" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "dest", + "value": "lan" + }, + { + "type": "option", + "name": "dest_port", + "value": "500" + }, + { + "type": "option", + "name": "proto", + "value": "udp" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow SSH on WAN" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "tcp" + }, + { + "type": "option", + "name": "dest_port", + "value": "22" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow HTTP on WAN" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "tcp" + }, + { + "type": "option", + "name": "dest_port", + "value": "80" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow HTTPS on WAN" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "tcp" + }, + { + "type": "option", + "name": "dest_port", + "value": "443" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow 8080 on WAN" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "tcp" + }, + { + "type": "option", + "name": "dest_port", + "value": "8080" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + }, + { + "name": "rule", + "options": [ + { + "type": "option", + "name": "name", + "value": "Allow 8443 on WAN" + }, + { + "type": "option", + "name": "src", + "value": "wan" + }, + { + "type": "option", + "name": "proto", + "value": "tcp" + }, + { + "type": "option", + "name": "dest_port", + "value": "8443" + }, + { + "type": "option", + "name": "target", + "value": "ACCEPT" + } + ] + } + ] + }, + { + "name": "luci", + "configs": [ + { + "name": "core", + "section": "main", + "options": [ + { + "type": "option", + "name": "lang", + "value": "auto" + }, + { + "type": "option", + "name": "mediaurlbase", + "value": "/luci-static/bootstrap" + }, + { + "type": "option", + "name": "resourcebase", + "value": "/luci-static/resources" + }, + { + "type": "option", + "name": "ubuspath", + "value": "/ubus/" + } + ] + }, + { + "name": "extern", + "section": "flash_keep", + "options": [ + { + "type": "option", + "name": "uci", + "value": "/etc/config/" + }, + { + "type": "option", + "name": "dropbear", + "value": "/etc/dropbear/" + }, + { + "type": "option", + "name": "openvpn", + "value": "/etc/openvpn/" + }, + { + "type": "option", + "name": "passwd", + "value": "/etc/passwd" + }, + { + "type": "option", + "name": "opkg", + "value": "/etc/opkg.conf" + }, + { + "type": "option", + "name": "firewall", + "value": "/etc/firewall.user" + }, + { + "type": "option", + "name": "uploads", + "value": "/lib/uci/upload/" + } + ] + }, + { + "name": "internal", + "section": "languages", + "options": null + }, + { + "name": "internal", + "section": "sauth", + "options": [ + { + "type": "option", + "name": "sessionpath", + "value": "/tmp/luci-sessions" + }, + { + "type": "option", + "name": "sessiontime", + "value": "3600" + } + ] + }, + { + "name": "internal", + "section": "ccache", + "options": [ + { + "type": "option", + "name": "enable", + "value": "1" + } + ] + }, + { + "name": "internal", + "section": "themes", + "options": [ + { + "type": "option", + "name": "Bootstrap", + "value": "/luci-static/bootstrap" + }, + { + "type": "option", + "name": "BootstrapDark", + "value": "/luci-static/bootstrap-dark" + }, + { + "type": "option", + "name": "BootstrapLight", + "value": "/luci-static/bootstrap-light" + } + ] + }, + { + "name": "internal", + "section": "apply", + "options": [ + { + "type": "option", + "name": "rollback", + "value": "90" + }, + { + "type": "option", + "name": "holdoff", + "value": "4" + }, + { + "type": "option", + "name": "timeout", + "value": "5" + }, + { + "type": "option", + "name": "display", + "value": "1.5" + } + ] + }, + { + "name": "internal", + "section": "diag", + "options": [ + { + "type": "option", + "name": "dns", + "value": "openwrt.org" + }, + { + "type": "option", + "name": "ping", + "value": "openwrt.org" + }, + { + "type": "option", + "name": "route", + "value": "openwrt.org" + } + ] + } + ] + }, + { + "name": "network", + "configs": [ + { + "name": "interface", + "section": "loopback", + "options": [ + { + "type": "option", + "name": "ifname", + "value": "lo" + }, + { + "type": "option", + "name": "proto", + "value": "static" + }, + { + "type": "option", + "name": "ipaddr", + "value": "127.0.0.1" + }, + { + "type": "option", + "name": "netmask", + "value": "255.0.0.0" + } + ] + }, + { + "name": "interface", + "section": "wan", + "options": [ + { + "type": "option", + "name": "ifname", + "value": "eth0" + }, + { + "type": "option", + "name": "proto", + "value": "dhcp" + } + ] + } + ] + }, + { + "name": "rpcd", + "configs": [ + { + "name": "rpcd", + "options": [ + { + "type": "option", + "name": "socket", + "value": "/var/run/ubus/ubus.sock" + }, + { + "type": "option", + "name": "timeout", + "value": "30" + } + ] + }, + { + "name": "login", + "options": [ + { + "type": "option", + "name": "username", + "value": "root" + }, + { + "type": "option", + "name": "password", + "value": "$p$root" + }, + { + "type": "list", + "name": "read", + "value": "*" + }, + { + "type": "list", + "name": "write", + "value": "*" + } + ] + } + ] + }, + { + "name": "system", + "configs": [ + { + "name": "system", + "options": [ + { + "type": "option", + "name": "hostname", + "value": "OpenWrt" + }, + { + "type": "option", + "name": "timezone", + "value": "UTC" + }, + { + "type": "option", + "name": "ttylogin", + "value": "0" + }, + { + "type": "option", + "name": "log_size", + "value": "64" + }, + { + "type": "option", + "name": "urandom_seed", + "value": "0" + } + ] + }, + { + "name": "timeserver", + "section": "ntp", + "options": [ + { + "type": "option", + "name": "enabled", + "value": "1" + }, + { + "type": "option", + "name": "enable_server", + "value": "0" + }, + { + "type": "list", + "name": "server", + "value": "0.openwrt.pool.ntp.org" + }, + { + "type": "list", + "name": "server", + "value": "1.openwrt.pool.ntp.org" + }, + { + "type": "list", + "name": "server", + "value": "2.openwrt.pool.ntp.org" + }, + { + "type": "list", + "name": "server", + "value": "3.openwrt.pool.ntp.org" + } + ] + } + ] + }, + { + "name": "ucitrack", + "configs": [ + { + "name": "network", + "options": [ + { + "type": "option", + "name": "init", + "value": "network" + }, + { + "type": "list", + "name": "affects", + "value": "dhcp" + } + ] + }, + { + "name": "wireless", + "options": [ + { + "type": "list", + "name": "affects", + "value": "network" + } + ] + }, + { + "name": "firewall", + "options": [ + { + "type": "option", + "name": "init", + "value": "firewall" + }, + { + "type": "list", + "name": "affects", + "value": "luci-splash" + }, + { + "type": "list", + "name": "affects", + "value": "qos" + }, + { + "type": "list", + "name": "affects", + "value": "miniupnpd" + } + ] + }, + { + "name": "olsr", + "options": [ + { + "type": "option", + "name": "init", + "value": "olsrd" + } + ] + }, + { + "name": "dhcp", + "options": [ + { + "type": "option", + "name": "init", + "value": "dnsmasq" + }, + { + "type": "list", + "name": "affects", + "value": "odhcpd" + } + ] + }, + { + "name": "odhcpd", + "options": [ + { + "type": "option", + "name": "init", + "value": "odhcpd" + } + ] + }, + { + "name": "dropbear", + "options": [ + { + "type": "option", + "name": "init", + "value": "dropbear" + } + ] + }, + { + "name": "httpd", + "options": [ + { + "type": "option", + "name": "init", + "value": "httpd" + } + ] + }, + { + "name": "fstab", + "options": [ + { + "type": "option", + "name": "exec", + "value": "/sbin/block mount" + } + ] + }, + { + "name": "qos", + "options": [ + { + "type": "option", + "name": "init", + "value": "qos" + } + ] + }, + { + "name": "system", + "options": [ + { + "type": "option", + "name": "init", + "value": "led" + }, + { + "type": "option", + "name": "exec", + "value": "/etc/init.d/log reload" + }, + { + "type": "list", + "name": "affects", + "value": "luci_statistics" + }, + { + "type": "list", + "name": "affects", + "value": "dhcp" + } + ] + }, + { + "name": "luci_splash", + "options": [ + { + "type": "option", + "name": "init", + "value": "luci_splash" + } + ] + }, + { + "name": "upnpd", + "options": [ + { + "type": "option", + "name": "init", + "value": "miniupnpd" + } + ] + }, + { + "name": "ntpclient", + "options": [ + { + "type": "option", + "name": "init", + "value": "ntpclient" + } + ] + }, + { + "name": "samba", + "options": [ + { + "type": "option", + "name": "init", + "value": "samba" + } + ] + }, + { + "name": "tinyproxy", + "options": [ + { + "type": "option", + "name": "init", + "value": "tinyproxy" + } + ] + } + ] + }, { "name": "uhttpd", "configs": [ @@ -23,12 +1492,12 @@ { "type": "list", "name": "listen_https", - "value": "0.0.0.0:8443" + "value": "0.0.0.0:4443" }, { "type": "list", "name": "listen_https", - "value": "[::]:8443" + "value": "[::]:4443" }, { "type": "option",