github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/plans/planfile/writer.go (about) 1 package planfile 2 3 import ( 4 "archive/zip" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/hashicorp/terraform/internal/configs/configload" 10 "github.com/hashicorp/terraform/internal/depsfile" 11 "github.com/hashicorp/terraform/internal/plans" 12 "github.com/hashicorp/terraform/internal/states/statefile" 13 ) 14 15 type CreateArgs struct { 16 // ConfigSnapshot is a snapshot of the configuration that the plan 17 // was created from. 18 ConfigSnapshot *configload.Snapshot 19 20 // PreviousRunStateFile is a representation of the state snapshot we used 21 // as the original input when creating this plan, containing the same 22 // information as recorded at the end of the previous apply except for 23 // upgrading managed resource instance data to the provider's latest 24 // schema versions. 25 PreviousRunStateFile *statefile.File 26 27 // BaseStateFile is a representation of the state snapshot we used to 28 // create the plan, which is the result of asking the providers to refresh 29 // all previously-stored objects to match the current situation in the 30 // remote system. (If this plan was created with refreshing disabled, 31 // this should be the same as PreviousRunStateFile.) 32 StateFile *statefile.File 33 34 // Plan records the plan itself, which is the main artifact inside a 35 // saved plan file. 36 Plan *plans.Plan 37 38 // DependencyLocks records the dependency lock information that we 39 // checked prior to creating the plan, so we can make sure that all of the 40 // same dependencies are still available when applying the plan. 41 DependencyLocks *depsfile.Locks 42 } 43 44 // Create creates a new plan file with the given filename, overwriting any 45 // file that might already exist there. 46 // 47 // A plan file contains both a snapshot of the configuration and of the latest 48 // state file in addition to the plan itself, so that Terraform can detect 49 // if the world has changed since the plan was created and thus refuse to 50 // apply it. 51 func Create(filename string, args CreateArgs) error { 52 f, err := os.Create(filename) 53 if err != nil { 54 return err 55 } 56 defer f.Close() 57 58 zw := zip.NewWriter(f) 59 defer zw.Close() 60 61 // tfplan file 62 { 63 w, err := zw.CreateHeader(&zip.FileHeader{ 64 Name: tfplanFilename, 65 Method: zip.Deflate, 66 Modified: time.Now(), 67 }) 68 if err != nil { 69 return fmt.Errorf("failed to create tfplan file: %s", err) 70 } 71 err = writeTfplan(args.Plan, w) 72 if err != nil { 73 return fmt.Errorf("failed to write plan: %s", err) 74 } 75 } 76 77 // tfstate file 78 { 79 w, err := zw.CreateHeader(&zip.FileHeader{ 80 Name: tfstateFilename, 81 Method: zip.Deflate, 82 Modified: time.Now(), 83 }) 84 if err != nil { 85 return fmt.Errorf("failed to create embedded tfstate file: %s", err) 86 } 87 err = statefile.Write(args.StateFile, w) 88 if err != nil { 89 return fmt.Errorf("failed to write state snapshot: %s", err) 90 } 91 } 92 93 // tfstate-prev file 94 { 95 w, err := zw.CreateHeader(&zip.FileHeader{ 96 Name: tfstatePreviousFilename, 97 Method: zip.Deflate, 98 Modified: time.Now(), 99 }) 100 if err != nil { 101 return fmt.Errorf("failed to create embedded tfstate-prev file: %s", err) 102 } 103 err = statefile.Write(args.PreviousRunStateFile, w) 104 if err != nil { 105 return fmt.Errorf("failed to write previous state snapshot: %s", err) 106 } 107 } 108 109 // tfconfig directory 110 { 111 err := writeConfigSnapshot(args.ConfigSnapshot, zw) 112 if err != nil { 113 return fmt.Errorf("failed to write config snapshot: %s", err) 114 } 115 } 116 117 // .terraform.lock.hcl file, containing dependency lock information 118 if args.DependencyLocks != nil { // (this was a later addition, so not all callers set it, but main callers should) 119 src, diags := depsfile.SaveLocksToBytes(args.DependencyLocks) 120 if diags.HasErrors() { 121 return fmt.Errorf("failed to write embedded dependency lock file: %s", diags.Err().Error()) 122 } 123 124 w, err := zw.CreateHeader(&zip.FileHeader{ 125 Name: dependencyLocksFilename, 126 Method: zip.Deflate, 127 Modified: time.Now(), 128 }) 129 if err != nil { 130 return fmt.Errorf("failed to create embedded dependency lock file: %s", err) 131 } 132 _, err = w.Write(src) 133 if err != nil { 134 return fmt.Errorf("failed to write embedded dependency lock file: %s", err) 135 } 136 } 137 138 return nil 139 }