0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-08-22 11:28:33 +00:00

file(file): handle remote file size check error in download_file resource (#1940)

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
Pavel Boldyrev 2025-05-01 23:17:17 -04:00 committed by GitHub
parent d5979c4b57
commit 37bdeccf9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 58 additions and 42 deletions

View File

@ -26,6 +26,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute" "github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
"github.com/bpg/terraform-provider-proxmox/fwprovider/config" "github.com/bpg/terraform-provider-proxmox/fwprovider/config"
@ -119,17 +120,29 @@ func (r sizeRequiresReplaceModifier) PlanModifyInt64(
} }
if state.Size.ValueInt64() != urlSize { if state.Size.ValueInt64() != urlSize {
resp.RequiresReplace = true if urlSize < 0 {
resp.PlanValue = types.Int64Value(urlSize) resp.Diagnostics.AddWarning(
"Could not read the file metadata from URL.",
fmt.Sprintf(
"The remote file at URL %q most likely doesnt exist or cant be accessed.\n"+
"To skip the remote file check, set `overwrite` to `false`.",
plan.URL.ValueString(),
),
)
} else {
resp.RequiresReplace = true
resp.PlanValue = types.Int64Value(urlSize)
resp.Diagnostics.AddWarning( resp.Diagnostics.AddWarning(
"The file size from url has changed.", "The file size from url has changed.",
fmt.Sprintf( fmt.Sprintf(
"Size from url %d does not match size from datastore: %d", "Size %d from url %q does not match size from datastore: %d",
urlSize, urlSize,
state.Size.ValueInt64(), plan.URL.ValueString(),
), state.Size.ValueInt64(),
) ),
)
}
return return
} }
@ -548,15 +561,13 @@ func (r *downloadFileResource) Read(
&state, &state,
) )
if err != nil { if err != nil {
resp.Diagnostics.AddError( tflog.Error(ctx, "Could not get file metadata from url", map[string]interface{}{
"Could not get file metadata from url.", "error": err,
err.Error(), "url": state.URL.ValueString(),
) })
// force size to -1, which is a special value used in sizeRequiresReplaceModifier
return resp.Private.SetKey(ctx, "url_size", []byte("-1"))
} } else if urlMetadata.Size != nil {
if urlMetadata.Size != nil {
setValue := []byte(strconv.FormatInt(*urlMetadata.Size, 10)) setValue := []byte(strconv.FormatInt(*urlMetadata.Size, 10))
resp.Private.SetKey(ctx, "url_size", setValue) resp.Private.SetKey(ctx, "url_size", setValue)
} }

View File

@ -28,6 +28,7 @@ import (
"github.com/bpg/terraform-provider-proxmox/proxmox/helpers/ptr" "github.com/bpg/terraform-provider-proxmox/proxmox/helpers/ptr"
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/storage" "github.com/bpg/terraform-provider-proxmox/proxmox/nodes/storage"
"github.com/bpg/terraform-provider-proxmox/proxmox/ssh" "github.com/bpg/terraform-provider-proxmox/proxmox/ssh"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
"github.com/bpg/terraform-provider-proxmox/utils" "github.com/bpg/terraform-provider-proxmox/utils"
) )
@ -163,6 +164,7 @@ func TestAccResourceDownloadFile(t *testing.T) {
Node: ptr.Ptr(te.NodeName), Node: ptr.Ptr(te.NodeName),
Storage: ptr.Ptr(te.DatastoreID), Storage: ptr.Ptr(te.DatastoreID),
URL: ptr.Ptr(fakeFileISO), URL: ptr.Ptr(fakeFileISO),
Verify: ptr.Ptr(types.CustomBool(false)),
}) })
require.NoError(t, err) require.NoError(t, err)

View File

@ -42,9 +42,9 @@ func TestAccResourceFile(t *testing.T) {
snippetRaw := fmt.Sprintf("snippet-raw-%s.txt", gofakeit.Word()) snippetRaw := fmt.Sprintf("snippet-raw-%s.txt", gofakeit.Word())
snippetURL := "https://raw.githubusercontent.com/yaml/yaml-test-suite/main/src/229Q.yaml" snippetURL := "https://raw.githubusercontent.com/yaml/yaml-test-suite/main/src/229Q.yaml"
snippetFile1 := strings.ReplaceAll(createFile(t, "snippet-file-1-*.yaml", "test snippet 1 - file").Name(), `\`, `/`) snippetFile1 := strings.ReplaceAll(CreateTempFile(t, "snippet-file-1-*.yaml", "test snippet 1 - file").Name(), `\`, `/`)
snippetFile2 := strings.ReplaceAll(createFile(t, "snippet-file-2-*.yaml", "test snippet 2 - file").Name(), `\`, `/`) snippetFile2 := strings.ReplaceAll(CreateTempFile(t, "snippet-file-2-*.yaml", "test snippet 2 - file").Name(), `\`, `/`)
fileISO := strings.ReplaceAll(createFile(t, "file-*.iso", "pretend it is an ISO").Name(), `\`, `/`) fileISO := strings.ReplaceAll(CreateTempFile(t, "file-*.iso", "pretend this is an ISO").Name(), `\`, `/`)
te.AddTemplateVars(map[string]interface{}{ te.AddTemplateVars(map[string]interface{}{
"SnippetRaw": snippetRaw, "SnippetRaw": snippetRaw,
@ -264,26 +264,6 @@ func uploadSnippetFile(t *testing.T, fileName string) {
require.NoError(t, err) require.NoError(t, err)
} }
func createFile(t *testing.T, namePattern string, content string) *os.File {
t.Helper()
f, err := os.CreateTemp("", namePattern)
require.NoError(t, err)
_, err = f.WriteString(content)
require.NoError(t, err)
defer func(f *os.File) {
_ = f.Close()
}(f)
t.Cleanup(func() {
_ = os.Remove(f.Name())
})
return f
}
func deleteSnippet(te *Environment, fname string) { func deleteSnippet(te *Environment, fname string) {
te.t.Helper() te.t.Helper()

View File

@ -8,10 +8,13 @@ package test
import ( import (
"fmt" "fmt"
"os"
"regexp" "regexp"
"testing"
"github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/stretchr/testify/require"
) )
// ResourceAttributes is a helper function to test resource attributes. // ResourceAttributes is a helper function to test resource attributes.
@ -69,3 +72,23 @@ func ResourceAttributesSet(res string, attrs []string) resource.TestCheckFunc {
return nil return nil
} }
} }
func CreateTempFile(t *testing.T, namePattern string, content string) *os.File {
t.Helper()
f, err := os.CreateTemp(t.TempDir(), namePattern)
require.NoError(t, err)
_, err = f.WriteString(content)
require.NoError(t, err)
defer func(f *os.File) {
_ = f.Close()
}(f)
t.Cleanup(func() {
_ = os.Remove(f.Name())
})
return f
}