github.com/beauknowssoftware/makehcl@v0.0.0-20200322000747-1b9bb1e1c008/internal/parse/parseDynamicRules.go (about)

     1  package parse
     2  
     3  import (
     4  	"github.com/pkg/errors"
     5  
     6  	"github.com/beauknowssoftware/makehcl/internal/definition"
     7  	"github.com/hashicorp/hcl/v2"
     8  	"github.com/zclconf/go-cty/cty"
     9  )
    10  
    11  var (
    12  	dynamicRuleListSchema = hcl.BodySchema{
    13  		Attributes: []hcl.AttributeSchema{
    14  			{
    15  				Name:     "alias",
    16  				Required: false,
    17  			},
    18  			{
    19  				Name:     "for_each",
    20  				Required: true,
    21  			},
    22  			{
    23  				Name:     "as",
    24  				Required: false,
    25  			},
    26  		},
    27  	}
    28  )
    29  
    30  type dynamicRule struct {
    31  	alias string
    32  	rules []*definition.Rule
    33  }
    34  
    35  func constructDynamicRules(blk *hcl.Block, ctx *hcl.EvalContext) (*dynamicRule, error) {
    36  	con, body, diag := blk.Body.PartialContent(&dynamicRuleListSchema)
    37  	if diag.HasErrors() {
    38  		return nil, diag
    39  	}
    40  
    41  	forEach, err := evaluateIterable(con.Attributes["for_each"].Expr, ctx)
    42  	if err != nil {
    43  		err = errors.Wrap(err, "failed to evaluate for_each")
    44  		return nil, err
    45  	}
    46  
    47  	var dr dynamicRule
    48  
    49  	as := "rule"
    50  	if asVal, hasAs := con.Attributes["as"]; hasAs {
    51  		as, err = evaluateString(asVal.Expr, ctx)
    52  		if err != nil {
    53  			err = errors.Wrap(err, "failed to evaluate as")
    54  			return nil, err
    55  		}
    56  	}
    57  
    58  	if aliasVal, hasName := con.Attributes["alias"]; hasName {
    59  		dr.alias, err = evaluateString(aliasVal.Expr, ctx)
    60  		if err != nil {
    61  			err = errors.Wrap(err, "failed to evaluate alias")
    62  			return nil, err
    63  		}
    64  	}
    65  
    66  	dr.rules = make([]*definition.Rule, 0, len(forEach))
    67  
    68  	for _, each := range forEach {
    69  		ectx := ctx.NewChild()
    70  		ectx.Variables = map[string]cty.Value{
    71  			as: each,
    72  		}
    73  
    74  		r, err := fillRule(body, ectx)
    75  		if err != nil {
    76  			return nil, err
    77  		}
    78  
    79  		dr.rules = append(dr.rules, r)
    80  	}
    81  
    82  	return &dr, nil
    83  }