mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-30 18:42:58 +00:00
Initial work on file resource
This commit is contained in:
parent
1921fc0531
commit
e2541de215
@ -13,6 +13,7 @@ FEATURES:
|
|||||||
* **New Data Source:** `proxmox_virtual_environment_user`
|
* **New Data Source:** `proxmox_virtual_environment_user`
|
||||||
* **New Data Source:** `proxmox_virtual_environment_users`
|
* **New Data Source:** `proxmox_virtual_environment_users`
|
||||||
* **New Data Source:** `proxmox_virtual_environment_version`
|
* **New Data Source:** `proxmox_virtual_environment_version`
|
||||||
|
* **New Resource:** `proxmox_virtual_environment_file`
|
||||||
* **New Resource:** `proxmox_virtual_environment_group`
|
* **New Resource:** `proxmox_virtual_environment_group`
|
||||||
* **New Resource:** `proxmox_virtual_environment_pool`
|
* **New Resource:** `proxmox_virtual_environment_pool`
|
||||||
* **New Resource:** `proxmox_virtual_environment_role`
|
* **New Resource:** `proxmox_virtual_environment_role`
|
||||||
|
12
README.md
12
README.md
@ -181,6 +181,18 @@ This data source doesn't accept arguments.
|
|||||||
|
|
||||||
#### Virtual Environment
|
#### Virtual Environment
|
||||||
|
|
||||||
|
##### File (proxmox_virtual_environment_file)
|
||||||
|
|
||||||
|
###### Arguments
|
||||||
|
* `datastore_id` - (Required) The datastore id
|
||||||
|
* `file_name` - (Optional) The file name to use in the datastore (leave undefined to use source file name)
|
||||||
|
* `node_name` - (Required) The node name
|
||||||
|
* `source` - (Required) A path to a file
|
||||||
|
* `template` - (Required) Whether this is a container template
|
||||||
|
|
||||||
|
###### Attributes
|
||||||
|
This resource doesn't expose any additional attributes.
|
||||||
|
|
||||||
##### Group (proxmox_virtual_environment_group)
|
##### Group (proxmox_virtual_environment_group)
|
||||||
|
|
||||||
###### Arguments
|
###### Arguments
|
||||||
|
@ -42,9 +42,10 @@ func dataSourceVirtualEnvironmentDatastores() *schema.Resource {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mkDataSourceVirtualEnvironmentDatastoresDatastoreIDs: &schema.Schema{
|
mkDataSourceVirtualEnvironmentDatastoresDatastoreIDs: &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeList,
|
||||||
Description: "The datastore id",
|
Description: "The datastore id",
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
},
|
},
|
||||||
mkDataSourceVirtualEnvironmentDatastoresEnabled: &schema.Schema{
|
mkDataSourceVirtualEnvironmentDatastoresEnabled: &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
@ -54,7 +55,7 @@ func dataSourceVirtualEnvironmentDatastores() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkDataSourceVirtualEnvironmentDatastoresNodeName: &schema.Schema{
|
mkDataSourceVirtualEnvironmentDatastoresNodeName: &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Description: "The node id",
|
Description: "The node name",
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
mkDataSourceVirtualEnvironmentDatastoresShared: &schema.Schema{
|
mkDataSourceVirtualEnvironmentDatastoresShared: &schema.Schema{
|
||||||
|
BIN
example/assets/alpine-3.10-default_20190626_amd64.tar.xz
Normal file
BIN
example/assets/alpine-3.10-default_20190626_amd64.tar.xz
Normal file
Binary file not shown.
6
example/resource_virtual_environment_file.tf
Normal file
6
example/resource_virtual_environment_file.tf
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
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 = "${path.module}/assets/alpine-3.10-default_20190626_amd64.tar.xz"
|
||||||
|
template = true
|
||||||
|
}
|
@ -41,6 +41,7 @@ func Provider() *schema.Provider {
|
|||||||
"proxmox_virtual_environment_version": dataSourceVirtualEnvironmentVersion(),
|
"proxmox_virtual_environment_version": dataSourceVirtualEnvironmentVersion(),
|
||||||
},
|
},
|
||||||
ResourcesMap: map[string]*schema.Resource{
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
|
"proxmox_virtual_environment_file": resourceVirtualEnvironmentFile(),
|
||||||
"proxmox_virtual_environment_group": resourceVirtualEnvironmentGroup(),
|
"proxmox_virtual_environment_group": resourceVirtualEnvironmentGroup(),
|
||||||
"proxmox_virtual_environment_pool": resourceVirtualEnvironmentPool(),
|
"proxmox_virtual_environment_pool": resourceVirtualEnvironmentPool(),
|
||||||
"proxmox_virtual_environment_role": resourceVirtualEnvironmentRole(),
|
"proxmox_virtual_environment_role": resourceVirtualEnvironmentRole(),
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -38,6 +39,12 @@ type VirtualEnvironmentClient struct {
|
|||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VirtualEnvironmentMultiPartData enables multipart uploads in DoRequest.
|
||||||
|
type VirtualEnvironmentMultiPartData struct {
|
||||||
|
Boundary string
|
||||||
|
Reader io.Reader
|
||||||
|
}
|
||||||
|
|
||||||
// NewVirtualEnvironmentClient creates and initializes a VirtualEnvironmentClient instance.
|
// NewVirtualEnvironmentClient creates and initializes a VirtualEnvironmentClient instance.
|
||||||
func NewVirtualEnvironmentClient(endpoint, username, password string, insecure bool) (*VirtualEnvironmentClient, error) {
|
func NewVirtualEnvironmentClient(endpoint, username, password string, insecure bool) (*VirtualEnvironmentClient, error) {
|
||||||
url, err := url.ParseRequestURI(endpoint)
|
url, err := url.ParseRequestURI(endpoint)
|
||||||
@ -77,20 +84,36 @@ func NewVirtualEnvironmentClient(endpoint, username, password string, insecure b
|
|||||||
|
|
||||||
// DoRequest performs a HTTP request against a JSON API endpoint.
|
// DoRequest performs a HTTP request against a JSON API endpoint.
|
||||||
func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody interface{}, responseBody interface{}) error {
|
func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody interface{}, responseBody interface{}) error {
|
||||||
|
var reqBodyReader io.Reader
|
||||||
|
|
||||||
log.Printf("[DEBUG] Performing HTTP %s request (path: %s)", method, path)
|
log.Printf("[DEBUG] Performing HTTP %s request (path: %s)", method, path)
|
||||||
|
|
||||||
modifiedPath := path
|
modifiedPath := path
|
||||||
urlEncodedRequestBody := new(bytes.Buffer)
|
reqBodyType := ""
|
||||||
|
|
||||||
if requestBody != nil {
|
if requestBody != nil {
|
||||||
|
multipartData, multipart := requestBody.(*VirtualEnvironmentMultiPartData)
|
||||||
|
pipedBodyReader, pipedBody := requestBody.(*io.PipeReader)
|
||||||
|
|
||||||
|
if multipart {
|
||||||
|
reqBodyReader = multipartData.Reader
|
||||||
|
reqBodyType = fmt.Sprintf("multipart/form-data; boundary=%s", multipartData.Boundary)
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Added multipart request body to HTTP %s request (path: %s)", method, modifiedPath)
|
||||||
|
} else if pipedBody {
|
||||||
|
reqBodyReader = pipedBodyReader
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Added piped request body to HTTP %s request (path: %s)", method, modifiedPath)
|
||||||
|
} else {
|
||||||
v, err := query.Values(requestBody)
|
v, err := query.Values(requestBody)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to encode HTTP %s request (path: %s) - Reason: %s", method, path, err.Error())
|
return fmt.Errorf("Failed to encode HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
encodedValues := v.Encode()
|
encodedValues := v.Encode()
|
||||||
|
|
||||||
|
if encodedValues != "" {
|
||||||
if method == hmGET || method == hmHEAD {
|
if method == hmGET || method == hmHEAD {
|
||||||
if !strings.Contains(modifiedPath, "?") {
|
if !strings.Contains(modifiedPath, "?") {
|
||||||
modifiedPath = fmt.Sprintf("%s?%s", modifiedPath, encodedValues)
|
modifiedPath = fmt.Sprintf("%s?%s", modifiedPath, encodedValues)
|
||||||
@ -98,22 +121,27 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
|
|||||||
modifiedPath = fmt.Sprintf("%s&%s", modifiedPath, encodedValues)
|
modifiedPath = fmt.Sprintf("%s&%s", modifiedPath, encodedValues)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
urlEncodedRequestBody = bytes.NewBufferString(encodedValues)
|
reqBodyReader = bytes.NewBufferString(encodedValues)
|
||||||
|
reqBodyType = "application/x-www-form-urlencoded"
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] Added request body to HTTP %s request (path: %s) - Body: %s", method, path, encodedValues)
|
log.Printf("[DEBUG] Added request body to HTTP %s request (path: %s) - Body: %s", method, modifiedPath, encodedValues)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reqBodyReader = new(bytes.Buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(method, fmt.Sprintf("%s/%s/%s", c.Endpoint, basePathJSONAPI, modifiedPath), urlEncodedRequestBody)
|
req, err := http.NewRequest(method, fmt.Sprintf("%s/%s/%s", c.Endpoint, basePathJSONAPI, modifiedPath), reqBodyReader)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create HTTP %s request (path: %s) - Reason: %s", method, path, err.Error())
|
return fmt.Errorf("Failed to create HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Add("Accept", "application/json")
|
req.Header.Add("Accept", "application/json")
|
||||||
|
|
||||||
if req.Method != hmGET && req.Method != hmHEAD {
|
if reqBodyType != "" {
|
||||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Add("Content-Type", reqBodyType)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.AuthenticateRequest(req)
|
err = c.AuthenticateRequest(req)
|
||||||
@ -125,7 +153,7 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
|
|||||||
res, err := c.httpClient.Do(req)
|
res, err := c.httpClient.Do(req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to perform HTTP %s request (path: %s) - Reason: %s", method, path, err.Error())
|
return fmt.Errorf("Failed to perform HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.ValidateResponseCode(res)
|
err = c.ValidateResponseCode(res)
|
||||||
@ -138,7 +166,7 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
|
|||||||
err = json.NewDecoder(res.Body).Decode(responseBody)
|
err = json.NewDecoder(res.Body).Decode(responseBody)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to decode HTTP %s response (path: %s) - Reason: %s", method, path, err.Error())
|
return fmt.Errorf("Failed to decode HTTP %s response (path: %s) - Reason: %s", method, modifiedPath, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +178,7 @@ func (c *VirtualEnvironmentClient) ValidateResponseCode(res *http.Response) erro
|
|||||||
if res.StatusCode < 200 || res.StatusCode >= 300 {
|
if res.StatusCode < 200 || res.StatusCode >= 300 {
|
||||||
switch res.StatusCode {
|
switch res.StatusCode {
|
||||||
case 400:
|
case 400:
|
||||||
return fmt.Errorf("Received a HTTP %d response - This is most likely caused by a bug in the code, so please create a new issue on https://github.com/danitso/terraform-provider-proxmox/issues", res.StatusCode)
|
return fmt.Errorf("Received a HTTP %d response - Reason: %s", res.StatusCode, res.Status)
|
||||||
case 401:
|
case 401:
|
||||||
return fmt.Errorf("Received a HTTP %d response - Please verify that the specified credentials are valid", res.StatusCode)
|
return fmt.Errorf("Received a HTTP %d response - Please verify that the specified credentials are valid", res.StatusCode)
|
||||||
case 403:
|
case 403:
|
||||||
|
@ -5,8 +5,11 @@
|
|||||||
package proxmox
|
package proxmox
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"mime/multipart"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,7 +27,7 @@ type VirtualEnvironmentDatastoreListResponseBody struct {
|
|||||||
Data []*VirtualEnvironmentDatastoreListResponseData `json:"data,omitempty"`
|
Data []*VirtualEnvironmentDatastoreListResponseData `json:"data,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// VirtualEnvironmentDatastoreListResponseData contains the data from a node list response.
|
// VirtualEnvironmentDatastoreListResponseData contains the data from a datastore list response.
|
||||||
type VirtualEnvironmentDatastoreListResponseData struct {
|
type VirtualEnvironmentDatastoreListResponseData struct {
|
||||||
Active *CustomBool `json:"active,omitempty"`
|
Active *CustomBool `json:"active,omitempty"`
|
||||||
ContentTypes *CustomCommaSeparatedList `json:"content,omitempty"`
|
ContentTypes *CustomCommaSeparatedList `json:"content,omitempty"`
|
||||||
@ -38,6 +41,20 @@ type VirtualEnvironmentDatastoreListResponseData struct {
|
|||||||
Type string `json:"type,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"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListDatastores retrieves a list of nodes.
|
// ListDatastores retrieves a list of nodes.
|
||||||
func (c *VirtualEnvironmentClient) ListDatastores(nodeName string, d *VirtualEnvironmentDatastoreListRequestBody) ([]*VirtualEnvironmentDatastoreListResponseData, error) {
|
func (c *VirtualEnvironmentClient) ListDatastores(nodeName string, d *VirtualEnvironmentDatastoreListRequestBody) ([]*VirtualEnvironmentDatastoreListResponseData, error) {
|
||||||
resBody := &VirtualEnvironmentDatastoreListResponseBody{}
|
resBody := &VirtualEnvironmentDatastoreListResponseBody{}
|
||||||
@ -57,3 +74,47 @@ func (c *VirtualEnvironmentClient) ListDatastores(nodeName string, d *VirtualEnv
|
|||||||
|
|
||||||
return resBody.Data, nil
|
return resBody.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UploadFileToDatastore uploads a file to a datastore.
|
||||||
|
func (c *VirtualEnvironmentClient) UploadFileToDatastore(d *VirtualEnvironmentDatastoreUploadRequestBody) (*VirtualEnvironmentDatastoreUploadResponseBody, error) {
|
||||||
|
r, w := io.Pipe()
|
||||||
|
m := multipart.NewWriter(w)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer w.Close()
|
||||||
|
defer m.Close()
|
||||||
|
|
||||||
|
m.WriteField("content", d.ContentType)
|
||||||
|
|
||||||
|
part, err := m.CreateFormFile("filename", d.FileName)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(part, d.FileReader)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Due to Proxmox VE not supporting chunked transfers, we sadly need to load the file into memory.
|
||||||
|
// This is not optimal for large files but there's no alternative right now.
|
||||||
|
workaroundReader := new(bytes.Buffer)
|
||||||
|
workaroundReader.ReadFrom(r)
|
||||||
|
|
||||||
|
reqBody := &VirtualEnvironmentMultiPartData{
|
||||||
|
Boundary: m.Boundary(),
|
||||||
|
Reader: workaroundReader,
|
||||||
|
}
|
||||||
|
|
||||||
|
resBody := &VirtualEnvironmentDatastoreUploadResponseBody{}
|
||||||
|
err := c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/storage/%s/upload", d.NodeName, d.DatastoreID), reqBody, resBody)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resBody, nil
|
||||||
|
}
|
||||||
|
142
resource_virtual_environment_file.go
Normal file
142
resource_virtual_environment_file.go
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/* 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 (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/danitso/terraform-provider-proxmox/proxmox"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
mkResourceVirtualEnvironmentFileDatastoreID = "datastore_id"
|
||||||
|
mkResourceVirtualEnvironmentFileFileName = "file_name"
|
||||||
|
mkResourceVirtualEnvironmentFileNodeName = "node_name"
|
||||||
|
mkResourceVirtualEnvironmentFileSource = "source"
|
||||||
|
mkResourceVirtualEnvironmentFileTemplate = "template"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceVirtualEnvironmentFile() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentFileDatastoreID: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The datastore id",
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentFileFileName: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The file name to use in the datastore",
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Default: "",
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentFileNodeName: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The node name",
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentFileSource: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The path to a file",
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentFileTemplate: &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Description: "Whether this is a container template",
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Create: resourceVirtualEnvironmentFileCreate,
|
||||||
|
Read: resourceVirtualEnvironmentFileRead,
|
||||||
|
Delete: resourceVirtualEnvironmentFileDelete,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{}) error {
|
||||||
|
config := m.(providerConfiguration)
|
||||||
|
veClient, err := config.GetVEClient()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string)
|
||||||
|
fileName := d.Get(mkResourceVirtualEnvironmentFileFileName).(string)
|
||||||
|
nodeName := d.Get(mkResourceVirtualEnvironmentFileNodeName).(string)
|
||||||
|
source := d.Get(mkResourceVirtualEnvironmentFileSource).(string)
|
||||||
|
template := d.Get(mkResourceVirtualEnvironmentFileTemplate).(bool)
|
||||||
|
|
||||||
|
if fileName == "" {
|
||||||
|
fileName = filepath.Base(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(source)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
contentType := "iso"
|
||||||
|
|
||||||
|
if template {
|
||||||
|
contentType = "vztmpl"
|
||||||
|
}
|
||||||
|
|
||||||
|
body := &proxmox.VirtualEnvironmentDatastoreUploadRequestBody{
|
||||||
|
ContentType: contentType,
|
||||||
|
DatastoreID: datastoreID,
|
||||||
|
FileName: fileName,
|
||||||
|
FileReader: file,
|
||||||
|
NodeName: nodeName,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = veClient.UploadFileToDatastore(body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(fmt.Sprintf("%s:%s:%s", nodeName, datastoreID, fileName))
|
||||||
|
|
||||||
|
return resourceVirtualEnvironmentFileRead(d, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualEnvironmentFileRead(d *schema.ResourceData, m interface{}) error {
|
||||||
|
/*
|
||||||
|
config := m.(providerConfiguration)
|
||||||
|
veClient, err := config.GetVEClient()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualEnvironmentFileDelete(d *schema.ResourceData, m interface{}) error {
|
||||||
|
/*
|
||||||
|
config := m.(providerConfiguration)
|
||||||
|
veClient, err := config.GetVEClient()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
d.SetId("")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
35
resource_virtual_environment_file_test.go
Normal file
35
resource_virtual_environment_file_test.go
Normal file
@ -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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestResourceVirtualEnvironmentFileInstantiation tests whether the ResourceVirtualEnvironmentFile instance can be instantiated.
|
||||||
|
func TestResourceVirtualEnvironmentFileInstantiation(t *testing.T) {
|
||||||
|
s := resourceVirtualEnvironmentFile()
|
||||||
|
|
||||||
|
if s == nil {
|
||||||
|
t.Fatalf("Cannot instantiate resourceVirtualEnvironmentFile")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestResourceVirtualEnvironmentFileSchema tests the resourceVirtualEnvironmentFile schema.
|
||||||
|
func TestResourceVirtualEnvironmentFileSchema(t *testing.T) {
|
||||||
|
s := resourceVirtualEnvironmentFile()
|
||||||
|
|
||||||
|
attributeKeys := []string{}
|
||||||
|
|
||||||
|
for _, v := range attributeKeys {
|
||||||
|
if s.Schema[v] == nil {
|
||||||
|
t.Fatalf("Error in resourceVirtualEnvironmentFile.Schema: Missing attribute \"%s\"", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Schema[v].Computed != true {
|
||||||
|
t.Fatalf("Error in resourceVirtualEnvironmentFile.Schema: Attribute \"%s\" is not computed", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user