Skip to content

Commit

Permalink
fix(Importer): Add extended resource import function
Browse files Browse the repository at this point in the history
Closes #403
  • Loading branch information
vaerh committed Apr 9, 2024
1 parent 660f63d commit 713d9ee
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
49 changes: 49 additions & 0 deletions routeros/provider_schema_helpers.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package routeros

import (
"context"
"fmt"
"regexp"
"strconv"
Expand Down Expand Up @@ -679,3 +680,51 @@ var DeleteSystemObject = []diag.Diagnostic{{
"This action will remove the object from the Terraform state. " +
"See also: 'terraform state rm' https://developer.hashicorp.com/terraform/cli/commands/state/rm",
}}

// ImportStateCustomContext is an implementation of StateContextFunc that can be used to
// import resources with the ability to explicitly or implicitly specify a key field.
// `terraform [global options] import [options] ADDR ID`.
// During import the content of the `ID` is checked and depending on the specified string it is possible to automatically search for the internal Mikrotik identifier.
// Logic of `ID` processing
// - The first character of the string contains an asterisk (standard Mikrotik identifier `*3E`): import without additional search.
// - String containing no "=" character (`wifi-01`): the "name" field is used for searching.
// - String containing only one "=" character (`"comment=hAP-ac3"`): the "word left" and "word right" pair is used for searching.
func ImportStateCustomContext(s map[string]*schema.Schema) schema.StateContextFunc {
return func(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
id := d.Id()
fieldName := "name"

if len(id) == 0 || id[0] == '*' {
return []*schema.ResourceData{d}, nil
} else {
// By default, we filter by the "name" field
if s := strings.Split(id, "="); len(s) == 2 {
// field=value
fieldName = s[0]
id = s[1]
}
}

path := s[MetaResourcePath].Default.(string)

res, err := ReadItemsFiltered([]string{SnakeToKebab(fieldName) + "=" + id}, path, m.(Client))
if err != nil {
return nil, err
}

switch len(*res) {
case 0:
return nil, fmt.Errorf("resource not found: %v=%v", fieldName, id)
case 1:
retId, ok := (*res)[0][Id.String()]
if !ok {
return nil, fmt.Errorf("attribute %v not found in the response", Id.String())
}
d.SetId(retId)
default:
return nil, fmt.Errorf("more than one resource found: %v=%v", fieldName, id)
}

return []*schema.ResourceData{d}, nil
}
}
2 changes: 1 addition & 1 deletion routeros/resource_wifi.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func ResourceWifi() *schema.Resource {
DeleteContext: DefaultDelete(resSchema),

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: ImportStateCustomContext(resSchema),
},

Schema: resSchema,
Expand Down

0 comments on commit 713d9ee

Please sign in to comment.