Skip to content

Commit 4d78720

Browse files
authored
Merge pull request #797 from ovh/dev/aamstutz/ip-firewall-rule-import
feat: Add import capability to resource ovh_ip_firewall_rule
2 parents 2d5633b + 81daf97 commit 4d78720

3 files changed

+63
-1
lines changed

ovh/resource_ip_firewall_rule.go

+47
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@ import (
55
"errors"
66
"fmt"
77
"net/url"
8+
"strconv"
9+
"strings"
810
"time"
911

12+
"github.com/hashicorp/terraform-plugin-framework/path"
1013
"github.com/hashicorp/terraform-plugin-framework/resource"
14+
"github.com/hashicorp/terraform-plugin-log/tflog"
1115
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
1216
"github.com/ovh/go-ovh/ovh"
17+
ovhtypes "github.com/ovh/terraform-provider-ovh/ovh/types"
1318
)
1419

1520
var _ resource.ResourceWithConfigure = (*ipFirewallRuleResource)(nil)
21+
var _ resource.ResourceWithImportState = (*ipFirewallRuleResource)(nil)
1622

1723
func NewIpFirewallRuleResource() resource.Resource {
1824
return &ipFirewallRuleResource{}
@@ -47,6 +53,26 @@ func (d *ipFirewallRuleResource) Schema(ctx context.Context, req resource.Schema
4753
resp.Schema = IpFirewallRuleResourceSchema(ctx)
4854
}
4955

56+
func (r *ipFirewallRuleResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
57+
splits := strings.Split(req.ID, "|")
58+
if len(splits) != 3 {
59+
resp.Diagnostics.AddError("Given ID is malformed", "ID must be formatted like the following: <ip>|<ip_on_firewall>|<sequence>")
60+
return
61+
}
62+
63+
ip := splits[0]
64+
ipOnFirewall := splits[1]
65+
sequence, err := strconv.Atoi(splits[2])
66+
if err != nil {
67+
resp.Diagnostics.AddError("Given firewall sequence number must be an integer", err.Error())
68+
return
69+
}
70+
71+
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("ip"), ip)...)
72+
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("ip_on_firewall"), ipOnFirewall)...)
73+
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("sequence"), sequence)...)
74+
}
75+
5076
func (r *ipFirewallRuleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
5177
var (
5278
data IpFirewallRuleModel
@@ -129,6 +155,27 @@ func (r *ipFirewallRuleResource) Read(ctx context.Context, req resource.ReadRequ
129155

130156
responseData.MergeWith(&data)
131157

158+
// In case the resource is being imported, the fields `source_port` and `destination_port` are not returned
159+
// by the API, so we must use fields `source_port_desc` and `destination_port_desc` to retrieve the values.
160+
if responseData.SourcePort.IsNull() && strings.HasPrefix(responseData.SourcePortDesc.ValueString(), "eq ") {
161+
port := strings.TrimPrefix(responseData.SourcePortDesc.ValueString(), "eq ")
162+
portNumber, err := strconv.ParseInt(port, 10, 64)
163+
if err != nil {
164+
tflog.Warn(ctx, fmt.Sprintf("failed to parse source port from desc: %s", err))
165+
} else {
166+
responseData.SourcePort = ovhtypes.NewTfInt64Value(portNumber)
167+
}
168+
}
169+
if responseData.DestinationPort.IsNull() && strings.HasPrefix(responseData.DestinationPortDesc.ValueString(), "eq ") {
170+
port := strings.TrimPrefix(responseData.DestinationPortDesc.ValueString(), "eq ")
171+
portNumber, err := strconv.ParseInt(port, 10, 64)
172+
if err != nil {
173+
tflog.Warn(ctx, fmt.Sprintf("failed to parse destination port from desc: %s", err))
174+
} else {
175+
responseData.DestinationPort = ovhtypes.NewTfInt64Value(portNumber)
176+
}
177+
}
178+
132179
// Save updated data into Terraform state
133180
resp.Diagnostics.Append(resp.State.Set(ctx, &responseData)...)
134181
}

ovh/resource_ip_firewall_rule_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ func TestAccIPFirewallRule_basic(t *testing.T) {
6161
"ovh_ip_firewall_rule.rule", "source_port_desc", "eq 44"),
6262
),
6363
},
64+
{
65+
ImportStateId: fmt.Sprintf("%s|%s|0", ip, ip),
66+
ResourceName: "ovh_ip_firewall_rule.rule",
67+
ImportState: true,
68+
ImportStateVerify: true,
69+
ImportStateVerifyIdentifierAttribute: "ip_on_firewall",
70+
},
6471
},
6572
})
6673
}

website/docs/r/ip_firewall_rule.html.markdown

+9-1
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,12 @@ resource "ovh_ip_firewall_rule" "my_firewall_rule" {
4747
* `source` - IPv4 CIDR notation (e.g., 192.0.2.0/24)
4848
* `source_port` - Source port for your rule. Only with TCP/UDP protocol
4949
* `source_port_desc` - String description of field `source_port`
50-
* `tcp_option` - TCP option on your rule (syn|established)
50+
* `tcp_option` - TCP option on your rule (syn|established)
51+
52+
## Import
53+
54+
The resource can be imported using the properties `ip`, `ip_on_firewall` and `sequence`, separated by "|" E.g.,
55+
56+
```bash
57+
$ terraform import ovh_ip_firewall_rule.my_firewall_rule '127.0.0.1|127.0.0.2|0'
58+
```

0 commit comments

Comments
 (0)