Refactor hcl2_upgrade (#10787)
This commit is contained in:
parent
4242cf3151
commit
502708b86a
|
@ -270,11 +270,7 @@ func (uc UnhandleableArgumentError) Error() string {
|
||||||
# Visit %s for more infos.`, uc.Call, uc.Correspondance, uc.Docs)
|
# Visit %s for more infos.`, uc.Call, uc.Correspondance, uc.Docs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// transposeTemplatingCalls executes parts of blocks as go template files and replaces
|
func fallbackReturn(err error, s []byte) []byte {
|
||||||
// their result with their hcl2 variant. If something goes wrong the template
|
|
||||||
// containing the go template string is returned.
|
|
||||||
func transposeTemplatingCalls(s []byte) []byte {
|
|
||||||
fallbackReturn := func(err error) []byte {
|
|
||||||
if strings.Contains(err.Error(), "unhandled") {
|
if strings.Contains(err.Error(), "unhandled") {
|
||||||
return append([]byte(fmt.Sprintf("\n# %s\n", err)), s...)
|
return append([]byte(fmt.Sprintf("\n# %s\n", err)), s...)
|
||||||
}
|
}
|
||||||
|
@ -282,6 +278,10 @@ func transposeTemplatingCalls(s []byte) []byte {
|
||||||
return append([]byte(fmt.Sprintf("\n# could not parse template for following block: %q\n", err)), s...)
|
return append([]byte(fmt.Sprintf("\n# could not parse template for following block: %q\n", err)), s...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// transposeTemplatingCalls executes parts of blocks as go template files and replaces
|
||||||
|
// their result with their hcl2 variant. If something goes wrong the template
|
||||||
|
// containing the go template string is returned.
|
||||||
|
func transposeTemplatingCalls(s []byte) []byte {
|
||||||
funcErrors := &multierror.Error{
|
funcErrors := &multierror.Error{
|
||||||
ErrorFormat: func(es []error) string {
|
ErrorFormat: func(es []error) string {
|
||||||
if len(es) == 1 {
|
if len(es) == 1 {
|
||||||
|
@ -437,14 +437,14 @@ func transposeTemplatingCalls(s []byte) []byte {
|
||||||
Parse(string(s))
|
Parse(string(s))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fallbackReturn(err)
|
return fallbackReturn(err, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
str := &bytes.Buffer{}
|
str := &bytes.Buffer{}
|
||||||
// PASSTHROUGHS is a map of variable-specific golang text template fields
|
// PASSTHROUGHS is a map of variable-specific golang text template fields
|
||||||
// that should remain in the text template format.
|
// that should remain in the text template format.
|
||||||
if err := tpl.Execute(str, PASSTHROUGHS); err != nil {
|
if err := tpl.Execute(str, PASSTHROUGHS); err != nil {
|
||||||
return fallbackReturn(err)
|
return fallbackReturn(err, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
out := str.Bytes()
|
out := str.Bytes()
|
||||||
|
@ -461,14 +461,6 @@ func transposeTemplatingCalls(s []byte) []byte {
|
||||||
// In variableTransposeTemplatingCalls the definition of aws_secretsmanager function will create a data source
|
// In variableTransposeTemplatingCalls the definition of aws_secretsmanager function will create a data source
|
||||||
// with the same name as the variable.
|
// with the same name as the variable.
|
||||||
func variableTransposeTemplatingCalls(s []byte) (isLocal bool, body []byte) {
|
func variableTransposeTemplatingCalls(s []byte) (isLocal bool, body []byte) {
|
||||||
fallbackReturn := func(err error) []byte {
|
|
||||||
if strings.Contains(err.Error(), "unhandled") {
|
|
||||||
return append([]byte(fmt.Sprintf("\n# %s\n", err)), s...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return append([]byte(fmt.Sprintf("\n# could not parse template for following block: %q\n", err)), s...)
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsLocal := func(a ...string) string {
|
setIsLocal := func(a ...string) string {
|
||||||
isLocal = true
|
isLocal = true
|
||||||
return ""
|
return ""
|
||||||
|
@ -510,14 +502,14 @@ func variableTransposeTemplatingCalls(s []byte) (isLocal bool, body []byte) {
|
||||||
Parse(string(s))
|
Parse(string(s))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return isLocal, fallbackReturn(err)
|
return isLocal, fallbackReturn(err, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
str := &bytes.Buffer{}
|
str := &bytes.Buffer{}
|
||||||
// PASSTHROUGHS is a map of variable-specific golang text template fields
|
// PASSTHROUGHS is a map of variable-specific golang text template fields
|
||||||
// that should remain in the text template format.
|
// that should remain in the text template format.
|
||||||
if err := tpl.Execute(str, PASSTHROUGHS); err != nil {
|
if err := tpl.Execute(str, PASSTHROUGHS); err != nil {
|
||||||
return isLocal, fallbackReturn(err)
|
return isLocal, fallbackReturn(err, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return isLocal, str.Bytes()
|
return isLocal, str.Bytes()
|
||||||
|
@ -682,12 +674,49 @@ type VariableParser struct {
|
||||||
localsOut []byte
|
localsOut []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeLocal(variable *template.Variable, sensitive bool, localBody *hclwrite.Body, localsContent *hclwrite.File, hasLocals *bool) []byte {
|
||||||
|
if sensitive {
|
||||||
|
// Create Local block because this is sensitive
|
||||||
|
sensitiveLocalContent := hclwrite.NewEmptyFile()
|
||||||
|
body := sensitiveLocalContent.Body()
|
||||||
|
body.AppendNewline()
|
||||||
|
sensitiveLocalBody := body.AppendNewBlock("local", []string{variable.Key}).Body()
|
||||||
|
sensitiveLocalBody.SetAttributeValue("sensitive", cty.BoolVal(true))
|
||||||
|
sensitiveLocalBody.SetAttributeValue("expression", hcl2shim.HCL2ValueFromConfigValue(variable.Default))
|
||||||
|
localsVariableMap[variable.Key] = "local"
|
||||||
|
return sensitiveLocalContent.Bytes()
|
||||||
|
}
|
||||||
|
localBody.SetAttributeValue(variable.Key, hcl2shim.HCL2ValueFromConfigValue(variable.Default))
|
||||||
|
localsVariableMap[variable.Key] = "locals"
|
||||||
|
*hasLocals = true
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeVariable(variable *template.Variable, sensitive bool) []byte {
|
||||||
|
variablesContent := hclwrite.NewEmptyFile()
|
||||||
|
variablesBody := variablesContent.Body()
|
||||||
|
variablesBody.AppendNewline()
|
||||||
|
variableBody := variablesBody.AppendNewBlock("variable", []string{variable.Key}).Body()
|
||||||
|
variableBody.SetAttributeRaw("type", hclwrite.Tokens{&hclwrite.Token{Bytes: []byte("string")}})
|
||||||
|
|
||||||
|
if variable.Default != "" || !variable.Required {
|
||||||
|
shimmed := hcl2shim.HCL2ValueFromConfigValue(variable.Default)
|
||||||
|
variableBody.SetAttributeValue("default", shimmed)
|
||||||
|
}
|
||||||
|
if sensitive {
|
||||||
|
variableBody.SetAttributeValue("sensitive", cty.BoolVal(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
return variablesContent.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
func (p *VariableParser) Parse(tpl *template.Template) error {
|
func (p *VariableParser) Parse(tpl *template.Template) error {
|
||||||
// OutPut Locals and Local blocks
|
// Output Locals and Local blocks
|
||||||
localsContent := hclwrite.NewEmptyFile()
|
localsContent := hclwrite.NewEmptyFile()
|
||||||
localsBody := localsContent.Body()
|
localsBody := localsContent.Body()
|
||||||
localsBody.AppendNewline()
|
localsBody.AppendNewline()
|
||||||
localBody := localsBody.AppendNewBlock("locals", nil).Body()
|
localBody := localsBody.AppendNewBlock("locals", nil).Body()
|
||||||
|
hasLocals := false
|
||||||
|
|
||||||
if len(p.variablesOut) == 0 {
|
if len(p.variablesOut) == 0 {
|
||||||
p.variablesOut = []byte{}
|
p.variablesOut = []byte{}
|
||||||
|
@ -707,47 +736,34 @@ func (p *VariableParser) Parse(tpl *template.Template) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
hasLocals := false
|
|
||||||
for _, variable := range variables {
|
for _, variable := range variables {
|
||||||
variablesContent := hclwrite.NewEmptyFile()
|
// Create new HCL2 "variables" block, and populate the "value"
|
||||||
variablesBody := variablesContent.Body()
|
// field with the "Default" value from the JSON variable.
|
||||||
variablesBody.AppendNewline()
|
|
||||||
variableBody := variablesBody.AppendNewBlock("variable", []string{variable.Key}).Body()
|
|
||||||
variableBody.SetAttributeRaw("type", hclwrite.Tokens{&hclwrite.Token{Bytes: []byte("string")}})
|
|
||||||
|
|
||||||
if variable.Default != "" || !variable.Required {
|
// Interpolate Jsonval first as an hcl variable to determine if it is
|
||||||
variableBody.SetAttributeValue("default", hcl2shim.HCL2ValueFromConfigValue(variable.Default))
|
// a local.
|
||||||
}
|
isLocal, _ := variableTransposeTemplatingCalls([]byte(variable.Default))
|
||||||
sensitive := false
|
sensitive := false
|
||||||
if isSensitiveVariable(variable.Key, tpl.SensitiveVariables) {
|
if isSensitiveVariable(variable.Key, tpl.SensitiveVariables) {
|
||||||
sensitive = true
|
sensitive = true
|
||||||
variableBody.SetAttributeValue("sensitive", cty.BoolVal(true))
|
|
||||||
}
|
}
|
||||||
isLocal, out := variableTransposeTemplatingCalls(variablesContent.Bytes())
|
// Create final HCL block and append.
|
||||||
if isLocal {
|
if isLocal {
|
||||||
if sensitive {
|
sensitiveBlocks := makeLocal(variable, sensitive, localBody, localsContent, &hasLocals)
|
||||||
// Create Local block because this is sensitive
|
if len(sensitiveBlocks) > 0 {
|
||||||
localContent := hclwrite.NewEmptyFile()
|
p.localsOut = append(p.localsOut, transposeTemplatingCalls(sensitiveBlocks)...)
|
||||||
body := localContent.Body()
|
}
|
||||||
body.AppendNewline()
|
|
||||||
localBody := body.AppendNewBlock("local", []string{variable.Key}).Body()
|
|
||||||
localBody.SetAttributeValue("sensitive", cty.BoolVal(true))
|
|
||||||
localBody.SetAttributeValue("expression", hcl2shim.HCL2ValueFromConfigValue(variable.Default))
|
|
||||||
p.localsOut = append(p.localsOut, transposeTemplatingCalls(localContent.Bytes())...)
|
|
||||||
localsVariableMap[variable.Key] = "local"
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
localBody.SetAttributeValue(variable.Key, hcl2shim.HCL2ValueFromConfigValue(variable.Default))
|
|
||||||
localsVariableMap[variable.Key] = "locals"
|
|
||||||
hasLocals = true
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
varbytes := makeVariable(variable, sensitive)
|
||||||
|
_, out := variableTransposeTemplatingCalls(varbytes)
|
||||||
p.variablesOut = append(p.variablesOut, out...)
|
p.variablesOut = append(p.variablesOut, out...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasLocals {
|
if hasLocals == true {
|
||||||
p.localsOut = append(p.localsOut, transposeTemplatingCalls(localsContent.Bytes())...)
|
p.localsOut = append(p.localsOut, transposeTemplatingCalls(localsContent.Bytes())...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue