Pull request: upd-websvc

Merge in DNS/adguard-home from upd-websvc to master

Squashed commit of the following:

commit 30d6a2dc5083efd91479bcbe20f03c37baddbf94
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Aug 9 18:55:42 2022 +0300

    all: upd openapi, websvc
This commit is contained in:
Ainar Garipov 2022-08-10 13:39:28 +03:00
parent 70f85fca21
commit 50565bed3b
7 changed files with 135 additions and 31 deletions

View file

@ -154,10 +154,13 @@ func GetValidNetInterfacesForWeb() (netIfaces []*NetInterface, err error) {
return netIfaces, nil
}
// GetInterfaceByIP returns the name of interface containing provided ip.
// InterfaceByIP returns the name of the interface bound to ip.
//
// TODO(e.burkov): See TODO on GetValidInterfacesForWeb.
func GetInterfaceByIP(ip net.IP) string {
// TODO(a.garipov, e.burkov): This function is technically incorrect, since one
// IP address can be shared by multiple interfaces in some configurations.
//
// TODO(e.burkov): See TODO on GetValidNetInterfacesForWeb.
func InterfaceByIP(ip net.IP) (ifaceName string) {
ifaces, err := GetValidNetInterfacesForWeb()
if err != nil {
return ""
@ -177,7 +180,7 @@ func GetInterfaceByIP(ip net.IP) string {
// GetSubnet returns pointer to net.IPNet for the specified interface or nil if
// the search fails.
//
// TODO(e.burkov): See TODO on GetValidInterfacesForWeb.
// TODO(e.burkov): See TODO on GetValidNetInterfacesForWeb.
func GetSubnet(ifaceName string) *net.IPNet {
netIfaces, err := GetValidNetInterfacesForWeb()
if err != nil {

View file

@ -132,7 +132,7 @@ func TestGatewayIP(t *testing.T) {
}
}
func TestGetInterfaceByIP(t *testing.T) {
func TestInterfaceByIP(t *testing.T) {
ifaces, err := GetValidNetInterfacesForWeb()
require.NoError(t, err)
require.NotEmpty(t, ifaces)
@ -142,7 +142,7 @@ func TestGetInterfaceByIP(t *testing.T) {
require.NotEmpty(t, iface.Addresses)
for _, ip := range iface.Addresses {
ifaceName := GetInterfaceByIP(ip)
ifaceName := InterfaceByIP(ip)
require.Equal(t, iface.Name, ifaceName)
}
})

View file

@ -216,7 +216,7 @@ func (web *Web) handleInstallCheckConfig(w http.ResponseWriter, r *http.Request)
func handleStaticIP(ip net.IP, set bool) staticIPJSON {
resp := staticIPJSON{}
interfaceName := aghnet.GetInterfaceByIP(ip)
interfaceName := aghnet.InterfaceByIP(ip)
resp.Static = "no"
if len(interfaceName) == 0 {

View file

@ -8,12 +8,11 @@ import (
"context"
"io/fs"
"math/rand"
"net"
"net/netip"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/v1/websvc"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
)
// Main is the entry point of application.
@ -32,12 +31,9 @@ func Main(clientBuildFS fs.FS) {
// TODO(a.garipov): Make configurable.
web := websvc.New(&websvc.Config{
Addresses: []*netutil.IPPort{{
IP: net.IP{127, 0, 0, 1},
Port: 3001,
}},
Start: start,
Timeout: 60 * time.Second,
Addresses: []netip.AddrPort{netip.MustParseAddrPort("127.0.0.1:3001")},
Start: start,
Timeout: 60 * time.Second,
})
err := web.Start()

View file

@ -10,13 +10,13 @@ import (
"io"
"net"
"net/http"
"net/netip"
"sync"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/v1/agh"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
httptreemux "github.com/dimfeld/httptreemux/v5"
)
@ -27,11 +27,11 @@ type Config struct {
TLS *tls.Config
// Addresses are the addresses on which to serve the plain HTTP API.
Addresses []*netutil.IPPort
Addresses []netip.AddrPort
// SecureAddresses are the addresses on which to serve the HTTPS API. If
// SecureAddresses is not empty, TLS must not be nil.
SecureAddresses []*netutil.IPPort
SecureAddresses []netip.AddrPort
// Start is the time of start of AdGuard Home.
Start time.Time

View file

@ -3,14 +3,13 @@ package websvc_test
import (
"context"
"io"
"net"
"net/http"
"net/netip"
"net/url"
"testing"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/v1/websvc"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -30,11 +29,8 @@ func newTestServer(t testing.TB) (svc *websvc.Service, addr string) {
t.Helper()
c := &websvc.Config{
TLS: nil,
Addresses: []*netutil.IPPort{{
IP: net.IP{127, 0, 0, 1},
Port: 0,
}},
TLS: nil,
Addresses: []netip.AddrPort{netip.MustParseAddrPort("127.0.0.1:0")},
SecureAddresses: nil,
Timeout: testTimeout,
Start: testStart,

View file

@ -144,6 +144,13 @@
'/health-check':
'get':
'operationId': 'HealthCheck'
'responses':
'200':
'description': >
An OK response.
'content':
'text/plain':
'example': 'OK'
'servers':
- 'url': '/'
'summary': 'Check if the server is up.'
@ -874,6 +881,26 @@
'tags':
- 'settings'
'/settings/http':
'patch':
'operationId': 'PatchV1SettingsHttp'
'requestBody':
'$ref': '#/components/requestBodies/PatchV1SettingsHttpReq'
'responses':
'200':
'$ref': '#/components/responses/PatchV1SettingsHttpResp'
'400':
'$ref': '#/components/responses/BadRequestResp'
'401':
'$ref': '#/components/responses/UnauthorizedResp'
'422':
'$ref': '#/components/responses/UnprocessableEntityResp'
'500':
'$ref': '#/components/responses/InternalServerErrorResp'
'summary': 'Update web interface settings.'
'tags':
- 'settings'
'/settings/log':
'patch':
'operationId': 'PatchV1SettingsLog'
@ -1209,6 +1236,13 @@
'$ref': '#/components/schemas/PatchV1SettingsDnsReq'
'required': true
'PatchV1SettingsHttpReq':
'content':
'application/json':
'schema':
'$ref': '#/components/schemas/PatchV1SettingsHttpReq'
'required': true
'PatchV1SettingsLogReq':
'content':
'application/json':
@ -1604,6 +1638,14 @@
'description': >
A successful response to a `PATCH /api/v1/settings/dns` request.
'PatchV1SettingsHttpResp':
'content':
'application/json':
'schema':
'$ref': '#/components/schemas/PatchV1SettingsHttpResp'
'description': >
A successful response to a `PATCH /api/v1/settings/http` request.
'PatchV1SettingsLogResp':
'content':
'application/json':
@ -2229,6 +2271,9 @@
- 'description': >
DNS server settings.
'example':
'addresses':
- '127.0.0.1:53'
- '192.168.1.1:53'
'blocking_mode': 'default'
'bootstrap_servers':
- '9.9.9.10'
@ -2244,7 +2289,9 @@
'upstream_servers':
- '1.1.1.1'
- '8.8.8.8'
'upstream_timeout': '1s'
'required':
- 'addresses'
- 'blocking_mode'
- 'bootstrap_servers'
- 'cache_size'
@ -2256,6 +2303,7 @@
- 'rate_limit'
- 'upstream_mode'
- 'upstream_servers'
- 'upstream_timeout'
'DnsSettingsPatch':
'description': >
@ -2265,6 +2313,13 @@
'upstream_servers':
- '1.1.1.1'
'properties':
'addresses':
'description': >
Addresses on which to serve plain DNS, in ip:port format. Empty
array disables plain DNS.
'items':
'type': 'string'
'type': 'array'
'blocking_ipv4':
'description': >
IPv4 address to respond with when `blocking_mode` is `custom_ip`.
@ -2340,6 +2395,10 @@
'items':
'$ref': '#/components/schemas/UpstreamServerAddr'
'type': 'array'
'upstream_timeout':
'description': >
Upstream request timeout, as a human readable duration.
'type': 'string'
'type': 'object'
'DnsType':
@ -3038,6 +3097,8 @@
'$ref': '#/components/schemas/DhcpSettings'
'dns':
'$ref': '#/components/schemas/DnsSettings'
'http':
'$ref': '#/components/schemas/HttpSettings'
'log':
'$ref': '#/components/schemas/LogSettings'
'protection':
@ -3049,6 +3110,7 @@
'required':
- 'dhcp'
- 'dns'
- 'http'
- 'log'
- 'protection'
- 'stats'
@ -3432,6 +3494,53 @@
- 'version'
'type': 'object'
'HttpSettings':
'allOf':
- '$ref': '#/components/schemas/HttpSettingsPatch'
- 'description': >
HTTP interface server settings.
**TODO(a.garipov): Finish, split from TLS settings.**
'example':
'addresses':
- '127.0.0.1:80'
- '192.168.1.1:80'
'secure_addresses':
- '127.0.0.1:443'
- '192.168.1.1:443'
'force_https': true
'required':
- 'addresses'
- 'secure_addresses'
- 'force_https'
'HttpSettingsPatch':
'description': >
HTTP server settings update object.
'example':
'force_https': false
'properties':
'addresses':
'description': >
Addresses on which to serve the plain-HTTP web interface and API, in
ip:port format. Empty array disables the web interface over plain
HTTP.
'items':
'type': 'string'
'type': 'array'
'force_https':
'description': >
If `true`, enabled the HTTP-to-HTTPS redirect.
'type': 'boolean'
'secure_addresses':
'description': >
Addresses on which to serve the HTTPS web interface and API, in
ip:port format. Empty array disables the web interface over HTTPS.
'items':
'type': 'string'
'type': 'array'
'type': 'object'
'InternalServerErrorResp':
'example':
'code': 'RNT000'
@ -3725,6 +3834,12 @@
'PatchV1SettingsDnsResp':
'$ref': '#/components/schemas/DnsSettings'
'PatchV1SettingsHttpReq':
'$ref': '#/components/schemas/HttpSettingsPatch'
'PatchV1SettingsHttpResp':
'$ref': '#/components/schemas/HttpSettings'
'PatchV1SettingsLogReq':
'$ref': '#/components/schemas/LogSettingsPatch'
@ -4750,7 +4865,6 @@
'example':
'certificate_path': '/etc/ssl/example.com.cert'
'enabled': true
'force_https': true
'port_dns_over_quic': 784
'port_dns_over_tls': 853
'port_https': 443
@ -4758,7 +4872,6 @@
'server_name': 'dns.example.com'
'required':
- 'enabled'
- 'force_https'
- 'port_dns_over_quic'
- 'port_dns_over_tls'
- 'port_https'
@ -4793,10 +4906,6 @@
over HTTPS, and the DNS server will listen requests over
DNS-over-TLS and other protocols.
'type': 'boolean'
'force_https':
'description': >
If `true`, enabled the HTTP-to-HTTPS redirect.
'type': 'boolean'
'port_dns_over_quic':
'default': 784
'description': >