mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-12-15 11:22:49 +03:00
+ clients API
* /clients handler: new format + /clients/add handler + /clients/delete handler + /clients/update handler
This commit is contained in:
parent
6a7b1aba8b
commit
5fb7e44e79
436
clients.go
436
clients.go
@ -2,32 +2,264 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client information
|
// Client information
|
||||||
type Client struct {
|
type Client struct {
|
||||||
IP string
|
IP string
|
||||||
Name string
|
MAC string
|
||||||
//Source source // Hosts file / User settings / DHCP
|
Name string
|
||||||
|
UseOwnSettings bool // false: use global settings
|
||||||
|
FilteringEnabled bool
|
||||||
|
SafeSearchEnabled bool
|
||||||
|
SafeBrowsingEnabled bool
|
||||||
|
ParentalEnabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type clientJSON struct {
|
type clientJSON struct {
|
||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
Name string `json:"name"`
|
MAC string `json:"mac"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
UseGlobalSettings bool `json:"use_global_settings"`
|
||||||
|
FilteringEnabled bool `json:"filtering_enabled"`
|
||||||
|
ParentalEnabled bool `json:"parental_enabled"`
|
||||||
|
SafeSearchEnabled bool `json:"safebrowsing_enabled"`
|
||||||
|
SafeBrowsingEnabled bool `json:"safesearch_enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var clients []Client
|
type clientSource uint
|
||||||
var clientsFilled bool
|
|
||||||
|
const (
|
||||||
|
ClientSourceHostsFile clientSource = 0 // from /etc/hosts
|
||||||
|
ClientSourceRDNS clientSource = 1 // from rDNS
|
||||||
|
)
|
||||||
|
|
||||||
|
// ClientHost information
|
||||||
|
type ClientHost struct {
|
||||||
|
Host string
|
||||||
|
Source clientSource
|
||||||
|
}
|
||||||
|
|
||||||
|
type clientsContainer struct {
|
||||||
|
list map[string]*Client
|
||||||
|
ipIndex map[string]*Client
|
||||||
|
ipHost map[string]ClientHost // IP -> Hostname
|
||||||
|
lock sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
var clients clientsContainer
|
||||||
|
|
||||||
|
// Initialize clients container
|
||||||
|
func clientsInit() {
|
||||||
|
if clients.list != nil {
|
||||||
|
log.Fatal("clients.list != nil")
|
||||||
|
}
|
||||||
|
clients.list = make(map[string]*Client)
|
||||||
|
clients.ipIndex = make(map[string]*Client)
|
||||||
|
clients.ipHost = make(map[string]ClientHost)
|
||||||
|
|
||||||
|
clientsAddFromHostsFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
func clientsGetList() map[string]*Client {
|
||||||
|
return clients.list
|
||||||
|
}
|
||||||
|
|
||||||
|
func clientExists(ip string) bool {
|
||||||
|
clients.lock.Lock()
|
||||||
|
defer clients.lock.Unlock()
|
||||||
|
|
||||||
|
_, ok := clients.ipIndex[ip]
|
||||||
|
if ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
_, ok = clients.ipHost[ip]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for a client by IP
|
||||||
|
func clientFind(ip string) (Client, bool) {
|
||||||
|
clients.lock.Lock()
|
||||||
|
defer clients.lock.Unlock()
|
||||||
|
|
||||||
|
c, ok := clients.ipIndex[ip]
|
||||||
|
if ok {
|
||||||
|
return *c, true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c = range clients.list {
|
||||||
|
if len(c.MAC) != 0 {
|
||||||
|
mac, err := net.ParseMAC(c.MAC)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ipAddr := dhcpServer.FindIPbyMAC(mac)
|
||||||
|
if ipAddr == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ip == ipAddr.String() {
|
||||||
|
return *c, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Client{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if Client object's fields are correct
|
||||||
|
func clientCheck(c *Client) error {
|
||||||
|
if len(c.Name) == 0 {
|
||||||
|
return fmt.Errorf("Invalid Name")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len(c.IP) == 0 && len(c.MAC) == 0) ||
|
||||||
|
(len(c.IP) != 0 && len(c.MAC) != 0) {
|
||||||
|
return fmt.Errorf("IP or MAC required")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.IP) != 0 {
|
||||||
|
ip := net.ParseIP(c.IP)
|
||||||
|
if ip == nil {
|
||||||
|
return fmt.Errorf("Invalid IP")
|
||||||
|
}
|
||||||
|
c.IP = ip.String()
|
||||||
|
} else {
|
||||||
|
_, err := net.ParseMAC(c.MAC)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Invalid MAC: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a new client object
|
||||||
|
// Return true: success; false: client exists.
|
||||||
|
func clientAdd(c Client) (bool, error) {
|
||||||
|
e := clientCheck(&c)
|
||||||
|
if e != nil {
|
||||||
|
return false, e
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.lock.Lock()
|
||||||
|
defer clients.lock.Unlock()
|
||||||
|
|
||||||
|
// check Name index
|
||||||
|
_, ok := clients.list[c.Name]
|
||||||
|
if ok {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// check IP index
|
||||||
|
if len(c.IP) != 0 {
|
||||||
|
c2, ok := clients.ipIndex[c.IP]
|
||||||
|
if ok {
|
||||||
|
return false, fmt.Errorf("Another client uses the same IP address: %s", c2.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.list[c.Name] = &c
|
||||||
|
if len(c.IP) != 0 {
|
||||||
|
clients.ipIndex[c.IP] = &c
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Tracef("'%s': '%s' | '%s' -> [%d]", c.Name, c.IP, c.MAC, len(clients.list))
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a client
|
||||||
|
func clientDel(name string) bool {
|
||||||
|
clients.lock.Lock()
|
||||||
|
defer clients.lock.Unlock()
|
||||||
|
|
||||||
|
c, ok := clients.list[name]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(clients.list, name)
|
||||||
|
delete(clients.ipIndex, c.IP)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update a client
|
||||||
|
func clientUpdate(name string, c Client) error {
|
||||||
|
err := clientCheck(&c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.lock.Lock()
|
||||||
|
defer clients.lock.Unlock()
|
||||||
|
|
||||||
|
old, ok := clients.list[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Client not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// check Name index
|
||||||
|
if old.Name != c.Name {
|
||||||
|
_, ok = clients.list[c.Name]
|
||||||
|
if ok {
|
||||||
|
return fmt.Errorf("Client already exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check IP index
|
||||||
|
if old.IP != c.IP && len(c.IP) != 0 {
|
||||||
|
c2, ok := clients.ipIndex[c.IP]
|
||||||
|
if ok {
|
||||||
|
return fmt.Errorf("Another client uses the same IP address: %s", c2.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update Name index
|
||||||
|
if old.Name != c.Name {
|
||||||
|
delete(clients.list, old.Name)
|
||||||
|
}
|
||||||
|
clients.list[c.Name] = &c
|
||||||
|
|
||||||
|
// update IP index
|
||||||
|
if old.IP != c.IP {
|
||||||
|
delete(clients.ipIndex, old.IP)
|
||||||
|
}
|
||||||
|
if len(c.IP) != 0 {
|
||||||
|
clients.ipIndex[c.IP] = &c
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func clientAddHost(ip, host string, source clientSource) (bool, error) {
|
||||||
|
clients.lock.Lock()
|
||||||
|
defer clients.lock.Unlock()
|
||||||
|
|
||||||
|
// check index
|
||||||
|
_, ok := clients.ipHost[ip]
|
||||||
|
if ok {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.ipHost[ip] = ClientHost{
|
||||||
|
Host: host,
|
||||||
|
Source: source,
|
||||||
|
}
|
||||||
|
log.Tracef("'%s': '%s' -> [%d]", host, ip, len(clients.ipHost))
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Parse system 'hosts' file and fill clients array
|
// Parse system 'hosts' file and fill clients array
|
||||||
func fillClientInfo() {
|
func clientsAddFromHostsFile() {
|
||||||
hostsFn := "/etc/hosts"
|
hostsFn := "/etc/hosts"
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
hostsFn = os.ExpandEnv("$SystemRoot\\system32\\drivers\\etc\\hosts")
|
hostsFn = os.ExpandEnv("$SystemRoot\\system32\\drivers\\etc\\hosts")
|
||||||
@ -40,6 +272,7 @@ func fillClientInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lines := strings.Split(string(d), "\n")
|
lines := strings.Split(string(d), "\n")
|
||||||
|
n := 0
|
||||||
for _, ln := range lines {
|
for _, ln := range lines {
|
||||||
ln = strings.TrimSpace(ln)
|
ln = strings.TrimSpace(ln)
|
||||||
if len(ln) == 0 || ln[0] == '#' {
|
if len(ln) == 0 || ln[0] == '#' {
|
||||||
@ -51,33 +284,71 @@ func fillClientInfo() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var c Client
|
ok, e := clientAddHost(fields[0], fields[1], ClientSourceHostsFile)
|
||||||
c.IP = fields[0]
|
if e != nil {
|
||||||
c.Name = fields[1]
|
log.Tracef("%s", e)
|
||||||
clients = append(clients, c)
|
}
|
||||||
log.Tracef("%s -> %s", c.IP, c.Name)
|
if ok {
|
||||||
|
n++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Added %d client aliases from %s", len(clients), hostsFn)
|
log.Info("Added %d client aliases from %s", n, hostsFn)
|
||||||
clientsFilled = true
|
}
|
||||||
|
|
||||||
|
type clientHostJSON struct {
|
||||||
|
IP string `json:"ip"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Source string `json:"source"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type clientListJSON struct {
|
||||||
|
Clients []clientJSON `json:"clients"`
|
||||||
|
AutoClients []clientHostJSON `json:"auto_clients"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// respond with information about configured clients
|
// respond with information about configured clients
|
||||||
func handleGetClients(w http.ResponseWriter, r *http.Request) {
|
func handleGetClients(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Tracef("%s %v", r.Method, r.URL)
|
log.Tracef("%s %v", r.Method, r.URL)
|
||||||
|
|
||||||
if !clientsFilled {
|
data := clientListJSON{}
|
||||||
fillClientInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
data := []clientJSON{}
|
clients.lock.Lock()
|
||||||
for _, c := range clients {
|
for _, c := range clients.list {
|
||||||
cj := clientJSON{
|
cj := clientJSON{
|
||||||
IP: c.IP,
|
IP: c.IP,
|
||||||
Name: c.Name,
|
MAC: c.MAC,
|
||||||
|
Name: c.Name,
|
||||||
|
UseGlobalSettings: !c.UseOwnSettings,
|
||||||
|
FilteringEnabled: c.FilteringEnabled,
|
||||||
|
ParentalEnabled: c.ParentalEnabled,
|
||||||
|
SafeSearchEnabled: c.SafeSearchEnabled,
|
||||||
|
SafeBrowsingEnabled: c.SafeBrowsingEnabled,
|
||||||
}
|
}
|
||||||
data = append(data, cj)
|
|
||||||
|
if len(c.MAC) != 0 {
|
||||||
|
hwAddr, _ := net.ParseMAC(c.MAC)
|
||||||
|
ipAddr := dhcpServer.FindIPbyMAC(hwAddr)
|
||||||
|
if ipAddr != nil {
|
||||||
|
cj.IP = ipAddr.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.Clients = append(data.Clients, cj)
|
||||||
}
|
}
|
||||||
|
for ip, ch := range clients.ipHost {
|
||||||
|
cj := clientHostJSON{
|
||||||
|
IP: ip,
|
||||||
|
Name: ch.Host,
|
||||||
|
}
|
||||||
|
cj.Source = "etc/hosts"
|
||||||
|
if ch.Source == ClientSourceRDNS {
|
||||||
|
cj.Source = "rDNS"
|
||||||
|
}
|
||||||
|
data.AutoClients = append(data.AutoClients, cj)
|
||||||
|
}
|
||||||
|
clients.lock.Unlock()
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
e := json.NewEncoder(w).Encode(data)
|
e := json.NewEncoder(w).Encode(data)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
@ -86,7 +357,126 @@ func handleGetClients(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert JSON object to Client object
|
||||||
|
func jsonToClient(cj clientJSON) (*Client, error) {
|
||||||
|
c := Client{
|
||||||
|
IP: cj.IP,
|
||||||
|
MAC: cj.MAC,
|
||||||
|
Name: cj.Name,
|
||||||
|
UseOwnSettings: !cj.UseGlobalSettings,
|
||||||
|
FilteringEnabled: cj.FilteringEnabled,
|
||||||
|
ParentalEnabled: cj.ParentalEnabled,
|
||||||
|
SafeSearchEnabled: cj.SafeSearchEnabled,
|
||||||
|
SafeBrowsingEnabled: cj.SafeBrowsingEnabled,
|
||||||
|
}
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a new client
|
||||||
|
func handleAddClient(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Tracef("%s %v", r.Method, r.URL)
|
||||||
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, http.StatusBadRequest, "failed to read request body: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cj := clientJSON{}
|
||||||
|
err = json.Unmarshal(body, &cj)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, http.StatusBadRequest, "JSON parse: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := jsonToClient(cj)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, http.StatusBadRequest, "%s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ok, err := clientAdd(*c)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, http.StatusBadRequest, "%s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
httpError(w, http.StatusBadRequest, "Client already exists")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = writeAllConfigsAndReloadDNS()
|
||||||
|
returnOK(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove client
|
||||||
|
func handleDelClient(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Tracef("%s %v", r.Method, r.URL)
|
||||||
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, http.StatusBadRequest, "failed to read request body: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cj := clientJSON{}
|
||||||
|
err = json.Unmarshal(body, &cj)
|
||||||
|
if err != nil || len(cj.Name) == 0 {
|
||||||
|
httpError(w, http.StatusBadRequest, "JSON parse: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !clientDel(cj.Name) {
|
||||||
|
httpError(w, http.StatusBadRequest, "Client not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = writeAllConfigsAndReloadDNS()
|
||||||
|
returnOK(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
type clientUpdateJSON struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Data clientJSON `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update client's properties
|
||||||
|
func handleUpdateClient(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Tracef("%s %v", r.Method, r.URL)
|
||||||
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, http.StatusBadRequest, "failed to read request body: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var dj clientUpdateJSON
|
||||||
|
err = json.Unmarshal(body, &dj)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, http.StatusBadRequest, "JSON parse: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(dj.Name) == 0 {
|
||||||
|
httpError(w, http.StatusBadRequest, "Invalid request")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := jsonToClient(dj.Data)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, http.StatusBadRequest, "%s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = clientUpdate(dj.Name, *c)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, http.StatusBadRequest, "%s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = writeAllConfigsAndReloadDNS()
|
||||||
|
returnOK(w)
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterClientsHandlers registers HTTP handlers
|
// RegisterClientsHandlers registers HTTP handlers
|
||||||
func RegisterClientsHandlers() {
|
func RegisterClientsHandlers() {
|
||||||
http.HandleFunc("/control/clients", postInstall(optionalAuth(ensureGET(handleGetClients))))
|
http.HandleFunc("/control/clients", postInstall(optionalAuth(ensureGET(handleGetClients))))
|
||||||
|
http.HandleFunc("/control/clients/add", postInstall(optionalAuth(ensurePOST(handleAddClient))))
|
||||||
|
http.HandleFunc("/control/clients/delete", postInstall(optionalAuth(ensurePOST(handleDelClient))))
|
||||||
|
http.HandleFunc("/control/clients/update", postInstall(optionalAuth(ensurePOST(handleUpdateClient))))
|
||||||
}
|
}
|
||||||
|
122
clients_test.go
Normal file
122
clients_test.go
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestClients(t *testing.T) {
|
||||||
|
var c Client
|
||||||
|
var e error
|
||||||
|
var b bool
|
||||||
|
|
||||||
|
clientsInit()
|
||||||
|
|
||||||
|
// add
|
||||||
|
c = Client{
|
||||||
|
IP: "1.1.1.1",
|
||||||
|
Name: "client1",
|
||||||
|
}
|
||||||
|
b, e = clientAdd(c)
|
||||||
|
if !b || e != nil {
|
||||||
|
t.Fatalf("clientAdd #1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// add #2
|
||||||
|
c = Client{
|
||||||
|
IP: "2.2.2.2",
|
||||||
|
Name: "client2",
|
||||||
|
}
|
||||||
|
b, e = clientAdd(c)
|
||||||
|
if !b || e != nil {
|
||||||
|
t.Fatalf("clientAdd #2")
|
||||||
|
}
|
||||||
|
|
||||||
|
// failed add - name in use
|
||||||
|
c = Client{
|
||||||
|
IP: "1.2.3.5",
|
||||||
|
Name: "client1",
|
||||||
|
}
|
||||||
|
b, e = clientAdd(c)
|
||||||
|
if b {
|
||||||
|
t.Fatalf("clientAdd - name in use")
|
||||||
|
}
|
||||||
|
|
||||||
|
// failed add - ip in use
|
||||||
|
c = Client{
|
||||||
|
IP: "2.2.2.2",
|
||||||
|
Name: "client3",
|
||||||
|
}
|
||||||
|
b, e = clientAdd(c)
|
||||||
|
if b || e == nil {
|
||||||
|
t.Fatalf("clientAdd - ip in use")
|
||||||
|
}
|
||||||
|
|
||||||
|
// get
|
||||||
|
if clientExists("1.2.3.4") {
|
||||||
|
t.Fatalf("clientExists")
|
||||||
|
}
|
||||||
|
if !clientExists("1.1.1.1") {
|
||||||
|
t.Fatalf("clientExists #1")
|
||||||
|
}
|
||||||
|
if !clientExists("2.2.2.2") {
|
||||||
|
t.Fatalf("clientExists #2")
|
||||||
|
}
|
||||||
|
|
||||||
|
// failed update - no such name
|
||||||
|
c.IP = "1.2.3.0"
|
||||||
|
c.Name = "client3"
|
||||||
|
if clientUpdate("client3", c) == nil {
|
||||||
|
t.Fatalf("clientUpdate")
|
||||||
|
}
|
||||||
|
|
||||||
|
// failed update - name in use
|
||||||
|
c.IP = "1.2.3.0"
|
||||||
|
c.Name = "client2"
|
||||||
|
if clientUpdate("client1", c) == nil {
|
||||||
|
t.Fatalf("clientUpdate - name in use")
|
||||||
|
}
|
||||||
|
|
||||||
|
// failed update - ip in use
|
||||||
|
c.IP = "2.2.2.2"
|
||||||
|
c.Name = "client1"
|
||||||
|
if clientUpdate("client1", c) == nil {
|
||||||
|
t.Fatalf("clientUpdate - ip in use")
|
||||||
|
}
|
||||||
|
|
||||||
|
// update
|
||||||
|
c.IP = "1.1.1.2"
|
||||||
|
c.Name = "client1"
|
||||||
|
if clientUpdate("client1", c) != nil {
|
||||||
|
t.Fatalf("clientUpdate")
|
||||||
|
}
|
||||||
|
|
||||||
|
// get after update
|
||||||
|
if clientExists("1.1.1.1") || !clientExists("1.1.1.2") {
|
||||||
|
t.Fatalf("clientExists - get after update")
|
||||||
|
}
|
||||||
|
|
||||||
|
// failed remove - no such name
|
||||||
|
if clientDel("client3") {
|
||||||
|
t.Fatalf("clientDel - no such name")
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove
|
||||||
|
if !clientDel("client1") || clientExists("1.1.1.2") {
|
||||||
|
t.Fatalf("clientDel")
|
||||||
|
}
|
||||||
|
|
||||||
|
// add host client
|
||||||
|
b, e = clientAddHost("1.1.1.1", "host", ClientSourceHostsFile)
|
||||||
|
if !b || e != nil {
|
||||||
|
t.Fatalf("clientAddHost")
|
||||||
|
}
|
||||||
|
|
||||||
|
// failed add - ip exists
|
||||||
|
b, e = clientAddHost("1.1.1.1", "host", ClientSourceHostsFile)
|
||||||
|
if b {
|
||||||
|
t.Fatalf("clientAddHost - ip exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
// get
|
||||||
|
if !clientExists("1.1.1.1") {
|
||||||
|
t.Fatalf("clientAddHost")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user