Skip to content

feat(instance): read private ips #3074

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/resources/instance_private_nic.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ In addition to all arguments above, the following attributes are exported:
~> **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`

- `mac_address` - The MAC address of the private NIC.
- `private_ips` - The list of private IPv4 and IPv6 addresses associated with the resource.
- `id` - The ID of the IP address resource.
- `address` - The private IP address.

## Import

Expand Down
4 changes: 4 additions & 0 deletions docs/resources/instance_server.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ attached to the server. Updates to this field will trigger a stop/start of the s
- `private_network` - (Optional) The private network associated with the server.
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.

- `private_ips` - The list of private IPv4 and IPv6 addresses associated with the resource.
- `id` - The ID of the IP address resource.
- `address` - The private IP address.

- `boot_type` - The boot Type of the server. Possible values are: `local`, `bootscript` or `rescue`.

- `replace_on_type_change` - (Defaults to false) If true, the server will be replaced if `type` is changed. Otherwise, the server will migrate.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func DataSourceInstancePrivateNICRead(ctx context.Context, d *schema.ResourceDat
}

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

Expand Down
53 changes: 52 additions & 1 deletion internal/services/instance/private_nic.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ package instance
import (
"context"

"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
ipamAPI "github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/cdf"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/dsf"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/ipam"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
)

Expand Down Expand Up @@ -68,6 +71,25 @@ func ResourcePrivateNIC() *schema.Resource {
Description: "IPAM ip list, should be for internal use only",
ForceNew: true,
},
"private_ips": {
Type: schema.TypeList,
Computed: true,
Description: "List of private IPv4 and IPv6 addresses associated with the resource",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
Description: "The ID of the IP address resource",
},
"address": {
Type: schema.TypeString,
Computed: true,
Description: "The private IP address",
},
},
},
},
"ipam_ip_ids": {
Type: schema.TypeList,
Elem: &schema.Schema{
Expand Down Expand Up @@ -163,7 +185,36 @@ func ResourceInstancePrivateNICRead(ctx context.Context, d *schema.ResourceData,
_ = d.Set("tags", privateNIC.Tags)
}

return nil
region, err := zone.Region()
if err != nil {
return diag.FromErr(err)
}

diags := diag.Diagnostics{}
resourceType := ipamAPI.ResourceTypeInstancePrivateNic
opts := &ipam.GetResourcePrivateIPsOptions{
ResourceID: &privateNIC.ID,
ResourceType: &resourceType,
PrivateNetworkID: &privateNIC.PrivateNetworkID,
}

privateIPs, err := ipam.GetResourcePrivateIPs(ctx, m, region, opts)
if err != nil {
if !httperrors.Is403(err) {
return diag.FromErr(err)
}

diags = append(diags, diag.Diagnostic{
Severity: diag.Warning,
Summary: err.Error(),
Detail: "Got 403 while reading private IPs from IPAM API, please check your IAM permissions",
AttributePath: cty.GetAttrPath("private_ips"),
})
}

_ = d.Set("private_ips", privateIPs)

return diags
}

func ResourceInstancePrivateNICUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
Expand Down
2 changes: 2 additions & 0 deletions internal/services/instance/private_nic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ func TestAccPrivateNIC_Basic(t *testing.T) {
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "mac_address"),
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "private_network_id"),
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "server_id"),
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "private_ips.0.id"),
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "private_ips.0.address"),
),
},
},
Expand Down
68 changes: 65 additions & 3 deletions internal/services/instance/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1"
instanceSDK "github.com/scaleway/scaleway-sdk-go/api/instance/v1"
ipamAPI "github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
"github.com/scaleway/scaleway-sdk-go/api/marketplace/v2"
"github.com/scaleway/scaleway-sdk-go/scw"
scwvalidation "github.com/scaleway/scaleway-sdk-go/validation"
Expand All @@ -31,6 +32,7 @@ import (
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/instance/instancehelpers"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/ipam"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/vpc"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
Expand Down Expand Up @@ -350,6 +352,25 @@ func ResourceServer() *schema.Resource {
},
},
},
"private_ips": {
Type: schema.TypeList,
Computed: true,
Description: "List of private IPv4 addresses associated with the resource",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
Description: "The ID of the IPv4 address resource",
},
"address": {
Type: schema.TypeString,
Computed: true,
Description: "The private IPv4 address",
},
},
},
},
"zone": zonal.Schema(),
"organization_id": account.OrganizationIDSchema(),
"project_id": account.ProjectIDSchema(),
Expand Down Expand Up @@ -773,6 +794,47 @@ func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m i
return diag.FromErr(err)
}

privateNICIDs := []string(nil)
for _, nic := range ph.privateNICsMap {
privateNICIDs = append(privateNICIDs, nic.ID)
}

allPrivateIPs := []map[string]interface{}(nil)
diags := diag.Diagnostics{}
resourceType := ipamAPI.ResourceTypeInstancePrivateNic

region, err := zone.Region()
if err != nil {
return diag.FromErr(err)
}

for _, nicID := range privateNICIDs {
opts := &ipam.GetResourcePrivateIPsOptions{
ResourceType: &resourceType,
ResourceID: &nicID,
}

privateIPs, err := ipam.GetResourcePrivateIPs(ctx, m, region, opts)
if err != nil {
if !httperrors.Is403(err) {
return diag.FromErr(err)
}

diags = append(diags, diag.Diagnostic{
Severity: diag.Warning,
Summary: err.Error(),
Detail: "Got 403 while reading private IPs from IPAM API, please check your IAM permissions",
AttributePath: cty.GetAttrPath("private_ips"),
})
}

if privateIPs != nil {
allPrivateIPs = append(allPrivateIPs, privateIPs...)
}
}

_ = d.Set("private_ips", allPrivateIPs)

////
// Display warning if server will soon reach End of Service
////
Expand All @@ -787,7 +849,7 @@ func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m i

mostRelevantTypes := compatibleTypes.CompatibleTypes[:5]

return diag.Diagnostics{diag.Diagnostic{
diags = append(diags, diag.Diagnostic{
Severity: diag.Warning,
Detail: fmt.Sprintf("Instance type %q will soon reach End of Service", server.CommercialType),
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.
Expand All @@ -803,10 +865,10 @@ You can check the full list of compatible server types:
server.Zone,
),
AttributePath: cty.GetAttrPath("type"),
}}
})
}

return nil
return diags
}

//gocyclo:ignore
Expand Down
2 changes: 2 additions & 0 deletions internal/services/instance/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,8 @@ func TestAccServer_PrivateNetwork(t *testing.T) {
resource.TestCheckResourceAttrSet("scaleway_instance_server.base", "private_network.0.zone"),
resource.TestCheckResourceAttrPair("scaleway_instance_server.base", "private_network.0.pn_id",
"scaleway_vpc_private_network.internal", "id"),
resource.TestCheckResourceAttrSet("scaleway_instance_server.base", "private_ips.0.id"),
resource.TestCheckResourceAttrSet("scaleway_instance_server.base", "private_ips.0.address"),
),
},
{
Expand Down
2,910 changes: 1,994 additions & 916 deletions internal/services/instance/testdata/data-source-private-nic-basic.cassette.yaml

Large diffs are not rendered by default.

1,033 changes: 590 additions & 443 deletions internal/services/instance/testdata/private-nic-basic.cassette.yaml

Large diffs are not rendered by default.

1,851 changes: 1,244 additions & 607 deletions internal/services/instance/testdata/private-nic-tags.cassette.yaml

Large diffs are not rendered by default.

1,216 changes: 657 additions & 559 deletions internal/services/instance/testdata/private-nic-with-ipam.cassette.yaml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

4,811 changes: 2,822 additions & 1,989 deletions internal/services/instance/testdata/server-private-network.cassette.yaml

Large diffs are not rendered by default.

1,505 changes: 826 additions & 679 deletions internal/services/ipam/testdata/data-source-ipamip-instance-lb.cassette.yaml

Large diffs are not rendered by default.

1,354 changes: 775 additions & 579 deletions internal/services/ipam/testdata/data-source-ipamip-instance.cassette.yaml

Large diffs are not rendered by default.

4,384 changes: 2,927 additions & 1,457 deletions internal/services/vpc/testdata/vpc-route-basic.cassette.yaml

Large diffs are not rendered by default.

Loading
Loading