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
Catch exceptions in control blocks and fail the control #2987
Conversation
Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
…al test Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
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.
Fantastic work @clintoncwolfe. Thanks for the excellent documentation also!
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.
Looks great! I've added some comments. As usual 100% nitpicks. Feel free to disregard most.
|
||
## A profile context is created | ||
|
||
Like many things in InSpec core, a profile context is an anonymous class. (verify) |
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.
Could we remove (verify)
?
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.
This is a document for us, the inspec team. I wouldn't expect it to be consumed publicly, or if so, only by people trying to work on the guts of inspec. Much lower standdards - the goal is to capture tribal knowledge. It's incomplete, both structurally and content-wise. Some areas might even be factually incorrect. Here, I'm just tempering my certainty; the particular snipe-hunt I was on didn't entail me looking very hard at the profile context. Next time someone needs to know this sort of tribal knowledge, perhaps they can shore it up a bit more, if their research leads them in that direction.
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.
Ah, that makes sense. I suppose leaving those sorts of things in are fine then.
|
||
Like many things in InSpec core, a profile context is an anonymous class. (verify) | ||
|
||
Additionally, a control_eval_context is created. It is an instance of an anonymous class; it has a class<->relationship with its profile context. See `lib/inspec/control_eval_context.rb`. |
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.
I think we could do a reference link to that file if you so chose. I don't mind either way.
|
||
### Each control and their block are wrapped in an anonymous class | ||
|
||
The anonymous class generator is located at `lib/inspec/control_eval_context.rb:24`. At this point, the terminology switches from `control` to `rule`. Each context class inherits from Inspec::Rule, which provides the constructor. |
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.
Same as above, link is nice but not required.
|
||
### The block is instance_eval'd against the control context class | ||
|
||
See `lib/inspec/rule.rb:50`. We're now in two levels of instance eval'ing - the file is gradually being eval'd against the profile context anonymous class, and the current control's block is being instance eval'd against a control context anonymous class. |
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.
Another potential link
|
||
And, the describe and describe.one blocks are executed. | ||
|
||
### TODO: describe blocks are *not* instance-evaled |
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.
Should we remove the TODO?
Note: can skip a control with: | ||
Inspec::Rule.set_skip_rule(control, msg) | ||
|
||
## What else? |
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.
Could we drop this line?
@@ -0,0 +1,8 @@ | |||
name: profile-01 | |||
title: InSpec Profile | |||
maintainer: The Authors |
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.
Some of the other inspec.yml
(all others?) use different metadata values. Not sure if it important though.
See: https://github.com/chef/inspec/blob/master/test/unit/mock/profiles/aws-profile/inspec.yml
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.
I just used whatever inspec init profile
generated. Nothing in the metadata was relevant to the test underway.
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.
I figured, I'll mark it as approved, I don't think the copyright lines and such really matter. Was just going for consistency.
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.
Excellent documentation. =)
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.
Thanks for all the work @clintoncwolfe. Especially the documentation. It's always needed!
When a control block has any kind of exception thrown, we currently abort the run. If it's an Inspec exception, we (sometimes regrettably) suppress the stacktrace and exit with code 1. Other exceptions explode in the normal way.
This behavior goes again doctrine - that nothing in the profile code can derail the inspec run. In this PR, we catch the exception as early as possible; then to fail the control, we inject a dummy resource constructed so that the source location and exception error are preserved.
A functional test has been added to verify the new behavior. Additionally, a document has been added for future developers outlining how profile code is evaluated.
For special review: is the messaging produced when a control fails useful? Could it be reworded, or should we add some of the stack trace or other information available in the caught exception?
Fixes #2981