Skip to content

Commit e46db3a

Browse files
authored
Merge pull request #1101 from ovh/dev/aamstutz/fix-ip-move
fix: Correctly handle blocks in resource ovh_ip_move
2 parents 8dc1fa2 + 2cd41b1 commit e46db3a

File tree

4 files changed

+70
-18
lines changed

4 files changed

+70
-18
lines changed

.cds/terraform-provider-ovh.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,14 +736,14 @@ workflow:
736736
pipeline: terraform-provider-ovh-testacc
737737
when:
738738
- success
739-
Tests_TestAccIpMove_basic:
739+
Tests_IpMove:
740740
application: terraform-provider-ovh
741741
depends_on:
742742
- terraform-provider-ovh-pre-sweepers
743743
environment: acctests
744744
one_at_a_time: true
745745
parameters:
746-
testargs: -run TestAccIpMove_basic
746+
testargs: -run TestAccIpMove
747747
skipthispipeline: "{{.workflow.terraform-provider-ovh.pip.skipthistest.ip}}"
748748
pipeline: terraform-provider-ovh-testacc
749749
when:
@@ -923,7 +923,7 @@ workflow:
923923
- Tests_TestAccResourceCloudProjectFailoverIpAttachTestAccResourceCloudProject_basic
924924
- Tests_TestAccCloudProjectWorkflowBackup
925925
- Tests_TestAccResourceIpService_basic
926-
- Tests_TestAccIpMove_basic
926+
- Tests_IpMove
927927
- Tests_IPFirewall
928928
- Tests_IPMitigation
929929
- Tests_Okms

ovh/helpers/helpers.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -496,16 +496,24 @@ func ValidateHostingPrivateDatabaseUserGrant(value string) error {
496496
})
497497
}
498498

499-
func ServiceNameFromIpBlock(ip string) (*string, error) {
500-
parsedIp := net.ParseIP(ip)
501-
if parsedIp == nil {
502-
var err error
503-
parsedIp, _, err = net.ParseCIDR(ip)
504-
if err != nil {
505-
return nil, fmt.Errorf("ip %s is not valid IP nor a valid CIDR", ip)
499+
func ServiceNameFromIpBlock(ip string) (string, error) {
500+
if parsedIP, ipNet, err := net.ParseCIDR(ip); err == nil {
501+
prefixLength, _ := ipNet.Mask.Size()
502+
503+
if prefixLength == 32 {
504+
// Single IP, omit the mask
505+
return fmt.Sprintf("ip-%s", parsedIP.String()), nil
506506
}
507+
508+
// IP block, keep the mask
509+
return fmt.Sprintf("ip-%s/%d", parsedIP.String(), prefixLength), nil
510+
}
511+
512+
// If not a CIDR, try parsing as a single IP
513+
parsedIP := net.ParseIP(ip)
514+
if parsedIP == nil {
515+
return "", fmt.Errorf("ip %s is not a valid IP nor a valid CIDR", ip)
507516
}
508-
serviceName := fmt.Sprintf("ip-%s", parsedIp)
509517

510-
return &serviceName, nil
518+
return fmt.Sprintf("ip-%s", parsedIP.String()), nil
511519
}

ovh/resource_ip_move.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,13 @@ func resourceIpMoveSchema() map[string]*schema.Schema {
115115
func resoursIpMoveCreate(d *schema.ResourceData, meta interface{}) error {
116116
// later on this ID will be replaced by the task if when we need to create it (see resourceIpMoveUpdate)
117117
d.SetId(d.Get("ip").(string))
118-
return resourceIpMoveUpdate(d, meta)
118+
119+
err := resourceIpMoveUpdate(d, meta)
120+
if err != nil {
121+
d.SetId("")
122+
}
123+
124+
return err
119125
}
120126

121127
// resourceIpMoveUpdate will move an ip to a provided service name or detach (= park) it otherwise
@@ -160,19 +166,19 @@ func resourceIpMoveUpdate(d *schema.ResourceData, meta interface{}) error {
160166
} else {
161167
log.Printf("[WARNING] - resource ID %s is not an int64/not a task ID. Cannot get last task state", d.Id())
162168
}
163-
err = resourceIpServiceReadByServiceName(d, *serviceName, config)
169+
err = resourceIpServiceReadByServiceName(d, serviceName, config)
164170
if err != nil {
165171
return err
166172
}
167173

168174
currentlyRoutedService := GetRoutedToServiceName(d)
169175
// no need to update if ip is already routed to the appropriate service
170176
if reflect.DeepEqual(currentlyRoutedService, opts.To) {
171-
log.Printf("[DEBUG] Won't do anything as ip %s (service name = %s) is already routed to service %v", ip, *serviceName, currentlyRoutedService)
177+
log.Printf("[DEBUG] Won't do anything as ip %s (service name = %s) is already routed to service %v", ip, serviceName, currentlyRoutedService)
172178
return nil
173179
} else {
174180
if opts.To == nil {
175-
log.Printf("[DEBUG] Will move ip %s (service name = %s) from service %s to IP parking", ip, *serviceName, *currentlyRoutedService)
181+
log.Printf("[DEBUG] Will move ip %s (service name = %s) from service %s to IP parking", ip, serviceName, *currentlyRoutedService)
176182
endpoint := fmt.Sprintf("/ip/%s/park",
177183
url.PathEscape(ip),
178184
)
@@ -181,7 +187,7 @@ func resourceIpMoveUpdate(d *schema.ResourceData, meta interface{}) error {
181187
return fmt.Errorf("calling Post %s: %q", endpoint, err)
182188
}
183189
} else {
184-
log.Printf("[DEBUG] Will move ip %s (service name = %s) from service %v to service %s", ip, *serviceName, currentlyRoutedService, *opts.To)
190+
log.Printf("[DEBUG] Will move ip %s (service name = %s) from service %v to service %s", ip, serviceName, currentlyRoutedService, *opts.To)
185191
endpoint := fmt.Sprintf("/ip/%s/move",
186192
url.PathEscape(ip),
187193
)
@@ -269,7 +275,7 @@ func resourceIpRead(d *schema.ResourceData, meta interface{}) error {
269275
return err
270276
}
271277
config := meta.(*Config)
272-
return resourceIpServiceReadByServiceName(d, *serviceName, config)
278+
return resourceIpServiceReadByServiceName(d, serviceName, config)
273279
}
274280

275281
// resourceIpMoveDelete is an empty implementation as move do not actually create API objects but rather updates the underlying ip spec (by modifying its routed_to service)

ovh/resource_ip_move_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,41 @@ func TestAccIpMove_basic(t *testing.T) {
7070
},
7171
})
7272
}
73+
74+
func TestAccIpMove_block(t *testing.T) {
75+
ipBlock := os.Getenv("OVH_IP_BLOCK_MOVE_TEST")
76+
routedToServiceName := os.Getenv("OVH_IP_MOVE_SERVICE_NAME_TEST")
77+
78+
resource.Test(t, resource.TestCase{
79+
PreCheck: func() { testAccPreCheckIpMove(t) },
80+
Providers: testAccProviders,
81+
Steps: []resource.TestStep{
82+
{
83+
Config: fmt.Sprintf(`
84+
resource "ovh_ip_move" "move" {
85+
ip = "%s"
86+
routed_to {
87+
service_name = "%s"
88+
}
89+
}`,
90+
ipBlock, routedToServiceName),
91+
Check: resource.ComposeTestCheckFunc(
92+
resource.TestCheckResourceAttr("ovh_ip_move.move", "routed_to.0.service_name", routedToServiceName),
93+
),
94+
},
95+
{
96+
Config: fmt.Sprintf(`
97+
resource "ovh_ip_move" "move" {
98+
ip = "%s"
99+
routed_to {
100+
service_name = ""
101+
}
102+
}`,
103+
ipBlock),
104+
Check: resource.ComposeTestCheckFunc(
105+
resource.TestCheckResourceAttr("ovh_ip_move.move", "routed_to.0.service_name", ""),
106+
),
107+
},
108+
},
109+
})
110+
}

0 commit comments

Comments
 (0)