mirror of https://github.com/kubernetes/kops.git
Merge pull request #11542 from rifelpet/tf-fn
Add support for arbitrary terraform functions
This commit is contained in:
commit
06835e219d
|
@ -20,6 +20,7 @@ import (
|
|||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||
|
@ -103,11 +104,11 @@ func writeValue(body *hclwrite.Body, key string, value cty.Value) {
|
|||
// key = res_type.res_name.res_prop
|
||||
// key = file("${module.path}/foo")
|
||||
func writeLiteral(body *hclwrite.Body, key string, literal *terraformWriter.Literal) {
|
||||
if literal.FilePath != "" {
|
||||
if literal.FnName != "" {
|
||||
tokens := hclwrite.Tokens{
|
||||
{
|
||||
Type: hclsyntax.TokenIdent,
|
||||
Bytes: []byte(fmt.Sprintf("%v(%q)", literal.FileFn, literal.FilePath)),
|
||||
Bytes: []byte(fmt.Sprintf("%v(%v)", literal.FnName, strings.Join(literal.FnArgs, ", "))),
|
||||
},
|
||||
}
|
||||
body.SetAttributeRaw(key, tokens)
|
||||
|
@ -193,8 +194,11 @@ func writeMap(body *hclwrite.Body, key string, values map[string]cty.Value) {
|
|||
if literal, ok := refLiteral.Interface().(*terraformWriter.Literal); err == nil && ok {
|
||||
// For maps of literals we currently only support file references
|
||||
// If we ever need to support a map of strings to resource property references that can be added here
|
||||
if literal.FilePath != "" {
|
||||
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenIdent, Bytes: []byte(fmt.Sprintf("%v(%q)", literal.FileFn, literal.FilePath))})
|
||||
if literal.FnName != "" {
|
||||
tokens = append(tokens, &hclwrite.Token{
|
||||
Type: hclsyntax.TokenIdent,
|
||||
Bytes: []byte(fmt.Sprintf("%v(%v)", literal.FnName, strings.Join(literal.FnArgs, ", "))),
|
||||
})
|
||||
} else if literal.Value != "" {
|
||||
tokens = append(tokens, []*hclwrite.Token{
|
||||
{Type: hclsyntax.TokenOQuote, Bytes: []byte{'"'}, SpacesBefore: 1},
|
||||
|
|
|
@ -133,7 +133,7 @@ func TestWriteLiteral(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "file",
|
||||
literal: terraformWriter.LiteralFileExpression("${path.module}/foo", false),
|
||||
literal: terraformWriter.LiteralFunctionExpression("file", []string{"\"${path.module}/foo\""}),
|
||||
expected: `foo = file("${path.module}/foo")`,
|
||||
},
|
||||
}
|
||||
|
@ -272,13 +272,15 @@ func TestWriteMapLiterals(t *testing.T) {
|
|||
{
|
||||
name: "literal values",
|
||||
values: map[string]terraformWriter.Literal{
|
||||
"key1": *terraformWriter.LiteralFileExpression("${module.path}/path/to/value1", false),
|
||||
"key2": *terraformWriter.LiteralFileExpression("${module.path}/path/to/value2", true),
|
||||
"key1": *terraformWriter.LiteralFunctionExpression("file", []string{"\"${module.path}/path/to/value1\""}),
|
||||
"key2": *terraformWriter.LiteralFunctionExpression("filebase64", []string{"\"${module.path}/path/to/value2\""}),
|
||||
"key3": *terraformWriter.LiteralFunctionExpression("cidrsubnet", []string{"\"172.16.0.0/12\"", "4", "2"}),
|
||||
},
|
||||
expected: `
|
||||
metadata = {
|
||||
"key1" = file("${module.path}/path/to/value1")
|
||||
"key2" = filebase64("${module.path}/path/to/value2")
|
||||
"key3" = cidrsubnet("172.16.0.0/12", 4, 2)
|
||||
}
|
||||
`,
|
||||
},
|
||||
|
|
|
@ -20,17 +20,11 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
type fileFn string
|
||||
|
||||
const (
|
||||
fileFnFile fileFn = "file"
|
||||
fileFnFileBase64 fileFn = "filebase64"
|
||||
)
|
||||
|
||||
// Literal represents a literal in terraform syntax
|
||||
type Literal struct {
|
||||
// Value is only used in JSON output via the TerraformJSON feature flag
|
||||
|
@ -43,10 +37,12 @@ type Literal struct {
|
|||
ResourceName string `cty:"resource_name"`
|
||||
// ResourceProp represents the property of a resource in a literal reference
|
||||
ResourceProp string `cty:"resource_prop"`
|
||||
// FilePath represents the path for a file reference
|
||||
FilePath string `cty:"file_path"`
|
||||
// FileFn represents the function used to reference the file
|
||||
FileFn fileFn `cty:"file_fn"`
|
||||
|
||||
// FnName represents the name of a terraform function.
|
||||
FnName string `cty:"fn_name"`
|
||||
// FnArgs contains string representations of arguments to the function call.
|
||||
// Any string arguments must be quoted.
|
||||
FnArgs []string `cty:"fn_arg"`
|
||||
}
|
||||
|
||||
var _ json.Marshaler = &Literal{}
|
||||
|
@ -55,15 +51,11 @@ func (l *Literal) MarshalJSON() ([]byte, error) {
|
|||
return json.Marshal(&l.Value)
|
||||
}
|
||||
|
||||
func LiteralFileExpression(modulePath string, base64 bool) *Literal {
|
||||
fn := fileFnFile
|
||||
if base64 {
|
||||
fn = fileFnFileBase64
|
||||
}
|
||||
func LiteralFunctionExpression(functionName string, args []string) *Literal {
|
||||
return &Literal{
|
||||
Value: fmt.Sprintf("${%v(%q)}", fn, modulePath),
|
||||
FilePath: modulePath,
|
||||
FileFn: fn,
|
||||
Value: fmt.Sprintf("${%v(%v)}", functionName, strings.Join(args, ", ")),
|
||||
FnName: functionName,
|
||||
FnArgs: args,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,9 +75,12 @@ func (t *TerraformWriter) AddFileBytes(resourceType string, resourceName string,
|
|||
p := path.Join("data", id)
|
||||
t.Files[p] = data
|
||||
|
||||
modulePath := path.Join("${path.module}", p)
|
||||
l := LiteralFileExpression(modulePath, base64)
|
||||
return l, nil
|
||||
modulePath := fmt.Sprintf("%q", path.Join("${path.module}", p))
|
||||
fn := "file"
|
||||
if base64 {
|
||||
fn = "filebase64"
|
||||
}
|
||||
return LiteralFunctionExpression(fn, []string{modulePath}), nil
|
||||
}
|
||||
|
||||
func (t *TerraformWriter) RenderResource(resourceType string, resourceName string, e interface{}) error {
|
||||
|
|
Loading…
Reference in New Issue