0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 02:31:10 +00:00

fix(vm): prevent cloud-init password reset to ********** during update (#1864)

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
Pavel Boldyrev 2025-03-29 13:52:08 -04:00 committed by GitHub
parent c9fcb30762
commit 4f522ec342
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 54 additions and 12 deletions

View File

@ -488,11 +488,9 @@ func TestAccResourceVMInitialization(t *testing.T) {
upgrade = false
}
}`),
Check: resource.ComposeTestCheckFunc(
ResourceAttributes("proxmox_virtual_environment_vm.test_vm_cloudinit3", map[string]string{
"initialization.0.upgrade": "false",
}),
),
Check: ResourceAttributes("proxmox_virtual_environment_vm.test_vm_cloudinit3", map[string]string{
"initialization.0.upgrade": "false",
}),
}}},
{"native cloud-init: username should not change", []resource.TestStep{{
Config: te.RenderConfig(`
@ -505,12 +503,49 @@ func TestAccResourceVMInitialization(t *testing.T) {
}
}
}`),
Check: resource.ComposeTestCheckFunc(
NoResourceAttributesSet("proxmox_virtual_environment_vm.test_vm_cloudinit4", []string{
"initialization.0.username",
"initialization.0.password",
}),
),
Check: NoResourceAttributesSet("proxmox_virtual_environment_vm.test_vm_cloudinit4", []string{
"initialization.0.username",
"initialization.0.password",
}),
}}},
{"native cloud-init: username should not change after update", []resource.TestStep{{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm_cloudinit4" {
node_name = "{{.NodeName}}"
started = false
initialization {
user_account {
username = "ubuntu"
password = "password"
}
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_vm.test_vm_cloudinit4", map[string]string{
"initialization.0.user_account.0.username": "ubuntu",
// override by PVE, set when reading back from the API
// have to escape the asterisks because of regex match
"initialization.0.user_account.0.password": `\*\*\*\*\*\*\*\*\*\*`,
}),
}, {
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm_cloudinit4" {
node_name = "{{.NodeName}}"
started = false
initialization {
user_account {
username = "ubuntu"
password = "password"
}
dns {
servers = ["172.16.0.15", "172.16.0.16"]
domain = "example.com"
}
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_vm.test_vm_cloudinit4", map[string]string{
"initialization.0.user_account.0.username": "ubuntu",
"initialization.0.user_account.0.password": `\*\*\*\*\*\*\*\*\*\*`,
}),
}}},
}

View File

@ -296,6 +296,13 @@ const (
mkWatchdogAction = "action"
)
// MaskedPassword represents a value that PVE returns instead of the configured ciuser password when we read the
// VM config back, and we store this value in the state.
// I don't want to change this "security feature" at the moment to avoid breaking change, but
// the provider should avoid overriding config / state in general. Instead, the state encryption feature should
// be used for data protection.
const MaskedPassword = "**********"
// VM returns a resource that manages VMs.
func VM() *schema.Resource {
s := map[string]*schema.Schema{
@ -2932,7 +2939,7 @@ func vmGetCloudInitConfig(d *schema.ResourceData) *vms.CustomCloudInitConfig {
}
password := initializationUserAccountBlock[mkInitializationUserAccountPassword].(string)
if password != "" {
if password != "" && password != MaskedPassword {
initializationConfig.Password = &password
}