Skip to content

Commit

Permalink
Fix parsing of power parameters (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
skatsaounis authored Oct 6, 2023
1 parent 0aeaa6e commit a1a74b1
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 32 deletions.
6 changes: 3 additions & 3 deletions docs/resources/machine.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ Provides a resource to manage MAAS machines.
```terraform
resource "maas_machine" "virsh_vm1" {
power_type = "virsh"
power_parameters = {
power_parameters = jsonencode({
power_address = "qemu+ssh://[email protected]/system"
power_id = "test-vm1"
}
})
pxe_mac_address = "52:54:00:89:f5:3e"
}
```
Expand All @@ -28,7 +28,7 @@ resource "maas_machine" "virsh_vm1" {

### Required

- `power_parameters` (Map of String, Sensitive) A map with the parameters specific to the `power_type`. See [Power types](https://maas.io/docs/api#power-types) section for a list of the available power parameters for each power type.
- `power_parameters` (String, Sensitive) Serialized JSON string containing the parameters specific to the `power_type`. See [Power types](https://maas.io/docs/api#power-types) section for a list of the available power parameters for each power type.
- `power_type` (String) A power management type (e.g. `ipmi`).
- `pxe_mac_address` (String) The MAC address of the machine's PXE boot NIC.

Expand Down
16 changes: 8 additions & 8 deletions examples/1-machines.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#
resource "maas_machine" "virsh_vm1" {
power_type = "virsh"
power_parameters = {
power_parameters = jsonencode({
power_address = "qemu+ssh://[email protected]/system"
power_id = "test-vm1"
}
})
pxe_mac_address = "52:54:00:89:f5:3e"
}

Expand Down Expand Up @@ -74,10 +74,10 @@ resource "maas_network_interface_link" "virsh_vm1_nic3" {
#
resource "maas_machine" "virsh_vm2" {
power_type = "virsh"
power_parameters = {
power_parameters = jsonencode({
power_address = "qemu+ssh://[email protected]/system"
power_id = "test-vm2"
}
})
pxe_mac_address = "52:54:00:7c:f7:77"
}

Expand Down Expand Up @@ -186,10 +186,10 @@ resource "maas_block_device" "vdc" {
#
resource "maas_machine" "virsh_vm3" {
power_type = "virsh"
power_parameters = {
power_parameters = jsonencode({
power_address = "qemu+ssh://[email protected]/system"
power_id = "machine-01"
}
})
pxe_mac_address = "52:54:00:16:78:ec"
}

Expand All @@ -198,9 +198,9 @@ resource "maas_machine" "virsh_vm3" {
#
resource "maas_machine" "virsh_vm4" {
power_type = "virsh"
power_parameters = {
power_parameters = jsonencode({
power_address = "qemu+ssh://[email protected]/system"
power_id = "machine-05"
}
})
pxe_mac_address = "52:54:00:c4:74:96"
}
4 changes: 2 additions & 2 deletions examples/resources/maas_machine/resource.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
resource "maas_machine" "virsh_vm1" {
power_type = "virsh"
power_parameters = {
power_parameters = jsonencode({
power_address = "qemu+ssh://[email protected]/system"
power_id = "test-vm1"
}
})
pxe_mac_address = "52:54:00:89:f5:3e"
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/hashicorp/terraform-plugin-docs v0.16.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0
github.com/maas/gomaasclient v0.0.0-20230927145110-b2775d1ca870
github.com/maas/gomaasclient v0.0.0-20231005172544-633cecfc0171
github.com/stretchr/testify v1.8.4
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LE
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lunixbochs/vtclean v0.0.0-20160125035106-4fbf7632a2c6/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/maas/gomaasclient v0.0.0-20230927145110-b2775d1ca870 h1:CZ2i4fEX8xXOd5JBG+RhDILCQG5Cu0ZTFOL3qNg8Mns=
github.com/maas/gomaasclient v0.0.0-20230927145110-b2775d1ca870/go.mod h1:6Rf68yTVxSHE35pGymgAXdZQPja2lvX3mRRHHuqdr2M=
github.com/maas/gomaasclient v0.0.0-20231005172544-633cecfc0171 h1:um7H4xdQxGMHOZ2WhDhOtCJ3brybBely2zxp8XaFnGs=
github.com/maas/gomaasclient v0.0.0-20231005172544-633cecfc0171/go.mod h1:6Rf68yTVxSHE35pGymgAXdZQPja2lvX3mRRHHuqdr2M=
github.com/masterzen/azure-sdk-for-go v3.2.0-beta.0.20161014135628-ee4f0065d00c+incompatible/go.mod h1:mf8fjOu33zCqxUjuiU3I8S1lJMyEAlH+0F2+M5xl3hE=
github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc=
github.com/masterzen/winrm v0.0.0-20161014151040-7a535cd943fc/go.mod h1:CfZSN7zwz5gJiFhZJz49Uzk7mEBHIceWmbFmYx7Hf7E=
Expand Down
69 changes: 54 additions & 15 deletions maas/resource_maas_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import (
"context"
"fmt"
"log"
"reflect"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/maas/gomaasclient/client"
"github.com/maas/gomaasclient/entity"
Expand All @@ -21,6 +23,14 @@ func resourceMaasMachine() *schema.Resource {
ReadContext: resourceMachineRead,
UpdateContext: resourceMachineUpdate,
DeleteContext: resourceMachineDelete,
SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceMaasMachineResourceV0().CoreConfigSchema().ImpliedType(),
Upgrade: resourceMaasMachineStateUpgradeV0,
Version: 0,
},
},
Importer: &schema.ResourceImporter{
StateContext: func(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
client := m.(*client.Client)
Expand All @@ -32,10 +42,14 @@ func resourceMaasMachine() *schema.Resource {
if err != nil {
return nil, err
}
powerParamsString, err := structure.FlattenJsonToString(powerParams)
if err != nil {
return nil, err
}
tfState := map[string]interface{}{
"id": machine.SystemID,
"power_type": machine.PowerType,
"power_parameters": powerParams,
"power_parameters": powerParamsString,
"pxe_mac_address": machine.BootInterface.MACAddress,
"architecture": machine.Architecture,
}
Expand All @@ -60,13 +74,26 @@ func resourceMaasMachine() *schema.Resource {
false)),
},
"power_parameters": {
Type: schema.TypeMap,
Required: true,
Sensitive: true,
Description: "A map with the parameters specific to the `power_type`. See [Power types](https://maas.io/docs/api#power-types) section for a list of the available power parameters for each power type.",
Elem: &schema.Schema{
Type: schema.TypeString,
Type: schema.TypeString,
Required: true,
Sensitive: true,
ValidateFunc: validation.StringIsJSON,
DiffSuppressFunc: func(k, oldValue, newValue string, d *schema.ResourceData) bool {
oldMap, err := structure.ExpandJsonFromString(oldValue)
if err != nil {
return false
}
newMap, err := structure.ExpandJsonFromString(newValue)
if err != nil {
return false
}
return reflect.DeepEqual(oldMap, newMap)
},
StateFunc: func(v interface{}) string {
json, _ := structure.NormalizeJsonString(v)
return json
},
Description: "Serialized JSON string containing the parameters specific to the `power_type`. See [Power types](https://maas.io/docs/api#power-types) section for a list of the available power parameters for each power type.",
},
"pxe_mac_address": {
Type: schema.TypeString,
Expand Down Expand Up @@ -120,7 +147,11 @@ func resourceMachineCreate(ctx context.Context, d *schema.ResourceData, m interf
client := m.(*client.Client)

// Create MAAS machine
machine, err := client.Machines.Create(getMachineParams(d), getMachinePowerParams(d))
powerParams, err := getMachinePowerParams(d)
if err != nil {
return diag.FromErr(err)
}
machine, err := client.Machines.Create(getMachineParams(d), powerParams)
if err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -171,7 +202,11 @@ func resourceMachineUpdate(ctx context.Context, d *schema.ResourceData, m interf
if err != nil {
return diag.FromErr(err)
}
if _, err := client.Machine.Update(machine.SystemID, getMachineParams(d), getMachinePowerParams(d)); err != nil {
powerParams, err := getMachinePowerParams(d)
if err != nil {
return diag.FromErr(err)
}
if _, err := client.Machine.Update(machine.SystemID, getMachineParams(d), powerParams); err != nil {
return diag.FromErr(err)
}

Expand All @@ -189,13 +224,17 @@ func resourceMachineDelete(ctx context.Context, d *schema.ResourceData, m interf
return nil
}

func getMachinePowerParams(d *schema.ResourceData) map[string]string {
powerParams := d.Get("power_parameters").(map[string]interface{})
params := make(map[string]string, len(powerParams))
for k, v := range powerParams {
params[fmt.Sprintf("power_parameters_%s", k)] = v.(string)
func getMachinePowerParams(d *schema.ResourceData) (powerParams map[string]interface{}, err error) {
powerParams = make(map[string]interface{})
powerParamsString := d.Get("power_parameters").(string)
params, err := structure.ExpandJsonFromString(powerParamsString)
if err != nil {
return powerParams, err
}
for k, v := range params {
powerParams[fmt.Sprintf("power_parameters_%s", k)] = v
}
return params
return powerParams, nil
}

func getMachineParams(d *schema.ResourceData) *entity.MachineParams {
Expand Down
74 changes: 74 additions & 0 deletions maas/resource_maas_machine_migrate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package maas

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
)

func resourceMaasMachineResourceV0() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"power_type": {
Type: schema.TypeString,
Required: true,
},
"power_parameters": {
Type: schema.TypeMap,
Required: true,
Sensitive: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"pxe_mac_address": {
Type: schema.TypeString,
Required: true,
},
"architecture": {
Type: schema.TypeString,
Optional: true,
Default: "amd64/generic",
},
"min_hwe_kernel": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"hostname": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"domain": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"zone": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"pool": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}
}

func resourceMaasMachineStateUpgradeV0(ctx context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
// Convert power_parameters from map[string]string to a serialized JSON string.
oldPowerParametersRaw := rawState["power_parameters"].(map[string]interface{})
flattenedOldPowerParameters, err := structure.FlattenJsonToString(oldPowerParametersRaw)
if err != nil {
return nil, err
}

rawState["power_parameters"] = flattenedOldPowerParameters

return rawState, nil
}
37 changes: 37 additions & 0 deletions maas/resource_maas_machine_migrate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package maas

import (
"context"
"reflect"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
)

func testResourceMaasMachineInstanceStateDataV0() map[string]interface{} {
return map[string]interface{}{
"power_parameters": map[string]interface{}{
"power_user": "ubuntu",
},
}
}

func testResourceMaasMachineInstanceStateDataV1() map[string]interface{} {
flattenedV0, _ := structure.FlattenJsonToString(map[string]interface{}{
"power_user": "ubuntu",
})
return map[string]interface{}{"power_parameters": flattenedV0}
}

func TestResourceMaasMachineInstanceStateUpgradeV0(t *testing.T) {
ctx := context.Background()
expected := testResourceMaasMachineInstanceStateDataV1()
actual, err := resourceMaasMachineStateUpgradeV0(ctx, testResourceMaasMachineInstanceStateDataV0(), nil)
if err != nil {
t.Fatalf("error migrating state: %s", err)
}

if !reflect.DeepEqual(expected, actual) {
t.Fatalf("\n\nexpected:\n\n%#v\n\ngot:\n\n%#v\n\n", expected, actual)
}
}
2 changes: 1 addition & 1 deletion maas/resource_maas_vm_host_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ func resourceVMHostMachineUpdate(ctx context.Context, d *schema.ResourceData, m
client := m.(*client.Client)

// Update VM host machine
if _, err := client.Machine.Update(d.Id(), getVMHostMachineUpdateParams(d), map[string]string{}); err != nil {
if _, err := client.Machine.Update(d.Id(), getVMHostMachineUpdateParams(d), map[string]interface{}{}); err != nil {
return diag.FromErr(err)
}

Expand Down

0 comments on commit a1a74b1

Please sign in to comment.