2024-02-08 03:48:59 -06:00
// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
2023-05-12 17:05:00 -05:00
package genconfig
import (
"fmt"
"io"
"os"
2023-09-20 06:35:35 -05:00
"github.com/opentofu/opentofu/internal/tfdiags"
2023-05-12 17:05:00 -05:00
)
2023-05-30 02:17:02 -05:00
func ShouldWriteConfig ( out string ) bool {
2023-05-30 20:00:41 -05:00
// No specified out file, so don't write anything.
return len ( out ) != 0
2023-05-30 02:17:02 -05:00
}
func ValidateTargetFile ( out string ) ( diags tfdiags . Diagnostics ) {
2023-05-12 17:05:00 -05:00
if _ , err := os . Stat ( out ) ; ! os . IsNotExist ( err ) {
diags = diags . Append ( tfdiags . Sourceless (
tfdiags . Error ,
"Target generated file already exists" ,
2023-09-20 09:05:24 -05:00
"OpenTofu can only write generated config into a new file. Either choose a different target location or move all existing configuration out of the target file, delete it and try again." ) )
2023-05-12 17:05:00 -05:00
}
return diags
}
2023-05-30 02:17:02 -05:00
type Change struct {
Addr string
ImportID string
GeneratedConfig string
}
2023-05-12 17:05:00 -05:00
2023-05-30 02:17:02 -05:00
func ( c * Change ) MaybeWriteConfig ( writer io . Writer , out string ) ( io . Writer , bool , tfdiags . Diagnostics ) {
var wroteConfig bool
var diags tfdiags . Diagnostics
if len ( c . GeneratedConfig ) > 0 {
if writer == nil {
// Lazily create the generated file, in case we have no
// generated config to create.
if w , err := os . Create ( out ) ; err != nil {
if os . IsPermission ( err ) {
2023-05-12 17:05:00 -05:00
diags = diags . Append ( tfdiags . Sourceless (
tfdiags . Error ,
"Failed to create target generated file" ,
2023-09-20 09:05:24 -05:00
fmt . Sprintf ( "OpenTofu did not have permission to create the generated file (%s) in the target directory. Please modify permissions over the target directory, and try again." , out ) ) )
2023-05-30 02:17:02 -05:00
return nil , false , diags
2023-05-12 17:05:00 -05:00
}
diags = diags . Append ( tfdiags . Sourceless (
2023-05-30 02:17:02 -05:00
tfdiags . Error ,
"Failed to create target generated file" ,
2023-09-21 10:15:32 -05:00
fmt . Sprintf ( "OpenTofu could not create the generated file (%s) in the target directory: %v. Depending on the error message, this may be a bug in OpenTofu itself. If so, please report it!" , out , err ) ) )
2023-05-30 02:17:02 -05:00
return nil , false , diags
} else {
writer = w
2023-05-12 17:05:00 -05:00
}
2023-05-30 02:17:02 -05:00
2023-09-20 09:05:24 -05:00
header := "# __generated__ by OpenTofu\n# Please review these resources and move them into your main configuration files.\n"
2023-05-30 02:17:02 -05:00
// Missing the header from the file, isn't the end of the world
// so if this did return an error, then we will just ignore it.
_ , _ = writer . Write ( [ ] byte ( header ) )
2023-05-12 17:05:00 -05:00
}
2023-09-20 09:05:24 -05:00
header := "\n# __generated__ by OpenTofu"
2023-05-30 02:17:02 -05:00
if len ( c . ImportID ) > 0 {
header += fmt . Sprintf ( " from %q" , c . ImportID )
}
header += "\n"
if _ , err := writer . Write ( [ ] byte ( fmt . Sprintf ( "%s%s\n" , header , c . GeneratedConfig ) ) ) ; err != nil {
diags = diags . Append ( tfdiags . Sourceless (
tfdiags . Warning ,
"Failed to save generated config" ,
2023-09-21 10:15:32 -05:00
fmt . Sprintf ( "OpenTofu encountered an error while writing generated config: %v. The config for %s must be created manually before applying. Depending on the error message, this may be a bug in OpenTofu itself. If so, please report it!" , err , c . Addr ) ) )
2023-05-30 02:17:02 -05:00
}
wroteConfig = true
2023-05-24 05:16:05 -05:00
}
2023-05-30 02:17:02 -05:00
return writer , wroteConfig , diags
2023-05-12 17:05:00 -05:00
}