adguardhome-sync/pkg/client/client.go

309 lines
8.9 KiB
Go
Raw Normal View History

2021-03-28 06:40:59 +08:00
package client
import (
2021-03-28 20:09:31 +08:00
"crypto/tls"
2021-03-28 06:40:59 +08:00
"fmt"
2021-03-28 15:58:54 +08:00
"net/url"
2021-03-28 20:09:31 +08:00
"path"
2021-03-28 15:58:54 +08:00
2021-03-28 06:40:59 +08:00
"github.com/bakito/adguardhome-sync/pkg/log"
"github.com/bakito/adguardhome-sync/pkg/types"
"github.com/go-resty/resty/v2"
"go.uber.org/zap"
)
var (
l = log.GetLogger("client")
)
// New create a new client
2021-03-28 20:09:31 +08:00
func New(config types.AdGuardInstance) (Client, error) {
2021-03-28 06:40:59 +08:00
2021-03-28 20:09:31 +08:00
var apiURL string
if config.APIPath == "" {
apiURL = fmt.Sprintf("%s/control", config.URL)
} else {
apiURL = fmt.Sprintf("%s/%s", config.URL, config.APIPath)
2021-03-28 06:40:59 +08:00
}
u, err := url.Parse(apiURL)
if err != nil {
return nil, err
}
2021-03-28 20:09:31 +08:00
u.Path = path.Clean(u.Path)
cl := resty.New().SetHostURL(u.String()).SetDisableWarn(true)
if config.InsecureSkipVerify {
cl.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
}
if config.Username != "" && config.Password != "" {
cl = cl.SetBasicAuth(config.Username, config.Password)
}
2021-03-28 06:40:59 +08:00
return &client{
2021-03-28 17:32:41 +08:00
host: u.Host,
2021-03-28 06:40:59 +08:00
client: cl,
log: l.With("host", u.Host),
}, nil
}
// Client AdGuard Home API client interface
2021-03-28 06:40:59 +08:00
type Client interface {
2021-03-28 17:32:41 +08:00
Host() string
2021-03-28 06:40:59 +08:00
Status() (*types.Status, error)
2021-03-31 08:28:18 +08:00
ToggleProtection(enable bool) error
2021-03-28 06:40:59 +08:00
RewriteList() (*types.RewriteEntries, error)
AddRewriteEntries(e ...types.RewriteEntry) error
DeleteRewriteEntries(e ...types.RewriteEntry) error
Filtering() (*types.FilteringStatus, error)
2021-03-28 14:59:18 +08:00
ToggleFiltering(enabled bool, interval int) error
2021-03-28 06:40:59 +08:00
AddFilters(whitelist bool, e ...types.Filter) error
DeleteFilters(whitelist bool, e ...types.Filter) error
RefreshFilters(whitelist bool) error
SetCustomRules(rules types.UserRules) error
2021-03-31 08:28:18 +08:00
SafeBrowsing() (bool, error)
ToggleSafeBrowsing(enable bool) error
Parental() (bool, error)
2021-03-28 06:40:59 +08:00
ToggleParental(enable bool) error
2021-03-31 08:28:18 +08:00
SafeSearch() (bool, error)
2021-03-28 06:40:59 +08:00
ToggleSafeSearch(enable bool) error
2021-03-28 15:19:44 +08:00
2021-03-28 22:03:34 +08:00
Services() (*types.Services, error)
2021-03-28 15:19:44 +08:00
SetServices(services types.Services) error
2021-03-28 15:58:54 +08:00
Clients() (*types.Clients, error)
AddClients(client ...types.Client) error
UpdateClients(client ...types.Client) error
DeleteClients(client ...types.Client) error
2021-04-03 23:52:08 +08:00
QueryLogConfig() (*types.QueryLogConfig, error)
SetQueryLogConfig(enabled bool, interval int, anonymizeClientIP bool) error
StatsConfig() (*types.IntervalConfig, error)
SetStatsConfig(interval int) error
2021-03-28 06:40:59 +08:00
}
type client struct {
client *resty.Client
log *zap.SugaredLogger
2021-03-28 17:32:41 +08:00
host string
2021-03-28 06:40:59 +08:00
}
2021-03-28 17:32:41 +08:00
func (cl *client) Host() string {
return cl.host
}
2021-03-28 06:40:59 +08:00
func (cl *client) Status() (*types.Status, error) {
status := &types.Status{}
_, err := cl.client.R().EnableTrace().SetResult(status).Get("status")
return status, err
}
func (cl *client) RewriteList() (*types.RewriteEntries, error) {
rewrites := &types.RewriteEntries{}
_, err := cl.client.R().EnableTrace().SetResult(&rewrites).Get("/rewrite/list")
return rewrites, err
}
func (cl *client) AddRewriteEntries(entries ...types.RewriteEntry) error {
for _, e := range entries {
cl.log.With("domain", e.Domain, "answer", e.Answer).Info("Add rewrite entry")
_, err := cl.client.R().EnableTrace().SetBody(&e).Post("/rewrite/add")
if err != nil {
return err
}
}
return nil
}
func (cl *client) DeleteRewriteEntries(entries ...types.RewriteEntry) error {
for _, e := range entries {
cl.log.With("domain", e.Domain, "answer", e.Answer).Info("Delete rewrite entry")
_, err := cl.client.R().EnableTrace().SetBody(&e).Post("/rewrite/delete")
if err != nil {
return err
}
}
return nil
}
2021-03-31 08:28:18 +08:00
func (cl *client) SafeBrowsing() (bool, error) {
return cl.toggleStatus("safebrowsing")
}
func (cl *client) ToggleSafeBrowsing(enable bool) error {
return cl.toggleBool("safebrowsing", enable)
}
func (cl *client) Parental() (bool, error) {
return cl.toggleStatus("parental")
2021-03-28 06:40:59 +08:00
}
func (cl *client) ToggleParental(enable bool) error {
2021-03-31 08:28:18 +08:00
return cl.toggleBool("parental", enable)
}
func (cl *client) SafeSearch() (bool, error) {
return cl.toggleStatus("safesearch")
2021-03-28 06:40:59 +08:00
}
func (cl *client) ToggleSafeSearch(enable bool) error {
2021-03-31 08:28:18 +08:00
return cl.toggleBool("safesearch", enable)
2021-03-28 06:40:59 +08:00
}
2021-03-31 08:28:18 +08:00
func (cl *client) toggleStatus(mode string) (bool, error) {
2021-04-03 23:52:08 +08:00
fs := &types.EnableConfig{}
2021-03-31 08:28:18 +08:00
_, err := cl.client.R().EnableTrace().SetResult(fs).Get(fmt.Sprintf("/%s/status", mode))
return fs.Enabled, err
}
func (cl *client) toggleBool(mode string, enable bool) error {
2021-03-31 08:34:26 +08:00
cl.log.With("enable", enable).Info(fmt.Sprintf("Toggle %s", mode))
2021-03-28 06:40:59 +08:00
var target string
if enable {
target = "enable"
} else {
target = "disable"
}
_, err := cl.client.R().EnableTrace().Post(fmt.Sprintf("/%s/%s", mode, target))
return err
}
func (cl *client) Filtering() (*types.FilteringStatus, error) {
f := &types.FilteringStatus{}
_, err := cl.client.R().EnableTrace().SetResult(f).Get("/filtering/status")
return f, err
}
func (cl *client) AddFilters(whitelist bool, filters ...types.Filter) error {
for _, f := range filters {
cl.log.With("url", f.URL, "whitelist", whitelist).Info("Add filter")
ff := &types.Filter{Name: f.Name, URL: f.URL, Whitelist: whitelist}
_, err := cl.client.R().EnableTrace().SetBody(ff).Post("/filtering/add_url")
if err != nil {
return err
}
}
return nil
}
func (cl *client) DeleteFilters(whitelist bool, filters ...types.Filter) error {
for _, f := range filters {
cl.log.With("url", f.URL, "whitelist", whitelist).Info("Delete filter")
ff := &types.Filter{URL: f.URL, Whitelist: whitelist}
_, err := cl.client.R().EnableTrace().SetBody(ff).Post("/filtering/remove_url")
if err != nil {
return err
}
}
return nil
}
func (cl *client) RefreshFilters(whitelist bool) error {
cl.log.With("whitelist", whitelist).Info("Refresh filter")
_, err := cl.client.R().EnableTrace().SetBody(&types.RefreshFilter{Whitelist: whitelist}).Post("/filtering/refresh")
return err
}
2021-03-31 08:28:18 +08:00
func (cl *client) ToggleProtection(enable bool) error {
cl.log.With("enable", enable).Info("Toggle protection")
_, err := cl.client.R().EnableTrace().SetBody(&types.Protection{ProtectionEnabled: enable}).Post("/dns_config")
return err
}
2021-03-28 06:40:59 +08:00
func (cl *client) SetCustomRules(rules types.UserRules) error {
cl.log.With("rules", len(rules)).Info("Set user rules")
_, err := cl.client.R().EnableTrace().SetBody(rules.String()).Post("/filtering/set_rules")
return err
}
2021-03-28 14:59:18 +08:00
func (cl *client) ToggleFiltering(enabled bool, interval int) error {
cl.log.With("enabled", enabled, "interval", interval).Info("Toggle filtering")
2021-04-03 23:52:08 +08:00
_, err := cl.client.R().EnableTrace().SetBody(&types.FilteringConfig{
EnableConfig: types.EnableConfig{Enabled: enabled},
IntervalConfig: types.IntervalConfig{Interval: interval},
}).Post("/filtering/config")
2021-03-28 14:59:18 +08:00
return err
}
2021-03-28 15:19:44 +08:00
2021-03-28 22:03:34 +08:00
func (cl *client) Services() (*types.Services, error) {
2021-03-28 15:19:44 +08:00
svcs := &types.Services{}
_, err := cl.client.R().EnableTrace().SetResult(svcs).Get("/blocked_services/list")
2021-03-28 22:03:34 +08:00
return svcs, err
2021-03-28 15:19:44 +08:00
}
func (cl *client) SetServices(services types.Services) error {
cl.log.With("services", len(services)).Info("Set services")
_, err := cl.client.R().EnableTrace().SetBody(&services).Post("/blocked_services/set")
return err
}
2021-03-28 15:58:54 +08:00
func (cl *client) Clients() (*types.Clients, error) {
clients := &types.Clients{}
_, err := cl.client.R().EnableTrace().SetResult(clients).Get("/clients")
return clients, err
}
func (cl *client) AddClients(clients ...types.Client) error {
for _, client := range clients {
cl.log.With("name", client.Name).Info("Add client")
_, err := cl.client.R().EnableTrace().SetBody(&client).Post("/clients/add")
if err != nil {
return err
}
}
return nil
}
func (cl *client) UpdateClients(clients ...types.Client) error {
for _, client := range clients {
cl.log.With("name", client.Name).Info("Update client")
_, err := cl.client.R().EnableTrace().SetBody(&types.ClientUpdate{Name: client.Name, Data: client}).Post("/clients/update")
if err != nil {
return err
}
}
return nil
}
func (cl *client) DeleteClients(clients ...types.Client) error {
for _, client := range clients {
cl.log.With("name", client.Name).Info("Delete client")
_, err := cl.client.R().EnableTrace().SetBody(&client).Post("/clients/delete")
if err != nil {
return err
}
}
return nil
}
2021-04-03 23:52:08 +08:00
func (cl *client) QueryLogConfig() (*types.QueryLogConfig, error) {
qlc := &types.QueryLogConfig{}
_, err := cl.client.R().EnableTrace().SetResult(qlc).Get("/querylog_info")
return qlc, err
}
func (cl *client) SetQueryLogConfig(enabled bool, interval int, anonymizeClientIP bool) error {
cl.log.With("enabled", enabled, "interval", interval, "anonymizeClientIP", anonymizeClientIP).Info("Set query log config")
_, err := cl.client.R().EnableTrace().SetBody(&types.QueryLogConfig{
EnableConfig: types.EnableConfig{Enabled: enabled},
IntervalConfig: types.IntervalConfig{Interval: interval},
AnonymizeClientIP: anonymizeClientIP,
}).Post("/querylog_config")
return err
}
func (cl *client) StatsConfig() (*types.IntervalConfig, error) {
stats := &types.IntervalConfig{}
_, err := cl.client.R().EnableTrace().SetResult(stats).Get("/stats_info")
return stats, err
}
func (cl *client) SetStatsConfig(interval int) error {
cl.log.With("interval", interval).Info("Set stats config")
_, err := cl.client.R().EnableTrace().SetBody(&types.IntervalConfig{Interval: interval}).Post("/stats_config")
return err
}