From 1c3e6525b18f7c88d0155f856518a89415d0d95e Mon Sep 17 00:00:00 2001 From: Shulhan Date: Wed, 11 May 2022 01:55:01 +0700 Subject: cmd/resolver: implement command to add new record to hosts file The command has the following signature, resolver hosts.d rr add Given the hosts file name "hosts" and domain "my.hosts" with value "127.0.0.1", it will add new line "127.0.0.1 my.hosts" to the "hosts" file. If the domain name already exists, the new record will be appended instead of replaced. --- _doc/resolver.adoc | 21 +++++++++++++++++ _sys/usr/share/man/man1/resolver.1.gz | Bin 2470 -> 2811 bytes client.go | 32 +++++++++++++++++++++++++ cmd/resolver/main.go | 21 ++++++++++++++++- cmd/resolver/resolver.go | 43 ++++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletion(-) diff --git a/_doc/resolver.adoc b/_doc/resolver.adoc index 98bb5e3..f0d40de 100644 --- a/_doc/resolver.adoc +++ b/_doc/resolver.adoc @@ -171,6 +171,16 @@ Get the content of hosts file inside the hosts.d directory by file name. -- +hosts.d rr add :: ++ +-- +Insert a new record and save it to the hosts file identified by +"name". +If the domain name already exists, the new record will be appended +instead of replaced. +-- + + == EXIT STATUS Upon exit and success +resolver+ will return 0, or 1 otherwise. @@ -259,6 +269,17 @@ Get the content of hosts file named "myhosts" inside the hosts.d directory, } ] +Add new record "127.0.0.1 my.hosts" to hosts file named "hosts", + + $ resolver hosts.d rr add hosts my.hosts 127.0.0.1 + { + "Value": "127.0.0.1", + "Name": "my.hosts", + "Type": 1, + "Class": 1, + "TTL": 604800 + } + == AUTHOR diff --git a/_sys/usr/share/man/man1/resolver.1.gz b/_sys/usr/share/man/man1/resolver.1.gz index 635cd25..61dc96c 100644 Binary files a/_sys/usr/share/man/man1/resolver.1.gz and b/_sys/usr/share/man/man1/resolver.1.gz differ diff --git a/client.go b/client.go index bfea21a..cc4399e 100644 --- a/client.go +++ b/client.go @@ -348,3 +348,35 @@ func (cl *Client) HostsdGet(name string) (listrr []*dns.ResourceRecord, err erro } return listrr, nil } + +// HostsdRecordAdd add new resource record to the hosts file. +func (cl *Client) HostsdRecordAdd(hostsName, domain, value string) (record *dns.ResourceRecord, err error) { + var ( + logp = "HostsdRecordAdd" + res = libhttp.EndpointResponse{ + Data: &record, + } + params = url.Values{} + + resb []byte + ) + + params.Set(paramNameName, hostsName) + params.Set(paramNameDomain, domain) + params.Set(paramNameValue, value) + + _, resb, err = cl.PostForm(apiHostsdRR, nil, params) + if err != nil { + return nil, fmt.Errorf("%s: %w", logp, err) + } + + err = json.Unmarshal(resb, &res) + if err != nil { + return nil, fmt.Errorf("%s: %w", logp, err) + } + if res.Code != http.StatusOK { + return nil, fmt.Errorf("%s: %d %s", logp, res.Code, res.Message) + } + + return record, nil +} diff --git a/cmd/resolver/main.go b/cmd/resolver/main.go index 284c521..2c40b90 100644 --- a/cmd/resolver/main.go +++ b/cmd/resolver/main.go @@ -21,11 +21,13 @@ const ( cmdHostsd = "hosts.d" cmdQuery = "query" + subCmdAdd = "add" subCmdCreate = "create" subCmdDelete = "delete" subCmdDisable = "disable" subCmdEnable = "enable" subCmdGet = "get" + subCmdRR = "rr" subCmdRemove = "remove" subCmdSearch = "search" subCmdUpdate = "update" @@ -197,6 +199,13 @@ hosts.d get Get the content of hosts file inside the hosts.d directory by file name. +hosts.d rr add + + Insert a new record and save it to the hosts file identified by + "name". + If the domain name already exists, the new record will be appended + instead of replaced. + == Examples @@ -280,5 +289,15 @@ Get the content of hosts file named "myhosts" inside the hosts.d directory, "TTL": 604800 } ] -`) + +Add new record "127.0.0.1 my.hosts" to hosts file named "hosts", + + $ resolver hosts.d rr add hosts my.hosts 127.0.0.1 + { + "Value": "127.0.0.1", + "Name": "my.hosts", + "Type": 1, + "Class": 1, + "TTL": 604800 + }`) } diff --git a/cmd/resolver/resolver.go b/cmd/resolver/resolver.go index 1c55669..62ce953 100644 --- a/cmd/resolver/resolver.go +++ b/cmd/resolver/resolver.go @@ -319,11 +319,54 @@ func (rsol *resolver) doCmdHostsd(args []string) { fmt.Println(string(jsonb)) + case subCmdRR: + rsol.doCmdHostsdRecord(args[1:]) + default: log.Fatalf("resolver: %s: unknown sub command: %s", rsol.cmd, subCmd) } } +func (rsol *resolver) doCmdHostsdRecord(args []string) { + if len(args) == 0 { + log.Fatalf("resolver: %s %s %s: missing arguments", rsol.cmd, cmdHostsd, subCmdRR) + } + + var ( + subCmd = strings.ToLower(args[0]) + + resc *rescached.Client + record *dns.ResourceRecord + jsonb []byte + err error + ) + + switch subCmd { + case subCmdAdd: + args = args[1:] + if len(args) < 3 { + log.Fatalf("resolver: missing arguments") + } + + resc = rsol.newRescachedClient() + record, err = resc.HostsdRecordAdd(args[0], args[1], args[2]) + if err != nil { + log.Fatalf("resolver: %s", err) + } + + jsonb, err = json.MarshalIndent(record, "", " ") + if err != nil { + log.Fatalf("resolver: %s", err) + } + + fmt.Println(string(jsonb)) + + case subCmdDelete: + default: + log.Fatalf("resolver: %s %s: unknown command %s", rsol.cmd, subCmdRR, subCmd) + } +} + func (rsol *resolver) doCmdQuery(args []string) { var ( maxAttempts = defAttempts -- cgit v1.3