Skip to content

feat(ipam): show private ips on resources #2759

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

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
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/baremetal_server.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ In addition to all arguments above, the following attributes are exported:
- `status` - The private network status.
- `created_at` - The date and time of the creation of the private network.
- `updated_at` - The date and time of the last update of the private network.
- `private_ip` - The list of private IP addresses associated with the resource.
- `id` - The ID of the IP address resource.
- `address` - The private IP address.
- `ips` - (List of) The IPs of the server.
- `id` - The ID of the IP.
- `address` - The address of the IP.
Expand Down
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_ip` - The list of private IP 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 @@ -252,6 +252,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_ip` - The list of private IP addresses associated with the resource.
- `id` - The ID of the IP address resource.
- `address` - The private IP address.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would precise it is an IPv4


- `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
3 changes: 3 additions & 0 deletions docs/resources/k8s_pool.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ In addition to all arguments above, the following attributes are exported:
- `updated_at` - The last update date of the pool.
- `version` - The version of the pool.
- `current_size` - The size of the pool at the time the terraform state was updated.
- `private_ip` - The list of private IP addresses associated with the resource.
- `id` - The ID of the IP address resource.
- `address` - The private IP address.

## Zone

Expand Down
4 changes: 4 additions & 0 deletions docs/resources/lb.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ resource "scaleway_lb" "main" {

- `static_config` - (Deprecated) Please use `ipam_ids`. Define a local ip address of your choice for the load balancer instance.

- `private_ip` - The list of private IP addresses associated with the resource.
- `id` - The ID of the IP address resource.
- `address` - The private IP address.

- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which the Private Network was created.


Expand Down
3 changes: 3 additions & 0 deletions docs/resources/rdb_instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ are of the form `{region}/{id}`, e.g. `fr-par/11111111-1111-1111-1111-1111111111
- `port` - Port in the Private Network.
- `name` - Name of the endpoint.
- `hostname` - Hostname of the endpoint.
- `private_ip` - The list of private IP addresses associated with the resource.
- `id` - The ID of the IP address resource.
- `address` - The private IP address.
- `certificate` - Certificate of the Database Instance.
- `organization_id` - The organization ID the Database Instance is associated with.

Expand Down
4 changes: 4 additions & 0 deletions docs/resources/redis_cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ the form `{zone}/{id}`, e.g. `fr-par-1/11111111-1111-1111-1111-111111111111`
- `endpoint_id` - The ID of the endpoint.
- `zone` - The zone of the Private Network.

- `private_ip` - The list of private IP addresses associated with the resource.
- `id` - The ID of the IP address resource.
- `address` - The private IP address.

- `created_at` - The date and time of creation of the Redis™ cluster.
- `updated_at` - The date and time of the last update of the Redis™ cluster.
- `certificate` - The PEM of the certificate used by redis, only when `tls_enabled` is true
Expand Down
3 changes: 3 additions & 0 deletions docs/resources/vpc_gateway_network.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ In addition to all arguments above, the following attributes are exported:
- `created_at` - The date and time of the creation of the GatewayNetwork.
- `updated_at` - The date and time of the last update of the GatewayNetwork.
- `status` - The status of the Public Gateway's connection to the Private Network.
- `private_ip` - The list of private IP addresses associated with the resource.
- `id` - The ID of the IP address resource.
- `address` - The private IP address.

## Import

Expand Down
44 changes: 44 additions & 0 deletions internal/services/baremetal/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/scaleway/scaleway-sdk-go/api/baremetal/v1"
ipamAPI "github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
sdkValidation "github.com/scaleway/scaleway-sdk-go/validation"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/cdf"
Expand All @@ -18,6 +19,7 @@ import (
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/ipam"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
)
Expand Down Expand Up @@ -244,6 +246,25 @@ If this behaviour is wanted, please set 'reinstall_on_ssh_key_changes' argument
},
},
},
"private_ip": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would plural make sense here if it is a list?

Type: schema.TypeList,
Computed: true,
Description: "List of private IP 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",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would precise that it is an IPv4

},
},
},
},
},
CustomizeDiff: customdiff.Sequence(
cdf.LocalityCheck("private_network.#.id"),
Expand Down Expand Up @@ -464,12 +485,35 @@ func ResourceServerRead(ctx context.Context, d *schema.ResourceData, m interface
if err != nil {
return diag.FromErr(fmt.Errorf("failed to list server's private networks: %w", err))
}

pnRegion, err := server.Zone.Region()
if err != nil {
return diag.FromErr(err)
}
_ = d.Set("private_network", flattenPrivateNetworks(pnRegion, listPrivateNetworks.ServerPrivateNetworks))

privateNetworkIDs := make([]string, 0, len(listPrivateNetworks.ServerPrivateNetworks))
for _, pn := range listPrivateNetworks.ServerPrivateNetworks {
privateNetworkIDs = append(privateNetworkIDs, pn.PrivateNetworkID)
}

var allPrivateIPs []map[string]interface{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Considering server will have at least 1 IP per connected private network. This should be allocated for the minimum size.

for _, privateNetworkID := range privateNetworkIDs {
resourceType := ipamAPI.ResourceTypeBaremetalPrivateNic
opts := &ipam.GetResourcePrivateIPsOptions{
ResourceType: &resourceType,
PrivateNetworkID: &privateNetworkID,
}
privateIPs, err := ipam.GetResourcePrivateIPs(ctx, m, pnRegion, opts)
if err != nil {
return diag.FromErr(err)
}
if privateIPs != nil {
allPrivateIPs = append(allPrivateIPs, privateIPs...)
}
}
_ = d.Set("private_ip", allPrivateIPs)

return nil
}

Expand Down
2 changes: 2 additions & 0 deletions internal/services/baremetal/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,8 @@ func TestAccServer_CreateServerWithPrivateNetwork(t *testing.T) {
testAccCheckBaremetalServerExists(tt, "scaleway_baremetal_server.base"),
testAccCheckBaremetalServerHasPrivateNetwork(tt, "scaleway_baremetal_server.base"),
resource.TestCheckResourceAttrPair("scaleway_baremetal_server.base", "private_network.0.id", "scaleway_vpc_private_network.pn", "id"),
resource.TestCheckResourceAttrSet("scaleway_baremetal_server.base", "private_ip.0.id"),
resource.TestCheckResourceAttrSet("scaleway_baremetal_server.base", "private_ip.0.address"),
),
},
},
Expand Down
10,664 changes: 1,481 additions & 9,183 deletions internal/services/baremetal/testdata/server-add-another-private-network.cassette.yaml

Large diffs are not rendered by default.

10,339 changes: 1,392 additions & 8,947 deletions internal/services/baremetal/testdata/server-add-private-network.cassette.yaml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions internal/services/instance/private_nic.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import (
"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 +70,25 @@ func ResourcePrivateNIC() *schema.Resource {
Description: "IPAM ip list, should be for internal use only",
ForceNew: true,
},
"private_ip": {
Type: schema.TypeList,
Computed: true,
Description: "List of private IP 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",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would precise it is an IPv4

},
"address": {
Type: schema.TypeString,
Computed: true,
Description: "The private IP address",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would precise it is an IPv4

},
},
},
},
"ipam_ip_ids": {
Type: schema.TypeList,
Elem: &schema.Schema{
Expand Down Expand Up @@ -160,6 +181,23 @@ func ResourceInstancePrivateNICRead(ctx context.Context, d *schema.ResourceData,
_ = d.Set("tags", privateNIC.Tags)
}

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

resourceType := ipamAPI.ResourceTypeInstancePrivateNic
opts := &ipam.GetResourcePrivateIPsOptions{
ResourceID: &privateNIC.ID,
ResourceType: &resourceType,
PrivateNetworkID: &privateNIC.PrivateNetworkID,
}
privateIP, err := ipam.GetResourcePrivateIPs(ctx, m, region, opts)
if err != nil {
return diag.FromErr(err)
}
_ = d.Set("private_ip", privateIP)

return nil
}

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_ip.0.id"),
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "private_ip.0.address"),
),
},
},
Expand Down
47 changes: 47 additions & 0 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 @@ -30,6 +31,7 @@ import (
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
"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/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 @@ -336,6 +338,25 @@ func ResourceServer() *schema.Resource {
},
},
},
"private_ips": {
Type: schema.TypeList,
Computed: true,
Description: "List of private IP 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",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would precise it is an IPv4

},
"address": {
Type: schema.TypeString,
Computed: true,
Description: "The private IP address",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would precise it is an IPv4

},
},
},
},
"routed_ip_enabled": {
Type: schema.TypeBool,
Description: "If server supports routed IPs, default to true if public_ips is used",
Expand Down Expand Up @@ -758,6 +779,32 @@ func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m i
return diag.FromErr(err)
}

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

var allPrivateIPs []map[string]interface{}
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 {
return diag.FromErr(err)
}
if privateIPs != nil {
allPrivateIPs = append(allPrivateIPs, privateIPs...)
}
}
_ = d.Set("private_ips", allPrivateIPs)

return nil
}
return nil
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 @@ -1160,6 +1160,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,645 changes: 1,788 additions & 857 deletions internal/services/instance/testdata/data-source-private-nic-basic.cassette.yaml

Large diffs are not rendered by default.

1,174 changes: 734 additions & 440 deletions internal/services/instance/testdata/private-nic-basic.cassette.yaml

Large diffs are not rendered by default.

1,837 changes: 1,237 additions & 600 deletions internal/services/instance/testdata/private-nic-tags.cassette.yaml

Large diffs are not rendered by default.

Loading
Loading