diff --git a/CHANGELOG.md b/CHANGELOG.md index fa29836f..e6187831 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,15 @@ FEATURES: * **New Data Source:** `proxmox_virtual_environment_group` * **New Data Source:** `proxmox_virtual_environment_groups` +* **New Data Source:** `proxmox_virtual_environment_pool` +* **New Data Source:** `proxmox_virtual_environment_pools` * **New Data Source:** `proxmox_virtual_environment_role` * **New Data Source:** `proxmox_virtual_environment_roles` * **New Data Source:** `proxmox_virtual_environment_user` * **New Data Source:** `proxmox_virtual_environment_users` * **New Data Source:** `proxmox_virtual_environment_version` + * **New Resource:** `proxmox_virtual_environment_group` +* **New Resource:** `proxmox_virtual_environment_pool` * **New Resource:** `proxmox_virtual_environment_role` * **New Resource:** `proxmox_virtual_environment_user` diff --git a/README.md b/README.md index 8441d115..db9bd0d0 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,28 @@ This data source doesn't accept arguments. * `comments` - The group comments * `group_ids` - The group ids +##### Pool (proxmox_virtual_environment_pool) + +###### Arguments +* `pool_id` - (Required) The pool id + +###### Attributes +* `comment` - The pool comment +* `members` - The pool members + * `id` - The member id + * `node` - The node id + * `storage` - The storage id + * `type` - The member type + * `virtual_machine_id` - The virtual machine id + +##### Pools (proxmox_virtual_environment_pools) + +###### Arguments +This data source doesn't accept arguments. + +###### Attributes +* `pool_ids` - The pool ids + ##### Role (proxmox_virtual_environment_role) ###### Arguments @@ -128,6 +150,20 @@ This data source doesn't accept arguments. ###### Attributes * `members` - The group members as a list with `username@realm` entries +##### Pool (proxmox_virtual_environment_pool) + +###### Arguments +* `comment` - (Optional) The pool comment +* `pool_id` - (Required) The pool id + +###### Attributes +* `members` - The pool members + * `id` - The member id + * `node` - The node id + * `storage` - The storage id + * `type` - The member type + * `virtual_machine_id` - The virtual machine id + ##### Role (proxmox_virtual_environment_role) ###### Arguments diff --git a/data_source_virtual_environment_pool.go b/data_source_virtual_environment_pool.go new file mode 100644 index 00000000..a50f0c10 --- /dev/null +++ b/data_source_virtual_environment_pool.go @@ -0,0 +1,122 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package main + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +const ( + mkDataSourceVirtualEnvironmentPoolComment = "comment" + mkDataSourceVirtualEnvironmentPoolMembers = "members" + mkDataSourceVirtualEnvironmentPoolPoolID = "pool_id" +) + +func dataSourceVirtualEnvironmentPool() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkDataSourceVirtualEnvironmentPoolComment: &schema.Schema{ + Type: schema.TypeString, + Description: "The pool comment", + Computed: true, + }, + mkDataSourceVirtualEnvironmentPoolMembers: &schema.Schema{ + Type: schema.TypeList, + Description: "The pool members", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkResourceVirtualEnvironmentPoolMembersID: { + Type: schema.TypeString, + Required: true, + Description: "The member id", + }, + mkResourceVirtualEnvironmentPoolMembersNode: { + Type: schema.TypeString, + Required: true, + Description: "The node id", + }, + mkResourceVirtualEnvironmentPoolMembersStorage: { + Type: schema.TypeString, + Optional: true, + Description: "The storage id", + Default: "", + }, + mkResourceVirtualEnvironmentPoolMembersType: { + Type: schema.TypeString, + Required: true, + Description: "The member type", + }, + mkResourceVirtualEnvironmentPoolMembersVirtualMachineID: { + Type: schema.TypeInt, + Optional: true, + Description: "The virtual machine id", + Default: 0, + }, + }, + }, + }, + mkDataSourceVirtualEnvironmentPoolPoolID: &schema.Schema{ + Type: schema.TypeString, + Description: "The pool id", + Required: true, + }, + }, + Read: dataSourceVirtualEnvironmentPoolRead, + } +} + +func dataSourceVirtualEnvironmentPoolRead(d *schema.ResourceData, m interface{}) error { + config := m.(providerConfiguration) + veClient, err := config.GetVEClient() + + if err != nil { + return err + } + + poolID := d.Get(mkDataSourceVirtualEnvironmentPoolPoolID).(string) + pool, err := veClient.GetPool(poolID) + + if err != nil { + return err + } + + d.SetId(poolID) + + if pool.Comment != nil { + d.Set(mkDataSourceVirtualEnvironmentPoolComment, pool.Comment) + } else { + d.Set(mkDataSourceVirtualEnvironmentPoolComment, "") + } + + members := make([]interface{}, len(pool.Members)) + + for i, v := range pool.Members { + values := make(map[string]interface{}) + + values[mkResourceVirtualEnvironmentPoolMembersID] = v.ID + values[mkResourceVirtualEnvironmentPoolMembersNode] = v.Node + + if v.Storage != nil { + values[mkResourceVirtualEnvironmentPoolMembersStorage] = v.Storage + } else { + values[mkResourceVirtualEnvironmentPoolMembersStorage] = "" + } + + values[mkResourceVirtualEnvironmentPoolMembersType] = v.Type + + if v.VirtualMachineID != nil { + values[mkResourceVirtualEnvironmentPoolMembersVirtualMachineID] = v.VirtualMachineID + } else { + values[mkResourceVirtualEnvironmentPoolMembersVirtualMachineID] = 0 + } + + members[i] = values + } + + d.Set(mkResourceVirtualEnvironmentPoolMembers, members) + + return nil +} diff --git a/data_source_virtual_environment_pool_test.go b/data_source_virtual_environment_pool_test.go new file mode 100644 index 00000000..3a45cfc4 --- /dev/null +++ b/data_source_virtual_environment_pool_test.go @@ -0,0 +1,38 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package main + +import ( + "testing" +) + +// TestDataSourceVirtualEnvironmentPoolInstantiation tests whether the DataSourceVirtualEnvironmentPool instance can be instantiated. +func TestDataSourceVirtualEnvironmentPoolInstantiation(t *testing.T) { + s := dataSourceVirtualEnvironmentPool() + + if s == nil { + t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentPool") + } +} + +// TestDataSourceVirtualEnvironmentPoolSchema tests the dataSourceVirtualEnvironmentPool schema. +func TestDataSourceVirtualEnvironmentPoolSchema(t *testing.T) { + s := dataSourceVirtualEnvironmentPool() + + attributeKeys := []string{ + mkDataSourceVirtualEnvironmentPoolComment, + mkDataSourceVirtualEnvironmentPoolMembers, + } + + for _, v := range attributeKeys { + if s.Schema[v] == nil { + t.Fatalf("Error in dataSourceVirtualEnvironmentPool.Schema: Missing attribute \"%s\"", v) + } + + if s.Schema[v].Computed != true { + t.Fatalf("Error in dataSourceVirtualEnvironmentPool.Schema: Attribute \"%s\" is not computed", v) + } + } +} diff --git a/data_source_virtual_environment_pools.go b/data_source_virtual_environment_pools.go new file mode 100644 index 00000000..70f47501 --- /dev/null +++ b/data_source_virtual_environment_pools.go @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package main + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +const ( + mkDataSourceVirtualEnvironmentPoolsPoolIDs = "pool_ids" +) + +func dataSourceVirtualEnvironmentPools() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkDataSourceVirtualEnvironmentPoolsPoolIDs: &schema.Schema{ + Type: schema.TypeList, + Description: "The pool ids", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + Read: dataSourceVirtualEnvironmentPoolsRead, + } +} + +func dataSourceVirtualEnvironmentPoolsRead(d *schema.ResourceData, m interface{}) error { + config := m.(providerConfiguration) + veClient, err := config.GetVEClient() + + if err != nil { + return err + } + + list, err := veClient.ListPools() + + if err != nil { + return err + } + + poolIDs := make([]interface{}, len(list)) + + for i, v := range list { + poolIDs[i] = v.ID + } + + d.SetId("pools") + + d.Set(mkDataSourceVirtualEnvironmentPoolsPoolIDs, poolIDs) + + return nil +} diff --git a/data_source_virtual_environment_pools_test.go b/data_source_virtual_environment_pools_test.go new file mode 100644 index 00000000..427bdf86 --- /dev/null +++ b/data_source_virtual_environment_pools_test.go @@ -0,0 +1,37 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package main + +import ( + "testing" +) + +// TestDataSourceVirtualEnvironmentPoolsInstantiation tests whether the DataSourceVirtualEnvironmentPools instance can be instantiated. +func TestDataSourceVirtualEnvironmentPoolsInstantiation(t *testing.T) { + s := dataSourceVirtualEnvironmentPools() + + if s == nil { + t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentPools") + } +} + +// TestDataSourceVirtualEnvironmentPoolsSchema tests the dataSourceVirtualEnvironmentPools schema. +func TestDataSourceVirtualEnvironmentPoolsSchema(t *testing.T) { + s := dataSourceVirtualEnvironmentPools() + + attributeKeys := []string{ + mkDataSourceVirtualEnvironmentPoolsPoolIDs, + } + + for _, v := range attributeKeys { + if s.Schema[v] == nil { + t.Fatalf("Error in dataSourceVirtualEnvironmentPools.Schema: Missing attribute \"%s\"", v) + } + + if s.Schema[v].Computed != true { + t.Fatalf("Error in dataSourceVirtualEnvironmentPools.Schema: Attribute \"%s\" is not computed", v) + } + } +} diff --git a/example/data_source_virtual_environment_group.tf b/example/data_source_virtual_environment_group.tf index bf6d84b2..344a1438 100644 --- a/example/data_source_virtual_environment_group.tf +++ b/example/data_source_virtual_environment_group.tf @@ -2,10 +2,10 @@ data "proxmox_virtual_environment_group" "example" { group_id = "${proxmox_virtual_environment_group.example.id}" } -output "data_proxmox_virtual_environment_group_example_comments" { - value = "${data.proxmox_virtual_environment_group.example.*.comment}" +output "data_proxmox_virtual_environment_group_example_comment" { + value = "${data.proxmox_virtual_environment_group.example.comment}" } output "data_proxmox_virtual_environment_group_example_members" { - value = "${data.proxmox_virtual_environment_group.example.*.members}" + value = "${data.proxmox_virtual_environment_group.example.members}" } diff --git a/example/data_source_virtual_environment_pool.tf b/example/data_source_virtual_environment_pool.tf new file mode 100644 index 00000000..ad451464 --- /dev/null +++ b/example/data_source_virtual_environment_pool.tf @@ -0,0 +1,15 @@ +data "proxmox_virtual_environment_pool" "example" { + pool_id = "${proxmox_virtual_environment_pool.example.id}" +} + +output "data_proxmox_virtual_environment_pool_example_comment" { + value = "${data.proxmox_virtual_environment_pool.example.comment}" +} + +output "data_proxmox_virtual_environment_pool_example_members" { + value = "${data.proxmox_virtual_environment_pool.example.members}" +} + +output "data_proxmox_virtual_environment_pool_example_pool_id" { + value = "${data.proxmox_virtual_environment_pool.example.id}" +} diff --git a/example/data_source_virtual_environment_pools.tf b/example/data_source_virtual_environment_pools.tf new file mode 100644 index 00000000..5a285ed0 --- /dev/null +++ b/example/data_source_virtual_environment_pools.tf @@ -0,0 +1,9 @@ +data "proxmox_virtual_environment_pools" "example" { + depends_on = ["proxmox_virtual_environment_pool.example"] +} + +output "data_proxmox_virtual_environment_pools_example" { + value = "${map( + "pool_ids", data.proxmox_virtual_environment_pools.example.pool_ids, + )}" +} diff --git a/example/data_source_virtual_environment_users.tf b/example/data_source_virtual_environment_users.tf index 7adf7e77..ebbe7dfa 100644 --- a/example/data_source_virtual_environment_users.tf +++ b/example/data_source_virtual_environment_users.tf @@ -1,5 +1,5 @@ data "proxmox_virtual_environment_users" "example" { - depends_on = ["proxmox_virtual_environment_role.example"] + depends_on = ["proxmox_virtual_environment_user.example"] } output "data_proxmox_virtual_environment_users_example_comments" { diff --git a/example/resource_virtual_environment_pool.tf b/example/resource_virtual_environment_pool.tf new file mode 100644 index 00000000..eb76e4b2 --- /dev/null +++ b/example/resource_virtual_environment_pool.tf @@ -0,0 +1,16 @@ +resource "proxmox_virtual_environment_pool" "example" { + comment = "Managed by Terraform" + pool_id = "terraform-provider-proxmox-example" +} + +output "resource_proxmox_virtual_environment_pool_example_comment" { + value = "${proxmox_virtual_environment_pool.example.comment}" +} + +output "resource_proxmox_virtual_environment_pool_example_members" { + value = "${proxmox_virtual_environment_pool.example.members}" +} + +output "resource_proxmox_virtual_environment_pool_example_pool_id" { + value = "${proxmox_virtual_environment_pool.example.id}" +} diff --git a/provider.go b/provider.go index 3d5318a6..825aa2b0 100644 --- a/provider.go +++ b/provider.go @@ -30,6 +30,8 @@ func Provider() *schema.Provider { DataSourcesMap: map[string]*schema.Resource{ "proxmox_virtual_environment_group": dataSourceVirtualEnvironmentGroup(), "proxmox_virtual_environment_groups": dataSourceVirtualEnvironmentGroups(), + "proxmox_virtual_environment_pool": dataSourceVirtualEnvironmentPool(), + "proxmox_virtual_environment_pools": dataSourceVirtualEnvironmentPools(), "proxmox_virtual_environment_role": dataSourceVirtualEnvironmentRole(), "proxmox_virtual_environment_roles": dataSourceVirtualEnvironmentRoles(), "proxmox_virtual_environment_user": dataSourceVirtualEnvironmentUser(), @@ -38,6 +40,7 @@ func Provider() *schema.Provider { }, ResourcesMap: map[string]*schema.Resource{ "proxmox_virtual_environment_group": resourceVirtualEnvironmentGroup(), + "proxmox_virtual_environment_pool": resourceVirtualEnvironmentPool(), "proxmox_virtual_environment_role": resourceVirtualEnvironmentRole(), "proxmox_virtual_environment_user": resourceVirtualEnvironmentUser(), }, diff --git a/proxmox/virtual_environment.go b/proxmox/virtual_environment.go index b26bb085..500d8a72 100644 --- a/proxmox/virtual_environment.go +++ b/proxmox/virtual_environment.go @@ -151,7 +151,7 @@ func (c *VirtualEnvironmentClient) ValidateResponseCode(res *http.Response) erro return fmt.Errorf("Received a HTTP %d response - Please verify that the user account has the necessary permissions", res.StatusCode) case 404: return fmt.Errorf("Received a HTTP %d response - Please verify that the endpoint refers to a supported version of the Proxmox Virtual Environment API", res.StatusCode) - case 500: + case 500, 501, 502, 503: return fmt.Errorf("Received a HTTP %d response - Please verify that the Proxmox Virtual Environment API is healthy (status: %s)", res.StatusCode, res.Status) default: return fmt.Errorf("Received a HTTP %d response", res.StatusCode) diff --git a/proxmox/virtual_environment_pools.go b/proxmox/virtual_environment_pools.go new file mode 100644 index 00000000..9cebeae4 --- /dev/null +++ b/proxmox/virtual_environment_pools.go @@ -0,0 +1,109 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package proxmox + +import ( + "errors" + "fmt" + "net/url" + "sort" +) + +// VirtualEnvironmentPoolCreateRequestBody contains the data for an pool create request. +type VirtualEnvironmentPoolCreateRequestBody struct { + Comment *string `json:"comment,omitempty" url:"comment,omitempty"` + ID string `json:"groupid" url:"poolid"` +} + +// VirtualEnvironmentPoolGetResponseBody contains the body from an pool get response. +type VirtualEnvironmentPoolGetResponseBody struct { + Data *VirtualEnvironmentPoolGetResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentPoolGetResponseData contains the data from an pool get response. +type VirtualEnvironmentPoolGetResponseData struct { + Comment *string `json:"comment,omitempty"` + Members []VirtualEnvironmentPoolGetResponseMembers `json:"members,omitempty"` +} + +// VirtualEnvironmentPoolGetResponseMembers contains the members data from an pool get response. +type VirtualEnvironmentPoolGetResponseMembers struct { + ID string `json:"id"` + Node string `json:"node"` + Storage *string `json:"storage,omitempty"` + Type string `json:"type"` + VirtualMachineID *int `json:"vmid"` +} + +// VirtualEnvironmentPoolListResponseBody contains the body from an pool list response. +type VirtualEnvironmentPoolListResponseBody struct { + Data []*VirtualEnvironmentPoolListResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentPoolListResponseData contains the data from an pool list response. +type VirtualEnvironmentPoolListResponseData struct { + Comment *string `json:"comment,omitempty"` + ID string `json:"poolid"` +} + +// VirtualEnvironmentPoolUpdateRequestBody contains the data for an pool update request. +type VirtualEnvironmentPoolUpdateRequestBody struct { + Comment *string `json:"comment,omitempty" url:"comment,omitempty"` +} + +// CreatePool creates an pool. +func (c *VirtualEnvironmentClient) CreatePool(d *VirtualEnvironmentPoolCreateRequestBody) error { + return c.DoRequest(hmPOST, "pools", d, nil) +} + +// DeletePool deletes an pool. +func (c *VirtualEnvironmentClient) DeletePool(id string) error { + return c.DoRequest(hmDELETE, fmt.Sprintf("pools/%s", id), nil, nil) +} + +// GetPool retrieves an pool. +func (c *VirtualEnvironmentClient) GetPool(id string) (*VirtualEnvironmentPoolGetResponseData, error) { + resBody := &VirtualEnvironmentPoolGetResponseBody{} + err := c.DoRequest(hmGET, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, resBody) + + if err != nil { + return nil, err + } + + if resBody.Data == nil { + return nil, errors.New("The server did not include a data object in the response") + } + + sort.Slice(resBody.Data.Members, func(i, j int) bool { + return resBody.Data.Members[i].ID < resBody.Data.Members[j].ID + }) + + return resBody.Data, nil +} + +// ListPools retrieves a list of pools. +func (c *VirtualEnvironmentClient) ListPools() ([]*VirtualEnvironmentPoolListResponseData, error) { + resBody := &VirtualEnvironmentPoolListResponseBody{} + err := c.DoRequest(hmGET, "pools", nil, resBody) + + if err != nil { + return nil, err + } + + if resBody.Data == nil { + return nil, errors.New("The server did not include a data object in the response") + } + + sort.Slice(resBody.Data, func(i, j int) bool { + return resBody.Data[i].ID < resBody.Data[j].ID + }) + + return resBody.Data, nil +} + +// UpdatePool updates an pool. +func (c *VirtualEnvironmentClient) UpdatePool(id string, d *VirtualEnvironmentPoolUpdateRequestBody) error { + return c.DoRequest(hmPUT, fmt.Sprintf("pools/%s", id), d, nil) +} diff --git a/resource_virtual_environment_pool.go b/resource_virtual_environment_pool.go new file mode 100644 index 00000000..173dccb3 --- /dev/null +++ b/resource_virtual_environment_pool.go @@ -0,0 +1,218 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package main + +import ( + "strings" + + "github.com/danitso/terraform-provider-proxmox/proxmox" + "github.com/hashicorp/terraform/helper/schema" +) + +const ( + mkResourceVirtualEnvironmentPoolComment = "comment" + mkResourceVirtualEnvironmentPoolMembers = "members" + mkResourceVirtualEnvironmentPoolMembersID = "id" + mkResourceVirtualEnvironmentPoolMembersNode = "node" + mkResourceVirtualEnvironmentPoolMembersStorage = "storage" + mkResourceVirtualEnvironmentPoolMembersType = "type" + mkResourceVirtualEnvironmentPoolMembersVirtualMachineID = "virtual_machine_id" + mkResourceVirtualEnvironmentPoolPoolID = "pool_id" +) + +func resourceVirtualEnvironmentPool() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkResourceVirtualEnvironmentPoolComment: &schema.Schema{ + Type: schema.TypeString, + Description: "The pool comment", + Optional: true, + Default: "", + }, + mkResourceVirtualEnvironmentPoolMembers: &schema.Schema{ + Type: schema.TypeList, + Description: "The pool members", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkResourceVirtualEnvironmentPoolMembersID: { + Type: schema.TypeString, + Required: true, + Description: "The member id", + }, + mkResourceVirtualEnvironmentPoolMembersNode: { + Type: schema.TypeString, + Required: true, + Description: "The node id", + }, + mkResourceVirtualEnvironmentPoolMembersStorage: { + Type: schema.TypeString, + Optional: true, + Description: "The storage id", + Default: "", + }, + mkResourceVirtualEnvironmentPoolMembersType: { + Type: schema.TypeString, + Required: true, + Description: "The member type", + }, + mkResourceVirtualEnvironmentPoolMembersVirtualMachineID: { + Type: schema.TypeInt, + Optional: true, + Description: "The virtual machine id", + Default: 0, + }, + }, + }, + }, + mkResourceVirtualEnvironmentPoolPoolID: &schema.Schema{ + Type: schema.TypeString, + Description: "The pool id", + Required: true, + ForceNew: true, + }, + }, + Create: resourceVirtualEnvironmentPoolCreate, + Read: resourceVirtualEnvironmentPoolRead, + Update: resourceVirtualEnvironmentPoolUpdate, + Delete: resourceVirtualEnvironmentPoolDelete, + } +} + +func resourceVirtualEnvironmentPoolCreate(d *schema.ResourceData, m interface{}) error { + config := m.(providerConfiguration) + veClient, err := config.GetVEClient() + + if err != nil { + return err + } + + comment := d.Get(mkResourceVirtualEnvironmentPoolComment).(string) + poolID := d.Get(mkResourceVirtualEnvironmentPoolPoolID).(string) + + body := &proxmox.VirtualEnvironmentPoolCreateRequestBody{ + Comment: &comment, + ID: poolID, + } + + err = veClient.CreatePool(body) + + if err != nil { + return err + } + + d.SetId(poolID) + + return resourceVirtualEnvironmentPoolRead(d, m) +} + +func resourceVirtualEnvironmentPoolRead(d *schema.ResourceData, m interface{}) error { + config := m.(providerConfiguration) + veClient, err := config.GetVEClient() + + if err != nil { + return err + } + + poolID := d.Id() + pool, err := veClient.GetPool(poolID) + + if err != nil { + if strings.Contains(err.Error(), "HTTP 404") { + d.SetId("") + + return nil + } + + return err + } + + d.SetId(poolID) + + if pool.Comment != nil { + d.Set(mkResourceVirtualEnvironmentPoolComment, pool.Comment) + } else { + d.Set(mkResourceVirtualEnvironmentPoolComment, "") + } + + members := make([]interface{}, len(pool.Members)) + + for i, v := range pool.Members { + values := make(map[string]interface{}) + + values[mkResourceVirtualEnvironmentPoolMembersID] = v.ID + values[mkResourceVirtualEnvironmentPoolMembersNode] = v.Node + + if v.Storage != nil { + values[mkResourceVirtualEnvironmentPoolMembersStorage] = v.Storage + } else { + values[mkResourceVirtualEnvironmentPoolMembersStorage] = "" + } + + values[mkResourceVirtualEnvironmentPoolMembersType] = v.Type + + if v.VirtualMachineID != nil { + values[mkResourceVirtualEnvironmentPoolMembersVirtualMachineID] = v.VirtualMachineID + } else { + values[mkResourceVirtualEnvironmentPoolMembersVirtualMachineID] = 0 + } + + members[i] = values + } + + d.Set(mkResourceVirtualEnvironmentPoolMembers, members) + + return nil +} + +func resourceVirtualEnvironmentPoolUpdate(d *schema.ResourceData, m interface{}) error { + config := m.(providerConfiguration) + veClient, err := config.GetVEClient() + + if err != nil { + return err + } + + comment := d.Get(mkResourceVirtualEnvironmentPoolComment).(string) + poolID := d.Id() + + body := &proxmox.VirtualEnvironmentPoolUpdateRequestBody{ + Comment: &comment, + } + + err = veClient.UpdatePool(poolID, body) + + if err != nil { + return err + } + + return resourceVirtualEnvironmentPoolRead(d, m) +} + +func resourceVirtualEnvironmentPoolDelete(d *schema.ResourceData, m interface{}) error { + config := m.(providerConfiguration) + veClient, err := config.GetVEClient() + + if err != nil { + return err + } + + poolID := d.Id() + err = veClient.DeletePool(poolID) + + if err != nil { + if strings.Contains(err.Error(), "HTTP 404") { + d.SetId("") + + return nil + } + + return err + } + + d.SetId("") + + return nil +} diff --git a/resource_virtual_environment_pool_test.go b/resource_virtual_environment_pool_test.go new file mode 100644 index 00000000..3b4f5fab --- /dev/null +++ b/resource_virtual_environment_pool_test.go @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package main + +import ( + "testing" +) + +// TestResourceVirtualEnvironmentPoolInstantiation tests whether the ResourceVirtualEnvironmentPool instance can be instantiated. +func TestResourceVirtualEnvironmentPoolInstantiation(t *testing.T) { + s := resourceVirtualEnvironmentPool() + + if s == nil { + t.Fatalf("Cannot instantiate resourceVirtualEnvironmentPool") + } +} + +// TestResourceVirtualEnvironmentPoolSchema tests the resourceVirtualEnvironmentPool schema. +func TestResourceVirtualEnvironmentPoolSchema(t *testing.T) { + s := resourceVirtualEnvironmentPool() + + attributeKeys := []string{} + + for _, v := range attributeKeys { + if s.Schema[v] == nil { + t.Fatalf("Error in resourceVirtualEnvironmentPool.Schema: Missing attribute \"%s\"", v) + } + + if s.Schema[v].Computed != true { + t.Fatalf("Error in resourceVirtualEnvironmentPool.Schema: Attribute \"%s\" is not computed", v) + } + } +} diff --git a/resource_virtual_environment_user.go b/resource_virtual_environment_user.go index c0b3b510..f342da41 100644 --- a/resource_virtual_environment_user.go +++ b/resource_virtual_environment_user.go @@ -10,6 +10,7 @@ import ( "github.com/danitso/terraform-provider-proxmox/proxmox" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" ) const ( @@ -47,10 +48,11 @@ func resourceVirtualEnvironmentUser() *schema.Resource { Default: true, }, mkResourceVirtualEnvironmentUserExpirationDate: &schema.Schema{ - Type: schema.TypeString, - Description: "The user account's expiration date", - Optional: true, - Default: time.Unix(0, 0).UTC().Format(time.RFC3339), + Type: schema.TypeString, + Description: "The user account's expiration date", + Optional: true, + Default: time.Unix(0, 0).UTC().Format(time.RFC3339), + ValidateFunc: validation.ValidateRFC3339TimeString, }, mkResourceVirtualEnvironmentUserFirstName: &schema.Schema{ Type: schema.TypeString,