Skip to content

Commit

Permalink
Merge pull request #394 from wynro/master
Browse files Browse the repository at this point in the history
 Add support for pool resource
  • Loading branch information
ggongaware authored Sep 24, 2021
2 parents 49ff4af + 703d844 commit ae544b5
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 0 deletions.
15 changes: 15 additions & 0 deletions proxmox/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func Provider() *schema.Provider {
"proxmox_vm_qemu": resourceVmQemu(),
"proxmox_lxc": resourceLxc(),
"proxmox_lxc_disk": resourceLxcDisk(),
"proxmox_pool": resourcePool(),
// TODO - proxmox_storage_iso
// TODO - proxmox_bridge
// TODO - proxmox_vm_qemu_template
Expand Down Expand Up @@ -289,3 +290,17 @@ func parseResourceId(resId string) (targetNode string, resType string, vmId int,
vmId, err = strconv.Atoi(idMatch[3])
return
}

func clusterResourceId(resType string, resId string) string {
return fmt.Sprintf("%s/%s", resType, resId)
}

var rxClusterRsId = regexp.MustCompile("([^/]+)/([^/]+)")

func parseClusterResourceId(resId string) (resType string, id string, err error) {
if !rxClusterRsId.MatchString(resId) {
return "", "", fmt.Errorf("Invalid resource format: %s. Must be type/resId", resId)
}
idMatch := rxClusterRsId.FindStringSubmatch(resId)
return idMatch[1], idMatch[2], nil
}
60 changes: 60 additions & 0 deletions proxmox/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package proxmox

import (
"errors"
"testing"
)

func TestParseClusteResources(t *testing.T) {
type ParseClusterResourceTestResult struct {
ResourceType string
ResourceId string
Error error
}

tests := []struct {
name string
input string
output ParseClusterResourceTestResult
}{{
name: "basic pools",
input: "pools/test-pool",
output: ParseClusterResourceTestResult{
ResourceType: "pools",
ResourceId: "test-pool",
},
}, {
name: "basic storage",
input: "storage/backups",
output: ParseClusterResourceTestResult{
ResourceType: "storage",
ResourceId: "backups",
},
}, {
name: "invalid resource",
input: "storage",
output: ParseClusterResourceTestResult{
Error: errors.New("Invalid resource format: storage. Must be type/resId"),
},
}}

for _, test := range tests {
t.Run(test.name, func(*testing.T) {
resType, resId, err := parseClusterResourceId(test.input)

if test.output.Error != nil && err != nil &&
err.Error() != test.output.Error.Error() {
t.Errorf("%s: error expected `%+v`, got `%+v`",
test.name, test.output.Error, err)
}
if resType != test.output.ResourceType {
t.Errorf("%s: resource type expected `%+v`, got `%+v`",
test.name, test.output.ResourceType, resType)
}
if resId != test.output.ResourceId {
t.Errorf("%s: resource id expected `%+v`, got `%+v`",
test.name, test.output.ResourceId, resId)
}
})
}
}
136 changes: 136 additions & 0 deletions proxmox/resource_pool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package proxmox

import (
"fmt"

pxapi "github.com/Telmate/proxmox-api-go/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

var poolResourceDef *schema.Resource

func resourcePool() *schema.Resource {
*pxapi.Debug = true

poolResourceDef = &schema.Resource{
Create: resourcePoolCreate,
Read: resourcePoolRead,
Update: resourcePoolUpdate,
Delete: resourcePoolDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"poolid": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"comment": {
Type: schema.TypeString,
Optional: true,
},
},
}

return poolResourceDef
}

func resourcePoolCreate(d *schema.ResourceData, meta interface{}) error {
pconf := meta.(*providerConfiguration)
client := pconf.Client
lock := pmParallelBegin(pconf)
defer lock.unlock()

poolid := d.Get("poolid").(string)
comment := d.Get("comment").(string)

err := client.CreatePool(poolid, comment)
if err != nil {
return err
}

d.SetId(clusterResourceId("pools", poolid))

return _resourcePoolRead(d, meta)
}

func resourcePoolRead(d *schema.ResourceData, meta interface{}) error {
pconf := meta.(*providerConfiguration)
lock := pmParallelBegin(pconf)
defer lock.unlock()
return _resourcePoolRead(d, meta)
}

func _resourcePoolRead(d *schema.ResourceData, meta interface{}) error {
pconf := meta.(*providerConfiguration)
client := pconf.Client

_, poolID, err := parseClusterResourceId(d.Id())
if err != nil {
d.SetId("")
return fmt.Errorf("Unexpected error when trying to read and parse resource id: %v", err)
}

logger, _ := CreateSubLogger("resource_pool_read")
logger.Info().Str("poolid", poolID).Msg("Reading configuration for poolid")

poolInfo, err := client.GetPoolInfo(poolID)
if err != nil {
d.SetId("")
return nil
}

d.SetId(clusterResourceId("pools", poolID))
d.Set("comment", "")
if poolInfo["data"].(map[string]interface{})["comment"] != nil {
d.Set("comment", poolInfo["data"].(map[string]interface{})["comment"].(string))
}

// DEBUG print the read result
logger.Debug().Str("poolid", poolID).Msgf("Finished pool read resulting in data: '%+v'", poolInfo["data"])
return nil
}

func resourcePoolUpdate(d *schema.ResourceData, meta interface{}) error {
pconf := meta.(*providerConfiguration)
lock := pmParallelBegin(pconf)
defer lock.unlock()

logger, _ := CreateSubLogger("resource_pool_update")

client := pconf.Client
_, poolID, err := parseClusterResourceId(d.Id())
if err != nil {
return err
}

logger.Info().Str("poolid", poolID).Msg("Starting update of the Pool resource")

if d.HasChange("comment") {
nextComment := d.Get("comment").(string)
err := client.UpdatePoolComment(poolID, nextComment)
if err != nil {
return err
}
}

return _resourcePoolRead(d, meta)
}

func resourcePoolDelete(d *schema.ResourceData, meta interface{}) error {
pconf := meta.(*providerConfiguration)
lock := pmParallelBegin(pconf)
defer lock.unlock()

client := pconf.Client
_, poolID, err := parseClusterResourceId(d.Id())

err = client.DeletePool(poolID)
if err != nil {
return err
}

return nil
}

0 comments on commit ae544b5

Please sign in to comment.