Skip to content

Commit

Permalink
Introduce ephemeral marks (#358)
Browse files Browse the repository at this point in the history
* Bump aqua installer and registry

* Introduce ephemeral marks
  • Loading branch information
wata727 authored Jan 6, 2025
1 parent f713e5c commit 8449fae
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 125 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
prepare:
curl -sSfL https://raw.githubusercontent.com/aquaproj/aqua-installer/v2.1.1/aqua-installer | bash
curl -sSfL https://raw.githubusercontent.com/aquaproj/aqua-installer/v3.0.1/aqua-installer | bash
@echo ''
@echo 'Add $${AQUA_ROOT_DIR}/bin to the environment variable PATH.'
@echo 'export PATH="$${AQUA_ROOT_DIR:-$${XDG_DATA_HOME:-$$HOME/.local/share}/aquaproj-aqua}/bin:$$PATH"'
Expand Down
2 changes: 1 addition & 1 deletion aqua.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# - all
registries:
- type: standard
ref: v3.159.0 # renovate: depName=aquaproj/aqua-registry
ref: v4.290.0 # renovate: depName=aquaproj/aqua-registry
packages:
- name: protocolbuffers/protobuf/protoc@v22.3
- name: protocolbuffers/protobuf-go/protoc-gen-go@v1.30.0
Expand Down
7 changes: 6 additions & 1 deletion plugin/internal/fromproto/fromproto.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,14 @@ func Value(value []byte, ty cty.Type, valueMarks []*proto.ValueMark) (cty.Value,
pvm[idx] = cty.PathValueMarks{
Path: AttributePath(mark.Path),
}
vm := []interface{}{}
if mark.Sensitive {
pvm[idx].Marks = cty.NewValueMarks(marks.Sensitive)
vm = append(vm, marks.Sensitive)
}
if mark.Ephemeral {
vm = append(vm, marks.Ephemeral)
}
pvm[idx].Marks = cty.NewValueMarks(vm...)
}

return val.MarkWithPaths(pvm), nil
Expand Down
15 changes: 12 additions & 3 deletions plugin/internal/plugin2host/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/terraform-linters/tflint-plugin-sdk/plugin/internal/proto"
"github.com/terraform-linters/tflint-plugin-sdk/plugin/internal/toproto"
"github.com/terraform-linters/tflint-plugin-sdk/terraform/addrs"
"github.com/terraform-linters/tflint-plugin-sdk/terraform/lang/marks"
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/gocty"
Expand Down Expand Up @@ -314,7 +315,11 @@ func (c *GRPCClient) EvaluateExpr(expr hcl.Expression, target interface{}, opts

if err != nil {
// If it cannot be represented as a Go value, exit without invoking the callback rather than returning an error.
if errors.Is(err, tflint.ErrUnknownValue) || errors.Is(err, tflint.ErrNullValue) || errors.Is(err, tflint.ErrSensitive) || errors.Is(err, tflint.ErrUnevaluable) {
if errors.Is(err, tflint.ErrUnknownValue) ||
errors.Is(err, tflint.ErrNullValue) ||
errors.Is(err, tflint.ErrSensitive) ||
errors.Is(err, tflint.ErrEphemeral) ||
errors.Is(err, tflint.ErrUnevaluable) {
return nil
}
return err
Expand Down Expand Up @@ -391,7 +396,7 @@ func (c *GRPCClient) evaluateExpr(expr hcl.Expression, target interface{}, opts
return gocty.FromCtyValue(val, target)
}

// Returns an error if the value cannot be decoded to a Go value (e.g. unknown, null, sensitive).
// Returns an error if the value cannot be decoded to a Go value (e.g. unknown, null, marked).
// This allows the caller to handle the value by the errors package.
err = cty.Walk(val, func(path cty.Path, v cty.Value) (bool, error) {
if !v.IsKnown() {
Expand All @@ -402,10 +407,14 @@ func (c *GRPCClient) evaluateExpr(expr hcl.Expression, target interface{}, opts
logger.Debug(fmt.Sprintf("null value found in %s", expr.Range()))
return false, tflint.ErrNullValue
}
if v.IsMarked() {
if v.HasMark(marks.Sensitive) {
logger.Debug(fmt.Sprintf("sensitive value found in %s", expr.Range()))
return false, tflint.ErrSensitive
}
if v.HasMark(marks.Ephemeral) {
logger.Debug(fmt.Sprintf("ephemeral value found in %s", expr.Range()))
return false, tflint.ErrEphemeral
}
return true, nil
})
if err != nil {
Expand Down
62 changes: 62 additions & 0 deletions plugin/internal/plugin2host/plugin2host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2015,6 +2015,42 @@ func TestEvaluateExpr(t *testing.T) {
GetFileImpl: fileExists,
ErrCheck: neverHappend,
},
{
Name: "ephemeral",
Expr: hclExpr(`var.foo`),
TargetType: reflect.TypeOf(""),
ServerImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
return evalExpr(expr, &hcl.EvalContext{
Variables: map[string]cty.Value{
"var": cty.MapVal(map[string]cty.Value{
"foo": cty.StringVal("bar").Mark(marks.Ephemeral),
}),
},
})
},
Want: "",
GetFileImpl: fileExists,
ErrCheck: func(err error) bool {
return !errors.Is(err, tflint.ErrEphemeral)
},
},
{
Name: "ephemeral as cty.Value",
Expr: hclExpr(`var.foo`),
TargetType: reflect.TypeOf(cty.Value{}),
ServerImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
return evalExpr(expr, &hcl.EvalContext{
Variables: map[string]cty.Value{
"var": cty.MapVal(map[string]cty.Value{
"foo": cty.StringVal("bar").Mark(marks.Ephemeral),
}),
},
})
},
Want: cty.StringVal("bar").Mark(marks.Ephemeral),
GetFileImpl: fileExists,
ErrCheck: neverHappend,
},
}

for _, test := range tests {
Expand Down Expand Up @@ -2334,6 +2370,32 @@ func TestEvaluateExpr_callback(t *testing.T) {
return err == nil || err.Error() != `value is cty.StringVal("foo").Mark(marks.Sensitive)`
},
},
{
name: "callback with ephemeral value as Go value",
expr: hclExpr(`var.foo`),
target: func(val string) error {
return fmt.Errorf("value is %s", val)
},
serverImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
return cty.StringVal("foo").Mark(marks.Ephemeral), nil
},
getFileImpl: fileExists,
errCheck: neverHappend,
},
{
name: "callback with ephemeral value as cty.Value",
expr: hclExpr(`var.foo`),
target: func(val cty.Value) error {
return fmt.Errorf("value is %s", val.GoString())
},
serverImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
return cty.StringVal("foo").Mark(marks.Ephemeral), nil
},
getFileImpl: fileExists,
errCheck: func(err error) bool {
return err == nil || err.Error() != `value is cty.StringVal("foo").Mark(marks.Ephemeral)`
},
},
}

for _, test := range tests {
Expand Down
Loading

0 comments on commit 8449fae

Please sign in to comment.