Skip to content

Commit cc6e1c6

Browse files
committed
feat(vpc): add support for ResourceIdentity
1 parent 13e1fd9 commit cc6e1c6

File tree

4 files changed

+231
-4
lines changed

4 files changed

+231
-4
lines changed

internal/services/vpc/acl.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package vpc
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
78
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -10,6 +11,7 @@ import (
1011
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
1112
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
1213
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
14+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
1315
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
1416
)
1517

@@ -20,7 +22,56 @@ func ResourceACL() *schema.Resource {
2022
UpdateContext: ResourceVPCACLUpdate,
2123
DeleteContext: ResourceVPCACLDelete,
2224
Importer: &schema.ResourceImporter{
23-
StateContext: schema.ImportStatePassthroughContext,
25+
StateContext: func(
26+
ctx context.Context,
27+
d *schema.ResourceData,
28+
m interface{},
29+
) ([]*schema.ResourceData, error) {
30+
// If importing by ID (e.g. "fr-par/8cef…"), we just set the ID field to state, allowing the read to fill in the rest of the data
31+
if d.Id() != "" {
32+
return []*schema.ResourceData{d}, nil
33+
}
34+
35+
// Otherwise, we're importing by identity “identity = { id = ..., region = ... }”
36+
identity, err := d.Identity()
37+
if err != nil {
38+
return nil, fmt.Errorf("error retrieving identity: %w", err)
39+
}
40+
41+
rawID := identity.Get("id").(string)
42+
regionVal := identity.Get("region").(string)
43+
if regionVal == "" {
44+
region, err := meta.ExtractRegion(d, m)
45+
if err != nil {
46+
return nil, fmt.Errorf("identity.region was not set")
47+
48+
}
49+
regionVal = region.String()
50+
}
51+
52+
localizedID := fmt.Sprintf("%s/%s", regionVal, rawID)
53+
54+
d.SetId(localizedID)
55+
56+
return []*schema.ResourceData{d}, nil
57+
},
58+
},
59+
Identity: &schema.ResourceIdentity{
60+
Version: 0,
61+
SchemaFunc: func() map[string]*schema.Schema {
62+
return map[string]*schema.Schema{
63+
"id": {
64+
Type: schema.TypeString,
65+
RequiredForImport: true,
66+
Description: "The ACL ID (e.g. `11111111-1111-1111-1111-111111111111`)",
67+
},
68+
"region": {
69+
Type: schema.TypeString,
70+
OptionalForImport: true,
71+
Description: "The region of the VPC. If omitted during import, defaults from provider",
72+
},
73+
}
74+
},
2475
},
2576
SchemaVersion: 0,
2677
Schema: map[string]*schema.Schema{

internal/services/vpc/private_network.go

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package vpc
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
78
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
@@ -25,7 +26,56 @@ func ResourcePrivateNetwork() *schema.Resource {
2526
UpdateContext: ResourceVPCPrivateNetworkUpdate,
2627
DeleteContext: ResourceVPCPrivateNetworkDelete,
2728
Importer: &schema.ResourceImporter{
28-
StateContext: schema.ImportStatePassthroughContext,
29+
StateContext: func(
30+
ctx context.Context,
31+
d *schema.ResourceData,
32+
m interface{},
33+
) ([]*schema.ResourceData, error) {
34+
// If importing by ID (e.g. "fr-par/8cef…"), we just set the ID field to state, allowing the read to fill in the rest of the data
35+
if d.Id() != "" {
36+
return []*schema.ResourceData{d}, nil
37+
}
38+
39+
// Otherwise, we're importing by identity “identity = { id = ..., region = ... }”
40+
identity, err := d.Identity()
41+
if err != nil {
42+
return nil, fmt.Errorf("error retrieving identity: %w", err)
43+
}
44+
45+
rawID := identity.Get("id").(string)
46+
regionVal := identity.Get("region").(string)
47+
if regionVal == "" {
48+
region, err := meta.ExtractRegion(d, m)
49+
if err != nil {
50+
return nil, fmt.Errorf("identity.region was not set")
51+
52+
}
53+
regionVal = region.String()
54+
}
55+
56+
localizedID := fmt.Sprintf("%s/%s", regionVal, rawID)
57+
58+
d.SetId(localizedID)
59+
60+
return []*schema.ResourceData{d}, nil
61+
},
62+
},
63+
Identity: &schema.ResourceIdentity{
64+
Version: 0,
65+
SchemaFunc: func() map[string]*schema.Schema {
66+
return map[string]*schema.Schema{
67+
"id": {
68+
Type: schema.TypeString,
69+
RequiredForImport: true,
70+
Description: "The Private Network ID (e.g. `11111111-1111-1111-1111-111111111111`)",
71+
},
72+
"region": {
73+
Type: schema.TypeString,
74+
OptionalForImport: true,
75+
Description: "The region of the VPC. If omitted during import, defaults from provider",
76+
},
77+
}
78+
},
2979
},
3080
SchemaVersion: 1,
3181
StateUpgraders: []schema.StateUpgrader{
@@ -266,6 +316,18 @@ func ResourceVPCPrivateNetworkRead(ctx context.Context, d *schema.ResourceData,
266316
_ = d.Set("ipv4_subnet", ipv4Subnet)
267317
_ = d.Set("ipv6_subnets", ipv6Subnets)
268318

319+
identity, err := d.Identity()
320+
if err != nil {
321+
return diag.FromErr(err)
322+
}
323+
324+
if err = identity.Set("id", pn.ID); err != nil {
325+
return diag.FromErr(err)
326+
}
327+
if err = identity.Set("region", region); err != nil {
328+
return diag.FromErr(err)
329+
}
330+
269331
return nil
270332
}
271333

internal/services/vpc/route.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package vpc
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
78
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -11,6 +12,7 @@ import (
1112
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
1213
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
1314
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
15+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
1416
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
1517
)
1618

@@ -21,7 +23,56 @@ func ResourceRoute() *schema.Resource {
2123
UpdateContext: ResourceRouteUpdate,
2224
DeleteContext: ResourceRouteDelete,
2325
Importer: &schema.ResourceImporter{
24-
StateContext: schema.ImportStatePassthroughContext,
26+
StateContext: func(
27+
ctx context.Context,
28+
d *schema.ResourceData,
29+
m interface{},
30+
) ([]*schema.ResourceData, error) {
31+
// If importing by ID (e.g. "fr-par/8cef…"), we just set the ID field to state, allowing the read to fill in the rest of the data
32+
if d.Id() != "" {
33+
return []*schema.ResourceData{d}, nil
34+
}
35+
36+
// Otherwise, we're importing by identity “identity = { id = ..., region = ... }”
37+
identity, err := d.Identity()
38+
if err != nil {
39+
return nil, fmt.Errorf("error retrieving identity: %w", err)
40+
}
41+
42+
rawID := identity.Get("id").(string)
43+
regionVal := identity.Get("region").(string)
44+
if regionVal == "" {
45+
region, err := meta.ExtractRegion(d, m)
46+
if err != nil {
47+
return nil, fmt.Errorf("identity.region was not set")
48+
49+
}
50+
regionVal = region.String()
51+
}
52+
53+
localizedID := fmt.Sprintf("%s/%s", regionVal, rawID)
54+
55+
d.SetId(localizedID)
56+
57+
return []*schema.ResourceData{d}, nil
58+
},
59+
},
60+
Identity: &schema.ResourceIdentity{
61+
Version: 0,
62+
SchemaFunc: func() map[string]*schema.Schema {
63+
return map[string]*schema.Schema{
64+
"id": {
65+
Type: schema.TypeString,
66+
RequiredForImport: true,
67+
Description: "The Route ID (e.g. `11111111-1111-1111-1111-111111111111`)",
68+
},
69+
"region": {
70+
Type: schema.TypeString,
71+
OptionalForImport: true,
72+
Description: "The region of the VPC. If omitted during import, defaults from provider",
73+
},
74+
}
75+
},
2576
},
2677
SchemaVersion: 0,
2778
Schema: map[string]*schema.Schema{

internal/services/vpc/vpc.go

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ package vpc
33
import (
44
"context"
55
"errors"
6+
"fmt"
67

78
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
89
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
910
"github.com/scaleway/scaleway-sdk-go/api/vpc/v2"
1011
"github.com/scaleway/scaleway-sdk-go/scw"
1112
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
1213
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
14+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
1315
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
1416
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
1517
)
@@ -21,7 +23,56 @@ func ResourceVPC() *schema.Resource {
2123
UpdateContext: ResourceVPCUpdate,
2224
DeleteContext: ResourceVPCDelete,
2325
Importer: &schema.ResourceImporter{
24-
StateContext: schema.ImportStatePassthroughContext,
26+
StateContext: func(
27+
ctx context.Context,
28+
d *schema.ResourceData,
29+
m interface{},
30+
) ([]*schema.ResourceData, error) {
31+
// If importing by ID (e.g. "fr-par/8cef…"), we just set the ID field to state, allowing the read to fill in the rest of the data
32+
if d.Id() != "" {
33+
return []*schema.ResourceData{d}, nil
34+
}
35+
36+
// Otherwise, we're importing by identity “identity = { id = ..., region = ... }”
37+
identity, err := d.Identity()
38+
if err != nil {
39+
return nil, fmt.Errorf("error retrieving identity: %w", err)
40+
}
41+
42+
rawID := identity.Get("id").(string)
43+
regionVal := identity.Get("region").(string)
44+
if regionVal == "" {
45+
region, err := meta.ExtractRegion(d, m)
46+
if err != nil {
47+
return nil, fmt.Errorf("identity.region was not set")
48+
49+
}
50+
regionVal = region.String()
51+
}
52+
53+
localizedID := fmt.Sprintf("%s/%s", regionVal, rawID)
54+
55+
d.SetId(localizedID)
56+
57+
return []*schema.ResourceData{d}, nil
58+
},
59+
},
60+
Identity: &schema.ResourceIdentity{
61+
Version: 0,
62+
SchemaFunc: func() map[string]*schema.Schema {
63+
return map[string]*schema.Schema{
64+
"id": {
65+
Type: schema.TypeString,
66+
RequiredForImport: true,
67+
Description: "The VPC ID (e.g. `11111111-1111-1111-1111-111111111111`)",
68+
},
69+
"region": {
70+
Type: schema.TypeString,
71+
OptionalForImport: true,
72+
Description: "The region of the VPC. If omitted during import, defaults from provider",
73+
},
74+
}
75+
},
2576
},
2677
SchemaVersion: 0,
2778
Schema: map[string]*schema.Schema{
@@ -131,6 +182,18 @@ func ResourceVPCRead(ctx context.Context, d *schema.ResourceData, m interface{})
131182
_ = d.Set("tags", res.Tags)
132183
}
133184

185+
identity, err := d.Identity()
186+
if err != nil {
187+
return diag.FromErr(err)
188+
}
189+
190+
if err = identity.Set("id", res.ID); err != nil {
191+
return diag.FromErr(err)
192+
}
193+
if err = identity.Set("region", region); err != nil {
194+
return diag.FromErr(err)
195+
}
196+
134197
return nil
135198
}
136199

0 commit comments

Comments
 (0)