diff --git a/README.md b/README.md
index db46bf9..2daf691 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
- Terraform v0.12.x
- - https://github.com/n3integration/terraform-godaddy/releases/tag/v1.7.0
+ - https://github.com/n3integration/terraform-godaddy/releases/tag/v1.7.1
- Terraform v0.11.x
- https://github.com/n3integration/terraform-godaddy/releases/tag/v1.6.4
- Terraform v0.10.x
@@ -55,6 +55,7 @@ types include:
* MX
* NS
* SOA
+* SRV
* TXT
```terraform
@@ -82,6 +83,16 @@ resource "godaddy_domain_record" "gd-fancy-domain" {
priority = 1
}
+ record {
+ name = "@"
+ type = "SRV"
+ data = "host.example.com"
+ ttl = 3600
+ service = "_ldap"
+ protocol = "_tcp"
+ port = 389
+ }
+
// specify any A records associated with the domain
addresses = ["192.168.1.2", "192.168.1.3"]
@@ -101,7 +112,7 @@ fully automated imports.
## License
-Copyright 2019 n3integration@gmail.com
+Copyright 2020 n3integration@gmail.com
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/api/types.go b/api/types.go
index 7ba3c7c..1356502 100644
--- a/api/types.go
+++ b/api/types.go
@@ -1,6 +1,7 @@
package api
import (
+ "errors"
"fmt"
"strings"
)
@@ -44,6 +45,8 @@ func (rt RecordType) String() string {
return NSType
case SOA:
return SOAType
+ case SRV:
+ return SRVType
case TXT:
return TXTType
}
@@ -53,6 +56,8 @@ func (rt RecordType) String() string {
const (
DefaultTTL = 3600
DefaultPriority = 0
+ DefaultWeight = 0
+ DefaultPort = 0
StatusActive = "ACTIVE"
StatusCancelled = "CANCELLED"
@@ -64,11 +69,12 @@ const (
MXType = "MX"
NSType = "NS"
SOAType = "SOA"
+ SRVType = "SRV"
TXTType = "TXT"
)
var supportedTypes = []string{
- AType, AAAAType, CNameType, MXType, NSType, SOAType, TXTType,
+ AType, AAAAType, CNameType, MXType, NSType, SOAType, SRVType, TXTType,
}
// Domain encapsulates a domain resource
@@ -83,16 +89,19 @@ type DomainRecord struct {
Type string `json:"type,omitempty"`
Name string `json:"name"`
Data string `json:"data"`
- Priority int `json:"priority,omitempty"`
+ Priority int `json:"priority"`
TTL int `json:"ttl"`
- // Service string `json:"service"`
- // Protocol string `json:"protocol"`
- // Port int `json:"port"`
- // Weight int `json:"weight"`
+ Service string `json:"service,omitempty"`
+ Protocol string `json:"protocol,omitempty"`
+ Weight int `json:"weight"`
+ Port *int `json:"port,omitempty"`
}
+// DomainRecordOpt provides support for setting optional parameters
+type DomainRecordOpt func(*DomainRecord) error
+
// NewDomainRecord validates and constructs a DomainRecord, if valid.
-func NewDomainRecord(name, t, data string, ttl int, priority int) (*DomainRecord, error) {
+func NewDomainRecord(name, t, data string, ttl int, opts ...DomainRecordOpt) (*DomainRecord, error) {
name = strings.TrimSpace(name)
data = strings.TrimSpace(data)
if err := ValidateData(t, data); err != nil {
@@ -101,52 +110,109 @@ func NewDomainRecord(name, t, data string, ttl int, priority int) (*DomainRecord
parts := strings.Split(name, ".")
if len(parts) < 1 || len(parts) > 255 {
- return nil, fmt.Errorf("name must be between 1..255 octets")
+ return nil, errors.New("name must be between 1..255 octets")
}
for _, part := range parts {
if len(part) > 63 {
- return nil, fmt.Errorf("invalid domain name. name octets should be less than 63 characters")
+ return nil, errors.New("invalid domain name. name octets should be less than 63 characters")
}
}
if ttl < 0 {
- return nil, fmt.Errorf("ttl must be a positive value")
- }
- if err := ValidatePriority(priority); err != nil {
- return nil, err
+ return nil, errors.New("ttl must be a positive value")
}
if !isSupportedType(t) {
return nil, fmt.Errorf("type must be one of: %s", supportedTypes)
}
- return &DomainRecord{
- Name: name,
- Type: t,
- Data: data,
- TTL: ttl,
- Priority: priority,
- }, nil
+ dr := &DomainRecord{
+ Name: name,
+ Type: t,
+ Data: data,
+ TTL: ttl,
+ }
+ for _, opt := range opts {
+ if err := opt(dr); err != nil {
+ return nil, err
+ }
+ }
+ return dr, nil
+}
+
+func Priority(priority int) DomainRecordOpt {
+ return func(rec *DomainRecord) error {
+ if err := ValidatePriority(priority); err != nil {
+ return err
+ }
+ rec.Priority = priority
+ return nil
+ }
+}
+
+func Weight(weight int) DomainRecordOpt {
+ return func(rec *DomainRecord) error {
+ if err := ValidateWeight(weight); err != nil {
+ return err
+ }
+ rec.Weight = weight
+ return nil
+ }
+}
+
+func Port(port int) DomainRecordOpt {
+ return func(rec *DomainRecord) error {
+ if port == 0 {
+ return nil
+ }
+ if err := ValidatePort(port); err != nil {
+ return err
+ }
+ rec.Port = &port
+ return nil
+ }
+}
+
+func Service(service string) DomainRecordOpt {
+ return func(rec *DomainRecord) error {
+ if strings.TrimSpace(service) != "" && !strings.HasPrefix(service, "_") {
+ return errors.New("service must start with an underscore (e.g. _ldap)")
+ }
+ rec.Service = service
+ return nil
+ }
+}
+
+func Protocol(proto string) DomainRecordOpt {
+ return func(rec *DomainRecord) error {
+ if strings.TrimSpace(proto) != "" && !strings.HasPrefix(proto, "_") {
+ return errors.New("protocol must start with an underscore (e.g. _tcp)")
+ }
+ rec.Protocol = proto
+ return nil
+ }
}
// NewNSRecord constructs a nameserver record from the supplied data
func NewNSRecord(data string) (*DomainRecord, error) {
- return NewDomainRecord(Ptr, NSType, data, DefaultTTL, DefaultPriority)
+ return NewDomainRecord(Ptr, NSType, data, DefaultTTL)
}
// NewARecord constructs a new address record from the supplied data
func NewARecord(data string) (*DomainRecord, error) {
- return NewDomainRecord(Ptr, AType, data, DefaultTTL, DefaultPriority)
+ return NewDomainRecord(Ptr, AType, data, DefaultTTL)
}
// ValidateData performs bounds checking on a data element
func ValidateData(t, data string) error {
switch t {
+ case SRVType:
+ return nil
case TXTType:
if len(data) < 0 || len(data) > 512 {
- return fmt.Errorf("TXT data must be between 0..512 characters in length")
+ return errors.New("TXT data must be between 0..512 characters in length")
}
default:
if len(data) < 0 || len(data) > 255 {
- return fmt.Errorf("data must be between 0..255 characters in length")
+ return errors.New("data must be between 0..255 characters in length")
}
}
return nil
@@ -155,7 +221,21 @@ func ValidateData(t, data string) error {
// ValidatePriority performs bounds checking on priority element
func ValidatePriority(priority int) error {
if priority < 0 || priority > 65535 {
- return fmt.Errorf("priority must be between 0..65535 (16 bit)")
+ return errors.New("priority must be between 0..65535 (16 bit)")
+ }
+ return nil
+}
+
+func ValidateWeight(weight int) error {
+ if weight < 0 || weight > 100 {
+ return errors.New("weight must be between 0..100")
+ }
+ return nil
+}
+
+func ValidatePort(port int) error {
+ if port < 1 || port > 65535 {
+ return errors.New("port must be between 1..65535")
}
return nil
}
diff --git a/api/types_test.go b/api/types_test.go
index 0d6090c..792a8c8 100644
--- a/api/types_test.go
+++ b/api/types_test.go
@@ -18,7 +18,7 @@ func TestNewDomainRecord(t *testing.T) {
}
for _, test := range criteria {
t.Run(test.Name, func(t *testing.T) {
- if _, err := NewDomainRecord(test.Domain, "A", "127.0.0.1", 60, 0); err != nil {
+ if _, err := NewDomainRecord(test.Domain, "A", "127.0.0.1", 60); err != nil {
if !test.Negative {
t.Errorf("failed to create new domain record: %s", err)
}
@@ -34,4 +34,4 @@ func randBinaryString(n int) string {
out[i] = binRunes[rand.Intn(len(binRunes))]
}
return string(out)
-}
\ No newline at end of file
+}
diff --git a/install.sh b/install.sh
index a1a6f70..02ee3ec 100755
--- a/install.sh
+++ b/install.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-version=1.7.0
+version=1.7.1
os=$(uname -s | tr '[:upper:]' '[:lower:]')
mach=$(uname -m)
diff --git a/plugin/terraform-godaddy/resource_dns_record.go b/plugin/terraform-godaddy/resource_dns_record.go
index c558eee..0c4f0cf 100644
--- a/plugin/terraform-godaddy/resource_dns_record.go
+++ b/plugin/terraform-godaddy/resource_dns_record.go
@@ -22,6 +22,10 @@ const (
recData = "data"
recTTL = "ttl"
recPriority = "priority"
+ recWeight = "weight"
+ recProto = "protocol"
+ recService = "service"
+ recPort = "port"
)
type domainRecordResource struct {
@@ -67,7 +71,11 @@ func newDomainRecordResource(d *schema.ResourceData) (*domainRecordResource, err
t,
data[recData].(string),
data[recTTL].(int),
- data[recPriority].(int))
+ api.Priority(data[recPriority].(int)),
+ api.Weight(data[recWeight].(int)),
+ api.Port(data[recPort].(int)),
+ api.Service(data[recService].(string)),
+ api.Protocol(data[recProto].(string)))
if err != nil {
return r, err
@@ -175,6 +183,24 @@ func resourceDomainRecord() *schema.Resource {
Optional: true,
Default: api.DefaultPriority,
},
+ recWeight: {
+ Type: schema.TypeInt,
+ Optional: true,
+ Default: api.DefaultWeight,
+ },
+ recService: {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+ recProto: {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+ recPort: {
+ Type: schema.TypeInt,
+ Optional: true,
+ Default: api.DefaultPort,
+ },
},
},
},
@@ -293,6 +319,10 @@ func flattenRecords(list []*api.DomainRecord) []map[string]interface{} {
recData: r.Data,
recTTL: r.TTL,
recPriority: r.Priority,
+ recWeight: r.Weight,
+ recPort: r.Port,
+ recService: r.Service,
+ recProto: r.Protocol,
}
}
return result