Skip to content

Commit d49361e

Browse files
authored
Merge pull request #79 from terraform-linters/extend_runner_api_for_accessing_root_provider
tflint: Extend runner API for accessing the root provider configuration
2 parents 4b81c5b + 2205685 commit d49361e

File tree

5 files changed

+92
-0
lines changed

5 files changed

+92
-0
lines changed

helper/runner.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ func (r *Runner) Config() (*configs.Config, error) {
118118
return r.config, nil
119119
}
120120

121+
// RootProvider returns the provider configuration.
122+
// In the helper runner, it always returns its own provider.
123+
func (r *Runner) RootProvider(name string) (*configs.Provider, error) {
124+
return r.config.Module.ProviderConfigs[name], nil
125+
}
126+
121127
// EvaluateExpr returns a value of the passed expression.
122128
// Note that some features are limited
123129
func (r *Runner) EvaluateExpr(expr hcl.Expression, ret interface{}) error {
@@ -159,6 +165,12 @@ func (r *Runner) EvaluateExpr(expr hcl.Expression, ret interface{}) error {
159165
return gocty.FromCtyValue(val, ret)
160166
}
161167

168+
// EvaluateExprOnRootCtx returns a value of the passed expression.
169+
// Note this is just alias of EvaluateExpr.
170+
func (r *Runner) EvaluateExprOnRootCtx(expr hcl.Expression, ret interface{}) error {
171+
return r.EvaluateExpr(expr, ret)
172+
}
173+
162174
// EmitIssueOnExpr adds an issue to the runner itself.
163175
func (r *Runner) EmitIssueOnExpr(rule tflint.Rule, message string, expr hcl.Expression) error {
164176
r.Issues = append(r.Issues, &Issue{

tflint/client/client.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,26 @@ func (c *Client) Config() (*configs.Config, error) {
170170
return config, nil
171171
}
172172

173+
// RootProvider calls the server-side RootProvider method and returns the provider configuration.
174+
func (c *Client) RootProvider(name string) (*configs.Provider, error) {
175+
log.Printf("[DEBUG] Accessing to the `%s` provider config in the root module", name)
176+
177+
var response RootProviderResponse
178+
if err := c.rpcClient.Call("Plugin.RootProvider", RootProviderRequest{Name: name}, &response); err != nil {
179+
return nil, err
180+
}
181+
if response.Err != nil {
182+
return nil, response.Err
183+
}
184+
185+
provider, diags := decodeProvider(response.Provider)
186+
if diags.HasErrors() {
187+
return nil, diags
188+
}
189+
190+
return provider, nil
191+
}
192+
173193
// EvaluateExpr calls the server-side EvalExpr method and reflects the response
174194
// in the passed argument.
175195
func (c *Client) EvaluateExpr(expr hcl.Expression, ret interface{}) error {
@@ -207,6 +227,43 @@ func (c *Client) EvaluateExpr(expr hcl.Expression, ret interface{}) error {
207227
return nil
208228
}
209229

230+
// EvaluateExprOnRootCtx calls the server-side EvalExprOnRootCtx method and reflects the response
231+
// in the passed argument.
232+
func (c *Client) EvaluateExprOnRootCtx(expr hcl.Expression, ret interface{}) error {
233+
var response EvalExprResponse
234+
var err error
235+
236+
src, err := ioutil.ReadFile(expr.Range().Filename)
237+
if err != nil {
238+
return err
239+
}
240+
req := EvalExprRequest{Ret: ret}
241+
req.Expr, req.ExprRange = encodeExpr(src, expr)
242+
if err := c.rpcClient.Call("Plugin.EvalExprOnRootCtx", req, &response); err != nil {
243+
return err
244+
}
245+
if response.Err != nil {
246+
return response.Err
247+
}
248+
249+
err = gocty.FromCtyValue(response.Val, ret)
250+
if err != nil {
251+
err := &tflint.Error{
252+
Code: tflint.TypeMismatchError,
253+
Level: tflint.ErrorLevel,
254+
Message: fmt.Sprintf(
255+
"Invalid type expression in %s:%d",
256+
expr.Range().Filename,
257+
expr.Range().Start.Line,
258+
),
259+
Cause: err,
260+
}
261+
log.Printf("[ERROR] %s", err)
262+
return err
263+
}
264+
return nil
265+
}
266+
210267
// EmitIssueOnExpr calls the server-side EmitIssue method with the passed expression.
211268
func (c *Client) EmitIssueOnExpr(rule tflint.Rule, message string, expr hcl.Expression) error {
212269
req := &EmitIssueRequest{

tflint/client/decode_provider.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ type Provider struct {
2323
}
2424

2525
func decodeProvider(provider *Provider) (*configs.Provider, hcl.Diagnostics) {
26+
if provider == nil {
27+
return nil, nil
28+
}
29+
2630
versionConstraint, diags := parseVersionConstraint(provider.Version, provider.VersionRange)
2731
if diags.HasErrors() {
2832
return nil, diags

tflint/client/rpc.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ type ConfigResponse struct {
6767
Err error
6868
}
6969

70+
// RootProviderRequest is a request to the server-side RootProvider method.
71+
type RootProviderRequest struct {
72+
Name string
73+
}
74+
75+
// RootProviderResponse is a response to the server-side RootProvider method.
76+
type RootProviderResponse struct {
77+
Provider *Provider
78+
Err error
79+
}
80+
7081
// EvalExprRequest is a request to the server-side EvalExpr method.
7182
type EvalExprRequest struct {
7283
Expr []byte

tflint/interface.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,19 @@ type Runner interface {
5353
// This object contains almost all accessible data structures from plugins.
5454
Config() (*configs.Config, error)
5555

56+
// RootProvider returns the provider configuration in the root module.
57+
// It can be used by child modules to access the credentials defined in the root module.
58+
RootProvider(name string) (*configs.Provider, error)
59+
5660
// EvaluateExpr evaluates the passed expression and reflects the result in ret.
5761
// Since this function returns an application error, it is expected to use the EnsureNoError
5862
// to determine whether to continue processing.
5963
EvaluateExpr(expr hcl.Expression, ret interface{}) error
6064

65+
// EvaluateExprOnRootCtx is the equivalent of EvaluateExpr method in the context of the root module.
66+
// Its main use is to evaluate the provider block obtained by the RootProvider method.
67+
EvaluateExprOnRootCtx(expr hcl.Expression, ret interface{}) error
68+
6169
// EmitIssue sends an issue with an expression to TFLint. You need to pass the message of the issue and the expression.
6270
EmitIssueOnExpr(rule Rule, message string, expr hcl.Expression) error
6371

0 commit comments

Comments
 (0)