-
Notifications
You must be signed in to change notification settings - Fork 21
/
data_source_dns_zone.go
130 lines (118 loc) · 3.89 KB
/
data_source_dns_zone.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package ionoscloud
import (
"context"
"fmt"
"log"
"strings"
"github.com/ionos-cloud/terraform-provider-ionoscloud/v6/services"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
dns "github.com/ionos-cloud/sdk-go-dns"
)
func dataSourceDNSZone() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceZoneRead,
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Description: "The ID of your DNS Zone.",
ValidateDiagFunc: validation.ToDiagFunc(validation.IsUUID),
Optional: true,
},
"name": {
Type: schema.TypeString,
Description: "The name of your DNS Zone.",
Optional: true,
},
"partial_match": {
Type: schema.TypeBool,
Description: "Whether partial matching is allowed or not when using name argument.",
Default: false,
Optional: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"nameservers": {
Type: schema.TypeList,
Description: "A list of available name servers.",
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
}
}
func dataSourceZoneRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(services.SdkBundle).DNSClient
idValue, idOk := d.GetOk("id")
nameValue, nameOk := d.GetOk("name")
partialMatch := d.Get("partial_match").(bool)
id := idValue.(string)
name := nameValue.(string)
if idOk && nameOk {
return diag.FromErr(fmt.Errorf("ID and name cannot be both specified at the same time"))
}
if !idOk && !nameOk {
return diag.FromErr(fmt.Errorf("please provide either the DNS Zone ID or name"))
}
if partialMatch && !nameOk {
return diag.FromErr(fmt.Errorf("partial_match can only be used together with the name attribute"))
}
var zone dns.ZoneRead
var err error
if idOk {
zone, _, err = client.GetZoneById(ctx, id)
if err != nil {
return diag.FromErr(fmt.Errorf("an error occured while fetching the DNS Zone with ID: %s, error: %w", id, err))
}
} else {
var results []dns.ZoneRead
log.Printf("[INFO] Populating data source for DNS Zone using name %s and partial_match %t", name, partialMatch)
if partialMatch {
// By default, when providing the name as a filter, for the GET requests, partial match
// is true.
zones, _, err := client.ListZones(ctx, name)
if err != nil {
return diag.FromErr(fmt.Errorf("an error occured while fetching DNS Zones: %w", err))
}
results = *zones.Items
} else {
// In order to have an exact name match, we must retrieve all the DNS Zones and then
// build a list of exact matches based on the response, there is no other way since using
// filter.zoneName only does a partial match.
zones, _, err := client.ListZones(ctx, "")
if err != nil {
return diag.FromErr(fmt.Errorf("an error occured while fetching DNS Zones: %w", err))
}
for _, zoneItem := range *zones.Items {
// Since each zone has a unique name, there is no need to keep on searching if
// we already found the required zone.
if len(results) == 1 {
break
}
if zoneItem.Properties != nil && zoneItem.Properties.ZoneName != nil && strings.EqualFold(*zoneItem.Properties.ZoneName, name) {
results = append(results, zoneItem)
}
}
}
if results == nil || len(results) == 0 {
return diag.FromErr(fmt.Errorf("no DNS Zone found with the specified name = %s", name))
} else if len(results) > 1 {
return diag.FromErr(fmt.Errorf("more than one DNS Zone found with the specified name = %s", name))
} else {
zone = results[0]
}
}
if err := client.SetZoneData(d, zone); err != nil {
return diag.FromErr(err)
}
return nil
}