Skip to content

Commit 0ef5457

Browse files
jeansebastienhremyleonejaime Bernabe
authored
feat(instance): Adding the datasource for instance ip (scaleway#870)
* feat(instance): Adding the datasource for instance ip * refactoring: using ParseIP to validate the IP * fix: use proper validation * minor fixes * style(tfproviderlint): S019: schema should omit Computed, Optional, or Required set to false * fix: avoiding one api call if the ID is passed Co-authored-by: Rémy Léone <[email protected]> Co-authored-by: jaime Bernabe <[email protected]>
1 parent 8ea9492 commit 0ef5457

6 files changed

+839
-0
lines changed

docs/data-sources/instance_ip.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
page_title: "Scaleway: scaleway_instance_ip"
3+
description: |-
4+
Gets information about an instance IP.
5+
---
6+
7+
# scaleway_instance_ip
8+
9+
Gets information about an instance IP.
10+
11+
## Example Usage
12+
13+
```hcl
14+
# Get info by IP address
15+
data "scaleway_instance_ip" "my_ip" {
16+
address = "0.0.0.0"
17+
}
18+
19+
# Get info by ID
20+
data "scaleway_instance_ip" "my_ip" {
21+
id = "fr-par-1/11111111-1111-1111-1111-111111111111"
22+
}
23+
```
24+
25+
## Argument Reference
26+
27+
- `address` - (Optional) The IPv4 address to retrieve
28+
Only one of `address` and `id` should be specified.
29+
30+
- `id` - (Optional) The ID of the IP address to retrieve
31+
Only one of `address` and `id` should be specified.
32+
33+
- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which the IP should be reserved.
34+
35+
- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the IP is associated with.
36+
37+
## Attributes Reference
38+
39+
In addition to all above arguments, the following attributes are exported:
40+
41+
- `id` - The ID of the IP.
42+
- `address` - The IP address.
43+
- `reverse` - The reverse dns attached to this IP
44+
- `organization_id` - The organization ID the IP is associated with.

scaleway/data_source_instance_ip.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package scaleway
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
9+
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
10+
"github.com/scaleway/scaleway-sdk-go/scw"
11+
)
12+
13+
func dataSourceScalewayInstanceIP() *schema.Resource {
14+
// Generate datasource schema from resource
15+
dsSchema := datasourceSchemaFromResourceSchema(resourceScalewayInstanceIP().Schema)
16+
17+
dsSchema["id"] = &schema.Schema{
18+
Type: schema.TypeString,
19+
Optional: true,
20+
Description: "The ID of the IP address",
21+
ValidateFunc: validationUUIDorUUIDWithLocality(),
22+
ConflictsWith: []string{"address"},
23+
}
24+
dsSchema["address"] = &schema.Schema{
25+
Type: schema.TypeString,
26+
Optional: true,
27+
Description: "The IP address",
28+
ConflictsWith: []string{"id"},
29+
ValidateFunc: validation.IsIPv4Address,
30+
}
31+
32+
return &schema.Resource{
33+
ReadContext: dataSourceScalewayInstanceIPRead,
34+
35+
Schema: dsSchema,
36+
}
37+
}
38+
39+
func dataSourceScalewayInstanceIPRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
40+
instanceAPI, zone, err := instanceAPIWithZone(d, meta)
41+
if err != nil {
42+
return diag.FromErr(err)
43+
}
44+
45+
id, ok := d.GetOk("id")
46+
var ID string
47+
if !ok {
48+
res, err := instanceAPI.GetIP(&instance.GetIPRequest{
49+
IP: d.Get("address").(string),
50+
Zone: zone,
51+
}, scw.WithContext(ctx))
52+
if err != nil {
53+
// We check for 403 because instance API returns 403 for a deleted IP
54+
if is404Error(err) || is403Error(err) {
55+
d.SetId("")
56+
return nil
57+
}
58+
return diag.FromErr(err)
59+
}
60+
ID = res.IP.ID
61+
} else {
62+
_, ID, _ = parseLocalizedID(id.(string))
63+
}
64+
d.SetId(newZonedIDString(zone, ID))
65+
66+
return resourceScalewayInstanceIPRead(ctx, d, meta)
67+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package scaleway
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
7+
)
8+
9+
func TestAccScalewayDataSourceInstanceIP_Basic(t *testing.T) {
10+
tt := NewTestTools(t)
11+
defer tt.Cleanup()
12+
resource.ParallelTest(t, resource.TestCase{
13+
PreCheck: func() { testAccPreCheck(t) },
14+
ProviderFactories: tt.ProviderFactories,
15+
CheckDestroy: testAccCheckScalewayInstanceServerDestroy(tt),
16+
Steps: []resource.TestStep{
17+
{
18+
Config: `resource "scaleway_instance_ip" "ip" {}`,
19+
},
20+
{
21+
Config: `
22+
resource "scaleway_instance_ip" "ip" {}
23+
24+
data "scaleway_instance_ip" "ip-from-address" {
25+
address = "${scaleway_instance_ip.ip.address}"
26+
}
27+
28+
data "scaleway_instance_ip" "ip-from-id" {
29+
id = "${scaleway_instance_ip.ip.id}"
30+
}
31+
`,
32+
Check: resource.ComposeTestCheckFunc(
33+
testCheckResourceAttrIP("scaleway_instance_ip.ip", "address"),
34+
testCheckResourceAttrIP("data.scaleway_instance_ip.ip-from-address", "address"),
35+
testCheckResourceAttrIP("data.scaleway_instance_ip.ip-from-id", "address"),
36+
resource.TestCheckResourceAttrPair("scaleway_instance_ip.ip", "address", "data.scaleway_instance_ip.ip-from-address", "address"),
37+
resource.TestCheckResourceAttrPair("scaleway_instance_ip.ip", "address", "data.scaleway_instance_ip.ip-from-id", "address"),
38+
),
39+
},
40+
},
41+
})
42+
}

scaleway/helpers_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,13 @@ func testCheckResourceAttrIPv6(name string, key string) resource.TestCheckFunc {
216216
return nil
217217
})
218218
}
219+
220+
func testCheckResourceAttrIP(name string, key string) resource.TestCheckFunc {
221+
return testCheckResourceAttrFunc(name, key, func(value string) error {
222+
ip := net.ParseIP(value)
223+
if ip == nil {
224+
return fmt.Errorf("%s is not a valid IP", value)
225+
}
226+
return nil
227+
})
228+
}

scaleway/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
9393

9494
DataSourcesMap: map[string]*schema.Resource{
9595
"scaleway_account_ssh_key": dataSourceScalewayAccountSSHKey(),
96+
"scaleway_instance_ip": dataSourceScalewayInstanceIP(),
9697
"scaleway_instance_security_group": dataSourceScalewayInstanceSecurityGroup(),
9798
"scaleway_instance_server": dataSourceScalewayInstanceServer(),
9899
"scaleway_instance_image": dataSourceScalewayInstanceImage(),

0 commit comments

Comments
 (0)