diff --git a/README.md b/README.md index 90116548..26bce375 100644 --- a/README.md +++ b/README.md @@ -239,11 +239,13 @@ This data source doesn't accept arguments. ##### File (proxmox_virtual_environment_file) ###### Arguments +* `content_type` - (Optional) The content type (`backup`, `images`, `iso` or `vztmpl`) * `datastore_id` - (Required) The datastore id * `node_name` - (Required) The node name * `override_file_name` - (Optional) The file name to use instead of the source file name * `source` - (Required) A path to a local file or a URL -* `template` - (Required) Whether this is a container template (`vztmpl` instead of `iso`) +* `source_checksum` - (Optional) The SHA256 checksum of the source file +* `source_insecure` - (Optional) Whether to skip the TLS verification step for HTTPS sources (defaults to `false`) ###### Attributes * `file_modification_date` - The file modification date (RFC 3339) diff --git a/example/resource_virtual_environment_file.tf b/example/resource_virtual_environment_file.tf index fe31c17d..686067be 100644 --- a/example/resource_virtual_environment_file.tf +++ b/example/resource_virtual_environment_file.tf @@ -1,42 +1,43 @@ -resource "proxmox_virtual_environment_file" "alpine_template" { - datastore_id = "${element(data.proxmox_virtual_environment_datastores.example.datastore_ids, index(data.proxmox_virtual_environment_datastores.example.datastore_ids, "local"))}" - node_name = "${data.proxmox_virtual_environment_datastores.example.node_name}" - source = "http://download.proxmox.com/images/system/alpine-3.10-default_20190626_amd64.tar.xz" - template = true +resource "proxmox_virtual_environment_file" "ubuntu_cloud_image" { + content_type = "iso" + datastore_id = "${element(data.proxmox_virtual_environment_datastores.example.datastore_ids, index(data.proxmox_virtual_environment_datastores.example.datastore_ids, "local"))}" + node_name = "${data.proxmox_virtual_environment_datastores.example.node_name}" + source = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img" + source_checksum = "6afb97af96b671572389935d6579557357ad7bbf2c2dd2cb52879c957c85dbee" } -output "resource_proxmox_virtual_environment_file_alpine_template_datastore_id" { - value = "${proxmox_virtual_environment_file.alpine_template.datastore_id}" +output "resource_proxmox_virtual_environment_file_ubuntu_cloud_image_content_type" { + value = "${proxmox_virtual_environment_file.ubuntu_cloud_image.content_type}" } -output "resource_proxmox_virtual_environment_file_alpine_template_file_modification_date" { - value = "${proxmox_virtual_environment_file.alpine_template.file_modification_date}" +output "resource_proxmox_virtual_environment_file_ubuntu_cloud_image_datastore_id" { + value = "${proxmox_virtual_environment_file.ubuntu_cloud_image.datastore_id}" } -output "resource_proxmox_virtual_environment_file_alpine_template_file_name" { - value = "${proxmox_virtual_environment_file.alpine_template.file_name}" +output "resource_proxmox_virtual_environment_file_ubuntu_cloud_image_file_modification_date" { + value = "${proxmox_virtual_environment_file.ubuntu_cloud_image.file_modification_date}" } -output "resource_proxmox_virtual_environment_file_alpine_template_file_size" { - value = "${proxmox_virtual_environment_file.alpine_template.file_size}" +output "resource_proxmox_virtual_environment_file_ubuntu_cloud_image_file_name" { + value = "${proxmox_virtual_environment_file.ubuntu_cloud_image.file_name}" } -output "resource_proxmox_virtual_environment_file_alpine_template_file_tag" { - value = "${proxmox_virtual_environment_file.alpine_template.file_tag}" +output "resource_proxmox_virtual_environment_file_ubuntu_cloud_image_file_size" { + value = "${proxmox_virtual_environment_file.ubuntu_cloud_image.file_size}" } -output "resource_proxmox_virtual_environment_file_alpine_template_id" { - value = "${proxmox_virtual_environment_file.alpine_template.id}" +output "resource_proxmox_virtual_environment_file_ubuntu_cloud_image_file_tag" { + value = "${proxmox_virtual_environment_file.ubuntu_cloud_image.file_tag}" } -output "resource_proxmox_virtual_environment_file_alpine_template_node_name" { - value = "${proxmox_virtual_environment_file.alpine_template.node_name}" +output "resource_proxmox_virtual_environment_file_ubuntu_cloud_image_id" { + value = "${proxmox_virtual_environment_file.ubuntu_cloud_image.id}" } -output "resource_proxmox_virtual_environment_file_alpine_template_source" { - value = "${proxmox_virtual_environment_file.alpine_template.source}" +output "resource_proxmox_virtual_environment_file_ubuntu_cloud_image_node_name" { + value = "${proxmox_virtual_environment_file.ubuntu_cloud_image.node_name}" } -output "resource_proxmox_virtual_environment_file_alpine_template_template" { - value = "${proxmox_virtual_environment_file.alpine_template.template}" +output "resource_proxmox_virtual_environment_file_ubuntu_cloud_image_source" { + value = "${proxmox_virtual_environment_file.ubuntu_cloud_image.source}" } diff --git a/example/resource_virtual_environment_group.tf b/example/resource_virtual_environment_group.tf index b0cc383c..b0ca8b2e 100644 --- a/example/resource_virtual_environment_group.tf +++ b/example/resource_virtual_environment_group.tf @@ -1,6 +1,6 @@ resource "proxmox_virtual_environment_group" "example" { acl { - path = "/vms/1" + path = "/vms/100" role_id = "${proxmox_virtual_environment_role.example.id}" } diff --git a/proxmox/common_types.go b/proxmox/common_types.go index 8b287dbe..0fb8c8d5 100644 --- a/proxmox/common_types.go +++ b/proxmox/common_types.go @@ -18,6 +18,9 @@ type CustomBool bool // CustomCommaSeparatedList allows a JSON string to also be a string array. type CustomCommaSeparatedList []string +// CustomLineBreakSeparatedList allows a multiline JSON string to also be a string array. +type CustomLineBreakSeparatedList []string + // CustomPrivileges allows a JSON object of privileges to also be a string array. type CustomPrivileges []string @@ -67,6 +70,28 @@ func (r *CustomCommaSeparatedList) UnmarshalJSON(b []byte) error { return nil } +// MarshalJSON converts a boolean to a JSON value. +func (r *CustomLineBreakSeparatedList) MarshalJSON() ([]byte, error) { + s := strings.Join(*r, "\n") + + return json.Marshal(s) +} + +// UnmarshalJSON converts a JSON value to a boolean. +func (r *CustomLineBreakSeparatedList) UnmarshalJSON(b []byte) error { + var s string + + err := json.Unmarshal(b, &s) + + if err != nil { + return err + } + + *r = strings.Split(s, "\n") + + return nil +} + // MarshalJSON converts a boolean to a JSON value. func (r *CustomPrivileges) MarshalJSON() ([]byte, error) { var privileges map[string]CustomBool diff --git a/proxmox/virtual_environment_acl.go b/proxmox/virtual_environment_acl.go index 97efa097..f7d21496 100644 --- a/proxmox/virtual_environment_acl.go +++ b/proxmox/virtual_environment_acl.go @@ -9,30 +9,6 @@ import ( "sort" ) -// VirtualEnvironmentACLGetResponseBody contains the body from an access control list response. -type VirtualEnvironmentACLGetResponseBody struct { - Data []*VirtualEnvironmentACLGetResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentACLGetResponseData contains the data from an access control list response. -type VirtualEnvironmentACLGetResponseData struct { - Path string `json:"path"` - Propagate *CustomBool `json:"propagate,omitempty"` - RoleID string `json:"roleid"` - Type string `json:"type"` - UserOrGroupID string `json:"ugid"` -} - -// VirtualEnvironmentACLUpdateRequestBody contains the data for an access control list update request. -type VirtualEnvironmentACLUpdateRequestBody struct { - Delete *CustomBool `json:"delete,omitempty" url:"delete,omitempty,int"` - Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"` - Path string `json:"path" url:"path"` - Propagate *CustomBool `json:"propagate,omitempty" url:"propagate,omitempty,int"` - Roles []string `json:"roles" url:"roles,comma"` - Users []string `json:"users,omitempty" url:"users,omitempty,comma"` -} - // GetACL retrieves the access control list. func (c *VirtualEnvironmentClient) GetACL() ([]*VirtualEnvironmentACLGetResponseData, error) { resBody := &VirtualEnvironmentACLGetResponseBody{} diff --git a/proxmox/virtual_environment_acl_types.go b/proxmox/virtual_environment_acl_types.go new file mode 100644 index 00000000..7b3e453c --- /dev/null +++ b/proxmox/virtual_environment_acl_types.go @@ -0,0 +1,29 @@ +/* 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 + +// VirtualEnvironmentACLGetResponseBody contains the body from an access control list response. +type VirtualEnvironmentACLGetResponseBody struct { + Data []*VirtualEnvironmentACLGetResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentACLGetResponseData contains the data from an access control list response. +type VirtualEnvironmentACLGetResponseData struct { + Path string `json:"path"` + Propagate *CustomBool `json:"propagate,omitempty"` + RoleID string `json:"roleid"` + Type string `json:"type"` + UserOrGroupID string `json:"ugid"` +} + +// VirtualEnvironmentACLUpdateRequestBody contains the data for an access control list update request. +type VirtualEnvironmentACLUpdateRequestBody struct { + Delete *CustomBool `json:"delete,omitempty" url:"delete,omitempty,int"` + Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"` + Path string `json:"path" url:"path"` + Propagate *CustomBool `json:"propagate,omitempty" url:"propagate,omitempty,int"` + Roles []string `json:"roles" url:"roles,comma"` + Users []string `json:"users,omitempty" url:"users,omitempty,comma"` +} diff --git a/proxmox/virtual_environment_authentication.go b/proxmox/virtual_environment_authentication.go index 8e2fb712..19eb5290 100644 --- a/proxmox/virtual_environment_authentication.go +++ b/proxmox/virtual_environment_authentication.go @@ -13,29 +13,6 @@ import ( "net/url" ) -// VirtualEnvironmentAuthenticationResponseBody contains the body from an authentication response. -type VirtualEnvironmentAuthenticationResponseBody struct { - Data *VirtualEnvironmentAuthenticationResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentAuthenticationResponseCapabilities contains the supported capabilities for a session. -type VirtualEnvironmentAuthenticationResponseCapabilities struct { - Access *CustomPrivileges `json:"access,omitempty"` - Datacenter *CustomPrivileges `json:"dc,omitempty"` - Nodes *CustomPrivileges `json:"nodes,omitempty"` - Storage *CustomPrivileges `json:"storage,omitempty"` - VMs *CustomPrivileges `json:"vms,omitempty"` -} - -// VirtualEnvironmentAuthenticationResponseData contains the data from an authentication response. -type VirtualEnvironmentAuthenticationResponseData struct { - ClusterName *string `json:"clustername,omitempty"` - CSRFPreventionToken *string `json:"CSRFPreventionToken,omitempty"` - Capabilities *VirtualEnvironmentAuthenticationResponseCapabilities `json:"cap,omitempty"` - Ticket *string `json:"ticket,omitempty"` - Username string `json:"username"` -} - // Authenticate authenticates against the specified endpoint. func (c *VirtualEnvironmentClient) Authenticate(reset bool) error { if c.authenticationData != nil && !reset { diff --git a/proxmox/virtual_environment_authentication_types.go b/proxmox/virtual_environment_authentication_types.go new file mode 100644 index 00000000..73ffb99d --- /dev/null +++ b/proxmox/virtual_environment_authentication_types.go @@ -0,0 +1,28 @@ +/* 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 + +// VirtualEnvironmentAuthenticationResponseBody contains the body from an authentication response. +type VirtualEnvironmentAuthenticationResponseBody struct { + Data *VirtualEnvironmentAuthenticationResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentAuthenticationResponseCapabilities contains the supported capabilities for a session. +type VirtualEnvironmentAuthenticationResponseCapabilities struct { + Access *CustomPrivileges `json:"access,omitempty"` + Datacenter *CustomPrivileges `json:"dc,omitempty"` + Nodes *CustomPrivileges `json:"nodes,omitempty"` + Storage *CustomPrivileges `json:"storage,omitempty"` + VMs *CustomPrivileges `json:"vms,omitempty"` +} + +// VirtualEnvironmentAuthenticationResponseData contains the data from an authentication response. +type VirtualEnvironmentAuthenticationResponseData struct { + ClusterName *string `json:"clustername,omitempty"` + CSRFPreventionToken *string `json:"CSRFPreventionToken,omitempty"` + Capabilities *VirtualEnvironmentAuthenticationResponseCapabilities `json:"cap,omitempty"` + Ticket *string `json:"ticket,omitempty"` + Username string `json:"username"` +} diff --git a/proxmox/virtual_environment.go b/proxmox/virtual_environment_client.go similarity index 76% rename from proxmox/virtual_environment.go rename to proxmox/virtual_environment_client.go index 6ebb5508..316f26fd 100644 --- a/proxmox/virtual_environment.go +++ b/proxmox/virtual_environment_client.go @@ -19,33 +19,6 @@ import ( "github.com/google/go-querystring/query" ) -const ( - basePathJSONAPI = "api2/json" - hmDELETE = "DELETE" - hmGET = "GET" - hmHEAD = "HEAD" - hmPOST = "POST" - hmPUT = "PUT" -) - -// VirtualEnvironmentClient implements an API client for the Proxmox Virtual Environment API. -type VirtualEnvironmentClient struct { - Endpoint string - Insecure bool - Password string - Username string - - authenticationData *VirtualEnvironmentAuthenticationResponseData - httpClient *http.Client -} - -// VirtualEnvironmentMultiPartData enables multipart uploads in DoRequest. -type VirtualEnvironmentMultiPartData struct { - Boundary string - Reader io.Reader - Size *int64 -} - // NewVirtualEnvironmentClient creates and initializes a VirtualEnvironmentClient instance. func NewVirtualEnvironmentClient(endpoint, username, password string, insecure bool) (*VirtualEnvironmentClient, error) { url, err := url.ParseRequestURI(endpoint) @@ -185,19 +158,34 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in // ValidateResponseCode ensures that a response is valid. func (c *VirtualEnvironmentClient) ValidateResponseCode(res *http.Response) error { if res.StatusCode < 200 || res.StatusCode >= 300 { + status := strings.TrimPrefix(res.Status, fmt.Sprintf("%d ", res.StatusCode)) + + errRes := &VirtualEnvironmentErrorResponseBody{} + err := json.NewDecoder(res.Body).Decode(errRes) + + if err == nil && errRes.Errors != nil { + errList := []string{} + + for k, v := range *errRes.Errors { + errList = append(errList, fmt.Sprintf("%s: %s", k, strings.TrimRight(v, "\n\r"))) + } + + status = fmt.Sprintf("%s (%s)", status, strings.Join(errList, " - ")) + } + switch res.StatusCode { - case 400: - return fmt.Errorf("Received a HTTP %d response - Reason: %s", res.StatusCode, res.Status) + case 400, 500: + return fmt.Errorf("Received an HTTP %d response - Reason: %s", res.StatusCode, status) case 401: - return fmt.Errorf("Received a HTTP %d response - Please verify that the specified credentials are valid", res.StatusCode) + return fmt.Errorf("Received an HTTP %d response - Please verify that the specified credentials are valid", res.StatusCode) case 403: - return fmt.Errorf("Received a HTTP %d response - Please verify that the user account has the necessary permissions", res.StatusCode) + return fmt.Errorf("Received an 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, 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) + return fmt.Errorf("Received an HTTP %d response - Please verify that the endpoint refers to a supported version of the Proxmox Virtual Environment API", res.StatusCode) + case 501, 502, 503: + return fmt.Errorf("Received an HTTP %d response - Please verify that the Proxmox Virtual Environment API is healthy", res.StatusCode) default: - return fmt.Errorf("Received a HTTP %d response", res.StatusCode) + return fmt.Errorf("Received an HTTP %d response", res.StatusCode) } } diff --git a/proxmox/virtual_environment_client_types.go b/proxmox/virtual_environment_client_types.go new file mode 100644 index 00000000..4f1e6203 --- /dev/null +++ b/proxmox/virtual_environment_client_types.go @@ -0,0 +1,43 @@ +/* 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 ( + "io" + "net/http" +) + +const ( + basePathJSONAPI = "api2/json" + hmDELETE = "DELETE" + hmGET = "GET" + hmHEAD = "HEAD" + hmPOST = "POST" + hmPUT = "PUT" +) + +// VirtualEnvironmentClient implements an API client for the Proxmox Virtual Environment API. +type VirtualEnvironmentClient struct { + Endpoint string + Insecure bool + Password string + Username string + + authenticationData *VirtualEnvironmentAuthenticationResponseData + httpClient *http.Client +} + +// VirtualEnvironmentErrorResponseBody contains the body of an error response. +type VirtualEnvironmentErrorResponseBody struct { + Data *string + Errors *map[string]string +} + +// VirtualEnvironmentMultiPartData enables multipart uploads in DoRequest. +type VirtualEnvironmentMultiPartData struct { + Boundary string + Reader io.Reader + Size *int64 +} diff --git a/proxmox/virtual_environment_datastores.go b/proxmox/virtual_environment_datastores.go index bf49111f..52533fea 100644 --- a/proxmox/virtual_environment_datastores.go +++ b/proxmox/virtual_environment_datastores.go @@ -15,64 +15,6 @@ import ( "sort" ) -// VirtualEnvironmentDatastoreFileListResponseBody contains the body from a datastore content list response. -type VirtualEnvironmentDatastoreFileListResponseBody struct { - Data []*VirtualEnvironmentDatastoreFileListResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentDatastoreFileListResponseData contains the data from a datastore content list response. -type VirtualEnvironmentDatastoreFileListResponseData struct { - ContentType string `json:"content"` - FileFormat string `json:"format"` - FileSize int `json:"size"` - ParentVolumeID *string `json:"parent,omitempty"` - SpaceUsed *int `json:"used,omitempty"` - VMID *int `json:"vmid,omitempty"` - VolumeID string `json:"volid"` -} - -// VirtualEnvironmentDatastoreListRequestBody contains the body for a datastore list request. -type VirtualEnvironmentDatastoreListRequestBody struct { - ContentTypes CustomCommaSeparatedList `json:"content,omitempty" url:"content,omitempty,comma"` - Enabled *CustomBool `json:"enabled,omitempty" url:"enabled,omitempty,int"` - Format *CustomBool `json:"format,omitempty" url:"format,omitempty,int"` - ID *string `json:"storage,omitempty" url:"storage,omitempty"` - Target *string `json:"target,omitempty" url:"target,omitempty"` -} - -// VirtualEnvironmentDatastoreListResponseBody contains the body from a datastore list response. -type VirtualEnvironmentDatastoreListResponseBody struct { - Data []*VirtualEnvironmentDatastoreListResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentDatastoreListResponseData contains the data from a datastore list response. -type VirtualEnvironmentDatastoreListResponseData struct { - Active *CustomBool `json:"active,omitempty"` - ContentTypes *CustomCommaSeparatedList `json:"content,omitempty"` - Enabled *CustomBool `json:"enabled,omitempty"` - ID string `json:"storage,omitempty"` - Shared *CustomBool `json:"shared,omitempty"` - SpaceAvailable *int `json:"avail,omitempty"` - SpaceTotal *int `json:"total,omitempty"` - SpaceUsed *int `json:"used,omitempty"` - SpaceUsedPercentage *float64 `json:"used_fraction,omitempty"` - Type string `json:"type,omitempty"` -} - -// VirtualEnvironmentDatastoreUploadRequestBody contains the body for a datastore upload request. -type VirtualEnvironmentDatastoreUploadRequestBody struct { - ContentType string `json:"content,omitempty"` - DatastoreID string `json:"storage,omitempty"` - FileName string `json:"filename,omitempty"` - FileReader io.Reader `json:"-"` - NodeName string `json:"node,omitempty"` -} - -// VirtualEnvironmentDatastoreUploadResponseBody contains the body from a datastore upload response. -type VirtualEnvironmentDatastoreUploadResponseBody struct { - UploadID *string `json:"data,omitempty"` -} - // DeleteDatastoreFile deletes a file in a datastore. func (c *VirtualEnvironmentClient) DeleteDatastoreFile(nodeName, datastoreID, volumeID string) error { err := c.DoRequest(hmDELETE, fmt.Sprintf("nodes/%s/storage/%s/content/%s", url.PathEscape(nodeName), url.PathEscape(datastoreID), url.PathEscape(volumeID)), nil, nil) diff --git a/proxmox/virtual_environment_datastores_types.go b/proxmox/virtual_environment_datastores_types.go new file mode 100644 index 00000000..66f6c280 --- /dev/null +++ b/proxmox/virtual_environment_datastores_types.go @@ -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 proxmox + +import ( + "io" +) + +// VirtualEnvironmentDatastoreFileListResponseBody contains the body from a datastore content list response. +type VirtualEnvironmentDatastoreFileListResponseBody struct { + Data []*VirtualEnvironmentDatastoreFileListResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentDatastoreFileListResponseData contains the data from a datastore content list response. +type VirtualEnvironmentDatastoreFileListResponseData struct { + ContentType string `json:"content"` + FileFormat string `json:"format"` + FileSize int `json:"size"` + ParentVolumeID *string `json:"parent,omitempty"` + SpaceUsed *int `json:"used,omitempty"` + VMID *int `json:"vmid,omitempty"` + VolumeID string `json:"volid"` +} + +// VirtualEnvironmentDatastoreListRequestBody contains the body for a datastore list request. +type VirtualEnvironmentDatastoreListRequestBody struct { + ContentTypes CustomCommaSeparatedList `json:"content,omitempty" url:"content,omitempty,comma"` + Enabled *CustomBool `json:"enabled,omitempty" url:"enabled,omitempty,int"` + Format *CustomBool `json:"format,omitempty" url:"format,omitempty,int"` + ID *string `json:"storage,omitempty" url:"storage,omitempty"` + Target *string `json:"target,omitempty" url:"target,omitempty"` +} + +// VirtualEnvironmentDatastoreListResponseBody contains the body from a datastore list response. +type VirtualEnvironmentDatastoreListResponseBody struct { + Data []*VirtualEnvironmentDatastoreListResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentDatastoreListResponseData contains the data from a datastore list response. +type VirtualEnvironmentDatastoreListResponseData struct { + Active *CustomBool `json:"active,omitempty"` + ContentTypes *CustomCommaSeparatedList `json:"content,omitempty"` + Enabled *CustomBool `json:"enabled,omitempty"` + ID string `json:"storage,omitempty"` + Shared *CustomBool `json:"shared,omitempty"` + SpaceAvailable *int `json:"avail,omitempty"` + SpaceTotal *int `json:"total,omitempty"` + SpaceUsed *int `json:"used,omitempty"` + SpaceUsedPercentage *float64 `json:"used_fraction,omitempty"` + Type string `json:"type,omitempty"` +} + +// VirtualEnvironmentDatastoreUploadRequestBody contains the body for a datastore upload request. +type VirtualEnvironmentDatastoreUploadRequestBody struct { + ContentType string `json:"content,omitempty"` + DatastoreID string `json:"storage,omitempty"` + FileName string `json:"filename,omitempty"` + FileReader io.Reader `json:"-"` + NodeName string `json:"node,omitempty"` +} + +// VirtualEnvironmentDatastoreUploadResponseBody contains the body from a datastore upload response. +type VirtualEnvironmentDatastoreUploadResponseBody struct { + UploadID *string `json:"data,omitempty"` +} diff --git a/proxmox/virtual_environment_groups.go b/proxmox/virtual_environment_groups.go index 63cdc2a3..cde6fdcc 100644 --- a/proxmox/virtual_environment_groups.go +++ b/proxmox/virtual_environment_groups.go @@ -11,39 +11,6 @@ import ( "sort" ) -// VirtualEnvironmentGroupCreateRequestBody contains the data for an access group create request. -type VirtualEnvironmentGroupCreateRequestBody struct { - Comment *string `json:"comment,omitempty" url:"comment,omitempty"` - ID string `json:"groupid" url:"groupid"` -} - -// VirtualEnvironmentGroupGetResponseBody contains the body from an access group get response. -type VirtualEnvironmentGroupGetResponseBody struct { - Data *VirtualEnvironmentGroupGetResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentGroupGetResponseData contains the data from an access group get response. -type VirtualEnvironmentGroupGetResponseData struct { - Comment *string `json:"comment,omitempty"` - Members []string `json:"members"` -} - -// VirtualEnvironmentGroupListResponseBody contains the body from an access group list response. -type VirtualEnvironmentGroupListResponseBody struct { - Data []*VirtualEnvironmentGroupListResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentGroupListResponseData contains the data from an access group list response. -type VirtualEnvironmentGroupListResponseData struct { - Comment *string `json:"comment,omitempty"` - ID string `json:"groupid"` -} - -// VirtualEnvironmentGroupUpdateRequestBody contains the data for an access group update request. -type VirtualEnvironmentGroupUpdateRequestBody struct { - Comment *string `json:"comment,omitempty" url:"comment,omitempty"` -} - // CreateGroup creates an access group. func (c *VirtualEnvironmentClient) CreateGroup(d *VirtualEnvironmentGroupCreateRequestBody) error { return c.DoRequest(hmPOST, "access/groups", d, nil) diff --git a/proxmox/virtual_environment_groups_types.go b/proxmox/virtual_environment_groups_types.go new file mode 100644 index 00000000..c6792fbb --- /dev/null +++ b/proxmox/virtual_environment_groups_types.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 proxmox + +// VirtualEnvironmentGroupCreateRequestBody contains the data for an access group create request. +type VirtualEnvironmentGroupCreateRequestBody struct { + Comment *string `json:"comment,omitempty" url:"comment,omitempty"` + ID string `json:"groupid" url:"groupid"` +} + +// VirtualEnvironmentGroupGetResponseBody contains the body from an access group get response. +type VirtualEnvironmentGroupGetResponseBody struct { + Data *VirtualEnvironmentGroupGetResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentGroupGetResponseData contains the data from an access group get response. +type VirtualEnvironmentGroupGetResponseData struct { + Comment *string `json:"comment,omitempty"` + Members []string `json:"members"` +} + +// VirtualEnvironmentGroupListResponseBody contains the body from an access group list response. +type VirtualEnvironmentGroupListResponseBody struct { + Data []*VirtualEnvironmentGroupListResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentGroupListResponseData contains the data from an access group list response. +type VirtualEnvironmentGroupListResponseData struct { + Comment *string `json:"comment,omitempty"` + ID string `json:"groupid"` +} + +// VirtualEnvironmentGroupUpdateRequestBody contains the data for an access group update request. +type VirtualEnvironmentGroupUpdateRequestBody struct { + Comment *string `json:"comment,omitempty" url:"comment,omitempty"` +} diff --git a/proxmox/virtual_environment_nodes.go b/proxmox/virtual_environment_nodes.go index 17719bcd..d0b5387e 100644 --- a/proxmox/virtual_environment_nodes.go +++ b/proxmox/virtual_environment_nodes.go @@ -9,24 +9,6 @@ import ( "sort" ) -// VirtualEnvironmentNodeListResponseBody contains the body from a node list response. -type VirtualEnvironmentNodeListResponseBody struct { - Data []*VirtualEnvironmentNodeListResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentNodeListResponseData contains the data from a node list response. -type VirtualEnvironmentNodeListResponseData struct { - CPUCount *int `json:"maxcpu,omitempty"` - CPUUtilization *float64 `json:"cpu,omitempty"` - MemoryAvailable *int `json:"maxmem,omitempty"` - MemoryUsed *int `json:"mem,omitempty"` - Name string `json:"node"` - SSLFingerprint *string `json:"ssl_fingerprint,omitempty"` - Status *string `json:"status"` - SupportLevel *string `json:"level,omitempty"` - Uptime *int `json:"uptime"` -} - // ListNodes retrieves a list of nodes. func (c *VirtualEnvironmentClient) ListNodes() ([]*VirtualEnvironmentNodeListResponseData, error) { resBody := &VirtualEnvironmentNodeListResponseBody{} diff --git a/proxmox/virtual_environment_nodes_types.go b/proxmox/virtual_environment_nodes_types.go new file mode 100644 index 00000000..c6ee725a --- /dev/null +++ b/proxmox/virtual_environment_nodes_types.go @@ -0,0 +1,23 @@ +/* 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 + +// VirtualEnvironmentNodeListResponseBody contains the body from a node list response. +type VirtualEnvironmentNodeListResponseBody struct { + Data []*VirtualEnvironmentNodeListResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentNodeListResponseData contains the data from a node list response. +type VirtualEnvironmentNodeListResponseData struct { + CPUCount *int `json:"maxcpu,omitempty"` + CPUUtilization *float64 `json:"cpu,omitempty"` + MemoryAvailable *int `json:"maxmem,omitempty"` + MemoryUsed *int `json:"mem,omitempty"` + Name string `json:"node"` + SSLFingerprint *string `json:"ssl_fingerprint,omitempty"` + Status *string `json:"status"` + SupportLevel *string `json:"level,omitempty"` + Uptime *int `json:"uptime"` +} diff --git a/proxmox/virtual_environment_pools.go b/proxmox/virtual_environment_pools.go index 33992d6e..1050a283 100644 --- a/proxmox/virtual_environment_pools.go +++ b/proxmox/virtual_environment_pools.go @@ -11,48 +11,6 @@ import ( "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"` - DatastoreID *string `json:"storage,omitempty"` - Type string `json:"type"` - VMID *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) diff --git a/proxmox/virtual_environment_pools_types.go b/proxmox/virtual_environment_pools_types.go new file mode 100644 index 00000000..d7fa9b57 --- /dev/null +++ b/proxmox/virtual_environment_pools_types.go @@ -0,0 +1,47 @@ +/* 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 + +// 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"` + DatastoreID *string `json:"storage,omitempty"` + Type string `json:"type"` + VMID *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"` +} diff --git a/proxmox/virtual_environment_roles.go b/proxmox/virtual_environment_roles.go index 5b9a4db0..902ff9bb 100644 --- a/proxmox/virtual_environment_roles.go +++ b/proxmox/virtual_environment_roles.go @@ -11,34 +11,6 @@ import ( "sort" ) -// VirtualEnvironmentRoleCreateRequestBody contains the data for an access group create request. -type VirtualEnvironmentRoleCreateRequestBody struct { - ID string `json:"roleid" url:"roleid"` - Privileges CustomPrivileges `json:"privs" url:"privs,comma"` -} - -// VirtualEnvironmentRoleGetResponseBody contains the body from an access group get response. -type VirtualEnvironmentRoleGetResponseBody struct { - Data *CustomPrivileges `json:"data,omitempty"` -} - -// VirtualEnvironmentRoleListResponseBody contains the body from an access group list response. -type VirtualEnvironmentRoleListResponseBody struct { - Data []*VirtualEnvironmentRoleListResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentRoleListResponseData contains the data from an access group list response. -type VirtualEnvironmentRoleListResponseData struct { - ID string `json:"roleid"` - Privileges *CustomPrivileges `json:"privs,omitempty"` - Special *CustomBool `json:"special,omitempty"` -} - -// VirtualEnvironmentRoleUpdateRequestBody contains the data for an access group update request. -type VirtualEnvironmentRoleUpdateRequestBody struct { - Privileges CustomPrivileges `json:"privs" url:"privs,comma"` -} - // CreateRole creates an access role. func (c *VirtualEnvironmentClient) CreateRole(d *VirtualEnvironmentRoleCreateRequestBody) error { return c.DoRequest(hmPOST, "access/roles", d, nil) diff --git a/proxmox/virtual_environment_roles_types.go b/proxmox/virtual_environment_roles_types.go new file mode 100644 index 00000000..de6f3e04 --- /dev/null +++ b/proxmox/virtual_environment_roles_types.go @@ -0,0 +1,33 @@ +/* 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 + +// VirtualEnvironmentRoleCreateRequestBody contains the data for an access group create request. +type VirtualEnvironmentRoleCreateRequestBody struct { + ID string `json:"roleid" url:"roleid"` + Privileges CustomPrivileges `json:"privs" url:"privs,comma"` +} + +// VirtualEnvironmentRoleGetResponseBody contains the body from an access group get response. +type VirtualEnvironmentRoleGetResponseBody struct { + Data *CustomPrivileges `json:"data,omitempty"` +} + +// VirtualEnvironmentRoleListResponseBody contains the body from an access group list response. +type VirtualEnvironmentRoleListResponseBody struct { + Data []*VirtualEnvironmentRoleListResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentRoleListResponseData contains the data from an access group list response. +type VirtualEnvironmentRoleListResponseData struct { + ID string `json:"roleid"` + Privileges *CustomPrivileges `json:"privs,omitempty"` + Special *CustomBool `json:"special,omitempty"` +} + +// VirtualEnvironmentRoleUpdateRequestBody contains the data for an access group update request. +type VirtualEnvironmentRoleUpdateRequestBody struct { + Privileges CustomPrivileges `json:"privs" url:"privs,comma"` +} diff --git a/proxmox/virtual_environment_users.go b/proxmox/virtual_environment_users.go index 527e8ac7..1bce0839 100644 --- a/proxmox/virtual_environment_users.go +++ b/proxmox/virtual_environment_users.go @@ -12,74 +12,6 @@ import ( "time" ) -// VirtualEnvironmentUserChangePasswordRequestBody contains the data for a user password change request. -type VirtualEnvironmentUserChangePasswordRequestBody struct { - ID string `json:"userid" url:"userid"` - Password string `json:"password" url:"password"` -} - -// VirtualEnvironmentUserCreateRequestBody contains the data for an user create request. -type VirtualEnvironmentUserCreateRequestBody struct { - Comment *string `json:"comment,omitempty" url:"comment,omitempty"` - Email *string `json:"email,omitempty" url:"email,omitempty"` - Enabled *CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"` - ExpirationDate *CustomTimestamp `json:"expire,omitempty" url:"expire,omitempty,unix"` - FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"` - Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"` - ID string `json:"userid" url:"userid"` - Keys *string `json:"keys,omitempty" url:"keys,omitempty"` - LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"` - Password string `json:"password" url:"password"` -} - -// VirtualEnvironmentUserGetResponseBody contains the body from an user get response. -type VirtualEnvironmentUserGetResponseBody struct { - Data *VirtualEnvironmentUserGetResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentUserGetResponseData contains the data from an user get response. -type VirtualEnvironmentUserGetResponseData struct { - Comment *string `json:"comment,omitempty"` - Email *string `json:"email,omitempty"` - Enabled *CustomBool `json:"enable,omitempty"` - ExpirationDate *CustomTimestamp `json:"expire,omitempty"` - FirstName *string `json:"firstname,omitempty"` - Groups *[]string `json:"groups,omitempty"` - Keys *string `json:"keys,omitempty"` - LastName *string `json:"lastname,omitempty"` -} - -// VirtualEnvironmentUserListResponseBody contains the body from an user list response. -type VirtualEnvironmentUserListResponseBody struct { - Data []*VirtualEnvironmentUserListResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentUserListResponseData contains the data from an user list response. -type VirtualEnvironmentUserListResponseData struct { - Comment *string `json:"comment,omitempty"` - Email *string `json:"email,omitempty"` - Enabled *CustomBool `json:"enable,omitempty"` - ExpirationDate *CustomTimestamp `json:"expire,omitempty"` - FirstName *string `json:"firstname,omitempty"` - Groups *[]string `json:"groups,omitempty"` - ID string `json:"userid"` - Keys *string `json:"keys,omitempty"` - LastName *string `json:"lastname,omitempty"` -} - -// VirtualEnvironmentUserUpdateRequestBody contains the data for an user update request. -type VirtualEnvironmentUserUpdateRequestBody struct { - Append *CustomBool `json:"append,omitempty" url:"append,omitempty"` - Comment *string `json:"comment,omitempty" url:"comment,omitempty"` - Email *string `json:"email,omitempty" url:"email,omitempty"` - Enabled *CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"` - ExpirationDate *CustomTimestamp `json:"expire,omitempty" url:"expire,omitempty,unix"` - FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"` - Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"` - Keys *string `json:"keys,omitempty" url:"keys,omitempty"` - LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"` -} - // ChangeUserPassword changes a user's password. func (c *VirtualEnvironmentClient) ChangeUserPassword(id, password string) error { d := VirtualEnvironmentUserChangePasswordRequestBody{ diff --git a/proxmox/virtual_environment_users_types.go b/proxmox/virtual_environment_users_types.go new file mode 100644 index 00000000..982034b9 --- /dev/null +++ b/proxmox/virtual_environment_users_types.go @@ -0,0 +1,73 @@ +/* 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 + +// VirtualEnvironmentUserChangePasswordRequestBody contains the data for a user password change request. +type VirtualEnvironmentUserChangePasswordRequestBody struct { + ID string `json:"userid" url:"userid"` + Password string `json:"password" url:"password"` +} + +// VirtualEnvironmentUserCreateRequestBody contains the data for an user create request. +type VirtualEnvironmentUserCreateRequestBody struct { + Comment *string `json:"comment,omitempty" url:"comment,omitempty"` + Email *string `json:"email,omitempty" url:"email,omitempty"` + Enabled *CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"` + ExpirationDate *CustomTimestamp `json:"expire,omitempty" url:"expire,omitempty,unix"` + FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"` + Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"` + ID string `json:"userid" url:"userid"` + Keys *string `json:"keys,omitempty" url:"keys,omitempty"` + LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"` + Password string `json:"password" url:"password"` +} + +// VirtualEnvironmentUserGetResponseBody contains the body from an user get response. +type VirtualEnvironmentUserGetResponseBody struct { + Data *VirtualEnvironmentUserGetResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentUserGetResponseData contains the data from an user get response. +type VirtualEnvironmentUserGetResponseData struct { + Comment *string `json:"comment,omitempty"` + Email *string `json:"email,omitempty"` + Enabled *CustomBool `json:"enable,omitempty"` + ExpirationDate *CustomTimestamp `json:"expire,omitempty"` + FirstName *string `json:"firstname,omitempty"` + Groups *[]string `json:"groups,omitempty"` + Keys *string `json:"keys,omitempty"` + LastName *string `json:"lastname,omitempty"` +} + +// VirtualEnvironmentUserListResponseBody contains the body from an user list response. +type VirtualEnvironmentUserListResponseBody struct { + Data []*VirtualEnvironmentUserListResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentUserListResponseData contains the data from an user list response. +type VirtualEnvironmentUserListResponseData struct { + Comment *string `json:"comment,omitempty"` + Email *string `json:"email,omitempty"` + Enabled *CustomBool `json:"enable,omitempty"` + ExpirationDate *CustomTimestamp `json:"expire,omitempty"` + FirstName *string `json:"firstname,omitempty"` + Groups *[]string `json:"groups,omitempty"` + ID string `json:"userid"` + Keys *string `json:"keys,omitempty"` + LastName *string `json:"lastname,omitempty"` +} + +// VirtualEnvironmentUserUpdateRequestBody contains the data for an user update request. +type VirtualEnvironmentUserUpdateRequestBody struct { + Append *CustomBool `json:"append,omitempty" url:"append,omitempty"` + Comment *string `json:"comment,omitempty" url:"comment,omitempty"` + Email *string `json:"email,omitempty" url:"email,omitempty"` + Enabled *CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"` + ExpirationDate *CustomTimestamp `json:"expire,omitempty" url:"expire,omitempty,unix"` + FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"` + Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"` + Keys *string `json:"keys,omitempty" url:"keys,omitempty"` + LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"` +} diff --git a/proxmox/virtual_environment_version.go b/proxmox/virtual_environment_version.go index 346d7ecc..35e27300 100644 --- a/proxmox/virtual_environment_version.go +++ b/proxmox/virtual_environment_version.go @@ -8,19 +8,6 @@ import ( "errors" ) -// VirtualEnvironmentVersionResponseBody contains the body from a version response. -type VirtualEnvironmentVersionResponseBody struct { - Data *VirtualEnvironmentVersionResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentVersionResponseData contains the data from a version response. -type VirtualEnvironmentVersionResponseData struct { - Keyboard string `json:"keyboard"` - Release string `json:"release"` - RepositoryID string `json:"repoid"` - Version string `json:"version"` -} - // Version retrieves the version information. func (c *VirtualEnvironmentClient) Version() (*VirtualEnvironmentVersionResponseData, error) { resBody := &VirtualEnvironmentVersionResponseBody{} diff --git a/proxmox/virtual_environment_version_types.go b/proxmox/virtual_environment_version_types.go new file mode 100644 index 00000000..c42fe5ec --- /dev/null +++ b/proxmox/virtual_environment_version_types.go @@ -0,0 +1,18 @@ +/* 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 + +// VirtualEnvironmentVersionResponseBody contains the body from a version response. +type VirtualEnvironmentVersionResponseBody struct { + Data *VirtualEnvironmentVersionResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentVersionResponseData contains the data from a version response. +type VirtualEnvironmentVersionResponseData struct { + Keyboard string `json:"keyboard"` + Release string `json:"release"` + RepositoryID string `json:"repoid"` + Version string `json:"version"` +} diff --git a/proxmox/virtual_environment_vm.go b/proxmox/virtual_environment_vm.go index f4a89139..8dc2ee82 100644 --- a/proxmox/virtual_environment_vm.go +++ b/proxmox/virtual_environment_vm.go @@ -6,46 +6,34 @@ package proxmox import ( "errors" + "fmt" + "net/url" ) -// VirtualEnvironmentVMGetResponseBody contains the body from an virtual machine get response. -type VirtualEnvironmentVMGetResponseBody struct { - Data *VirtualEnvironmentVMGetResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentVMGetResponseData contains the data from an virtual machine get response. -type VirtualEnvironmentVMGetResponseData struct { - ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"` -} - -// VirtualEnvironmentVMListResponseBody contains the body from an virtual machine list response. -type VirtualEnvironmentVMListResponseBody struct { - Data []*VirtualEnvironmentVMListResponseData `json:"data,omitempty"` -} - -// VirtualEnvironmentVMListResponseData contains the data from an virtual machine list response. -type VirtualEnvironmentVMListResponseData struct { - ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"` -} - -// VirtualEnvironmentVMUpdateRequestBody contains the data for an virtual machine update request. -type VirtualEnvironmentVMUpdateRequestBody struct { - ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"` -} - // CreateVM creates an virtual machine. -func (c *VirtualEnvironmentClient) CreateVM(d *VirtualEnvironmentVMCreateRequestBody) error { - return c.DoRequest(hmPOST, "nodes/%s/qemu", d, nil) +func (c *VirtualEnvironmentClient) CreateVM(nodeName string, d *VirtualEnvironmentVMCreateRequestBody) error { + return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu", url.PathEscape(nodeName)), d, nil) } // DeleteVM deletes an virtual machine. -func (c *VirtualEnvironmentClient) DeleteVM(id string) error { - return errors.New("Not implemented") +func (c *VirtualEnvironmentClient) DeleteVM(nodeName string, vmID int) error { + return c.DoRequest(hmDELETE, fmt.Sprintf("nodes/%s/qemu/%d", url.PathEscape(nodeName), vmID), nil, nil) } // GetVM retrieves an virtual machine. func (c *VirtualEnvironmentClient) GetVM(nodeName string, vmID int) (*VirtualEnvironmentVMGetResponseData, error) { - return nil, errors.New("Not implemented") + resBody := &VirtualEnvironmentVMGetResponseBody{} + err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), 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 } // ListVMs retrieves a list of virtual machines. @@ -53,7 +41,12 @@ func (c *VirtualEnvironmentClient) ListVMs() ([]*VirtualEnvironmentVMListRespons return nil, errors.New("Not implemented") } -// UpdateVM updates an virtual machine. -func (c *VirtualEnvironmentClient) UpdateVM(id string, d *VirtualEnvironmentVMUpdateRequestBody) error { - return errors.New("Not implemented") +// UpdateVM updates a virtual machine. +func (c *VirtualEnvironmentClient) UpdateVM(nodeName string, vmID int, d *VirtualEnvironmentVMUpdateRequestBody) error { + return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), d, nil) +} + +// UpdateVMAsync updates a virtual machine asynchronously. +func (c *VirtualEnvironmentClient) UpdateVMAsync(nodeName string, vmID int, d *VirtualEnvironmentVMUpdateRequestBody) error { + return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), d, nil) } diff --git a/proxmox/virtual_environment_vm_types.go b/proxmox/virtual_environment_vm_types.go index ec183554..fdb99b42 100644 --- a/proxmox/virtual_environment_vm_types.go +++ b/proxmox/virtual_environment_vm_types.go @@ -197,76 +197,162 @@ type CustomWatchdogDevice struct { // VirtualEnvironmentVMCreateRequestBody contains the data for an virtual machine create request. type VirtualEnvironmentVMCreateRequestBody struct { - ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"` - Agent *CustomAgent `json:"agent,omitempty" url:"agent,omitempty"` - AllocatedMemory *int `json:"memory,omitempty" url:"memory,omitempty"` - AllowReboot *CustomBool `json:"reboot,omitempty" url:"reboot,omitempty,int"` - AudioDevice *CustomAudioDevice `json:"audio0,omitempty" url:"audio0,omitempty"` - Autostart *CustomBool `json:"autostart,omitempty" url:"autostart,omitempty,int"` - BackupFile *string `json:"archive,omitempty" url:"archive,omitempty"` - BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"` - BIOS *string `json:"bios,omitempty" url:"bios,omitempty"` - BootDiskID *string `json:"bootdisk,omitempty" url:"bootdisk,omitempty"` - BootOrder *string `json:"boot,omitempty" url:"boot,omitempty"` - CDROM *string `json:"cdrom,omitempty" url:"cdrom,omitempty"` - CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,omitempty"` - CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"` - CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"` - CPULimit *int `json:"cpulimit,omitempty" url:"cpulimit,omitempty"` - CPUSockets *int `json:"sockets,omitempty" url:"sockets,omitempty"` - CPUUnits *int `json:"cpuunits,omitempty" url:"cpuunits,omitempty"` - DeletionProtection *CustomBool `json:"protection,omitempty" url:"force,omitempty,int"` - Description *string `json:"description,omitempty" url:"description,omitempty"` - EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty" url:"efidisk0,omitempty"` - FloatingMemory *int `json:"balloon,omitempty" url:"balloon,omitempty"` - FloatingMemoryShares *int `json:"shares,omitempty" url:"shares,omitempty"` - Freeze *CustomBool `json:"freeze,omitempty" url:"freeze,omitempty,int"` - HookScript *string `json:"hookscript,omitempty" url:"hookscript,omitempty"` - Hotplug []string `json:"hotplug,omitempty" url:"hotplug,omitempty,comma"` - Hugepages *string `json:"hugepages,omitempty" url:"hugepages,omitempty"` - IDEDevices CustomIDEDevices `json:"ide,omitempty" url:"ide,omitempty"` - KeyboardLayout *string `json:"keyboard,omitempty" url:"keyboard,omitempty"` - KVMArguments []string `json:"args,omitempty" url:"args,omitempty,space"` - KVMEnabled *CustomBool `json:"kvm,omitempty" url:"kvm,omitempty,int"` - LocalTime *CustomBool `json:"localtime,omitempty" url:"localtime,omitempty,int"` - Lock *string `json:"lock,omitempty" url:"lock,omitempty"` - MachineType *string `json:"machine,omitempty" url:"machine,omitempty"` - MigrateDowntime *float64 `json:"migrate_downtime,omitempty" url:"migrate_downtime,omitempty"` - MigrateSpeed *int `json:"migrate_speed,omitempty" url:"migrate_speed,omitempty"` - Name *string `json:"name,omitempty" url:"name,omitempty"` - NetworkDevices CustomNetworkDevices `json:"net,omitempty" url:"net,omitempty"` - NodeName string `json:"node" url:"node"` - NUMADevices CustomNUMADevices `json:"numa_devices,omitempty" url:"numa,omitempty"` - NUMAEnabled *CustomBool `json:"numa,omitempty" url:"numa,omitempty,int"` - OSType *string `json:"ostype,omitempty" url:"ostype,omitempty"` - Overwrite *CustomBool `json:"force,omitempty" url:"force,omitempty,int"` - PCIDevices CustomPCIDevices `json:"hostpci,omitempty" url:"hostpci,omitempty"` - Revert *string `json:"revert,omitempty" url:"revert,omitempty"` - SATADevices CustomSATADevices `json:"sata,omitempty" url:"sata,omitempty"` - SCSIDevices CustomSCSIDevices `json:"scsi,omitempty" url:"sata,omitempty"` - SCSIHardware *string `json:"scsihw,omitempty" url:"scsihw,omitempty"` - SerialDevices CustomSerialDevices `json:"serial,omitempty" url:"serial,omitempty"` - SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty" url:"ivshmem,omitempty"` - SkipLock *CustomBool `json:"skiplock,omitempty" url:"skiplock,omitempty,int"` - SMBIOS *CustomSMBIOS `json:"smbios1,omitempty" url:"smbios1,omitempty"` - SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty" url:"spice_enhancements,omitempty"` - StartDate *string `json:"startdate,omitempty" url:"startdate,omitempty"` - StartOnBoot *CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"` - StartupOrder *CustomStartupOrder `json:"startup,omitempty" url:"startup,omitempty"` - TabletDeviceEnabled *CustomBool `json:"tablet,omitempty" url:"tablet,omitempty,int"` - Tags *string `json:"tags,omitempty" url:"tags,omitempty"` - Template *CustomBool `json:"template,omitempty" url:"template,omitempty,int"` - TimeDriftFixEnabled *CustomBool `json:"tdf,omitempty" url:"tdf,omitempty,int"` - USBDevices CustomUSBDevices `json:"usb,omitempty" url:"usb,omitempty"` - VGADevice *CustomVGADevice `json:"vga,omitempty" url:"vga,omitempty"` - VirtualCPUCount *int `json:"vcpus,omitempty" url:"vcpus,omitempty"` - VirtualIODevices CustomVirtualIODevices `json:"virtio,omitempty" url:"virtio,omitempty"` - VMGenerationID *string `json:"vmgenid,omitempty" url:"vmgenid,omitempty"` - VMID int `json:"vmid" url:"vmid"` - VMStateDatastoreID *string `json:"vmstatestorage,omitempty" url:"vmstatestorage,omitempty"` - WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty" url:"watchdog,omitempty"` + ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"` + Agent *CustomAgent `json:"agent,omitempty" url:"agent,omitempty"` + AllocatedMemory *int `json:"memory,omitempty" url:"memory,omitempty"` + AllowReboot *CustomBool `json:"reboot,omitempty" url:"reboot,omitempty,int"` + AudioDevice *CustomAudioDevice `json:"audio0,omitempty" url:"audio0,omitempty"` + Autostart *CustomBool `json:"autostart,omitempty" url:"autostart,omitempty,int"` + BackupFile *string `json:"archive,omitempty" url:"archive,omitempty"` + BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"` + BIOS *string `json:"bios,omitempty" url:"bios,omitempty"` + BootDiskID *string `json:"bootdisk,omitempty" url:"bootdisk,omitempty"` + BootOrder *string `json:"boot,omitempty" url:"boot,omitempty"` + CDROM *string `json:"cdrom,omitempty" url:"cdrom,omitempty"` + CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,omitempty"` + CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"` + CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"` + CPULimit *int `json:"cpulimit,omitempty" url:"cpulimit,omitempty"` + CPUSockets *int `json:"sockets,omitempty" url:"sockets,omitempty"` + CPUUnits *int `json:"cpuunits,omitempty" url:"cpuunits,omitempty"` + DeletionProtection *CustomBool `json:"protection,omitempty" url:"force,omitempty,int"` + Description *string `json:"description,omitempty" url:"description,omitempty"` + EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty" url:"efidisk0,omitempty"` + FloatingMemory *int `json:"balloon,omitempty" url:"balloon,omitempty"` + FloatingMemoryShares *int `json:"shares,omitempty" url:"shares,omitempty"` + Freeze *CustomBool `json:"freeze,omitempty" url:"freeze,omitempty,int"` + HookScript *string `json:"hookscript,omitempty" url:"hookscript,omitempty"` + Hotplug CustomCommaSeparatedList `json:"hotplug,omitempty" url:"hotplug,omitempty,comma"` + Hugepages *string `json:"hugepages,omitempty" url:"hugepages,omitempty"` + IDEDevices CustomIDEDevices `json:"ide,omitempty" url:"ide,omitempty"` + KeyboardLayout *string `json:"keyboard,omitempty" url:"keyboard,omitempty"` + KVMArguments CustomLineBreakSeparatedList `json:"args,omitempty" url:"args,omitempty,space"` + KVMEnabled *CustomBool `json:"kvm,omitempty" url:"kvm,omitempty,int"` + LocalTime *CustomBool `json:"localtime,omitempty" url:"localtime,omitempty,int"` + Lock *string `json:"lock,omitempty" url:"lock,omitempty"` + MachineType *string `json:"machine,omitempty" url:"machine,omitempty"` + MigrateDowntime *float64 `json:"migrate_downtime,omitempty" url:"migrate_downtime,omitempty"` + MigrateSpeed *int `json:"migrate_speed,omitempty" url:"migrate_speed,omitempty"` + Name *string `json:"name,omitempty" url:"name,omitempty"` + NetworkDevices CustomNetworkDevices `json:"net,omitempty" url:"net,omitempty"` + NUMADevices CustomNUMADevices `json:"numa_devices,omitempty" url:"numa,omitempty"` + NUMAEnabled *CustomBool `json:"numa,omitempty" url:"numa,omitempty,int"` + OSType *string `json:"ostype,omitempty" url:"ostype,omitempty"` + Overwrite *CustomBool `json:"force,omitempty" url:"force,omitempty,int"` + PCIDevices CustomPCIDevices `json:"hostpci,omitempty" url:"hostpci,omitempty"` + Revert *string `json:"revert,omitempty" url:"revert,omitempty"` + SATADevices CustomSATADevices `json:"sata,omitempty" url:"sata,omitempty"` + SCSIDevices CustomSCSIDevices `json:"scsi,omitempty" url:"sata,omitempty"` + SCSIHardware *string `json:"scsihw,omitempty" url:"scsihw,omitempty"` + SerialDevices CustomSerialDevices `json:"serial,omitempty" url:"serial,omitempty"` + SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty" url:"ivshmem,omitempty"` + SkipLock *CustomBool `json:"skiplock,omitempty" url:"skiplock,omitempty,int"` + SMBIOS *CustomSMBIOS `json:"smbios1,omitempty" url:"smbios1,omitempty"` + SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty" url:"spice_enhancements,omitempty"` + StartDate *string `json:"startdate,omitempty" url:"startdate,omitempty"` + StartOnBoot *CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"` + StartupOrder *CustomStartupOrder `json:"startup,omitempty" url:"startup,omitempty"` + TabletDeviceEnabled *CustomBool `json:"tablet,omitempty" url:"tablet,omitempty,int"` + Tags *string `json:"tags,omitempty" url:"tags,omitempty"` + Template *CustomBool `json:"template,omitempty" url:"template,omitempty,int"` + TimeDriftFixEnabled *CustomBool `json:"tdf,omitempty" url:"tdf,omitempty,int"` + USBDevices CustomUSBDevices `json:"usb,omitempty" url:"usb,omitempty"` + VGADevice *CustomVGADevice `json:"vga,omitempty" url:"vga,omitempty"` + VirtualCPUCount *int `json:"vcpus,omitempty" url:"vcpus,omitempty"` + VirtualIODevices CustomVirtualIODevices `json:"virtio,omitempty" url:"virtio,omitempty"` + VMGenerationID *string `json:"vmgenid,omitempty" url:"vmgenid,omitempty"` + VMStateDatastoreID *string `json:"vmstatestorage,omitempty" url:"vmstatestorage,omitempty"` + WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty" url:"watchdog,omitempty"` } +// VirtualEnvironmentVMGetResponseBody contains the body from an virtual machine get response. +type VirtualEnvironmentVMGetResponseBody struct { + Data *VirtualEnvironmentVMGetResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentVMGetResponseData contains the data from an virtual machine get response. +type VirtualEnvironmentVMGetResponseData struct { + ACPI *CustomBool `json:"acpi,omitempty"` + Agent *CustomAgent `json:"agent,omitempty"` + AllocatedMemory *int `json:"memory,omitempty"` + AllowReboot *CustomBool `json:"reboot,omitempty"` + AudioDevice *CustomAudioDevice `json:"audio0,omitempty"` + Autostart *CustomBool `json:"autostart,omitempty"` + BackupFile *string `json:"archive,omitempty"` + BandwidthLimit *int `json:"bwlimit,omitempty"` + BIOS *string `json:"bios,omitempty"` + BootDiskID *string `json:"bootdisk,omitempty"` + BootOrder *string `json:"boot,omitempty"` + CDROM *string `json:"cdrom,omitempty"` + CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty"` + CPUArchitecture *string `json:"arch,omitempty"` + CPUCores *int `json:"cores,omitempty"` + CPULimit *int `json:"cpulimit,omitempty"` + CPUSockets *int `json:"sockets,omitempty"` + CPUUnits *int `json:"cpuunits,omitempty"` + DeletionProtection *CustomBool `json:"protection,omitempty"` + Description *string `json:"description,omitempty"` + EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty"` + FloatingMemory *int `json:"balloon,omitempty"` + FloatingMemoryShares *int `json:"shares,omitempty"` + Freeze *CustomBool `json:"freeze,omitempty"` + HookScript *string `json:"hookscript,omitempty"` + Hotplug *CustomCommaSeparatedList `json:"hotplug,omitempty"` + Hugepages *string `json:"hugepages,omitempty"` + IDEDevices *CustomIDEDevices `json:"ide,omitempty"` + KeyboardLayout *string `json:"keyboard,omitempty"` + KVMArguments *CustomLineBreakSeparatedList `json:"args,omitempty"` + KVMEnabled *CustomBool `json:"kvm,omitempty"` + LocalTime *CustomBool `json:"localtime,omitempty"` + Lock *string `json:"lock,omitempty"` + MachineType *string `json:"machine,omitempty"` + MigrateDowntime *float64 `json:"migrate_downtime,omitempty"` + MigrateSpeed *int `json:"migrate_speed,omitempty"` + Name *string `json:"name,omitempty"` + NetworkDevices *CustomNetworkDevices `json:"net,omitempty"` + NUMADevices *CustomNUMADevices `json:"numa_devices,omitempty"` + NUMAEnabled *CustomBool `json:"numa,omitempty"` + OSType *string `json:"ostype,omitempty"` + Overwrite *CustomBool `json:"force,omitempty"` + PCIDevices *CustomPCIDevices `json:"hostpci,omitempty"` + Revert *string `json:"revert,omitempty"` + SATADevices *CustomSATADevices `json:"sata,omitempty"` + SCSIDevices *CustomSCSIDevices `json:"scsi,omitempty"` + SCSIHardware *string `json:"scsihw,omitempty"` + SerialDevices *CustomSerialDevices `json:"serial,omitempty"` + SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty"` + SkipLock *CustomBool `json:"skiplock,omitempty"` + SMBIOS *CustomSMBIOS `json:"smbios1,omitempty"` + SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty"` + StartDate *string `json:"startdate,omitempty"` + StartOnBoot *CustomBool `json:"onboot,omitempty"` + StartupOrder *CustomStartupOrder `json:"startup,omitempty"` + TabletDeviceEnabled *CustomBool `json:"tablet,omitempty"` + Tags *string `json:"tags,omitempty"` + Template *CustomBool `json:"template,omitempty"` + TimeDriftFixEnabled *CustomBool `json:"tdf,omitempty"` + USBDevices *CustomUSBDevices `json:"usb,omitempty"` + VGADevice *CustomVGADevice `json:"vga,omitempty"` + VirtualCPUCount *int `json:"vcpus,omitempty"` + VirtualIODevices *CustomVirtualIODevices `json:"virtio,omitempty"` + VMGenerationID *string `json:"vmgenid,omitempty"` + VMStateDatastoreID *string `json:"vmstatestorage,omitempty"` + WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty"` +} + +// VirtualEnvironmentVMListResponseBody contains the body from an virtual machine list response. +type VirtualEnvironmentVMListResponseBody struct { + Data []*VirtualEnvironmentVMListResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentVMListResponseData contains the data from an virtual machine list response. +type VirtualEnvironmentVMListResponseData struct { + ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"` +} + +// VirtualEnvironmentVMUpdateRequestBody contains the data for an virtual machine update request. +type VirtualEnvironmentVMUpdateRequestBody VirtualEnvironmentVMCreateRequestBody + // EncodeValues converts a CustomAgent struct to a URL vlaue. func (r CustomAgent) EncodeValues(key string, v *url.Values) error { enabled := 0 diff --git a/proxmoxtf/resource_virtual_environment_file.go b/proxmoxtf/resource_virtual_environment_file.go index b53f27c3..9f47a584 100644 --- a/proxmoxtf/resource_virtual_environment_file.go +++ b/proxmoxtf/resource_virtual_environment_file.go @@ -5,6 +5,8 @@ package proxmoxtf import ( + "crypto/sha256" + "crypto/tls" "errors" "fmt" "io" @@ -22,6 +24,7 @@ import ( ) const ( + mkResourceVirtualEnvironmentFileContentType = "content_type" mkResourceVirtualEnvironmentFileDatastoreID = "datastore_id" mkResourceVirtualEnvironmentFileFileModificationDate = "file_modification_date" mkResourceVirtualEnvironmentFileFileName = "file_name" @@ -31,12 +34,20 @@ const ( mkResourceVirtualEnvironmentFileNodeName = "node_name" mkResourceVirtualEnvironmentFileSource = "source" mkResourceVirtualEnvironmentFileSourceChanged = "source_changed" - mkResourceVirtualEnvironmentFileTemplate = "template" + mkResourceVirtualEnvironmentFileSourceChecksum = "source_checksum" + mkResourceVirtualEnvironmentFileSourceInsecure = "source_insecure" ) func resourceVirtualEnvironmentFile() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ + mkResourceVirtualEnvironmentFileContentType: &schema.Schema{ + Type: schema.TypeString, + Description: "The content type", + Optional: true, + ForceNew: true, + Default: "", + }, mkResourceVirtualEnvironmentFileDatastoreID: &schema.Schema{ Type: schema.TypeString, Description: "The datastore id", @@ -81,7 +92,7 @@ func resourceVirtualEnvironmentFile() *schema.Resource { }, mkResourceVirtualEnvironmentFileSource: &schema.Schema{ Type: schema.TypeString, - Description: "The path to a file", + Description: "A path to a local file or a URL", Required: true, ForceNew: true, }, @@ -92,11 +103,19 @@ func resourceVirtualEnvironmentFile() *schema.Resource { ForceNew: true, Default: false, }, - mkResourceVirtualEnvironmentFileTemplate: &schema.Schema{ - Type: schema.TypeBool, - Description: "Whether this is a container template", - Required: true, + mkResourceVirtualEnvironmentFileSourceChecksum: &schema.Schema{ + Type: schema.TypeString, + Description: "The SHA256 checksum of the source file", + Optional: true, ForceNew: true, + Default: "", + }, + mkResourceVirtualEnvironmentFileSourceInsecure: &schema.Schema{ + Type: schema.TypeBool, + Description: "Whether to skip the TLS verification step for HTTPS sources", + Optional: true, + ForceNew: true, + Default: false, }, }, Create: resourceVirtualEnvironmentFileCreate, @@ -113,6 +132,12 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{}) return err } + contentType, err := resourceVirtualEnvironmentFileGetContentType(d, m) + + if err != nil { + return err + } + datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string) fileName, err := resourceVirtualEnvironmentFileGetFileName(d, m) @@ -122,14 +147,24 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{}) nodeName := d.Get(mkResourceVirtualEnvironmentFileNodeName).(string) source := d.Get(mkResourceVirtualEnvironmentFileSource).(string) - template := d.Get(mkResourceVirtualEnvironmentFileTemplate).(bool) + sourceChecksum := d.Get(mkResourceVirtualEnvironmentFileSourceChecksum).(string) + sourceInsecure := d.Get(mkResourceVirtualEnvironmentFileSourceInsecure).(bool) - var sourceReader io.Reader + sourceFile := "" + // Download the source file, if it's not available locally. if resourceVirtualEnvironmentFileIsURL(d, m) { log.Printf("[DEBUG] Downloading file from '%s'", source) - res, err := http.Get(source) + httpClient := http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: sourceInsecure, + }, + }, + } + + res, err := httpClient.Get(source) if err != nil { return err @@ -157,38 +192,53 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{}) defer os.Remove(tempDownloadedFileName) - file, err := os.Open(tempDownloadedFileName) - - if err != nil { - return err - } - - defer file.Close() - - sourceReader = file + sourceFile = tempDownloadedFileName } else { - file, err := os.Open(source) + sourceFile = source + } + + // Calculate the checksum of the source file now that it's available locally. + if sourceChecksum != "" { + file, err := os.Open(sourceFile) if err != nil { return err } - defer file.Close() + h := sha256.New() + _, err = io.Copy(h, file) - sourceReader = file + if err != nil { + file.Close() + + return err + } + + file.Close() + + calculatedChecksum := fmt.Sprintf("%x", h.Sum(nil)) + + log.Printf("[DEBUG] The calculated SHA256 checksum for source \"%s\" is \"%s\"", source, calculatedChecksum) + + if sourceChecksum != calculatedChecksum { + return fmt.Errorf("The calculated SHA256 checksum \"%s\" does not match source checksum \"%s\"", calculatedChecksum, sourceChecksum) + } } - contentType := "iso" + // Open the source file for reading in order to upload it. + file, err := os.Open(sourceFile) - if template { - contentType = "vztmpl" + if err != nil { + return err } + defer file.Close() + body := &proxmox.VirtualEnvironmentDatastoreUploadRequestBody{ - ContentType: contentType, + ContentType: *contentType, DatastoreID: datastoreID, FileName: *fileName, - FileReader: sourceReader, + FileReader: file, NodeName: nodeName, } @@ -209,6 +259,47 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{}) return resourceVirtualEnvironmentFileRead(d, m) } +func resourceVirtualEnvironmentFileGetContentType(d *schema.ResourceData, m interface{}) (*string, error) { + contentType := d.Get(mkResourceVirtualEnvironmentFileContentType).(string) + source := d.Get(mkResourceVirtualEnvironmentFileSource).(string) + supportedTypes := []string{"backup", "images", "iso", "vztmpl"} + + if contentType == "" { + if strings.HasSuffix(source, ".tar.xz") { + contentType = "vztmpl" + } else { + ext := strings.TrimLeft(strings.ToLower(filepath.Ext(source)), ".") + + switch ext { + case "img", "iso": + contentType = "iso" + } + } + + if contentType == "" { + return nil, fmt.Errorf( + "Cannot determine the content type of source \"%s\" - Please manually define the \"%s\" argument (supported: %s)", + source, + mkResourceVirtualEnvironmentFileContentType, + strings.Join(supportedTypes, " or "), + ) + } + } + + for _, v := range supportedTypes { + if v == contentType { + return &contentType, nil + } + } + + return nil, fmt.Errorf( + "Unsupported content type \"%s\" for source \"%s\" (supported: %s)", + contentType, + source, + strings.Join(supportedTypes, " or "), + ) +} + func resourceVirtualEnvironmentFileGetFileName(d *schema.ResourceData, m interface{}) (*string, error) { fileName := d.Get(mkResourceVirtualEnvironmentFileOverrideFileName).(string) source := d.Get(mkResourceVirtualEnvironmentFileSource).(string) @@ -236,7 +327,6 @@ func resourceVirtualEnvironmentFileGetFileName(d *schema.ResourceData, m interfa } func resourceVirtualEnvironmentFileGetVolumeID(d *schema.ResourceData, m interface{}) (*string, error) { - contentType := "iso" fileName, err := resourceVirtualEnvironmentFileGetFileName(d, m) if err != nil { @@ -244,13 +334,13 @@ func resourceVirtualEnvironmentFileGetVolumeID(d *schema.ResourceData, m interfa } datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string) - template := d.Get(mkResourceVirtualEnvironmentFileTemplate).(bool) + contentType, err := resourceVirtualEnvironmentFileGetContentType(d, m) - if template { - contentType = "vztmpl" + if err != nil { + return nil, err } - volumeID := fmt.Sprintf("%s:%s/%s", datastoreID, contentType, *fileName) + volumeID := fmt.Sprintf("%s:%s/%s", datastoreID, *contentType, *fileName) return &volumeID, nil } diff --git a/proxmoxtf/resource_virtual_environment_file_test.go b/proxmoxtf/resource_virtual_environment_file_test.go index 4c6fa457..415f0836 100644 --- a/proxmoxtf/resource_virtual_environment_file_test.go +++ b/proxmoxtf/resource_virtual_environment_file_test.go @@ -27,12 +27,14 @@ func TestResourceVirtualEnvironmentFileSchema(t *testing.T) { mkResourceVirtualEnvironmentFileDatastoreID, mkResourceVirtualEnvironmentFileNodeName, mkResourceVirtualEnvironmentFileSource, - mkResourceVirtualEnvironmentFileTemplate, }) testOptionalArguments(t, s, []string{ + mkResourceVirtualEnvironmentFileContentType, mkResourceVirtualEnvironmentFileOverrideFileName, mkResourceVirtualEnvironmentFileSourceChanged, + mkResourceVirtualEnvironmentFileSourceChecksum, + mkResourceVirtualEnvironmentFileSourceInsecure, }) testComputedAttributes(t, s, []string{ @@ -43,6 +45,7 @@ func TestResourceVirtualEnvironmentFileSchema(t *testing.T) { }) testSchemaValueTypes(t, s, []string{ + mkResourceVirtualEnvironmentFileContentType, mkResourceVirtualEnvironmentFileDatastoreID, mkResourceVirtualEnvironmentFileFileModificationDate, mkResourceVirtualEnvironmentFileFileName, @@ -52,17 +55,20 @@ func TestResourceVirtualEnvironmentFileSchema(t *testing.T) { mkResourceVirtualEnvironmentFileSourceChanged, mkResourceVirtualEnvironmentFileNodeName, mkResourceVirtualEnvironmentFileSource, - mkResourceVirtualEnvironmentFileTemplate, + mkResourceVirtualEnvironmentFileSourceChecksum, + mkResourceVirtualEnvironmentFileSourceInsecure, }, []schema.ValueType{ schema.TypeString, schema.TypeString, schema.TypeString, + schema.TypeString, schema.TypeInt, schema.TypeString, schema.TypeString, schema.TypeBool, schema.TypeString, schema.TypeString, + schema.TypeString, schema.TypeBool, }) }