From 4147ff6a29500dd47cd905a0239abdc28cffc596 Mon Sep 17 00:00:00 2001 From: Leah Date: Wed, 5 Jul 2023 03:37:14 +0200 Subject: [PATCH] feat: add import support for a lot of resources (#390) * add import support for a lot of resources * fix lints * set user_id after importing (cherry picked from commit c3d09ed00f6e1d7b0bb3ab01a1fc5c81510aa2e1) * add tests, fix empty ID * add import docs * fix lint --- .../virtual_environment_cluster_firewall.md | 12 +++++ ...ronment_cluster_firewall_security_group.md | 8 ++++ .../virtual_environment_container.md | 8 ++++ docs/resources/virtual_environment_dns.md | 8 ++++ docs/resources/virtual_environment_file.md | 10 +++- docs/resources/virtual_environment_group.md | 8 ++++ docs/resources/virtual_environment_hosts.md | 12 +++++ docs/resources/virtual_environment_pool.md | 8 ++++ docs/resources/virtual_environment_role.md | 8 ++++ docs/resources/virtual_environment_time.md | 8 ++++ docs/resources/virtual_environment_user.md | 8 ++++ docs/resources/virtual_environment_vm.md | 8 ++++ .../resource/cluster/firewall/firewall.go | 3 ++ .../cluster/firewall/security_group.go | 3 ++ proxmoxtf/resource/container.go | 16 +++++++ proxmoxtf/resource/dns.go | 14 ++++++ proxmoxtf/resource/file.go | 32 +++++++++++++ proxmoxtf/resource/file_test.go | 39 ++++++++++++++++ proxmoxtf/resource/group.go | 3 ++ proxmoxtf/resource/hosts.go | 14 ++++++ proxmoxtf/resource/pool.go | 3 ++ proxmoxtf/resource/role.go | 3 ++ proxmoxtf/resource/time.go | 14 ++++++ proxmoxtf/resource/user.go | 10 +++- proxmoxtf/resource/utils.go | 24 ++-------- proxmoxtf/resource/utils_test.go | 46 ++++++++++++++++++- proxmoxtf/resource/vm.go | 16 +++++++ 27 files changed, 322 insertions(+), 24 deletions(-) diff --git a/docs/resources/virtual_environment_cluster_firewall.md b/docs/resources/virtual_environment_cluster_firewall.md index 407f19c4..f608ff2e 100644 --- a/docs/resources/virtual_environment_cluster_firewall.md +++ b/docs/resources/virtual_environment_cluster_firewall.md @@ -43,3 +43,15 @@ resource "proxmox_virtual_environment_cluster_firewall" "example" { ## Attribute Reference There are no additional attributes available for this resource. + +## Important Notes + +Be careful not to use this resource multiple times for the same node. + +## Import + +Instances can be imported without an ID, but you still need to pass one, e.g., + +```bash +$ terraform import proxmox_virtual_environment_cluster_firewall.example example +``` diff --git a/docs/resources/virtual_environment_cluster_firewall_security_group.md b/docs/resources/virtual_environment_cluster_firewall_security_group.md index 932ca430..7d3f028e 100644 --- a/docs/resources/virtual_environment_cluster_firewall_security_group.md +++ b/docs/resources/virtual_environment_cluster_firewall_security_group.md @@ -86,3 +86,11 @@ resource "proxmox_virtual_environment_cluster_firewall_security_group" "webserve - `pos` - Position of the rule in the list. There are no attribute references available for this resource. + +## Import + +Instances can be imported using the `name`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_cluster_firewall_security_group.webserver webserver +``` diff --git a/docs/resources/virtual_environment_container.md b/docs/resources/virtual_environment_container.md index 3af3245d..b09d5167 100644 --- a/docs/resources/virtual_environment_container.md +++ b/docs/resources/virtual_environment_container.md @@ -181,3 +181,11 @@ output "ubuntu_container_public_key" { ## Attribute Reference There are no additional attributes available for this resource. + +## Import + +Instances can be imported using the `node_name` and the `vm_id`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_container.ubuntu_container first-node/1234 +``` diff --git a/docs/resources/virtual_environment_dns.md b/docs/resources/virtual_environment_dns.md index 0fa4c4c8..48dccf4c 100644 --- a/docs/resources/virtual_environment_dns.md +++ b/docs/resources/virtual_environment_dns.md @@ -42,3 +42,11 @@ There are no additional attributes available for this resource. ## Important Notes Be careful not to use this resource multiple times for the same node. + +## Import + +Instances can be imported using the `node_name`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_dns.first_node first-node +``` diff --git a/docs/resources/virtual_environment_file.md b/docs/resources/virtual_environment_file.md index 3f809208..ae3b32ff 100644 --- a/docs/resources/virtual_environment_file.md +++ b/docs/resources/virtual_environment_file.md @@ -70,7 +70,7 @@ EOF - `file_name` - (Optional) The file name to use instead of the source file name. - `insecure` - (Optional) Whether to skip the TLS verification step for - HTTPSsources (defaults to `false`). + HTTPS sources (defaults to `false`). - `path` - (Required) A path to a local file or a URL. - `source_raw` - (Optional) The raw source (conflicts with `source_file`). - `data` - (Required) The raw data. @@ -93,3 +93,11 @@ file locally before uploading it. You must ensure that you have at least `Size-in-MB * 2 + 1` MB of storage space available (twice the size plus overhead because a multipart payload needs to be created as another temporary file). + +## Import + +Instances can be imported using the `node_name`, `datastore_id`, `content_type` and the `file_name`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_file.cloud_config pve/local/snippets/example.cloud-config.yaml +``` diff --git a/docs/resources/virtual_environment_group.md b/docs/resources/virtual_environment_group.md index 443f52e2..923ebe8a 100644 --- a/docs/resources/virtual_environment_group.md +++ b/docs/resources/virtual_environment_group.md @@ -32,3 +32,11 @@ resource "proxmox_virtual_environment_group" "operations_team" { ## Attribute Reference - `members` - The group members as a list of `username@realm` entries + +## Import + +Instances can be imported using the `group_id`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_group.operations_team operations-team +``` diff --git a/docs/resources/virtual_environment_hosts.md b/docs/resources/virtual_environment_hosts.md index f50dca26..deaf7167 100644 --- a/docs/resources/virtual_environment_hosts.md +++ b/docs/resources/virtual_environment_hosts.md @@ -42,3 +42,15 @@ resource "proxmox_virtual_environment_hosts" "first_node_host_entries" { - `entries` - The host entries (conversion of `addresses` and `hostnames` into objects). - `hostnames` - The hostnames associated with each of the IP addresses. + +## Important Notes + +Be careful not to use this resource multiple times for the same node. + +## Import + +Instances can be imported using the `node_name`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_hosts.first_node_host_entries first-node +``` diff --git a/docs/resources/virtual_environment_pool.md b/docs/resources/virtual_environment_pool.md index 259655cd..45a3feba 100644 --- a/docs/resources/virtual_environment_pool.md +++ b/docs/resources/virtual_environment_pool.md @@ -33,3 +33,11 @@ resource "proxmox_virtual_environment_pool" "operations_pool" { - `node_name` - The node name. - `type` - The member type. - `vm_id` - The virtual machine identifier. + +## Import + +Instances can be imported using the `pool_id`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_pool.operations_pool operations-pool +``` diff --git a/docs/resources/virtual_environment_role.md b/docs/resources/virtual_environment_role.md index f7f8f215..9e028099 100644 --- a/docs/resources/virtual_environment_role.md +++ b/docs/resources/virtual_environment_role.md @@ -31,3 +31,11 @@ resource "proxmox_virtual_environment_role" "operations_monitoring" { ## Attribute Reference There are no additional attributes available for this resource. + +## Import + +Instances can be imported using the `role_id`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_role.operations_monitoring operations-monitoring +``` diff --git a/docs/resources/virtual_environment_time.md b/docs/resources/virtual_environment_time.md index 9f369915..e41237fe 100644 --- a/docs/resources/virtual_environment_time.md +++ b/docs/resources/virtual_environment_time.md @@ -29,3 +29,11 @@ resource "proxmox_virtual_environment_time" "first_node_time" { - `local_time` - The node's local time. - `utc_time` - The node's local time formatted as UTC. + +## Import + +Instances can be imported using the `node_name`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_dns.first_node first-node +``` diff --git a/docs/resources/virtual_environment_user.md b/docs/resources/virtual_environment_user.md index 9b3e5875..e3e69428 100644 --- a/docs/resources/virtual_environment_user.md +++ b/docs/resources/virtual_environment_user.md @@ -55,3 +55,11 @@ resource "proxmox_virtual_environment_role" "operations_monitoring" { ## Attribute Reference There are no additional attributes available for this resource. + +## Import + +Instances can be imported using the `user_id`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_user.operations_automation operations-automation@pve +``` diff --git a/docs/resources/virtual_environment_vm.md b/docs/resources/virtual_environment_vm.md index 3b6fecfc..6dcf23c8 100644 --- a/docs/resources/virtual_environment_vm.md +++ b/docs/resources/virtual_environment_vm.md @@ -462,3 +462,11 @@ to force the migration step to migrate all disks to a specific datastore on the target node. If you need certain disks to be on specific datastores, set the `datastore_id` argument of the disks in the `disks` block to move the disks to the correct datastore after the cloning and migrating succeeded. + +## Import + +Instances can be imported using the `node_name` and the `vm_id`, e.g., + +```bash +$ terraform import proxmox_virtual_environment_vm.ubuntu_vm first-node/4321 +``` diff --git a/proxmoxtf/resource/cluster/firewall/firewall.go b/proxmoxtf/resource/cluster/firewall/firewall.go index ebee985e..47e2412b 100644 --- a/proxmoxtf/resource/cluster/firewall/firewall.go +++ b/proxmoxtf/resource/cluster/firewall/firewall.go @@ -107,6 +107,9 @@ func Firewall() *schema.Resource { ReadContext: selectFirewallAPI(firewallRead), UpdateContext: selectFirewallAPI(firewallUpdate), DeleteContext: selectFirewallAPI(firewallDelete), + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, } } diff --git a/proxmoxtf/resource/cluster/firewall/security_group.go b/proxmoxtf/resource/cluster/firewall/security_group.go index 200b10d3..710d25d9 100644 --- a/proxmoxtf/resource/cluster/firewall/security_group.go +++ b/proxmoxtf/resource/cluster/firewall/security_group.go @@ -50,6 +50,9 @@ func SecurityGroup() *schema.Resource { ReadContext: selectFirewallAPI(SecurityGroupRead), UpdateContext: selectFirewallAPI(SecurityGroupUpdate), DeleteContext: selectFirewallAPI(SecurityGroupDelete), + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, } } diff --git a/proxmoxtf/resource/container.go b/proxmoxtf/resource/container.go index f7cef5f6..f74807e8 100644 --- a/proxmoxtf/resource/container.go +++ b/proxmoxtf/resource/container.go @@ -643,6 +643,22 @@ func Container() *schema.Resource { ReadContext: containerRead, UpdateContext: containerUpdate, DeleteContext: containerDelete, + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, i interface{}) ([]*schema.ResourceData, error) { + node, id, err := parseImportIDWithNodeName(d.Id()) + if err != nil { + return nil, err + } + + d.SetId(id) + err = d.Set(mkResourceVirtualEnvironmentContainerNodeName, node) + if err != nil { + return nil, fmt.Errorf("failed setting state during import: %w", err) + } + + return []*schema.ResourceData{d}, nil + }, + }, } } diff --git a/proxmoxtf/resource/dns.go b/proxmoxtf/resource/dns.go index dc7d3a5f..3336baa3 100644 --- a/proxmoxtf/resource/dns.go +++ b/proxmoxtf/resource/dns.go @@ -54,6 +54,20 @@ func DNS() *schema.Resource { ReadContext: dnsRead, UpdateContext: dnsUpdate, DeleteContext: dnsDelete, + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, i interface{}) ([]*schema.ResourceData, error) { + nodeName := d.Id() + + err := d.Set(mkResourceVirtualEnvironmentDNSNodeName, nodeName) + if err != nil { + return nil, fmt.Errorf("failed setting state during import: %w", err) + } + + d.SetId(fmt.Sprintf("%s_dns", nodeName)) + + return []*schema.ResourceData{d}, nil + }, + }, } } diff --git a/proxmoxtf/resource/file.go b/proxmoxtf/resource/file.go index 4785e378..c63eaf67 100644 --- a/proxmoxtf/resource/file.go +++ b/proxmoxtf/resource/file.go @@ -193,9 +193,41 @@ func File() *schema.Resource { CreateContext: fileCreate, ReadContext: fileRead, DeleteContext: fileDelete, + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, i interface{}) ([]*schema.ResourceData, error) { + node, datastore, volumeID, err := fileParseImportID(d.Id()) + if err != nil { + return nil, err + } + + d.SetId(volumeID) + + err = d.Set(mkResourceVirtualEnvironmentFileNodeName, node) + if err != nil { + return nil, fmt.Errorf("failed setting state during import: %w", err) + } + + err = d.Set(mkResourceVirtualEnvironmentFileDatastoreID, datastore) + if err != nil { + return nil, fmt.Errorf("failed setting state during import: %w", err) + } + + return []*schema.ResourceData{d}, nil + }, + }, } } +func fileParseImportID(id string) (string, string, string, error) { + parts := strings.SplitN(id, "/", 4) + + if len(parts) != 4 || parts[0] == "" || parts[1] == "" || parts[2] == "" || parts[3] == "" { + return "", "", "", fmt.Errorf("unexpected format of ID (%s), expected node/datastore_id/content_type/file_name", id) + } + + return parts[0], parts[1], strings.Join(parts[2:], "/"), nil +} + func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics diff --git a/proxmoxtf/resource/file_test.go b/proxmoxtf/resource/file_test.go index 81edc426..622b64a7 100644 --- a/proxmoxtf/resource/file_test.go +++ b/proxmoxtf/resource/file_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) @@ -98,3 +99,41 @@ func TestFileSchema(t *testing.T) { mkResourceVirtualEnvironmentFileSourceRawResize: schema.TypeInt, }) } + +func Test_fileParseImportID(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + value string + valid bool + expectedNodeName string + expectedDatastoreID string + expectedVolumeID string + }{ + {"empty", "", false, "", "", ""}, + {"missing slash", "invalid", false, "", "", ""}, + {"missing parts", "invalid/invalid/invalid", false, "", "", ""}, + {"valid", "node/datastore_id/content_type/file_name", true, "node", "datastore_id", "content_type/file_name"}, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + require := require.New(t) + + nodeName, datastoreID, volumeID, err := fileParseImportID(tt.value) + + if !tt.valid { + require.Error(err) + return + } + + require.Nil(err) + require.Equal(tt.expectedNodeName, nodeName) + require.Equal(tt.expectedDatastoreID, datastoreID) + require.Equal(tt.expectedVolumeID, volumeID) + }) + } +} diff --git a/proxmoxtf/resource/group.go b/proxmoxtf/resource/group.go index 3b670a59..960e7e82 100644 --- a/proxmoxtf/resource/group.go +++ b/proxmoxtf/resource/group.go @@ -85,6 +85,9 @@ func Group() *schema.Resource { ReadContext: groupRead, UpdateContext: groupUpdate, DeleteContext: groupDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, } } diff --git a/proxmoxtf/resource/hosts.go b/proxmoxtf/resource/hosts.go index 5e56f368..33e77433 100644 --- a/proxmoxtf/resource/hosts.go +++ b/proxmoxtf/resource/hosts.go @@ -107,6 +107,20 @@ func Hosts() *schema.Resource { ReadContext: hostsRead, UpdateContext: hostsUpdate, DeleteContext: hostsDelete, + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, i interface{}) ([]*schema.ResourceData, error) { + nodeName := d.Id() + + err := d.Set(mkResourceVirtualEnvironmentHostsNodeName, nodeName) + if err != nil { + return nil, fmt.Errorf("failed setting state during import: %w", err) + } + + d.SetId(fmt.Sprintf("%s_hosts", nodeName)) + + return []*schema.ResourceData{d}, nil + }, + }, } } diff --git a/proxmoxtf/resource/pool.go b/proxmoxtf/resource/pool.go index a7147060..658a278a 100644 --- a/proxmoxtf/resource/pool.go +++ b/proxmoxtf/resource/pool.go @@ -85,6 +85,9 @@ func Pool() *schema.Resource { ReadContext: poolRead, UpdateContext: poolUpdate, DeleteContext: poolDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, } } diff --git a/proxmoxtf/resource/role.go b/proxmoxtf/resource/role.go index 6905d3b2..4afd96d9 100644 --- a/proxmoxtf/resource/role.go +++ b/proxmoxtf/resource/role.go @@ -44,6 +44,9 @@ func Role() *schema.Resource { ReadContext: roleRead, UpdateContext: roleUpdate, DeleteContext: roleDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, } } diff --git a/proxmoxtf/resource/time.go b/proxmoxtf/resource/time.go index c4b469b5..135f92d7 100644 --- a/proxmoxtf/resource/time.go +++ b/proxmoxtf/resource/time.go @@ -54,6 +54,20 @@ func Time() *schema.Resource { ReadContext: timeRead, UpdateContext: timeUpdate, DeleteContext: timeDelete, + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, i interface{}) ([]*schema.ResourceData, error) { + nodeName := d.Id() + + err := d.Set(mkResourceVirtualEnvironmentTimeNodeName, nodeName) + if err != nil { + return nil, fmt.Errorf("failed setting state during import: %w", err) + } + + d.SetId(fmt.Sprintf("%s_time", nodeName)) + + return []*schema.ResourceData{d}, nil + }, + }, } } diff --git a/proxmoxtf/resource/user.go b/proxmoxtf/resource/user.go index 10607a21..50e45d70 100644 --- a/proxmoxtf/resource/user.go +++ b/proxmoxtf/resource/user.go @@ -144,6 +144,9 @@ func User() *schema.Resource { ReadContext: userRead, UpdateContext: userUpdate, DeleteContext: userDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, } } @@ -248,6 +251,11 @@ func userRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D return diag.FromErr(err) } + var diags diag.Diagnostics + + err = d.Set(mkResourceVirtualEnvironmentUserUserID, userID) + diags = append(diags, diag.FromErr(err)...) + var aclParsed []interface{} for _, v := range acl { @@ -268,8 +276,6 @@ func userRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D } } - var diags diag.Diagnostics - err = d.Set(mkResourceVirtualEnvironmentUserACL, aclParsed) diags = append(diags, diag.FromErr(err)...) diff --git a/proxmoxtf/resource/utils.go b/proxmoxtf/resource/utils.go index a384b363..8abddf4b 100644 --- a/proxmoxtf/resource/utils.go +++ b/proxmoxtf/resource/utils.go @@ -7,7 +7,6 @@ package resource import ( - "errors" "fmt" "reflect" "regexp" @@ -16,9 +15,6 @@ import ( "time" "unicode" - "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -561,22 +557,12 @@ func getCloudInitTypeValidator() schema.SchemaValidateDiagFunc { }, false)) } -type ErrorDiags diag.Diagnostics +func parseImportIDWithNodeName(id string) (string, string, error) { + nodeName, id, found := strings.Cut(id, "/") -func (diags ErrorDiags) Errors() []error { - var es []error - for i := range diags { - if diags[i].Severity == diag.Error { - s := fmt.Sprintf("Error: %s", diags[i].Summary) - if diags[i].Detail != "" { - s = fmt.Sprintf("%s: %s", s, diags[i].Detail) - } - es = append(es, errors.New(s)) - } + if !found { + return "", "", fmt.Errorf("unexpected format of ID (%s), expected node/id", id) } - return es -} -func (diags ErrorDiags) Error() string { - return multierror.ListFormatFunc(diags.Errors()) + return nodeName, id, nil } diff --git a/proxmoxtf/resource/utils_test.go b/proxmoxtf/resource/utils_test.go index 48f4dc12..ae9e9bdf 100644 --- a/proxmoxtf/resource/utils_test.go +++ b/proxmoxtf/resource/utils_test.go @@ -8,6 +8,8 @@ package resource import ( "testing" + + "github.com/stretchr/testify/require" ) func Test_getCPUTypeValidator(t *testing.T) { @@ -29,11 +31,51 @@ func Test_getCPUTypeValidator(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() + require := require.New(t) + f := getCPUTypeValidator() res := f(tt.value, nil) - if !res.HasError() != tt.valid { - t.Errorf("validate: '%s', want %v got %v", tt.value, tt.valid, res) + + if tt.valid { + require.Empty(res, "validate: '%s'", tt.value) + } else { + require.NotEmpty(res, "validate: '%s'", tt.value) } }) } } + +func Test_parseImportIDWIthNodeName(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + value string + valid bool + expectedNodeName string + expectedID string + }{ + {"empty", "", false, "", ""}, + {"missing slash", "invalid", false, "", ""}, + {"valid", "host/id", true, "host", "id"}, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + require := require.New(t) + + nodeName, id, err := parseImportIDWithNodeName(tt.value) + + if !tt.valid { + require.Error(err) + return + } + + require.Nil(err) + require.Equal(tt.expectedNodeName, nodeName) + require.Equal(tt.expectedID, id) + }) + } +} diff --git a/proxmoxtf/resource/vm.go b/proxmoxtf/resource/vm.go index f65ba169..488c6c17 100644 --- a/proxmoxtf/resource/vm.go +++ b/proxmoxtf/resource/vm.go @@ -1344,6 +1344,22 @@ func VM() *schema.Resource { }, ), ), + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, i interface{}) ([]*schema.ResourceData, error) { + node, id, err := parseImportIDWithNodeName(d.Id()) + if err != nil { + return nil, err + } + + d.SetId(id) + err = d.Set(mkResourceVirtualEnvironmentVMNodeName, node) + if err != nil { + return nil, fmt.Errorf("failed setting state during import: %w", err) + } + + return []*schema.ResourceData{d}, nil + }, + }, } }