Skip to content

Commit

Permalink
Merge pull request #133 from maksym-nazarenko/refactor/dns_record
Browse files Browse the repository at this point in the history
Refactor/dns record
  • Loading branch information
ddelnano authored Jan 12, 2023
2 parents 7306508 + 5f91235 commit af8c34b
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 191 deletions.
43 changes: 2 additions & 41 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ import (
"errors"
"fmt"
"log"
"math"
"os"
"reflect"
"strconv"
"strings"
"time"

"github.com/go-routeros/routeros"
"github.com/go-routeros/routeros/proto"
Expand Down Expand Up @@ -241,51 +239,14 @@ func parseStruct(v *reflect.Value, sentence proto.Sentence) {
b, _ := strconv.ParseBool(pair.Value)
field.SetBool(b)
case reflect.Int:
if contains(tags, "ttlToSeconds") {
field.SetInt(int64(ttlToSeconds(pair.Value)))
} else {
intValue, _ := strconv.Atoi(pair.Value)
field.SetInt(int64(intValue))
}
intValue, _ := strconv.Atoi(pair.Value)
field.SetInt(int64(intValue))
}
}
}
}
}

func ttlToSeconds(ttl string) int {
parts := strings.Split(ttl, "d")

idx := 0
days := 0
var err error
if len(parts) == 2 {
idx = 1
days, err = strconv.Atoi(parts[0])

// We should be parsing an ascii number
// if this fails we should fail loudly
if err != nil {
panic(err)
}

// In the event we just get days parts[1] will be an
// empty string. Just coerce that into 0 seconds.
if parts[1] == "" {
parts[1] = "0s"
}
}
d, err := time.ParseDuration(parts[idx])

// We should never receive a duration greater than
// 23h59m59s. So this should always parse.
if err != nil {
panic(err)
}
return 86400*days + int(d)/int(math.Pow10(9))

}

func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
Expand Down
52 changes: 0 additions & 52 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,6 @@ import (
"github.com/stretchr/testify/assert"
)

func TestTtlToSeconds(t *testing.T) {
tests := []struct {
expected int
input string
}{
{300, "5m"},
{59, "59s"},
{301, "5m1s"},
{55259, "15h20m59s"},
{141659, "1d15h20m59s"},
{228059, "2d15h20m59s"},
{86400, "1d"},
}

for _, test := range tests {
actual := ttlToSeconds(test.input)
if test.expected != actual {
t.Errorf("Input %s returned %d instead of %d", test.input, actual, test.expected)
}
}
}

func TestUnmarshal(t *testing.T) {
type testStruct struct {
Name string
Expand Down Expand Up @@ -243,36 +221,6 @@ func TestUnmarshalOnSlices(t *testing.T) {
}
}

func TestUnmarshal_ttlToSeconds(t *testing.T) {
ttlStr := "5m"
expectedTtl := ttlToSeconds(ttlStr)
testStruct := struct {
Ttl int `mikrotik:"ttl,ttlToSeconds"`
}{}
reply := routeros.Reply{
Re: []*proto.Sentence{
{
Word: "!re",
List: []proto.Pair{
{
Key: "ttl",
Value: ttlStr,
},
},
},
},
}
err := Unmarshal(reply, &testStruct)

if err != nil {
t.Errorf("Failed to unmarshal with error: %v", err)
}

if testStruct.Ttl != expectedTtl {
t.Errorf("Failed to unmarshal ttl field with `ttlToSeconds`. Expected: '%d', received: %v", expectedTtl, testStruct.Ttl)
}
}

func TestMarshal(t *testing.T) {
action := "/test/owner/add"
testCases := []struct {
Expand Down
104 changes: 52 additions & 52 deletions client/dns.go
Original file line number Diff line number Diff line change
@@ -1,87 +1,87 @@
package client

import (
"fmt"
"log"
"github.com/ddelnano/terraform-provider-mikrotik/client/types"
"github.com/go-routeros/routeros"
)

type DnsRecord struct {
Id string `mikrotik:".id"`
Name string `mikrotik:"name"`
Ttl int `mikrotik:"ttl,ttlToSeconds"`
Address string `mikrotik:"address"`
Comment string `mikrotik:"comment"`
Id string `mikrotik:".id"`
Name string `mikrotik:"name"`
Ttl types.MikrotikDuration `mikrotik:"ttl"`
Address string `mikrotik:"address"`
Comment string `mikrotik:"comment"`
}

func (client Mikrotik) AddDnsRecord(d *DnsRecord) (*DnsRecord, error) {
c, err := client.getMikrotikClient()
func (d *DnsRecord) ActionToCommand(action Action) string {
return map[Action]string{
Add: "/ip/dns/static/add",
Find: "/ip/dns/static/print",
List: "/ip/dns/static/print",
Update: "/ip/dns/static/set",
Delete: "/ip/dns/static/remove",
}[action]
}

if err != nil {
return nil, err
}
cmd := Marshal("/ip/dns/static/add", d)
log.Printf("[INFO] Running the mikrotik command: `%s`", cmd)
r, err := c.RunArgs(cmd)
log.Printf("[DEBUG] /ip/dns/static/add returned %v", r)
func (d *DnsRecord) IDField() string {
return ".id"
}

if err != nil {
return nil, err
}
func (d *DnsRecord) ID() string {
return d.Id
}

return client.FindDnsRecord(d.Name)
func (d *DnsRecord) SetID(id string) {
d.Id = id
}

func (client Mikrotik) FindDnsRecord(name string) (*DnsRecord, error) {
c, err := client.getMikrotikClient()
func (d *DnsRecord) AfterAddHook(r *routeros.Reply) {
d.Id = r.Done.Map["ret"]
}

if err != nil {
return nil, err
}
cmd := []string{"/ip/dns/static/print", "?name=" + name}
log.Printf("[INFO] Running the mikrotik command: `%s`", cmd)
r, err := c.RunArgs(cmd)
func (d *DnsRecord) FindField() string {
return "name"
}

if err != nil {
return nil, err
}
func (d *DnsRecord) FindFieldValue() string {
return d.Name
}

log.Printf("[DEBUG] Found dns record: %v", r)
func (d *DnsRecord) DeleteField() string {
return "numbers"
}

record := DnsRecord{}
err = Unmarshal(*r, &record)
func (d *DnsRecord) DeleteFieldValue() string {
return d.Id
}

func (client Mikrotik) AddDnsRecord(d *DnsRecord) (*DnsRecord, error) {
res, err := client.Add(d)
if err != nil {
return nil, err
}

if record.Name == "" {
return nil, NewNotFound(fmt.Sprintf("dns record `%s` not found", name))
return res.(*DnsRecord), nil
}

func (client Mikrotik) FindDnsRecord(name string) (*DnsRecord, error) {
res, err := client.Find(&DnsRecord{Name: name})
if err != nil {
return nil, err
}

return &record, nil
return res.(*DnsRecord), nil
}

func (client Mikrotik) UpdateDnsRecord(d *DnsRecord) (*DnsRecord, error) {
c, err := client.getMikrotikClient()

res, err := client.Update(d)
if err != nil {
return nil, err
}
cmd := Marshal("/ip/dns/static/set", d)
log.Printf("[INFO] Running the mikrotik command: `%s`", cmd)
_, err = c.RunArgs(cmd)

return client.FindDnsRecord(d.Name)
return res.(*DnsRecord), nil
}

func (client Mikrotik) DeleteDnsRecord(id string) error {
c, err := client.getMikrotikClient()

if err != nil {
return err
}
cmd := []string{"/ip/dns/static/remove", "=numbers=" + id}
log.Printf("[INFO] Running the mikrotik command: `%s`", cmd)
_, err = c.RunArgs(cmd)
return err
return client.Delete(&DnsRecord{Id: id})
}
45 changes: 0 additions & 45 deletions client/dns_crud.go

This file was deleted.

3 changes: 2 additions & 1 deletion mikrotik/resource_dns_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"

"github.com/ddelnano/terraform-provider-mikrotik/client"
"github.com/ddelnano/terraform-provider-mikrotik/client/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
Expand Down Expand Up @@ -139,7 +140,7 @@ func prepareDnsRecord(d *schema.ResourceData) *client.DnsRecord {
dnsRecord := new(client.DnsRecord)

dnsRecord.Name = d.Get("name").(string)
dnsRecord.Ttl = d.Get("ttl").(int)
dnsRecord.Ttl = types.MikrotikDuration(d.Get("ttl").(int))
dnsRecord.Address = d.Get("address").(string)
dnsRecord.Comment = d.Get("comment").(string)

Expand Down

0 comments on commit af8c34b

Please sign in to comment.