-
Notifications
You must be signed in to change notification settings - Fork 878
fix(provisioner/terraform/tfparse): skip evaluation of unrelated parameters #16023
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
e56cac7
78d88fe
222fd90
de5541b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,7 +80,7 @@ func New(workdir string, opts ...Option) (*Parser, tfconfig.Diagnostics) { | |
} | ||
|
||
// WorkspaceTags looks for all coder_workspace_tags datasource in the module | ||
// and returns the raw values for the tags. Use | ||
// and returns the raw values for the tags. | ||
func (p *Parser) WorkspaceTags(ctx context.Context) (map[string]string, error) { | ||
tags := map[string]string{} | ||
var skipped []string | ||
|
@@ -166,13 +166,17 @@ func (p *Parser) WorkspaceTagDefaults(ctx context.Context) (map[string]string, e | |
return nil, xerrors.Errorf("extract workspace tags: %w", err) | ||
} | ||
|
||
if len(tags) == 0 { | ||
return map[string]string{}, nil | ||
} | ||
|
||
// To evaluate the expressions, we need to load the default values for | ||
// variables and parameters. | ||
varsDefaults, err := p.VariableDefaults(ctx) | ||
varsDefaults, err := p.VariableDefaults(ctx, tags) | ||
if err != nil { | ||
return nil, xerrors.Errorf("load variable defaults: %w", err) | ||
} | ||
paramsDefaults, err := p.CoderParameterDefaults(ctx, varsDefaults) | ||
paramsDefaults, err := p.CoderParameterDefaults(ctx, varsDefaults, tags) | ||
if err != nil { | ||
return nil, xerrors.Errorf("load parameter defaults: %w", err) | ||
} | ||
|
@@ -247,28 +251,39 @@ func WriteArchive(bs []byte, mimetype string, path string) error { | |
return nil | ||
} | ||
|
||
// VariableDefaults returns the default values for all variables passed to it. | ||
func (p *Parser) VariableDefaults(ctx context.Context) (map[string]string, error) { | ||
// VariableDefaults returns the default values for all variables referenced in the values of tags. | ||
func (p *Parser) VariableDefaults(ctx context.Context, tags map[string]string) (map[string]string, error) { | ||
var skipped []string | ||
// iterate through vars to get the default values for all | ||
// variables. | ||
// required variables. | ||
m := make(map[string]string) | ||
for _, v := range p.module.Variables { | ||
if v == nil { | ||
continue | ||
} | ||
var found bool | ||
for _, tv := range tags { | ||
if strings.Contains(tv, v.Name) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. won't a Like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is a test case: {
name: "overlapping var name",
files: map[string]string{
`main.tf`: `
// This file is the same as the above, except for this comment.
variable "a" {
type = string
default = "1"
}
variable "ab" {
description = "This is a variable of type string"
type = string
default = jsonencode(["a", "b"])
}
data "coder_workspace_tags" "tags" {
tags = {
"foo": "bar",
"a": var.a,
}
}`,
},
reqTags: map[string]string{"foo": "noclobber"},
wantTags: map[string]string{"owner": "", "scope": "organization", "foo": "bar", "a": "1"},
}, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha, we may then need to do some more "intelligent" parsing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the reason you do a contains because it could be an expression like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any way to parse the expression and get the actual tokens? Or we only have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. I'm looking into HCL traversals now as they might allow us to do this cleanly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I've modified the implementation to instead:
|
||
found = true | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: you could extract this block and the one below to a common helper function |
||
if !found { | ||
skipped = append(skipped, "var."+v.Name) | ||
continue | ||
} | ||
sv, err := interfaceToString(v.Default) | ||
if err != nil { | ||
return nil, xerrors.Errorf("can't convert variable default value to string: %v", err) | ||
} | ||
m[v.Name] = strings.Trim(sv, `"`) | ||
} | ||
p.logger.Debug(ctx, "found default values for variables", slog.F("defaults", m)) | ||
p.logger.Debug(ctx, "found default values for variables", slog.F("defaults", m), slog.F("skipped", skipped)) | ||
return m, nil | ||
} | ||
|
||
// CoderParameterDefaults returns the default values of all coder_parameter data sources | ||
// in the parsed module. | ||
func (p *Parser) CoderParameterDefaults(ctx context.Context, varsDefaults map[string]string) (map[string]string, error) { | ||
func (p *Parser) CoderParameterDefaults(ctx context.Context, varsDefaults map[string]string, tags map[string]string) (map[string]string, error) { | ||
defaultsM := make(map[string]string) | ||
var ( | ||
skipped []string | ||
|
@@ -290,6 +305,18 @@ func (p *Parser) CoderParameterDefaults(ctx context.Context, varsDefaults map[st | |
continue | ||
} | ||
|
||
var found bool | ||
needle := strings.Join([]string{"data", dataResource.Type, dataResource.Name}, ".") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I can tell, there is no way to break a variable reference over multiple lines e.g.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. correct 👍 |
||
for _, tv := range tags { | ||
if strings.Contains(tv, needle) { | ||
found = true | ||
} | ||
} | ||
if !found { | ||
skipped = append(skipped, needle) | ||
continue | ||
} | ||
|
||
// We know in which HCL file is the data resource defined. | ||
// NOTE: hclparse.Parser will cache multiple successive calls to parse the same file. | ||
file, diags = p.underlying.ParseHCLFile(dataResource.Pos.Filename) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.