Merge pull request 'fix: accept empty Terraform state imports' (#17) from fix/empty-terraform-state-import into main

Reviewed-on: #17
This commit is contained in:
eding 2026-08-23 19:44:53 +02:00
commit e8bcebf65f
2 changed files with 49 additions and 2 deletions

View file

@ -86,17 +86,39 @@ var runGitEnvironment = func(dir string, environment []string, args ...string) (
var verifyTalosVMs = verifyConfiguredTalosVMs
var terraformStateResources = func(terraformDir string, environment []string) ([]string, error) {
var terraformStateResources = listTerraformStateResources
var runTerraformStateList = func(terraformDir string, environment []string) ([]byte, []byte, error) {
command := exec.Command("terraform", "state", "list")
command.Dir = terraformDir
command.Env = append(os.Environ(), environment...)
state, err := command.Output()
var stdout, stderr bytes.Buffer
command.Stdout = &stdout
command.Stderr = &stderr
err := command.Run()
return stdout.Bytes(), stderr.Bytes(), err
}
func listTerraformStateResources(terraformDir string, environment []string) ([]string, error) {
state, stderr, err := runTerraformStateList(terraformDir, environment)
if err != nil {
if terraformNoStateFile(stderr) {
return nil, nil
}
return nil, fmt.Errorf("list Terraform state: %w", err)
}
return strings.Fields(string(state)), nil
}
func terraformNoStateFile(stderr []byte) bool {
for _, line := range strings.Split(string(stderr), "\n") {
if strings.TrimSpace(line) == "No state file was found!" {
return true
}
}
return false
}
var destroyTalosVMs = func(terraformDir string, environment []string) error {
return utils.RunCommandInDirEnv(terraformDir, environment, "terraform", "destroy", "-auto-approve", "-input=false", "-target=proxmox_virtual_environment_vm.vm")
}

View file

@ -911,6 +911,31 @@ func TestTerraformPlanPathIsAbsolute(t *testing.T) {
}
}
func TestTerraformStateResourcesAllowsNoStateFile(t *testing.T) {
original := runTerraformStateList
t.Cleanup(func() { runTerraformStateList = original })
runTerraformStateList = func(string, []string) ([]byte, []byte, error) {
return nil, []byte("No state file was found!\n"), errors.New("exit status 1")
}
resources, err := listTerraformStateResources("terraform", nil)
if err != nil || len(resources) != 0 {
t.Fatalf("no-state Terraform result = %q, %v; want empty resources and nil error", resources, err)
}
}
func TestTerraformStateResourcesRejectsUnexpectedStateError(t *testing.T) {
original := runTerraformStateList
t.Cleanup(func() { runTerraformStateList = original })
runTerraformStateList = func(string, []string) ([]byte, []byte, error) {
return nil, []byte("Error: failed to load backend\n"), errors.New("exit status 1")
}
if _, err := listTerraformStateResources("terraform", nil); err == nil || !strings.Contains(err.Error(), "list Terraform state") {
t.Fatalf("unexpected Terraform state error was accepted: %v", err)
}
}
func TestVerifyStateTalosVMsRejectsForeignAndMissingVMs(t *testing.T) {
cfg := config.Config{Talos: config.TalosConfig{Nodes: []config.TalosNode{{Name: "cp-01", ProxmoxNode: "pve", VMID: 100}, {Name: "worker-01", ProxmoxNode: "pve", VMID: 101}}}}
if err := verifyStateTalosVMs([]string{`proxmox_virtual_environment_vm.vm["cp-01"]`, `proxmox_virtual_environment_vm.vm["foreign"]`}, cfg, false); err == nil || !strings.Contains(err.Error(), "unconfigured") {