Pull request: 2509 type-safety vol.1
Merge in DNS/adguard-home from 2509-type-safety to master Updates #2509. Squashed commit of the following: commit 535968eb7de3a9e0817ddb57bc2320e5c5a55086 Author: Eugene Burkov <e.burkov@adguard.com> Date: Wed Jan 20 15:06:16 2021 +0300 dhcpd: fix comments commit dc79b80381fe7a8ecec6f9659fd23710c9229f59 Author: Eugene Burkov <e.burkov@adguard.com> Date: Wed Jan 20 14:08:10 2021 +0300 all: improve docs commit 156ebf6c9bad95f82cd121f019f3b59b77b18ba6 Author: Eugene Burkov <e.burkov@adguard.com> Date: Tue Jan 19 17:08:15 2021 +0300 all: improve JSON encoding and decoding
This commit is contained in:
parent
715df4cd92
commit
5a50efadb2
@ -3,6 +3,8 @@ package dhcpd
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
@ -33,6 +35,39 @@ type Lease struct {
|
||||
Expiry time.Time `json:"expires"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface for *Lease.
|
||||
func (l *Lease) MarshalJSON() ([]byte, error) {
|
||||
type lease Lease
|
||||
return json.Marshal(&struct {
|
||||
HWAddr string `json:"mac"`
|
||||
*lease
|
||||
}{
|
||||
HWAddr: l.HWAddr.String(),
|
||||
lease: (*lease)(l),
|
||||
})
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface for *Lease.
|
||||
func (l *Lease) UnmarshalJSON(data []byte) (err error) {
|
||||
type lease Lease
|
||||
aux := struct {
|
||||
HWAddr string `json:"mac"`
|
||||
*lease
|
||||
}{
|
||||
lease: (*lease)(l),
|
||||
}
|
||||
if err = json.Unmarshal(data, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.HWAddr, err = net.ParseMAC(aux.HWAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't parse MAC address: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ServerConfig - DHCP server configuration
|
||||
// field ordering is important -- yaml fields will mirror ordering from here
|
||||
type ServerConfig struct {
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/sysutil"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/util"
|
||||
@ -22,25 +21,6 @@ func httpError(r *http.Request, w http.ResponseWriter, code int, format string,
|
||||
http.Error(w, text, code)
|
||||
}
|
||||
|
||||
// []Lease -> JSON
|
||||
func convertLeases(inputLeases []Lease, includeExpires bool) []map[string]string {
|
||||
leases := []map[string]string{}
|
||||
for _, l := range inputLeases {
|
||||
lease := map[string]string{
|
||||
"mac": l.HWAddr.String(),
|
||||
"ip": l.IP.String(),
|
||||
"hostname": l.Hostname,
|
||||
}
|
||||
|
||||
if includeExpires {
|
||||
lease["expires"] = l.Expiry.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
leases = append(leases, lease)
|
||||
}
|
||||
return leases
|
||||
}
|
||||
|
||||
type v4ServerConfJSON struct {
|
||||
GatewayIP net.IP `json:"gateway_ip"`
|
||||
SubnetMask net.IP `json:"subnet_mask"`
|
||||
@ -49,22 +29,12 @@ type v4ServerConfJSON struct {
|
||||
LeaseDuration uint32 `json:"lease_duration"`
|
||||
}
|
||||
|
||||
func v4ServerConfToJSON(c V4ServerConf) v4ServerConfJSON {
|
||||
return v4ServerConfJSON{
|
||||
GatewayIP: c.GatewayIP,
|
||||
SubnetMask: c.SubnetMask,
|
||||
RangeStart: c.RangeStart,
|
||||
RangeEnd: c.RangeEnd,
|
||||
LeaseDuration: c.LeaseDuration,
|
||||
}
|
||||
}
|
||||
|
||||
func v4JSONToServerConf(j v4ServerConfJSON) V4ServerConf {
|
||||
return V4ServerConf{
|
||||
GatewayIP: j.GatewayIP.To4(),
|
||||
SubnetMask: j.SubnetMask.To4(),
|
||||
RangeStart: j.RangeStart.To4(),
|
||||
RangeEnd: j.RangeEnd.To4(),
|
||||
GatewayIP: j.GatewayIP,
|
||||
SubnetMask: j.SubnetMask,
|
||||
RangeStart: j.RangeStart,
|
||||
RangeEnd: j.RangeEnd,
|
||||
LeaseDuration: j.LeaseDuration,
|
||||
}
|
||||
}
|
||||
@ -74,13 +44,6 @@ type v6ServerConfJSON struct {
|
||||
LeaseDuration uint32 `json:"lease_duration"`
|
||||
}
|
||||
|
||||
func v6ServerConfToJSON(c V6ServerConf) v6ServerConfJSON {
|
||||
return v6ServerConfJSON{
|
||||
RangeStart: c.RangeStart,
|
||||
LeaseDuration: c.LeaseDuration,
|
||||
}
|
||||
}
|
||||
|
||||
func v6JSONToServerConf(j v6ServerConfJSON) V6ServerConf {
|
||||
return V6ServerConf{
|
||||
RangeStart: j.RangeStart,
|
||||
@ -88,25 +51,30 @@ func v6JSONToServerConf(j v6ServerConfJSON) V6ServerConf {
|
||||
}
|
||||
}
|
||||
|
||||
// dhcpStatusResponse is the response for /control/dhcp/status endpoint.
|
||||
type dhcpStatusResponse struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
IfaceName string `json:"interface_name"`
|
||||
V4 V4ServerConf `json:"v4"`
|
||||
V6 V6ServerConf `json:"v6"`
|
||||
Leases []Lease `json:"leases"`
|
||||
StaticLeases []Lease `json:"static_leases"`
|
||||
}
|
||||
|
||||
func (s *Server) handleDHCPStatus(w http.ResponseWriter, r *http.Request) {
|
||||
leases := convertLeases(s.Leases(LeasesDynamic), true)
|
||||
staticLeases := convertLeases(s.Leases(LeasesStatic), false)
|
||||
|
||||
v4conf := V4ServerConf{}
|
||||
s.srv4.WriteDiskConfig4(&v4conf)
|
||||
|
||||
v6conf := V6ServerConf{}
|
||||
s.srv6.WriteDiskConfig6(&v6conf)
|
||||
|
||||
status := map[string]interface{}{
|
||||
"enabled": s.conf.Enabled,
|
||||
"interface_name": s.conf.InterfaceName,
|
||||
"v4": v4ServerConfToJSON(v4conf),
|
||||
"v6": v6ServerConfToJSON(v6conf),
|
||||
"leases": leases,
|
||||
"static_leases": staticLeases,
|
||||
status := &dhcpStatusResponse{
|
||||
Enabled: s.conf.Enabled,
|
||||
IfaceName: s.conf.InterfaceName,
|
||||
V4: V4ServerConf{},
|
||||
V6: V6ServerConf{},
|
||||
}
|
||||
|
||||
s.srv4.WriteDiskConfig4(&status.V4)
|
||||
s.srv6.WriteDiskConfig6(&status.V6)
|
||||
|
||||
status.Leases = s.Leases(LeasesDynamic)
|
||||
status.StaticLeases = s.Leases(LeasesStatic)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
err := json.NewEncoder(w).Encode(status)
|
||||
if err != nil {
|
||||
@ -115,12 +83,6 @@ func (s *Server) handleDHCPStatus(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
type staticLeaseJSON struct {
|
||||
HWAddr string `json:"mac"`
|
||||
IP net.IP `json:"ip"`
|
||||
Hostname string `json:"hostname"`
|
||||
}
|
||||
|
||||
type dhcpServerConfigJSON struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
InterfaceName string `json:"interface_name"`
|
||||
@ -233,7 +195,7 @@ type netInterfaceJSON struct {
|
||||
}
|
||||
|
||||
func (s *Server) handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
|
||||
response := map[string]interface{}{}
|
||||
response := map[string]netInterfaceJSON{}
|
||||
|
||||
ifaces, err := util.GetValidNetInterfaces()
|
||||
if err != nil {
|
||||
@ -295,6 +257,40 @@ func (s *Server) handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// dhcpSearchOtherResult contains information about other DHCP server for
|
||||
// specific network interface.
|
||||
type dhcpSearchOtherResult struct {
|
||||
Found string `json:"found,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// dhcpStaticIPStatus contains information about static IP address for DHCP
|
||||
// server.
|
||||
type dhcpStaticIPStatus struct {
|
||||
Static string `json:"static"`
|
||||
IP string `json:"ip,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// dhcpSearchV4Result contains information about DHCPv4 server for specific
|
||||
// network interface.
|
||||
type dhcpSearchV4Result struct {
|
||||
OtherServer dhcpSearchOtherResult `json:"other_server"`
|
||||
StaticIP dhcpStaticIPStatus `json:"static_ip"`
|
||||
}
|
||||
|
||||
// dhcpSearchV6Result contains information about DHCPv6 server for specific
|
||||
// network interface.
|
||||
type dhcpSearchV6Result struct {
|
||||
OtherServer dhcpSearchOtherResult `json:"other_server"`
|
||||
}
|
||||
|
||||
// dhcpSearchResult is a response for /control/dhcp/find_active_dhcp endpoint.
|
||||
type dhcpSearchResult struct {
|
||||
V4 dhcpSearchV4Result `json:"v4"`
|
||||
V6 dhcpSearchV6Result `json:"v6"`
|
||||
}
|
||||
|
||||
// Perform the following tasks:
|
||||
// . Search for another DHCP server running
|
||||
// . Check if a static IP is configured for the network interface
|
||||
@ -317,50 +313,42 @@ func (s *Server) handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Reque
|
||||
return
|
||||
}
|
||||
|
||||
result := dhcpSearchResult{
|
||||
V4: dhcpSearchV4Result{
|
||||
OtherServer: dhcpSearchOtherResult{},
|
||||
StaticIP: dhcpStaticIPStatus{},
|
||||
},
|
||||
V6: dhcpSearchV6Result{
|
||||
OtherServer: dhcpSearchOtherResult{},
|
||||
},
|
||||
}
|
||||
|
||||
found4, err4 := CheckIfOtherDHCPServersPresentV4(interfaceName)
|
||||
|
||||
staticIP := map[string]interface{}{}
|
||||
isStaticIP, err := sysutil.IfaceHasStaticIP(interfaceName)
|
||||
staticIPStatus := "yes"
|
||||
if err != nil {
|
||||
staticIPStatus = "error"
|
||||
staticIP["error"] = err.Error()
|
||||
result.V4.StaticIP.Static = "error"
|
||||
result.V4.StaticIP.Error = err.Error()
|
||||
} else if !isStaticIP {
|
||||
staticIPStatus = "no"
|
||||
staticIP["ip"] = util.GetSubnet(interfaceName)
|
||||
result.V4.StaticIP.Static = "no"
|
||||
result.V4.StaticIP.IP = util.GetSubnet(interfaceName)
|
||||
}
|
||||
staticIP["static"] = staticIPStatus
|
||||
|
||||
v4 := map[string]interface{}{}
|
||||
othSrv := map[string]interface{}{}
|
||||
foundVal := "no"
|
||||
if found4 {
|
||||
foundVal = "yes"
|
||||
result.V4.OtherServer.Found = "yes"
|
||||
} else if err4 != nil {
|
||||
foundVal = "error"
|
||||
othSrv["error"] = err4.Error()
|
||||
result.V4.OtherServer.Found = "error"
|
||||
result.V4.OtherServer.Error = err4.Error()
|
||||
}
|
||||
othSrv["found"] = foundVal
|
||||
v4["other_server"] = othSrv
|
||||
v4["static_ip"] = staticIP
|
||||
|
||||
found6, err6 := CheckIfOtherDHCPServersPresentV6(interfaceName)
|
||||
|
||||
v6 := map[string]interface{}{}
|
||||
othSrv = map[string]interface{}{}
|
||||
foundVal = "no"
|
||||
if found6 {
|
||||
foundVal = "yes"
|
||||
result.V6.OtherServer.Found = "yes"
|
||||
} else if err6 != nil {
|
||||
foundVal = "error"
|
||||
othSrv["error"] = err6.Error()
|
||||
result.V6.OtherServer.Found = "error"
|
||||
result.V6.OtherServer.Error = err6.Error()
|
||||
}
|
||||
othSrv["found"] = foundVal
|
||||
v6["other_server"] = othSrv
|
||||
|
||||
result := map[string]interface{}{}
|
||||
result["v4"] = v4
|
||||
result["v6"] = v6
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
err = json.NewEncoder(w).Encode(result)
|
||||
@ -371,7 +359,7 @@ func (s *Server) handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
|
||||
func (s *Server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request) {
|
||||
lj := staticLeaseJSON{}
|
||||
lj := Lease{}
|
||||
err := json.NewDecoder(r.Body).Decode(&lj)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusBadRequest, "json.Decode: %s", err)
|
||||
@ -387,21 +375,10 @@ func (s *Server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request
|
||||
|
||||
ip4 := lj.IP.To4()
|
||||
|
||||
mac, err := net.ParseMAC(lj.HWAddr)
|
||||
lease := Lease{
|
||||
HWAddr: mac,
|
||||
}
|
||||
|
||||
if ip4 == nil {
|
||||
lease.IP = lj.IP.To16()
|
||||
lj.IP = lj.IP.To16()
|
||||
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusBadRequest, "invalid MAC")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
err = s.srv6.AddStaticLease(lease)
|
||||
err = s.srv6.AddStaticLease(lj)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusBadRequest, "%s", err)
|
||||
}
|
||||
@ -409,9 +386,8 @@ func (s *Server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
lease.IP = ip4
|
||||
lease.Hostname = lj.Hostname
|
||||
err = s.srv4.AddStaticLease(lease)
|
||||
lj.IP = ip4
|
||||
err = s.srv4.AddStaticLease(lj)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusBadRequest, "%s", err)
|
||||
|
||||
@ -420,7 +396,7 @@ func (s *Server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
|
||||
func (s *Server) handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Request) {
|
||||
lj := staticLeaseJSON{}
|
||||
lj := Lease{}
|
||||
err := json.NewDecoder(r.Body).Decode(&lj)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusBadRequest, "json.Decode: %s", err)
|
||||
@ -436,21 +412,10 @@ func (s *Server) handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Requ
|
||||
|
||||
ip4 := lj.IP.To4()
|
||||
|
||||
mac, err := net.ParseMAC(lj.HWAddr)
|
||||
lease := Lease{
|
||||
HWAddr: mac,
|
||||
}
|
||||
|
||||
if ip4 == nil {
|
||||
lease.IP = lj.IP.To16()
|
||||
lj.IP = lj.IP.To16()
|
||||
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusBadRequest, "invalid MAC")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
err = s.srv6.RemoveStaticLease(lease)
|
||||
err = s.srv6.RemoveStaticLease(lj)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusBadRequest, "%s", err)
|
||||
}
|
||||
@ -458,9 +423,8 @@ func (s *Server) handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Requ
|
||||
return
|
||||
}
|
||||
|
||||
lease.IP = ip4
|
||||
lease.Hostname = lj.Hostname
|
||||
err = s.srv4.RemoveStaticLease(lease)
|
||||
lj.IP = ip4
|
||||
err = s.srv4.RemoveStaticLease(lj)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusBadRequest, "%s", err)
|
||||
|
||||
|
@ -33,22 +33,22 @@ type DHCPServer interface {
|
||||
|
||||
// V4ServerConf - server configuration
|
||||
type V4ServerConf struct {
|
||||
Enabled bool `yaml:"-"`
|
||||
InterfaceName string `yaml:"-"`
|
||||
Enabled bool `yaml:"-" json:"-"`
|
||||
InterfaceName string `yaml:"-" json:"-"`
|
||||
|
||||
GatewayIP net.IP `yaml:"gateway_ip"`
|
||||
SubnetMask net.IP `yaml:"subnet_mask"`
|
||||
GatewayIP net.IP `yaml:"gateway_ip" json:"gateway_ip"`
|
||||
SubnetMask net.IP `yaml:"subnet_mask" json:"subnet_mask"`
|
||||
|
||||
// The first & the last IP address for dynamic leases
|
||||
// Bytes [0..2] of the last allowed IP address must match the first IP
|
||||
RangeStart net.IP `yaml:"range_start"`
|
||||
RangeEnd net.IP `yaml:"range_end"`
|
||||
RangeStart net.IP `yaml:"range_start" json:"range_start"`
|
||||
RangeEnd net.IP `yaml:"range_end" json:"range_end"`
|
||||
|
||||
LeaseDuration uint32 `yaml:"lease_duration"` // in seconds
|
||||
LeaseDuration uint32 `yaml:"lease_duration" json:"lease_duration"` // in seconds
|
||||
|
||||
// IP conflict detector: time (ms) to wait for ICMP reply
|
||||
// 0: disable
|
||||
ICMPTimeout uint32 `yaml:"icmp_timeout_msec"`
|
||||
ICMPTimeout uint32 `yaml:"icmp_timeout_msec" json:"-"`
|
||||
|
||||
// Custom Options.
|
||||
//
|
||||
@ -58,7 +58,7 @@ type V4ServerConf struct {
|
||||
//
|
||||
// Option with IP data (only 1 IP is supported):
|
||||
// DEC_CODE ip IP_ADDR
|
||||
Options []string `yaml:"options"`
|
||||
Options []string `yaml:"options" json:"-"`
|
||||
|
||||
ipStart net.IP // starting IP address for dynamic leases
|
||||
ipEnd net.IP // ending IP address for dynamic leases
|
||||
@ -74,17 +74,17 @@ type V4ServerConf struct {
|
||||
|
||||
// V6ServerConf - server configuration
|
||||
type V6ServerConf struct {
|
||||
Enabled bool `yaml:"-"`
|
||||
InterfaceName string `yaml:"-"`
|
||||
Enabled bool `yaml:"-" json:"-"`
|
||||
InterfaceName string `yaml:"-" json:"-"`
|
||||
|
||||
// The first IP address for dynamic leases
|
||||
// The last allowed IP address ends with 0xff byte
|
||||
RangeStart string `yaml:"range_start"`
|
||||
RangeStart string `yaml:"range_start" json:"range_start"`
|
||||
|
||||
LeaseDuration uint32 `yaml:"lease_duration"` // in seconds
|
||||
LeaseDuration uint32 `yaml:"lease_duration" json:"lease_duration"` // in seconds
|
||||
|
||||
RaSlaacOnly bool `yaml:"ra_slaac_only"` // send ICMPv6.RA packets without MO flags
|
||||
RaAllowSlaac bool `yaml:"ra_allow_slaac"` // send ICMPv6.RA packets with MO flags
|
||||
RaSlaacOnly bool `yaml:"ra_slaac_only" json:"-"` // send ICMPv6.RA packets without MO flags
|
||||
RaAllowSlaac bool `yaml:"ra_allow_slaac" json:"-"` // send ICMPv6.RA packets with MO flags
|
||||
|
||||
ipStart net.IP // starting IP address for dynamic leases
|
||||
leaseTime time.Duration // the time during which a dynamic lease is considered valid
|
||||
|
@ -77,7 +77,10 @@ func (s *v4Server) blacklisted(l *Lease) bool {
|
||||
|
||||
// GetLeases returns the list of current DHCP leases (thread-safe)
|
||||
func (s *v4Server) GetLeases(flags int) []Lease {
|
||||
var result []Lease
|
||||
// The function shouldn't return nil value because zero-length slice
|
||||
// behaves differently in cases like marshalling. Our front-end also
|
||||
// requires non-nil value in the response.
|
||||
result := []Lease{}
|
||||
now := time.Now().Unix()
|
||||
|
||||
s.leasesLock.Lock()
|
||||
|
@ -72,7 +72,10 @@ func (s *v6Server) ResetLeases(ll []*Lease) {
|
||||
|
||||
// GetLeases - get current leases
|
||||
func (s *v6Server) GetLeases(flags int) []Lease {
|
||||
var result []Lease
|
||||
// The function shouldn't return nil value because zero-length slice
|
||||
// behaves differently in cases like marshalling. Our front-end also
|
||||
// requires non-nil value in the response.
|
||||
result := []Lease{}
|
||||
s.leasesLock.Lock()
|
||||
for _, lease := range s.leases {
|
||||
if lease.Expiry.Unix() == leaseExpireStatic {
|
||||
|
@ -346,16 +346,12 @@ func (d *DNSFilter) handleSafeBrowsingDisable(w http.ResponseWriter, r *http.Req
|
||||
}
|
||||
|
||||
func (d *DNSFilter) handleSafeBrowsingStatus(w http.ResponseWriter, r *http.Request) {
|
||||
data := map[string]interface{}{
|
||||
"enabled": d.Config.SafeBrowsingEnabled,
|
||||
}
|
||||
jsonVal, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "Unable to marshal status json: %s", err)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, err = w.Write(jsonVal)
|
||||
err := json.NewEncoder(w).Encode(&struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}{
|
||||
Enabled: d.Config.SafeBrowsingEnabled,
|
||||
})
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "Unable to write response json: %s", err)
|
||||
return
|
||||
@ -373,17 +369,12 @@ func (d *DNSFilter) handleParentalDisable(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
|
||||
func (d *DNSFilter) handleParentalStatus(w http.ResponseWriter, r *http.Request) {
|
||||
data := map[string]interface{}{
|
||||
"enabled": d.Config.ParentalEnabled,
|
||||
}
|
||||
jsonVal, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "Unable to marshal status json: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, err = w.Write(jsonVal)
|
||||
err := json.NewEncoder(w).Encode(&struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}{
|
||||
Enabled: d.Config.ParentalEnabled,
|
||||
})
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "Unable to write response json: %s", err)
|
||||
return
|
||||
|
@ -133,17 +133,12 @@ func (d *DNSFilter) handleSafeSearchDisable(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
|
||||
func (d *DNSFilter) handleSafeSearchStatus(w http.ResponseWriter, r *http.Request) {
|
||||
data := map[string]interface{}{
|
||||
"enabled": d.Config.SafeSearchEnabled,
|
||||
}
|
||||
jsonVal, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "Unable to marshal status json: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, err = w.Write(jsonVal)
|
||||
err := json.NewEncoder(w).Encode(&struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}{
|
||||
Enabled: d.Config.SafeSearchEnabled,
|
||||
})
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "Unable to write response json: %s", err)
|
||||
return
|
||||
|
@ -350,7 +350,26 @@
|
||||
'application/json':
|
||||
'schema':
|
||||
'$ref': '#/components/schemas/DhcpStatus'
|
||||
'501':
|
||||
'500':
|
||||
'content':
|
||||
'application/json':
|
||||
'schema':
|
||||
'$ref': '#/components/schemas/Error'
|
||||
'description': 'Not implemented (for example, on Windows).'
|
||||
'/dhcp/interfaces':
|
||||
'get':
|
||||
'tags':
|
||||
- 'dhcp'
|
||||
'operationId': 'dhcpInterfaces'
|
||||
'summary': 'Gets the available interfaces'
|
||||
'responses':
|
||||
'200':
|
||||
'description': 'OK.'
|
||||
'content':
|
||||
'application/json':
|
||||
'schema':
|
||||
'$ref': '#/components/schemas/NetInterfaces'
|
||||
'500':
|
||||
'content':
|
||||
'application/json':
|
||||
'schema':
|
||||
@ -1620,6 +1639,12 @@
|
||||
'type': 'array'
|
||||
'items':
|
||||
'$ref': '#/components/schemas/DhcpStaticLease'
|
||||
'NetInterfaces':
|
||||
'type': 'object'
|
||||
'description': >
|
||||
Network interfaces dictionary, keys are interface names.
|
||||
'additionalProperties':
|
||||
'$ref': '#/components/schemas/NetInterface'
|
||||
|
||||
'DhcpSearchResult':
|
||||
'type': 'object'
|
||||
@ -1650,7 +1675,12 @@
|
||||
'properties':
|
||||
'found':
|
||||
'type': 'string'
|
||||
'description': 'yes|no|error'
|
||||
'enum':
|
||||
- 'yes'
|
||||
- 'no'
|
||||
- 'error'
|
||||
'description': >
|
||||
The result of searching the other DHCP server.
|
||||
'example': 'no'
|
||||
'error':
|
||||
'type': 'string'
|
||||
@ -1662,7 +1692,12 @@
|
||||
'properties':
|
||||
'static':
|
||||
'type': 'string'
|
||||
'description': 'yes|no|error'
|
||||
'enum':
|
||||
- 'yes'
|
||||
- 'no'
|
||||
- 'error'
|
||||
'description': >
|
||||
The result of determining static IP address.
|
||||
'example': 'yes'
|
||||
'ip':
|
||||
'type': 'string'
|
||||
@ -2015,11 +2050,7 @@
|
||||
'format': 'uint16'
|
||||
'example': 80
|
||||
'interfaces':
|
||||
'type': 'object'
|
||||
'description': >
|
||||
Network interfaces dictionary, keys are interface names.
|
||||
'additionalProperties':
|
||||
'$ref': '#/components/schemas/NetInterface'
|
||||
'$ref': '#/components/schemas/NetInterfaces'
|
||||
'AddressesInfoBeta':
|
||||
'type': 'object'
|
||||
'description': 'AdGuard Home addresses configuration'
|
||||
|
Loading…
Reference in New Issue
Block a user