// Reader is the main type used to read plan files. Create a Reader by calling
// Open.
//
// A plan file is a random-access file format, so methods of Reader must
// be used to access the individual portions of the file for further
// processing.
typeReaderstruct{
zip*zip.ReadCloser
}
// Open creates a Reader for the file at the given filename, or returns an
// error if the file doesn't seem to be a planfile.
funcOpen(filenamestring)(*Reader,error){
r,err:=zip.OpenReader(filename)
iferr!=nil{
// To give a better error message, we'll sniff to see if this looks
// like our old plan format from versions prior to 0.12.
ifb,sErr:=ioutil.ReadFile(filename);sErr==nil{
ifbytes.HasPrefix(b,[]byte("tfplan")){
returnnil,fmt.Errorf("the given plan file was created by an earlier version of Terraform; plan files cannot be shared between different Terraform versions")
}
}
returnnil,err
}
// Sniff to make sure this looks like a plan file, as opposed to any other
// random zip file the user might have around.
varplanFile*zip.File
for_,file:=ranger.File{
iffile.Name==tfplanFilename{
planFile=file
break
}
}
ifplanFile==nil{
returnnil,fmt.Errorf("the given file is not a valid plan file")
}
// For now, we'll just accept the presence of the tfplan file as enough,
// and wait to validate the version when the caller requests the plan
// itself.
return&Reader{
zip:r,
},nil
}
// ReadPlan reads the plan embedded in the plan file.
//
// Errors can be returned for various reasons, including if the plan file
// is not of an appropriate format version, if it was created by a different
// version of Terraform, if it is invalid, etc.
func(r*Reader)ReadPlan()(*plans.Plan,error){
varplanFile*zip.File
for_,file:=ranger.zip.File{
iffile.Name==tfplanFilename{
planFile=file
break
}
}
ifplanFile==nil{
// This should never happen because we checked for this file during
// Open, but we'll check anyway to be safe.
returnnil,fmt.Errorf("the plan file is invalid")
}
pr,err:=planFile.Open()
iferr!=nil{
returnnil,fmt.Errorf("failed to retrieve plan from plan file: %s",err)