From 44e2814adf69588e219c522fa415fa38cef9dc3a Mon Sep 17 00:00:00 2001 From: Pavel Boldyrev <627562+bpg@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:02:25 -0400 Subject: [PATCH] =?UTF-8?q?fix(file):=20respect=20`download=5Ffile.overrid?= =?UTF-8?q?e`=20attr=20when=20checking=20for=20th=E2=80=A6=20(#1537)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(file): respect `download_file.override` attr when checking for the file size change during update Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com> --- .../network/resource_linux_vlan_test.go | 2 +- fwprovider/resource_download_file.go | 8 +- fwprovider/resource_download_file_test.go | 123 +++++++++++++++++- 3 files changed, 125 insertions(+), 8 deletions(-) diff --git a/fwprovider/network/resource_linux_vlan_test.go b/fwprovider/network/resource_linux_vlan_test.go index c31e4411..adfd2db7 100644 --- a/fwprovider/network/resource_linux_vlan_test.go +++ b/fwprovider/network/resource_linux_vlan_test.go @@ -26,7 +26,7 @@ const ( func TestAccResourceLinuxVLAN(t *testing.T) { te := test.InitEnvironment(t) - iface := "enp1s0" + iface := "ens18" vlan1 := gofakeit.Number(10, 4094) customName := fmt.Sprintf("iface_%s", gofakeit.Word()) vlan2 := gofakeit.Number(10, 4094) diff --git a/fwprovider/resource_download_file.go b/fwprovider/resource_download_file.go index 2be3c909..872acbd0 100644 --- a/fwprovider/resource_download_file.go +++ b/fwprovider/resource_download_file.go @@ -42,10 +42,6 @@ var ( httpRegex = regexp.MustCompile(`https?://.*`) ) -func sizeRequiresReplace() planmodifier.Int64 { - return sizeRequiresReplaceModifier{} -} - type sizeRequiresReplaceModifier struct{} func (r sizeRequiresReplaceModifier) PlanModifyInt64( @@ -86,7 +82,7 @@ func (r sizeRequiresReplaceModifier) PlanModifyInt64( return } - if state.Size.ValueInt64() != originalStateSize { + if state.Size.ValueInt64() != originalStateSize && plan.Overwrite.ValueBool() { resp.RequiresReplace = true resp.PlanValue = types.Int64Value(originalStateSize) @@ -239,7 +235,7 @@ func (r *downloadFileResource) Schema( PlanModifiers: []planmodifier.Int64{ int64planmodifier.UseStateForUnknown(), int64planmodifier.RequiresReplace(), - sizeRequiresReplace(), + sizeRequiresReplaceModifier{}, }, }, "upload_timeout": schema.Int64Attribute{ diff --git a/fwprovider/resource_download_file_test.go b/fwprovider/resource_download_file_test.go index 45effc86..b451a2ef 100644 --- a/fwprovider/resource_download_file_test.go +++ b/fwprovider/resource_download_file_test.go @@ -10,15 +10,24 @@ package fwprovider_test import ( "context" + "net/url" + "os" + "path" + "path/filepath" + "strings" "testing" "time" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/stretchr/testify/require" "github.com/bpg/terraform-provider-proxmox/fwprovider/test" + "github.com/bpg/terraform-provider-proxmox/proxmox/api" "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/ssh" + "github.com/bpg/terraform-provider-proxmox/utils" ) const ( @@ -128,7 +137,8 @@ func TestAccResourceDownloadFile(t *testing.T) { ), }, }}, - {"override unmanaged file", []resource.TestStep{{ + {"override file", []resource.TestStep{{ + Destroy: false, PreConfig: func() { ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() @@ -157,6 +167,7 @@ func TestAccResourceDownloadFile(t *testing.T) { url = "{{.FakeFileISO}}" file_name = "fake_iso_file3.iso" overwrite_unmanaged = true + overwrite = false }`), Check: resource.ComposeTestCheckFunc( test.ResourceAttributes("proxmox_virtual_environment_download_file.iso_image3", map[string]string{ @@ -175,6 +186,47 @@ func TestAccResourceDownloadFile(t *testing.T) { "decompression_algorithm", }), ), + }, { + Destroy: false, + PreConfig: func() { + isoFile := strings.ReplaceAll(createFile(t, "fake_iso_file3.iso", "updated iso").Name(), `\`, `/`) + uploadIsoFile(t, isoFile) + }, + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_download_file" "iso_image3" { + content_type = "iso" + node_name = "{{.NodeName}}" + datastore_id = "{{.DatastoreID}}" + url = "{{.FakeFileISO}}" + file_name = "fake_iso_file3.iso" + overwrite_unmanaged = true + overwrite = false + }`), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectEmptyPlan(), + }, + }, + }, { + PreConfig: func() { + isoFile := strings.ReplaceAll(createFile(t, "fake_iso_file3.iso", "updated iso again").Name(), `\`, `/`) + uploadIsoFile(t, isoFile) + }, + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_download_file" "iso_image3" { + content_type = "iso" + node_name = "{{.NodeName}}" + datastore_id = "{{.DatastoreID}}" + url = "{{.FakeFileISO}}" + file_name = "fake_iso_file3.iso" + overwrite_unmanaged = true + overwrite = true + }`), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("proxmox_virtual_environment_download_file.iso_image3", plancheck.ResourceActionDestroyBeforeCreate), + }, + }, }}}, } @@ -187,3 +239,72 @@ func TestAccResourceDownloadFile(t *testing.T) { }) } } + +func uploadIsoFile(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/template", + &api.FileUploadRequest{ + ContentType: "iso", + FileName: fname, + File: f, + }) + require.NoError(t, err) +} + +type nodeResolver struct { + node ssh.ProxmoxNode +} + +func (c *nodeResolver) Resolve(_ context.Context, _ string) (ssh.ProxmoxNode, error) { + return c.node, nil +} + +func createFile(t *testing.T, namePattern string, content string) *os.File { + t.Helper() + + f, err := os.Create(path.Join(os.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 +}