Skip to content

Commit 942001a

Browse files
Mia-Crossyfodil
andauthored
feat(instance): read private IPs (#3074)
Co-authored-by: Yacine FODIL <[email protected]>
1 parent 89935f1 commit 942001a

18 files changed

+15229
-9811
lines changed

docs/resources/instance_private_nic.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ In addition to all arguments above, the following attributes are exported:
9393
~> **Important:** Instance private NICs' IDs are [zoned](../guides/regions_and_zones.md#resource-ids), which means they are of the form `{zone}/{id}`, e.g. `fr-par-1/11111111-1111-1111-1111-111111111111`
9494

9595
- `mac_address` - The MAC address of the private NIC.
96+
- `private_ips` - The list of private IPv4 and IPv6 addresses associated with the resource.
97+
- `id` - The ID of the IP address resource.
98+
- `address` - The private IP address.
9699

97100
## Import
98101

docs/resources/instance_server.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ attached to the server. Updates to this field will trigger a stop/start of the s
250250
- `private_network` - (Optional) The private network associated with the server.
251251
Use the `pn_id` key to attach a [private_network](https://www.scaleway.com/en/developers/api/instance/#path-private-nics-list-all-private-nics) on your instance.
252252

253+
- `private_ips` - The list of private IPv4 and IPv6 addresses associated with the resource.
254+
- `id` - The ID of the IP address resource.
255+
- `address` - The private IP address.
256+
253257
- `boot_type` - The boot Type of the server. Possible values are: `local`, `bootscript` or `rescue`.
254258

255259
- `replace_on_type_change` - (Defaults to false) If true, the server will be replaced if `type` is changed. Otherwise, the server will migrate.

internal/services/instance/data_source_instance_private_nic.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func DataSourceInstancePrivateNICRead(ctx context.Context, d *schema.ResourceDat
8484
}
8585

8686
diags := ResourceInstancePrivateNICRead(ctx, d, m)
87-
if diags != nil {
87+
if len(diags) > 0 {
8888
return append(diags, diag.Errorf("failed to read private nic state")...)
8989
}
9090

internal/services/instance/private_nic.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@ package instance
33
import (
44
"context"
55

6+
"github.com/hashicorp/go-cty/cty"
67
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
78
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
89
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
10+
ipamAPI "github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
911
"github.com/scaleway/scaleway-sdk-go/scw"
1012
"github.com/scaleway/terraform-provider-scaleway/v2/internal/cdf"
1113
"github.com/scaleway/terraform-provider-scaleway/v2/internal/dsf"
1214
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
1315
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
1416
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
1517
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
18+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/ipam"
1619
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
1720
)
1821

@@ -68,6 +71,25 @@ func ResourcePrivateNIC() *schema.Resource {
6871
Description: "IPAM ip list, should be for internal use only",
6972
ForceNew: true,
7073
},
74+
"private_ips": {
75+
Type: schema.TypeList,
76+
Computed: true,
77+
Description: "List of private IPv4 and IPv6 addresses associated with the resource",
78+
Elem: &schema.Resource{
79+
Schema: map[string]*schema.Schema{
80+
"id": {
81+
Type: schema.TypeString,
82+
Computed: true,
83+
Description: "The ID of the IP address resource",
84+
},
85+
"address": {
86+
Type: schema.TypeString,
87+
Computed: true,
88+
Description: "The private IP address",
89+
},
90+
},
91+
},
92+
},
7193
"ipam_ip_ids": {
7294
Type: schema.TypeList,
7395
Elem: &schema.Schema{
@@ -163,7 +185,36 @@ func ResourceInstancePrivateNICRead(ctx context.Context, d *schema.ResourceData,
163185
_ = d.Set("tags", privateNIC.Tags)
164186
}
165187

166-
return nil
188+
region, err := zone.Region()
189+
if err != nil {
190+
return diag.FromErr(err)
191+
}
192+
193+
diags := diag.Diagnostics{}
194+
resourceType := ipamAPI.ResourceTypeInstancePrivateNic
195+
opts := &ipam.GetResourcePrivateIPsOptions{
196+
ResourceID: &privateNIC.ID,
197+
ResourceType: &resourceType,
198+
PrivateNetworkID: &privateNIC.PrivateNetworkID,
199+
}
200+
201+
privateIPs, err := ipam.GetResourcePrivateIPs(ctx, m, region, opts)
202+
if err != nil {
203+
if !httperrors.Is403(err) {
204+
return diag.FromErr(err)
205+
}
206+
207+
diags = append(diags, diag.Diagnostic{
208+
Severity: diag.Warning,
209+
Summary: err.Error(),
210+
Detail: "Got 403 while reading private IPs from IPAM API, please check your IAM permissions",
211+
AttributePath: cty.GetAttrPath("private_ips"),
212+
})
213+
}
214+
215+
_ = d.Set("private_ips", privateIPs)
216+
217+
return diags
167218
}
168219

169220
func ResourceInstancePrivateNICUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {

internal/services/instance/private_nic_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ func TestAccPrivateNIC_Basic(t *testing.T) {
4141
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "mac_address"),
4242
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "private_network_id"),
4343
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "server_id"),
44+
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "private_ips.0.id"),
45+
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "private_ips.0.address"),
4446
),
4547
},
4648
},

internal/services/instance/server.go

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
2020
block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1"
2121
instanceSDK "github.com/scaleway/scaleway-sdk-go/api/instance/v1"
22+
ipamAPI "github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
2223
"github.com/scaleway/scaleway-sdk-go/api/marketplace/v2"
2324
"github.com/scaleway/scaleway-sdk-go/scw"
2425
scwvalidation "github.com/scaleway/scaleway-sdk-go/validation"
@@ -31,6 +32,7 @@ import (
3132
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
3233
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
3334
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/instance/instancehelpers"
35+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/ipam"
3436
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/vpc"
3537
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
3638
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
@@ -350,6 +352,25 @@ func ResourceServer() *schema.Resource {
350352
},
351353
},
352354
},
355+
"private_ips": {
356+
Type: schema.TypeList,
357+
Computed: true,
358+
Description: "List of private IPv4 addresses associated with the resource",
359+
Elem: &schema.Resource{
360+
Schema: map[string]*schema.Schema{
361+
"id": {
362+
Type: schema.TypeString,
363+
Computed: true,
364+
Description: "The ID of the IPv4 address resource",
365+
},
366+
"address": {
367+
Type: schema.TypeString,
368+
Computed: true,
369+
Description: "The private IPv4 address",
370+
},
371+
},
372+
},
373+
},
353374
"zone": zonal.Schema(),
354375
"organization_id": account.OrganizationIDSchema(),
355376
"project_id": account.ProjectIDSchema(),
@@ -773,6 +794,47 @@ func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m i
773794
return diag.FromErr(err)
774795
}
775796

797+
privateNICIDs := []string(nil)
798+
for _, nic := range ph.privateNICsMap {
799+
privateNICIDs = append(privateNICIDs, nic.ID)
800+
}
801+
802+
allPrivateIPs := []map[string]interface{}(nil)
803+
diags := diag.Diagnostics{}
804+
resourceType := ipamAPI.ResourceTypeInstancePrivateNic
805+
806+
region, err := zone.Region()
807+
if err != nil {
808+
return diag.FromErr(err)
809+
}
810+
811+
for _, nicID := range privateNICIDs {
812+
opts := &ipam.GetResourcePrivateIPsOptions{
813+
ResourceType: &resourceType,
814+
ResourceID: &nicID,
815+
}
816+
817+
privateIPs, err := ipam.GetResourcePrivateIPs(ctx, m, region, opts)
818+
if err != nil {
819+
if !httperrors.Is403(err) {
820+
return diag.FromErr(err)
821+
}
822+
823+
diags = append(diags, diag.Diagnostic{
824+
Severity: diag.Warning,
825+
Summary: err.Error(),
826+
Detail: "Got 403 while reading private IPs from IPAM API, please check your IAM permissions",
827+
AttributePath: cty.GetAttrPath("private_ips"),
828+
})
829+
}
830+
831+
if privateIPs != nil {
832+
allPrivateIPs = append(allPrivateIPs, privateIPs...)
833+
}
834+
}
835+
836+
_ = d.Set("private_ips", allPrivateIPs)
837+
776838
////
777839
// Display warning if server will soon reach End of Service
778840
////
@@ -787,7 +849,7 @@ func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m i
787849

788850
mostRelevantTypes := compatibleTypes.CompatibleTypes[:5]
789851

790-
return diag.Diagnostics{diag.Diagnostic{
852+
diags = append(diags, diag.Diagnostic{
791853
Severity: diag.Warning,
792854
Detail: fmt.Sprintf("Instance type %q will soon reach End of Service", server.CommercialType),
793855
Summary: fmt.Sprintf(`Your Instance will soon reach End of Service. You can check the exact date on the Scaleway console. We recommend that you migrate your Instance before that.
@@ -803,10 +865,10 @@ You can check the full list of compatible server types:
803865
server.Zone,
804866
),
805867
AttributePath: cty.GetAttrPath("type"),
806-
}}
868+
})
807869
}
808870

809-
return nil
871+
return diags
810872
}
811873

812874
//gocyclo:ignore

internal/services/instance/server_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,8 @@ func TestAccServer_PrivateNetwork(t *testing.T) {
11081108
resource.TestCheckResourceAttrSet("scaleway_instance_server.base", "private_network.0.zone"),
11091109
resource.TestCheckResourceAttrPair("scaleway_instance_server.base", "private_network.0.pn_id",
11101110
"scaleway_vpc_private_network.internal", "id"),
1111+
resource.TestCheckResourceAttrSet("scaleway_instance_server.base", "private_ips.0.id"),
1112+
resource.TestCheckResourceAttrSet("scaleway_instance_server.base", "private_ips.0.address"),
11111113
),
11121114
},
11131115
{

internal/services/instance/testdata/data-source-private-nic-basic.cassette.yaml

Lines changed: 1994 additions & 916 deletions
Large diffs are not rendered by default.

internal/services/instance/testdata/private-nic-basic.cassette.yaml

Lines changed: 590 additions & 443 deletions
Large diffs are not rendered by default.

internal/services/instance/testdata/private-nic-tags.cassette.yaml

Lines changed: 1244 additions & 607 deletions
Large diffs are not rendered by default.

internal/services/instance/testdata/private-nic-with-ipam.cassette.yaml

Lines changed: 657 additions & 559 deletions
Large diffs are not rendered by default.

internal/services/instance/testdata/server-private-network-missing-pnic.cassette.yaml

Lines changed: 1503 additions & 964 deletions
Large diffs are not rendered by default.

internal/services/instance/testdata/server-private-network.cassette.yaml

Lines changed: 2822 additions & 1989 deletions
Large diffs are not rendered by default.

internal/services/ipam/testdata/data-source-ipamip-instance-lb.cassette.yaml

Lines changed: 826 additions & 679 deletions
Large diffs are not rendered by default.

internal/services/ipam/testdata/data-source-ipamip-instance.cassette.yaml

Lines changed: 775 additions & 579 deletions
Large diffs are not rendered by default.

internal/services/vpc/testdata/vpc-route-basic.cassette.yaml

Lines changed: 2927 additions & 1457 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)