Skip to content

Commit f74dfd1

Browse files
committed
r/ip_reverse: rewrite of the resource
1 parent 79d4aa3 commit f74dfd1

6 files changed

+141
-159
lines changed

ovh/provider.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func Provider() *schema.Provider {
9898
"ovh_domain_zone": resourceDomainZone(),
9999
"ovh_domain_zone_record": resourceOvhDomainZoneRecord(),
100100
"ovh_domain_zone_redirection": resourceOvhDomainZoneRedirection(),
101-
"ovh_ip_reverse": resourceOvhIpReverse(),
101+
"ovh_ip_reverse": resourceIpReverse(),
102102
"ovh_ip_service": resourceIpService(),
103103
"ovh_iploadbalancing": resourceIpLoadbalancing(),
104104
"ovh_iploadbalancing_http_farm": resourceIpLoadbalancingHttpFarm(),

ovh/provider_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ func testAccPreCheckCredentials(t *testing.T) {
7373
// are set.
7474
func testAccPreCheckIp(t *testing.T) {
7575
testAccPreCheckCredentials(t)
76-
checkEnvOrSkip(t, "OVH_IP")
77-
checkEnvOrSkip(t, "OVH_IP_BLOCK")
78-
checkEnvOrSkip(t, "OVH_IP_REVERSE")
76+
checkEnvOrSkip(t, "OVH_IP_TEST")
77+
checkEnvOrSkip(t, "OVH_IP_BLOCK_TEST")
78+
checkEnvOrSkip(t, "OVH_IP_REVERSE_TEST")
7979
}
8080

8181
// Checks that the environment variables needed to order /ip/service for acceptance tests

ovh/resource_ip_reverse.go

+63-103
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,27 @@ package ovh
33
import (
44
"fmt"
55
"log"
6-
"net"
6+
"net/url"
77
"strings"
88

99
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1010
"github.com/ovh/terraform-provider-ovh/ovh/helpers"
11-
12-
"github.com/ovh/go-ovh/ovh"
1311
)
1412

15-
type OvhIpReverse struct {
16-
IpReverse string `json:"ipReverse"`
17-
Reverse string `json:"reverse"`
18-
}
19-
20-
func resourceOvhIpReverse() *schema.Resource {
13+
func resourceIpReverse() *schema.Resource {
2114
return &schema.Resource{
22-
Create: resourceOvhIpReverseCreate,
23-
Read: resourceOvhIpReverseRead,
24-
Update: resourceOvhIpReverseUpdate,
25-
Delete: resourceOvhIpReverseDelete,
15+
Create: resourceIpReverseCreate,
16+
Read: resourceIpReverseRead,
17+
Delete: resourceIpReverseDelete,
18+
Importer: &schema.ResourceImporter{
19+
State: resourceIpReverseImportState,
20+
},
2621

2722
Schema: map[string]*schema.Schema{
2823
"ip": {
2924
Type: schema.TypeString,
3025
Required: true,
26+
ForceNew: true,
3127
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
3228
err := helpers.ValidateIpBlock(v.(string))
3329
if err != nil {
@@ -36,9 +32,11 @@ func resourceOvhIpReverse() *schema.Resource {
3632
return
3733
},
3834
},
39-
"ipreverse": {
35+
36+
"ip_reverse": {
4037
Type: schema.TypeString,
41-
Optional: true,
38+
Required: true,
39+
ForceNew: true,
4240
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
4341
err := helpers.ValidateIp(v.(string))
4442
if err != nil {
@@ -47,130 +45,92 @@ func resourceOvhIpReverse() *schema.Resource {
4745
return
4846
},
4947
},
48+
5049
"reverse": {
5150
Type: schema.TypeString,
51+
ForceNew: true,
5252
Required: true,
5353
},
5454
},
5555
}
5656
}
5757

58-
func resourceOvhIpReverseCreate(d *schema.ResourceData, meta interface{}) error {
59-
provider := meta.(*Config)
60-
61-
// Create the new reverse
62-
newIp := d.Get("ip").(string)
63-
newReverse := &OvhIpReverse{
64-
Reverse: d.Get("reverse").(string),
65-
}
66-
67-
newIpReverse, ok := d.GetOk("ipreverse")
68-
if !ok || newIpReverse == "" {
69-
ipAddr, ipNet, _ := net.ParseCIDR(newIp)
70-
prefixSize, _ := ipNet.Mask.Size()
71-
72-
if ipAddr.To4() != nil && prefixSize != 32 {
73-
return fmt.Errorf("ipreverse must be set if ip (%s) is not a /32", newIp)
74-
} else if ipAddr.To4() == nil && prefixSize != 128 {
75-
return fmt.Errorf("ipreverse must be set if ip (%s) is not a /128", newIp)
76-
}
77-
78-
newIpReverse = ipAddr.String()
79-
d.Set("ipreverse", newIpReverse)
58+
func resourceIpReverseImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
59+
givenId := d.Id()
60+
splitId := strings.SplitN(givenId, ":", 2)
61+
if len(splitId) != 2 {
62+
return nil, fmt.Errorf("Import Id is not ip:ip_reverse formatted")
8063
}
64+
ip := splitId[0]
65+
ipReverse := splitId[1]
66+
d.SetId(ipReverse)
67+
d.Set("ip", ip)
68+
69+
results := make([]*schema.ResourceData, 1)
70+
results[0] = d
71+
return results, nil
72+
}
8173

82-
newReverse.IpReverse = newIpReverse.(string)
83-
84-
log.Printf("[DEBUG] OVH IP Reverse create configuration: %#v", newReverse)
85-
86-
resultReverse := OvhIpReverse{}
74+
func resourceIpReverseCreate(d *schema.ResourceData, meta interface{}) error {
75+
config := meta.(*Config)
8776

88-
err := provider.OVHClient.Post(
89-
fmt.Sprintf("/ip/%s/reverse", strings.Replace(newIp, "/", "%2F", 1)),
90-
newReverse,
91-
&resultReverse,
77+
// Create the new reverse
78+
ip := d.Get("ip").(string)
79+
opts := (&IpReverseCreateOpts{}).FromResource(d)
80+
res := &IpReverse{}
81+
82+
err := config.OVHClient.Post(
83+
fmt.Sprintf("/ip/%s/reverse", url.PathEscape(ip)),
84+
opts,
85+
&res,
9286
)
9387
if err != nil {
9488
return fmt.Errorf("Failed to create OVH IP Reverse: %s", err)
9589
}
9690

97-
d.SetId(fmt.Sprintf("%s_%s", newIp, resultReverse.IpReverse))
91+
d.SetId(res.IpReverse)
9892

99-
return resourceOvhIpReverseRead(d, meta)
93+
return resourceIpReverseRead(d, meta)
10094
}
10195

102-
func resourceOvhIpReverseRead(d *schema.ResourceData, meta interface{}) error {
103-
provider := meta.(*Config)
96+
func resourceIpReverseRead(d *schema.ResourceData, meta interface{}) error {
97+
config := meta.(*Config)
10498

105-
reverse := OvhIpReverse{}
99+
ip := d.Get("ip").(string)
100+
101+
res := &IpReverse{}
106102
endpoint := fmt.Sprintf(
107103
"/ip/%s/reverse/%s",
108-
strings.Replace(d.Get("ip").(string), "/", "%2F", 1),
109-
d.Get("ipreverse").(string),
104+
url.PathEscape(ip),
105+
url.PathEscape(d.Id()),
110106
)
111107

112-
if err := provider.OVHClient.Get(endpoint, &reverse); err != nil {
108+
if err := config.OVHClient.Get(endpoint, &res); err != nil {
113109
return helpers.CheckDeleted(d, err, endpoint)
114110
}
115111

116-
d.Set("ipreverse", reverse.IpReverse)
117-
d.Set("reverse", reverse.Reverse)
118-
119-
return nil
120-
}
121-
122-
func resourceOvhIpReverseUpdate(d *schema.ResourceData, meta interface{}) error {
123-
provider := meta.(*Config)
124-
125-
reverse := OvhIpReverse{}
126-
127-
if attr, ok := d.GetOk("ipreverse"); ok {
128-
reverse.IpReverse = attr.(string)
129-
}
130-
if attr, ok := d.GetOk("reverse"); ok {
131-
reverse.Reverse = attr.(string)
112+
for k, v := range res.ToMap() {
113+
d.Set(k, v)
132114
}
133115

134-
log.Printf("[DEBUG] OVH IP Reverse update configuration: %#v", reverse)
135-
136-
err := provider.OVHClient.Post(
137-
fmt.Sprintf("/ip/%s/reverse", strings.Replace(d.Get("ip").(string), "/", "%2F", 1)),
138-
reverse,
139-
nil,
140-
)
141-
if err != nil {
142-
return fmt.Errorf("Failed to update OVH IP Reverse: %s", err)
143-
}
144-
145-
return resourceOvhIpReverseRead(d, meta)
116+
return nil
146117
}
147118

148-
func resourceOvhIpReverseDelete(d *schema.ResourceData, meta interface{}) error {
149-
provider := meta.(*Config)
119+
func resourceIpReverseDelete(d *schema.ResourceData, meta interface{}) error {
120+
config := meta.(*Config)
150121

151122
log.Printf("[INFO] Deleting OVH IP Reverse: %s->%s", d.Get("reverse").(string), d.Get("ipreverse").(string))
152-
153-
err := provider.OVHClient.Delete(
154-
fmt.Sprintf("/ip/%s/reverse/%s", strings.Replace(d.Get("ip").(string), "/", "%2F", 1), d.Get("ipreverse").(string)),
155-
nil,
123+
ip := d.Get("ip").(string)
124+
endpoint := fmt.Sprintf(
125+
"/ip/%s/reverse/%s",
126+
url.PathEscape(ip),
127+
url.PathEscape(d.Id()),
156128
)
157129

158-
if err != nil {
159-
return fmt.Errorf("Error deleting OVH IP Reverse: %s", err)
160-
}
161-
162-
return nil
163-
}
164-
165-
func resourceOvhIpReverseExists(ip, ipreverse string, c *ovh.Client) error {
166-
reverse := OvhIpReverse{}
167-
endpoint := fmt.Sprintf("/ip/%s/reverse/%s", strings.Replace(ip, "/", "%2F", 1), ipreverse)
168-
169-
err := c.Get(endpoint, &reverse)
170-
if err != nil {
171-
return fmt.Errorf("calling %s:\n\t %q", endpoint, err)
130+
if err := config.OVHClient.Delete(endpoint, nil); err != nil {
131+
return helpers.CheckDeleted(d, err, endpoint)
172132
}
173-
log.Printf("[DEBUG] Read IP reverse: %s", reverse)
174133

134+
d.SetId("")
175135
return nil
176136
}

ovh/resource_ip_reverse_test.go

+42-46
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,23 @@ package ovh
33
import (
44
"fmt"
55
"log"
6+
"net/url"
67
"os"
7-
"strings"
88
"testing"
99
"time"
1010

1111
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
12-
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
1312

1413
"github.com/ovh/go-ovh/ovh"
1514
)
1615

17-
var testAccIpReverseConfig = fmt.Sprintf(`
16+
var testAccIpReverseConfig = `
1817
resource "ovh_ip_reverse" "reverse" {
1918
ip = "%s"
20-
ipreverse = "%s"
19+
ip_reverse = "%s"
2120
reverse = "%s"
2221
}
23-
`, os.Getenv("OVH_IP_BLOCK"), os.Getenv("OVH_IP"), os.Getenv("OVH_IP_REVERSE"))
22+
`
2423

2524
func init() {
2625
resource.AddTestSweepers("ovh_ip_reverse", &resource.Sweeper{
@@ -35,10 +34,13 @@ func testSweepIpReverse(region string) error {
3534
return fmt.Errorf("error getting client: %s", err)
3635
}
3736

38-
reverse := OvhIpReverse{}
39-
testIp := os.Getenv("OVH_IP_BLOCK")
40-
testIpReverse := os.Getenv("OVH_IP")
41-
endpoint := fmt.Sprintf("/ip/%s/reverse/%s", strings.Replace(testIp, "/", "%2F", 1), testIpReverse)
37+
reverse := IpReverse{}
38+
testIp := os.Getenv("OVH_IP_BLOCK_TEST")
39+
testIpReverse := os.Getenv("OVH_IP_TEST")
40+
endpoint := fmt.Sprintf("/ip/%s/reverse/%s",
41+
url.PathEscape(testIp),
42+
url.PathEscape(testIpReverse),
43+
)
4244
if err := client.Get(endpoint, &reverse); err != nil {
4345
if errOvh, ok := err.(*ovh.APIError); ok && errOvh.Code == 404 {
4446
// no ip reverse set, nothing to sweep
@@ -65,53 +67,47 @@ func testSweepIpReverse(region string) error {
6567
}
6668

6769
func TestAccIpReverse_basic(t *testing.T) {
70+
block := os.Getenv("OVH_IP_BLOCK_TEST")
71+
ip := os.Getenv("OVH_IP_TEST")
72+
reverse := os.Getenv("OVH_IP_REVERSE_TEST")
73+
74+
config := fmt.Sprintf(testAccIpReverseConfig, block, ip, reverse)
75+
6876
resource.Test(t, resource.TestCase{
69-
PreCheck: func() { testAccPreCheckIp(t) },
70-
Providers: testAccProviders,
71-
CheckDestroy: testAccCheckIpReverseDestroy,
77+
PreCheck: func() { testAccPreCheckIp(t) },
78+
Providers: testAccProviders,
7279
Steps: []resource.TestStep{
7380
{
74-
Config: testAccIpReverseConfig,
81+
Config: config,
7582
Check: resource.ComposeTestCheckFunc(
76-
testAccCheckIpReverseExists("ovh_ip_reverse.reverse", t),
83+
resource.TestCheckResourceAttr("ovh_ip_reverse.reverse", "ip", block),
84+
resource.TestCheckResourceAttr("ovh_ip_reverse.reverse", "ip_reverse", ip),
85+
resource.TestCheckResourceAttr("ovh_ip_reverse.reverse", "reverse", reverse),
7786
),
7887
},
7988
},
8089
})
8190
}
8291

83-
func testAccCheckIpReverseExists(n string, t *testing.T) resource.TestCheckFunc {
84-
return func(s *terraform.State) error {
85-
config := testAccProvider.Meta().(*Config)
86-
87-
rs, ok := s.RootModule().Resources[n]
88-
if !ok {
89-
return fmt.Errorf("Not found: %s", n)
90-
}
91-
92-
if rs.Primary.Attributes["ip"] == "" {
93-
return fmt.Errorf("No IP block is set")
94-
}
95-
96-
if rs.Primary.Attributes["ipreverse"] == "" {
97-
return fmt.Errorf("No IP is set")
98-
}
99-
100-
return resourceOvhIpReverseExists(rs.Primary.Attributes["ip"], rs.Primary.Attributes["ipreverse"], config.OVHClient)
101-
}
102-
}
92+
func TestAccIpReverse_importBasic(t *testing.T) {
93+
block := os.Getenv("OVH_IP_BLOCK_TEST")
94+
ip := os.Getenv("OVH_IP_TEST")
95+
reverse := os.Getenv("OVH_IP_REVERSE_TEST")
10396

104-
func testAccCheckIpReverseDestroy(s *terraform.State) error {
105-
config := testAccProvider.Meta().(*Config)
106-
for _, rs := range s.RootModule().Resources {
107-
if rs.Type != "ovh_ip_reverse" {
108-
continue
109-
}
97+
config := fmt.Sprintf(testAccIpReverseConfig, block, ip, reverse)
11098

111-
err := resourceOvhIpReverseExists(rs.Primary.Attributes["ip"], rs.Primary.Attributes["ipreverse"], config.OVHClient)
112-
if err == nil {
113-
return fmt.Errorf("IP Reverse still exists")
114-
}
115-
}
116-
return nil
99+
resource.Test(t, resource.TestCase{
100+
PreCheck: func() { testAccPreCheckIp(t) },
101+
Providers: testAccProviders,
102+
Steps: []resource.TestStep{
103+
{
104+
Config: config,
105+
},
106+
{
107+
ResourceName: "ovh_ip_reverse.reverse",
108+
ImportState: true,
109+
ImportStateVerify: true,
110+
},
111+
},
112+
})
117113
}

0 commit comments

Comments
 (0)