Skip to content

Commit

Permalink
Modernize state upgrader
Browse files Browse the repository at this point in the history
  • Loading branch information
YakDriver committed Feb 3, 2022
1 parent 273a796 commit d2effc3
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 62 deletions.
8 changes: 7 additions & 1 deletion internal/service/fsx/ontap_storage_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ func ResourceOntapStorageVirtualMachine() *schema.Resource {
},

SchemaVersion: 1,
MigrateState: resourceOntapStorageVirtualMachineMigrateState,
StateUpgraders: []schema.StateUpgrader{
{
Type: ResourceOntapStorageVirtualMachineV0().CoreConfigSchema().ImpliedType(),
Upgrade: ResourceOntapStorageVirtualMachineStateUpgradeV0,
Version: 0,
},
},

Schema: map[string]*schema.Schema{
"arn": {
Expand Down
223 changes: 204 additions & 19 deletions internal/service/fsx/ontap_storage_virtual_machine_migrate.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,217 @@
package fsx

import (
"fmt"
"context"
"log"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/aws/aws-sdk-go/service/fsx"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
)

func resourceOntapStorageVirtualMachineMigrateState(v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) {
switch v {
case 0:
log.Println("[INFO] Found FSx Ontap Storage Virtual Machine state v0; migrating to v1")
return migrateOntapStorageVirtualMachineStateV0toV1(is)
default:
return is, fmt.Errorf("Unexpected schema version: %d", v)
func ResourceOntapStorageVirtualMachineV0() *schema.Resource {
return &schema.Resource{
SchemaVersion: 0,
Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"active_directory_configuration": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"netbios_name": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return strings.EqualFold(old, new)
},
ValidateFunc: validation.StringLenBetween(1, 15),
},
"self_managed_active_directory_configuration": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dns_ips": {
Type: schema.TypeSet,
Required: true,
MinItems: 1,
MaxItems: 3,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.IsIPAddress,
},
},
"domain_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 255),
},
"file_system_administrators_group": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 256),
},
"organizational_unit_distinguidshed_name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 2000),
Deprecated: "use 'organizational_unit_distinguished_name' instead",
ConflictsWith: []string{"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name"},
},
"organizational_unit_distinguished_name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 2000),
ConflictsWith: []string{"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name"},
},
"password": {
Type: schema.TypeString,
Sensitive: true,
Required: true,
ValidateFunc: validation.StringLenBetween(1, 256),
},
"username": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringLenBetween(1, 256),
},
},
},
},
},
},
},
"endpoints": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"iscsi": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dns_name": {
Type: schema.TypeString,
Computed: true,
},
"ip_addresses": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
"management": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dns_name": {
Type: schema.TypeString,
Computed: true,
},
"ip_addresses": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
"nfs": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dns_name": {
Type: schema.TypeString,
Computed: true,
},
"ip_addresses": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
"smb": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dns_name": {
Type: schema.TypeString,
Computed: true,
},
"ip_addresses": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},
"file_system_id": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringLenBetween(11, 21),
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 47),
},
"root_volume_security_style": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice(fsx.StorageVirtualMachineRootVolumeSecurityStyle_Values(), false),
},
"subtype": {
Type: schema.TypeString,
Computed: true,
},
"svm_admin_password": {
Type: schema.TypeString,
Optional: true,
Sensitive: true,
ValidateFunc: validation.StringLenBetween(8, 50),
},
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
"uuid": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func migrateOntapStorageVirtualMachineStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) {
if is.Empty() || is.Attributes == nil {
log.Println("[DEBUG] Empty FSx Ontap Storage Virtual Machine state; nothing to migrate.")
return is, nil
}
func ResourceOntapStorageVirtualMachineStateUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
log.Printf("[DEBUG] Attributes before migration: %#v", rawState)

log.Printf("[DEBUG] Attributes before migration: %#v", is.Attributes)
is.Attributes["active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name"] = is.Attributes["active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name"]
delete(is.Attributes, "active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name")
rawState["active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name"] = rawState["active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name"]
delete(rawState, "active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name")

log.Printf("[DEBUG] Attributes after migration: %#v", is.Attributes)
return is, nil
log.Printf("[DEBUG] Attributes after migration: %#v", rawState)
return rawState, nil
}
63 changes: 21 additions & 42 deletions internal/service/fsx/ontap_storage_virtual_machine_migrate_test.go
Original file line number Diff line number Diff line change
@@ -1,56 +1,35 @@
package fsx_test

import (
"context"
"reflect"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
tffsx "github.com/hashicorp/terraform-provider-aws/internal/service/fsx"
)

func TestOntapStorageVirtualMachineMigrateState(t *testing.T) {
cases := map[string]struct {
StateVersion int
Attributes map[string]string
Expected map[string]string
Meta interface{}
}{
"v0_1-notDistinguidshed": {
StateVersion: 0,
Attributes: map[string]string{
"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name": "",
},
Expected: map[string]string{
"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name": "",
},
},
"v0_1-bitDistinguidshed": {
StateVersion: 0,
Attributes: map[string]string{
"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name": "MeArrugoDerrito",
},
Expected: map[string]string{
"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name": "MeArrugoDerrito",
},
},
func testOntapStorageVirtualMachineStateDataV0() map[string]interface{} {
return map[string]interface{}{
"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name": "MeArrugoDerrito",
}
}

for tn, tc := range cases {
is := &terraform.InstanceState{
ID: "some_id",
Attributes: tc.Attributes,
}
func testOntapStorageVirtualMachineStateDataV1() map[string]interface{} {
v0 := testOntapStorageVirtualMachineStateDataV0()
return map[string]interface{}{
"active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguished_name": v0["active_directory_configuration.0.self_managed_active_directory_configuration.0.organizational_unit_distinguidshed_name"],
}
}

is, err := tffsx.ResourceOntapStorageVirtualMachine().MigrateState(tc.StateVersion, is, tc.Meta)
if err != nil {
t.Fatalf("bad: %s, err: %#v", tn, err)
}
func TestOntapStorageVirtualMachineStateUpgradeV0(t *testing.T) {
expected := testOntapStorageVirtualMachineStateDataV1()
actual, err := tffsx.ResourceOntapStorageVirtualMachineStateUpgradeV0(context.Background(), testOntapStorageVirtualMachineStateDataV0(), nil)

if err != nil {
t.Fatalf("error migrating state: %s", err)
}

for k, v := range tc.Expected {
if is.Attributes[k] != v {
t.Fatalf(
"bad: %s\n\n expected: %#v -> %#v\n got: %#v -> %#v\n in: %#v",
tn, k, v, k, is.Attributes[k], is.Attributes)
}
}
if !reflect.DeepEqual(expected, actual) {
t.Fatalf("\n\nexpected:\n\n%#v\n\ngot:\n\n%#v\n\n", expected, actual)
}
}

0 comments on commit d2effc3

Please sign in to comment.