0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 18:42:58 +00:00

Latest work

This commit is contained in:
Dan Petersen 2019-12-07 21:15:59 +01:00
parent 3e1a9cdf78
commit 44aeabbc28
13 changed files with 232 additions and 45 deletions

View File

@ -2,4 +2,5 @@
FEATURES:
* **New Data Source:** `proxmox_virtual_environment_access_groups`
* **New Data Source:** `proxmox_virtual_environment_version`

View File

@ -37,6 +37,15 @@ If you're building the provider, follow the instructions to [install it as a plu
#### Virtual Environment
##### Access Groups (proxmox_virtual_environment_access_groups)
###### Arguments
This data source doesn't accept arguments.
###### Attributes
* `comments` - The group comments.
* `ids` - The group ids.
##### Version (proxmox_virtual_environment_version)
###### Arguments

View File

@ -0,0 +1,67 @@
/* 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 (
"errors"
"github.com/hashicorp/terraform/helper/schema"
)
const (
mkDataSourceVirtualEnvironmentAccessGroupsComments = "comments"
mkDataSourceVirtualEnvironmentAccessGroupsIDs = "ids"
)
// dataSourceVirtualEnvironmentAccessGroups retrieves a list of access groups.
func dataSourceVirtualEnvironmentAccessGroups() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
mkDataSourceVirtualEnvironmentAccessGroupsComments: &schema.Schema{
Type: schema.TypeList,
Description: "The group comments",
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
mkDataSourceVirtualEnvironmentAccessGroupsIDs: &schema.Schema{
Type: schema.TypeList,
Description: "The group ids",
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
Read: dataSourceVirtualEnvironmentAccessGroupsRead,
}
}
// dataSourceVirtualEnvironmentAccessGroupsRead retrieves a list of access groups.
func dataSourceVirtualEnvironmentAccessGroupsRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
if config.veClient == nil {
return errors.New("You must specify the virtual environment details in the provider configuration to use this data source")
}
list, err := config.veClient.ListAccessGroups()
if err != nil {
return err
}
comments := make([]interface{}, len(list))
ids := make([]interface{}, len(list))
for i, v := range list {
comments[i] = v.Comment
ids[i] = v.ID
}
d.SetId("access_groups")
d.Set(mkDataSourceVirtualEnvironmentAccessGroupsComments, comments)
d.Set(mkDataSourceVirtualEnvironmentAccessGroupsIDs, ids)
return nil
}

View File

@ -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"
)
// TestDataSourceVirtualEnvironmentAccessGroupsInstantiation tests whether the DataSourceVirtualEnvironmentAccessGroups instance can be instantiated.
func TestDataSourceVirtualEnvironmentAccessGroupsInstantiation(t *testing.T) {
s := dataSourceVirtualEnvironmentAccessGroups()
if s == nil {
t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentAccessGroups")
}
}
// TestDataSourceVirtualEnvironmentAccessGroupsSchema tests the dataSourceVirtualEnvironmentAccessGroups schema.
func TestDataSourceVirtualEnvironmentAccessGroupsSchema(t *testing.T) {
s := dataSourceVirtualEnvironmentAccessGroups()
attributeKeys := []string{
mkDataSourceVirtualEnvironmentAccessGroupsComments,
mkDataSourceVirtualEnvironmentAccessGroupsIDs,
}
for _, v := range attributeKeys {
if s.Schema[v] == nil {
t.Fatalf("Error in dataSourceVirtualEnvironmentAccessGroups.Schema: Missing attribute \"%s\"", v)
}
if s.Schema[v].Computed != true {
t.Fatalf("Error in dataSourceVirtualEnvironmentAccessGroups.Schema: Attribute \"%s\" is not computed", v)
}
}
}

View File

@ -64,7 +64,7 @@ func dataSourceVirtualEnvironmentVersionRead(d *schema.ResourceData, m interface
return err
}
d.SetId(version.Version)
d.SetId("version")
d.Set(mkDataSourceVirtualEnvironmentVersionKeyboard, version.Keyboard)
d.Set(mkDataSourceVirtualEnvironmentVersionRelease, version.Release)

View File

@ -22,6 +22,7 @@ func TestDataSourceVirtualEnvironmentVersionSchema(t *testing.T) {
s := dataSourceVirtualEnvironmentVersion()
attributeKeys := []string{
mkDataSourceVirtualEnvironmentVersionKeyboard,
mkDataSourceVirtualEnvironmentVersionRelease,
mkDataSourceVirtualEnvironmentVersionRepositoryID,
mkDataSourceVirtualEnvironmentVersionVersion,

View File

@ -0,0 +1,8 @@
data "proxmox_virtual_environment_access_groups" "example" {}
output "data_proxmox_virtual_environment_access_groups" {
value = "${map(
"comments", data.proxmox_virtual_environment_access_groups.example.comments,
"ids", data.proxmox_virtual_environment_access_groups.example.ids,
)}"
}

View File

@ -1,10 +1,10 @@
data "proxmox_virtual_environment_version" "ve_version" {}
data "proxmox_virtual_environment_version" "example" {}
output "proxmox_virtual_environment_version" {
output "data_proxmox_virtual_environment_version" {
value = "${map(
"keyboard", data.proxmox_virtual_environment_version.ve_version.keyboard,
"release", data.proxmox_virtual_environment_version.ve_version.release,
"repository_id", data.proxmox_virtual_environment_version.ve_version.repository_id,
"version", data.proxmox_virtual_environment_version.ve_version.version,
"keyboard", data.proxmox_virtual_environment_version.example.keyboard,
"release", data.proxmox_virtual_environment_version.example.release,
"repository_id", data.proxmox_virtual_environment_version.example.repository_id,
"version", data.proxmox_virtual_environment_version.example.version,
)}"
}

View File

@ -26,7 +26,8 @@ func Provider() *schema.Provider {
return &schema.Provider{
ConfigureFunc: providerConfigure,
DataSourcesMap: map[string]*schema.Resource{
"proxmox_virtual_environment_version": dataSourceVirtualEnvironmentVersion(),
"proxmox_virtual_environment_access_groups": dataSourceVirtualEnvironmentAccessGroups(),
"proxmox_virtual_environment_version": dataSourceVirtualEnvironmentVersion(),
},
ResourcesMap: map[string]*schema.Resource{},
Schema: map[string]*schema.Schema{

View File

@ -5,7 +5,9 @@
package proxmox
import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"net/http"
@ -13,7 +15,13 @@ import (
"strings"
)
const basePathJSONAPI = "api2/json"
const (
basePathJSONAPI = "api2/json"
hmDELETE = "DELETE"
hmGET = "GET"
hmPOST = "POST"
hmPUT = "PUT"
)
// VirtualEnvironmentClient implements an API client for the Proxmox Virtual Environment API.
type VirtualEnvironmentClient struct {
@ -63,8 +71,55 @@ func NewVirtualEnvironmentClient(endpoint, username, password string, insecure b
}, nil
}
// ValidateResponse ensures that a response is valid.
func (c *VirtualEnvironmentClient) ValidateResponse(res *http.Response) error {
// DoRequest performs a HTTP request against a JSON API endpoint.
func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody interface{}, responseBody interface{}) error {
jsonRequestBody := new(bytes.Buffer)
if requestBody != nil {
err := json.NewEncoder(jsonRequestBody).Encode(requestBody)
if err != nil {
return fmt.Errorf("Failed to encode HTTP %s request (path: %s)", method, path)
}
}
req, err := http.NewRequest(method, fmt.Sprintf("%s/%s/%s", c.Endpoint, basePathJSONAPI, path), jsonRequestBody)
if err != nil {
return fmt.Errorf("Failed to create HTTP %s request (path: %s)", method, path)
}
err = c.AuthenticateRequest(req)
if err != nil {
return err
}
req.Header.Add("Content-Type", "application/json")
res, err := c.httpClient.Do(req)
if err != nil {
return fmt.Errorf("Failed to perform HTTP %s request (path: %s)", method, path)
}
err = c.ValidateResponseCode(res)
if err != nil {
return err
}
err = json.NewDecoder(res.Body).Decode(responseBody)
if err != nil {
return fmt.Errorf("Failed to decode HTTP %s response (path: %s)", method, path)
}
return nil
}
// ValidateResponseCode ensures that a response is valid.
func (c *VirtualEnvironmentClient) ValidateResponseCode(res *http.Response) error {
if res.StatusCode < 200 || res.StatusCode >= 300 {
switch res.StatusCode {
case 401:

View File

@ -0,0 +1,36 @@
/* 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"
)
// VirtualEnvironmentAccessGroupListResponseBody contains the body from an access group list response.
type VirtualEnvironmentAccessGroupListResponseBody struct {
Data []*VirtualEnvironmentAccessGroupListResponseData `json:"data,omitempty"`
}
// VirtualEnvironmentAccessGroupListResponseData contains the data from an access group list response.
type VirtualEnvironmentAccessGroupListResponseData struct {
Comment string `json:"comment"`
ID string `json:"groupid"`
}
// ListAccessGroups retrieves a list of access groups.
func (c *VirtualEnvironmentClient) ListAccessGroups() ([]*VirtualEnvironmentAccessGroupListResponseData, error) {
resBody := &VirtualEnvironmentAccessGroupListResponseBody{}
err := c.DoRequest(hmGET, "access/groups", 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")
}
return resBody.Data, nil
}

View File

@ -29,6 +29,7 @@ type VirtualEnvironmentAuthenticationResponseCapabilities struct {
// VirtualEnvironmentAuthenticationResponseData contains the data from an authentication response.
type VirtualEnvironmentAuthenticationResponseData struct {
ClusterName string `json:"clustername,omitempty"`
CSRFPreventionToken string `json:"CSRFPreventionToken"`
Capabilities *VirtualEnvironmentAuthenticationResponseCapabilities `json:"cap,omitempty"`
Ticket string `json:"ticket"`
@ -42,7 +43,7 @@ func (c *VirtualEnvironmentClient) Authenticate(reset bool) error {
}
body := bytes.NewBufferString(fmt.Sprintf("username=%s&password=%s", url.QueryEscape(c.Username), url.QueryEscape(c.Password)))
req, err := http.NewRequest("POST", fmt.Sprintf("%s/%s/access/ticket", c.Endpoint, basePathJSONAPI), body)
req, err := http.NewRequest(hmPOST, fmt.Sprintf("%s/%s/access/ticket", c.Endpoint, basePathJSONAPI), body)
if err != nil {
return errors.New("Failed to create authentication request")
@ -56,7 +57,7 @@ func (c *VirtualEnvironmentClient) Authenticate(reset bool) error {
return errors.New("Failed to retrieve authentication response")
}
err = c.ValidateResponse(res)
err = c.ValidateResponseCode(res)
if err != nil {
return err
@ -103,8 +104,6 @@ func (c *VirtualEnvironmentClient) AuthenticateRequest(req *http.Request) error
Value: c.authenticationData.Ticket,
})
req.Header.Add("Content-Type", "application/json")
if req.Method != "GET" {
req.Header.Add("CSRFPreventionToken", c.authenticationData.CSRFPreventionToken)
}

View File

@ -5,11 +5,7 @@
package proxmox
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
)
// VirtualEnvironmentVersionResponseBody contains the body from a version response.
@ -27,37 +23,13 @@ type VirtualEnvironmentVersionResponseData struct {
// Version retrieves the version information.
func (c *VirtualEnvironmentClient) Version() (*VirtualEnvironmentVersionResponseData, error) {
req, err := http.NewRequest("GET", fmt.Sprintf("%s/%s/version", c.Endpoint, basePathJSONAPI), new(bytes.Buffer))
if err != nil {
return nil, errors.New("Failed to create version information request")
}
err = c.AuthenticateRequest(req)
resBody := &VirtualEnvironmentVersionResponseBody{}
err := c.DoRequest(hmGET, "version", nil, resBody)
if err != nil {
return nil, err
}
res, err := c.httpClient.Do(req)
if err != nil {
return nil, errors.New("Failed to perform version information request")
}
err = c.ValidateResponse(res)
if err != nil {
return nil, err
}
resBody := VirtualEnvironmentVersionResponseBody{}
err = json.NewDecoder(res.Body).Decode(&resBody)
if err != nil {
return nil, errors.New("Failed to decode version information response")
}
if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response")
}