1 package dns
2 3 import (
4 "encoding/json"
5 6 "gopkg.in/ns1/ns1-go.v2/rest/model/data"
7 )
8 9 // Zone wraps an NS1 /zone resource
10 type Zone struct {
11 // Zones have metadata tables, but no filters act on 'zone-level' meta.
12 Meta *data.Meta `json:"meta,omitempty"`
13 14 // Read-only fields
15 DNSServers []string `json:"dns_servers,omitempty"`
16 NetworkPools []string `json:"network_pools,omitempty"`
17 Pool string `json:"pool,omitempty"` // Deprecated
18 LocalTags []string `json:"local_tags,omitempty"` // Only relevant for DDI
19 20 ID string `json:"id,omitempty"`
21 Zone string `json:"zone,omitempty"`
22 23 TTL int `json:"ttl,omitempty"`
24 NxTTL int `json:"nx_ttl,omitempty"`
25 Retry int `json:"retry,omitempty"`
26 Serial int `json:"serial,omitempty"`
27 Refresh int `json:"refresh,omitempty"`
28 Expiry int `json:"expiry,omitempty"`
29 Hostmaster string `json:"hostmaster,omitempty"`
30 PrimaryMaster string `json:"primary_master,omitempty"`
31 32 // If this is a linked zone, Link points to an existing standard zone,
33 // reusing its configuration and records. Link is a zones' domain name.
34 Link *string `json:"link,omitempty"`
35 36 // Networks contains the network ids the zone is available. Most zones
37 // will be in the NSONE Global Network(which is id 0).
38 NetworkIDs []int `json:"-"`
39 // Networks is an Auxiliary field to help with JSON marshalling/unmarshalling of NetworkIDs for internal use only
40 Networks *[]int `json:"networks,omitempty"`
41 Records []*ZoneRecord `json:"records,omitempty"`
42 43 // Primary contains info to enable slaving of the zone by third party dns servers.
44 Primary *ZonePrimary `json:"primary,omitempty"`
45 // Secondary contains info for slaving the zone to a primary dns server.
46 Secondary *ZoneSecondary `json:"secondary,omitempty"`
47 48 // Whether or not DNSSEC is enabled on the zone. Note we use a pointer so
49 // leaving this unset will not change a previous setting.
50 DNSSEC *bool `json:"dnssec,omitempty"`
51 52 // Contains the key/value tag information associated to the zone
53 Tags map[string]string `json:"tags,omitempty"` // Only relevant for DDI
54 }
55 56 func (z Zone) MarshalJSON() ([]byte, error) {
57 type Alias Zone
58 aux := &struct {
59 *Alias
60 }{
61 Alias: (*Alias)(&z),
62 }
63 64 if z.NetworkIDs != nil {
65 aux.Networks = &z.NetworkIDs
66 } else {
67 aux.Networks = nil
68 }
69 70 return json.Marshal(aux)
71 }
72 73 func (z *Zone) UnmarshalJSON(data []byte) error {
74 type Alias Zone
75 aux := &struct {
76 *Alias
77 }{
78 Alias: (*Alias)(z),
79 }
80 81 if err := json.Unmarshal(data, &aux); err != nil {
82 return err
83 }
84 85 if aux.Networks != nil {
86 z.NetworkIDs = *aux.Networks
87 } else {
88 z.NetworkIDs = nil
89 }
90 91 return nil
92 }
93 94 func (z Zone) String() string {
95 return z.Zone
96 }
97 98 // ZoneRecord wraps Zone's "records" attribute
99 type ZoneRecord struct {
100 Domain string `json:"domain,omitempty"`
101 ID string `json:"id,omitempty"`
102 Link string `json:"link,omitempty"`
103 ShortAns []string `json:"short_answers,omitempty"`
104 Tier json.Number `json:"tier,omitempty"`
105 TTL int `json:"ttl,omitempty"`
106 Type string `json:"type,omitempty"`
107 108 // Contains the key/value tag information associated to the zone
109 Tags map[string]string `json:"tags,omitempty"` // Only relevant for DDI
110 111 // Read-only fields
112 LocalTags []string `json:"local_tags,omitempty"` // Only relevant for DDI
113 }
114 115 // ZonePrimary wraps a Zone's "primary" attribute
116 type ZonePrimary struct {
117 // Enabled determines whether AXFR queries (and optionally NOTIFY messages)
118 // will be enabled for the zone.
119 Enabled bool `json:"enabled"`
120 Secondaries []ZoneSecondaryServer `json:"secondaries"`
121 }
122 123 // ZoneSecondaryServer wraps elements of a Zone's "primary.secondary" attribute
124 type ZoneSecondaryServer struct {
125 // Read-Only
126 NetworkIDs []int `json:"networks,omitempty"`
127 128 IP string `json:"ip"`
129 Port int `json:"port,omitempty"`
130 Notify bool `json:"notify"`
131 }
132 133 // ZoneSecondary wraps a Zone's "secondary" attribute
134 type ZoneSecondary struct {
135 // Read-Only fields
136 Expired bool `json:"expired,omitempty"`
137 LastXfr int `json:"last_xfr,omitempty"`
138 Status string `json:"status,omitempty"`
139 Error *string `json:"error"`
140 141 PrimaryIP string `json:"primary_ip,omitempty"`
142 PrimaryPort int `json:"primary_port,omitempty"`
143 PrimaryNetwork int `json:"primary_network"`
144 Enabled bool `json:"enabled"`
145 146 OtherIPs []string `json:"other_ips,omitempty"`
147 OtherPorts []int `json:"other_ports,omitempty"`
148 OtherNetworks []int `json:"other_networks,omitempty"`
149 OtherNotifyOnly []bool `json:"other_notify_only,omitempty"`
150 151 TSIG *TSIG `json:"tsig,omitempty"`
152 }
153 154 // TSIG is a zones transaction signature.
155 type TSIG struct {
156 // Key is the encrypted TSIG key(read-only)
157 Key string `json:"key,omitempty"`
158 159 // Whether TSIG is enabled for a secondary zone.
160 Enabled bool `json:"enabled,omitempty"`
161 // Which hashing algorithm
162 Hash string `json:"hash,omitempty"`
163 // Name of the TSIG key
164 Name string `json:"name,omitempty"`
165 // Whether TSIG notifies are signed
166 SignedNotifies bool `json:"signed_notifies,omitempty"`
167 }
168 169 // NewZone takes a zone domain name and creates a new zone.
170 func NewZone(zone string) *Zone {
171 z := Zone{
172 Zone: zone,
173 }
174 return &z
175 }
176 177 // MakePrimary enables Primary, disables Secondary, and sets primary's
178 // Secondaries to all provided ZoneSecondaryServers
179 func (z *Zone) MakePrimary(secondaries ...ZoneSecondaryServer) {
180 z.Secondary = nil
181 z.Primary = &ZonePrimary{
182 Enabled: true,
183 Secondaries: secondaries,
184 }
185 if z.Primary.Secondaries == nil {
186 z.Primary.Secondaries = make([]ZoneSecondaryServer, 0)
187 }
188 }
189 190 // MakeSecondary enables Secondary, disables Primary, and sets secondary's
191 // Primary_ip to provided ip. Sets secondary's primary_port to default of 53.
192 func (z *Zone) MakeSecondary(ip string) {
193 z.Secondary = &ZoneSecondary{
194 Enabled: true,
195 PrimaryIP: ip,
196 PrimaryPort: 53,
197 }
198 z.Primary = &ZonePrimary{
199 Enabled: false,
200 Secondaries: make([]ZoneSecondaryServer, 0),
201 }
202 }
203 204 // LinkTo sets Link to a target zone domain name and unsets all other configuration properties.
205 // No other zone configuration properties (such as refresh, retry, etc) may be specified,
206 // since they are all pulled from the target zone. Linked zones, once created, cannot be
207 // configured at all and cannot have records added to them. They may only be deleted, which
208 // does not affect the target zone at all.
209 func (z *Zone) LinkTo(to string) {
210 z.Meta = nil
211 z.TTL = 0
212 z.NxTTL = 0
213 z.Retry = 0
214 z.Refresh = 0
215 z.Expiry = 0
216 z.Primary = nil
217 z.DNSServers = nil
218 z.NetworkIDs = nil
219 z.NetworkPools = nil
220 z.Hostmaster = ""
221 z.Pool = ""
222 z.Secondary = nil
223 z.Link = &to
224 z.DNSSEC = nil
225 }
226