0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 02:31:10 +00:00
terraform-provider-proxmox/fwprovider/test/resource_file_test.go
Pavel Boldyrev 37bdeccf9b
file(file): handle remote file size check error in download_file resource (#1940)
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
2025-05-01 23:17:17 -04:00

273 lines
7.7 KiB
Go

//go:build acceptance || all
/*
* 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 test
import (
"context"
"fmt"
"net/url"
"os"
"path/filepath"
"regexp"
"strings"
"testing"
"github.com/brianvoe/gofakeit/v7"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/stretchr/testify/require"
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
"github.com/bpg/terraform-provider-proxmox/proxmox/ssh"
"github.com/bpg/terraform-provider-proxmox/utils"
)
type nodeResolver struct {
node ssh.ProxmoxNode
}
func (c *nodeResolver) Resolve(_ context.Context, _ string) (ssh.ProxmoxNode, error) {
return c.node, nil
}
func TestAccResourceFile(t *testing.T) {
te := InitEnvironment(t)
snippetRaw := fmt.Sprintf("snippet-raw-%s.txt", gofakeit.Word())
snippetURL := "https://raw.githubusercontent.com/yaml/yaml-test-suite/main/src/229Q.yaml"
snippetFile1 := strings.ReplaceAll(CreateTempFile(t, "snippet-file-1-*.yaml", "test snippet 1 - file").Name(), `\`, `/`)
snippetFile2 := strings.ReplaceAll(CreateTempFile(t, "snippet-file-2-*.yaml", "test snippet 2 - file").Name(), `\`, `/`)
fileISO := strings.ReplaceAll(CreateTempFile(t, "file-*.iso", "pretend this is an ISO").Name(), `\`, `/`)
te.AddTemplateVars(map[string]interface{}{
"SnippetRaw": snippetRaw,
"SnippetURL": snippetURL,
"SnippetFile1": snippetFile1,
"SnippetFile2": snippetFile2,
"FileISO": fileISO,
})
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: te.AccProviders,
PreCheck: func() {
uploadSnippetFile(t, snippetFile2)
t.Cleanup(func() {
deleteSnippet(te, filepath.Base(snippetFile1))
deleteSnippet(te, filepath.Base(snippetFile2))
_ = os.Remove(snippetFile1)
_ = os.Remove(snippetFile2)
_ = os.Remove(fileISO)
})
},
Steps: []resource.TestStep{
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_file" "test_raw" {
content_type = "snippets"
datastore_id = "local"
node_name = "{{.NodeName}}"
source_raw {
data = <<EOF
test snippet
EOF
file_name = "{{.SnippetRaw}}"
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_file.test_raw", map[string]string{
"content_type": "snippets",
"file_name": snippetRaw,
"source_raw.0.file_name": snippetRaw,
"source_raw.0.data": "test snippet\n",
"id": fmt.Sprintf("local:snippets/%s", snippetRaw),
}),
},
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_file {
path = "{{.SnippetFile1}}"
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_file.test", map[string]string{
"content_type": "snippets",
"file_name": filepath.Base(snippetFile1),
"id": fmt.Sprintf("local:snippets/%s", filepath.Base(snippetFile1)),
}),
},
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_file {
path = "{{.SnippetURL}}"
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_file.test", map[string]string{
"content_type": "snippets",
"file_name": filepath.Base(snippetURL),
"id": fmt.Sprintf("local:snippets/%s", filepath.Base(snippetURL)),
}),
},
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_file {
path = "{{.FileISO}}"
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_file.test", map[string]string{
"content_type": "iso",
"file_name": filepath.Base(fileISO),
"id": fmt.Sprintf("local:iso/%s", filepath.Base(fileISO)),
}),
},
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_raw {
data = <<EOF
test snippet
EOF
file_name = "foo.yaml"
}
source_file {
path = "bar.yaml"
}
}`),
ExpectError: regexp.MustCompile("please specify .* - not both"),
},
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
content_type = "iso"
source_file {
path = "https://github.com"
}
}`),
ExpectError: regexp.MustCompile("failed to determine file name from the URL"),
},
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
}`),
ExpectError: regexp.MustCompile("missing argument"),
},
// Do not allow to overwrite the file
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
overwrite = false
source_file {
path = "{{.SnippetFile2}}"
}
}`),
ExpectError: regexp.MustCompile("already exists"),
},
// Allow to overwrite the file by default
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_file {
path = "{{.SnippetFile2}}"
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_file.test", map[string]string{
"content_type": "snippets",
"file_name": filepath.Base(snippetFile2),
"id": fmt.Sprintf("local:snippets/%s", filepath.Base(snippetFile2)),
}),
},
// Update testing
{
PreConfig: func() {
deleteSnippet(te, filepath.Base(snippetFile1))
},
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_file {
path = "{{.SnippetFile1}}"
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_file.test", map[string]string{
"content_type": "snippets",
"file_name": filepath.Base(snippetFile1),
"id": fmt.Sprintf("local:snippets/%s", filepath.Base(snippetFile1)),
}),
},
},
})
}
func uploadSnippetFile(t *testing.T, fileName string) {
t.Helper()
endpoint := utils.GetAnyStringEnv("PROXMOX_VE_ENDPOINT")
u, err := url.ParseRequestURI(endpoint)
require.NoError(t, err)
sshAgent := utils.GetAnyBoolEnv("PROXMOX_VE_SSH_AGENT")
sshUsername := utils.GetAnyStringEnv("PROXMOX_VE_SSH_USERNAME")
sshAgentSocket := utils.GetAnyStringEnv("SSH_AUTH_SOCK", "PROXMOX_VE_SSH_AUTH_SOCK")
sshPrivateKey := utils.GetAnyStringEnv("PROXMOX_VE_SSH_PRIVATE_KEY")
sshPort := utils.GetAnyIntEnv("PROXMOX_VE_ACC_NODE_SSH_PORT")
sshClient, err := ssh.NewClient(
sshUsername, "", sshAgent, sshAgentSocket, sshPrivateKey,
"", "", "",
&nodeResolver{
node: ssh.ProxmoxNode{
Address: u.Hostname(),
Port: int32(sshPort),
},
},
)
require.NoError(t, err)
f, err := os.Open(fileName)
require.NoError(t, err)
defer func(f *os.File) {
_ = f.Close()
}(f)
fname := filepath.Base(fileName)
err = sshClient.NodeStreamUpload(context.Background(), "pve", "/var/lib/vz/",
&api.FileUploadRequest{
ContentType: "snippets",
FileName: fname,
File: f,
})
require.NoError(t, err)
}
func deleteSnippet(te *Environment, fname string) {
te.t.Helper()
err := te.NodeStorageClient().DeleteDatastoreFile(context.Background(), fmt.Sprintf("snippets/%s", fname))
require.NoError(te.t, err)
}