Skip to content

Commit ae544b5

Browse files
authored
Merge pull request #394 from wynro/master
Add support for pool resource
2 parents 49ff4af + 703d844 commit ae544b5

File tree

3 files changed

+211
-0
lines changed

3 files changed

+211
-0
lines changed

proxmox/provider.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ func Provider() *schema.Provider {
122122
"proxmox_vm_qemu": resourceVmQemu(),
123123
"proxmox_lxc": resourceLxc(),
124124
"proxmox_lxc_disk": resourceLxcDisk(),
125+
"proxmox_pool": resourcePool(),
125126
// TODO - proxmox_storage_iso
126127
// TODO - proxmox_bridge
127128
// TODO - proxmox_vm_qemu_template
@@ -289,3 +290,17 @@ func parseResourceId(resId string) (targetNode string, resType string, vmId int,
289290
vmId, err = strconv.Atoi(idMatch[3])
290291
return
291292
}
293+
294+
func clusterResourceId(resType string, resId string) string {
295+
return fmt.Sprintf("%s/%s", resType, resId)
296+
}
297+
298+
var rxClusterRsId = regexp.MustCompile("([^/]+)/([^/]+)")
299+
300+
func parseClusterResourceId(resId string) (resType string, id string, err error) {
301+
if !rxClusterRsId.MatchString(resId) {
302+
return "", "", fmt.Errorf("Invalid resource format: %s. Must be type/resId", resId)
303+
}
304+
idMatch := rxClusterRsId.FindStringSubmatch(resId)
305+
return idMatch[1], idMatch[2], nil
306+
}

proxmox/provider_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package proxmox
2+
3+
import (
4+
"errors"
5+
"testing"
6+
)
7+
8+
func TestParseClusteResources(t *testing.T) {
9+
type ParseClusterResourceTestResult struct {
10+
ResourceType string
11+
ResourceId string
12+
Error error
13+
}
14+
15+
tests := []struct {
16+
name string
17+
input string
18+
output ParseClusterResourceTestResult
19+
}{{
20+
name: "basic pools",
21+
input: "pools/test-pool",
22+
output: ParseClusterResourceTestResult{
23+
ResourceType: "pools",
24+
ResourceId: "test-pool",
25+
},
26+
}, {
27+
name: "basic storage",
28+
input: "storage/backups",
29+
output: ParseClusterResourceTestResult{
30+
ResourceType: "storage",
31+
ResourceId: "backups",
32+
},
33+
}, {
34+
name: "invalid resource",
35+
input: "storage",
36+
output: ParseClusterResourceTestResult{
37+
Error: errors.New("Invalid resource format: storage. Must be type/resId"),
38+
},
39+
}}
40+
41+
for _, test := range tests {
42+
t.Run(test.name, func(*testing.T) {
43+
resType, resId, err := parseClusterResourceId(test.input)
44+
45+
if test.output.Error != nil && err != nil &&
46+
err.Error() != test.output.Error.Error() {
47+
t.Errorf("%s: error expected `%+v`, got `%+v`",
48+
test.name, test.output.Error, err)
49+
}
50+
if resType != test.output.ResourceType {
51+
t.Errorf("%s: resource type expected `%+v`, got `%+v`",
52+
test.name, test.output.ResourceType, resType)
53+
}
54+
if resId != test.output.ResourceId {
55+
t.Errorf("%s: resource id expected `%+v`, got `%+v`",
56+
test.name, test.output.ResourceId, resId)
57+
}
58+
})
59+
}
60+
}

proxmox/resource_pool.go

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package proxmox
2+
3+
import (
4+
"fmt"
5+
6+
pxapi "github.com/Telmate/proxmox-api-go/proxmox"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
)
9+
10+
var poolResourceDef *schema.Resource
11+
12+
func resourcePool() *schema.Resource {
13+
*pxapi.Debug = true
14+
15+
poolResourceDef = &schema.Resource{
16+
Create: resourcePoolCreate,
17+
Read: resourcePoolRead,
18+
Update: resourcePoolUpdate,
19+
Delete: resourcePoolDelete,
20+
Importer: &schema.ResourceImporter{
21+
State: schema.ImportStatePassthrough,
22+
},
23+
24+
Schema: map[string]*schema.Schema{
25+
"poolid": {
26+
Type: schema.TypeString,
27+
Required: true,
28+
ForceNew: true,
29+
},
30+
"comment": {
31+
Type: schema.TypeString,
32+
Optional: true,
33+
},
34+
},
35+
}
36+
37+
return poolResourceDef
38+
}
39+
40+
func resourcePoolCreate(d *schema.ResourceData, meta interface{}) error {
41+
pconf := meta.(*providerConfiguration)
42+
client := pconf.Client
43+
lock := pmParallelBegin(pconf)
44+
defer lock.unlock()
45+
46+
poolid := d.Get("poolid").(string)
47+
comment := d.Get("comment").(string)
48+
49+
err := client.CreatePool(poolid, comment)
50+
if err != nil {
51+
return err
52+
}
53+
54+
d.SetId(clusterResourceId("pools", poolid))
55+
56+
return _resourcePoolRead(d, meta)
57+
}
58+
59+
func resourcePoolRead(d *schema.ResourceData, meta interface{}) error {
60+
pconf := meta.(*providerConfiguration)
61+
lock := pmParallelBegin(pconf)
62+
defer lock.unlock()
63+
return _resourcePoolRead(d, meta)
64+
}
65+
66+
func _resourcePoolRead(d *schema.ResourceData, meta interface{}) error {
67+
pconf := meta.(*providerConfiguration)
68+
client := pconf.Client
69+
70+
_, poolID, err := parseClusterResourceId(d.Id())
71+
if err != nil {
72+
d.SetId("")
73+
return fmt.Errorf("Unexpected error when trying to read and parse resource id: %v", err)
74+
}
75+
76+
logger, _ := CreateSubLogger("resource_pool_read")
77+
logger.Info().Str("poolid", poolID).Msg("Reading configuration for poolid")
78+
79+
poolInfo, err := client.GetPoolInfo(poolID)
80+
if err != nil {
81+
d.SetId("")
82+
return nil
83+
}
84+
85+
d.SetId(clusterResourceId("pools", poolID))
86+
d.Set("comment", "")
87+
if poolInfo["data"].(map[string]interface{})["comment"] != nil {
88+
d.Set("comment", poolInfo["data"].(map[string]interface{})["comment"].(string))
89+
}
90+
91+
// DEBUG print the read result
92+
logger.Debug().Str("poolid", poolID).Msgf("Finished pool read resulting in data: '%+v'", poolInfo["data"])
93+
return nil
94+
}
95+
96+
func resourcePoolUpdate(d *schema.ResourceData, meta interface{}) error {
97+
pconf := meta.(*providerConfiguration)
98+
lock := pmParallelBegin(pconf)
99+
defer lock.unlock()
100+
101+
logger, _ := CreateSubLogger("resource_pool_update")
102+
103+
client := pconf.Client
104+
_, poolID, err := parseClusterResourceId(d.Id())
105+
if err != nil {
106+
return err
107+
}
108+
109+
logger.Info().Str("poolid", poolID).Msg("Starting update of the Pool resource")
110+
111+
if d.HasChange("comment") {
112+
nextComment := d.Get("comment").(string)
113+
err := client.UpdatePoolComment(poolID, nextComment)
114+
if err != nil {
115+
return err
116+
}
117+
}
118+
119+
return _resourcePoolRead(d, meta)
120+
}
121+
122+
func resourcePoolDelete(d *schema.ResourceData, meta interface{}) error {
123+
pconf := meta.(*providerConfiguration)
124+
lock := pmParallelBegin(pconf)
125+
defer lock.unlock()
126+
127+
client := pconf.Client
128+
_, poolID, err := parseClusterResourceId(d.Id())
129+
130+
err = client.DeletePool(poolID)
131+
if err != nil {
132+
return err
133+
}
134+
135+
return nil
136+
}

0 commit comments

Comments
 (0)