github.com/bigcommerce/nomad@v0.9.3-bc/helper/pluginutils/hclutils/util.go (about)

     1  package hclutils
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  
     7  	"github.com/hashicorp/hcl2/hcl"
     8  	hjson "github.com/hashicorp/hcl2/hcl/json"
     9  	"github.com/hashicorp/hcl2/hcldec"
    10  	"github.com/hashicorp/nomad/nomad/structs"
    11  	"github.com/ugorji/go/codec"
    12  	"github.com/zclconf/go-cty/cty"
    13  	"github.com/zclconf/go-cty/cty/function"
    14  	"github.com/zclconf/go-cty/cty/function/stdlib"
    15  )
    16  
    17  // ParseHclInterface is used to convert an interface value representing a hcl2
    18  // body and return the interpolated value. Vars may be nil if there are no
    19  // variables to interpolate.
    20  func ParseHclInterface(val interface{}, spec hcldec.Spec, vars map[string]cty.Value) (cty.Value, hcl.Diagnostics) {
    21  	evalCtx := &hcl.EvalContext{
    22  		Variables: vars,
    23  		Functions: GetStdlibFuncs(),
    24  	}
    25  
    26  	// Encode to json
    27  	var buf bytes.Buffer
    28  	enc := codec.NewEncoder(&buf, structs.JsonHandle)
    29  	err := enc.Encode(val)
    30  	if err != nil {
    31  		// Convert to a hcl diagnostics message
    32  		return cty.NilVal, hcl.Diagnostics([]*hcl.Diagnostic{
    33  			{
    34  				Severity: hcl.DiagError,
    35  				Summary:  "Failed to JSON encode value",
    36  				Detail:   fmt.Sprintf("JSON encoding failed: %v", err),
    37  			}})
    38  	}
    39  
    40  	// Parse the json as hcl2
    41  	hclFile, diag := hjson.Parse(buf.Bytes(), "")
    42  	if diag.HasErrors() {
    43  		return cty.NilVal, diag
    44  	}
    45  
    46  	value, decDiag := hcldec.Decode(hclFile.Body, spec, evalCtx)
    47  	diag = diag.Extend(decDiag)
    48  	if diag.HasErrors() {
    49  		return cty.NilVal, diag
    50  	}
    51  
    52  	return value, diag
    53  }
    54  
    55  // GetStdlibFuncs returns the set of stdlib functions.
    56  func GetStdlibFuncs() map[string]function.Function {
    57  	return map[string]function.Function{
    58  		"abs":        stdlib.AbsoluteFunc,
    59  		"coalesce":   stdlib.CoalesceFunc,
    60  		"concat":     stdlib.ConcatFunc,
    61  		"hasindex":   stdlib.HasIndexFunc,
    62  		"int":        stdlib.IntFunc,
    63  		"jsondecode": stdlib.JSONDecodeFunc,
    64  		"jsonencode": stdlib.JSONEncodeFunc,
    65  		"length":     stdlib.LengthFunc,
    66  		"lower":      stdlib.LowerFunc,
    67  		"max":        stdlib.MaxFunc,
    68  		"min":        stdlib.MinFunc,
    69  		"reverse":    stdlib.ReverseFunc,
    70  		"strlen":     stdlib.StrlenFunc,
    71  		"substr":     stdlib.SubstrFunc,
    72  		"upper":      stdlib.UpperFunc,
    73  	}
    74  }