mirror of
https://github.com/inspec/inspec
synced 2024-11-27 15:10:44 +00:00
f5ec7c9c65
Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com>
100 lines
4.2 KiB
Markdown
100 lines
4.2 KiB
Markdown
# Centralized Deprecation Facility
|
|
|
|
## Overview
|
|
|
|
The centralized deprecation facility is used to deprecate (retire, withdraw, etc) features both within InSpec core code, InSpec core resources, plugins, and custom resources.
|
|
|
|
The most important goal of the deprecation facility was to collect decisions about what actions should be taken for a deprecation in a central place, so that it is easier to handle major version changes.
|
|
|
|
### Example
|
|
|
|
```
|
|
# In some code in InSpec core
|
|
def something_crufty
|
|
Inspec.deprecate :old_feature, 'Don't call something_crufty anymore'
|
|
end
|
|
```
|
|
|
|
If that gets called, `inspec` will consult the deprecation configuration, and then execute one of four actions: warn, fail_control, exit, or ignore.
|
|
|
|
## Concepts
|
|
|
|
### Basic Concept: Anti-Feature Flags
|
|
|
|
In many applications, `feature flags` are used to deploy new feature code, without actually revealing it to the user. When certain conditions are met, the deployment team enables the flags, and the feature goes live.
|
|
|
|
Inverting this idea, we could use flags to withdraw features. For example, if we wish to retire the `lusers` property on the `shadow` resource, we might add:
|
|
|
|
```
|
|
# In lib/resources/shadow.rb
|
|
def lusers
|
|
Inspec.deprecate :old_shadow_fields, 'Please use the `users` property instead.'
|
|
end
|
|
```
|
|
|
|
Then, in `etc/deprecations.json` in version 3.5, we might add:
|
|
```
|
|
"groups": {
|
|
"old_shadow_features": { "action": "ignore" }
|
|
}
|
|
```
|
|
|
|
This makes the deprecation silent - it is there and ready to be triggered, but has no effect yet. We can add more deprecation declarations, using the `old_shadow_features` group. Then, when we decide that we'll start warning about it in v4.0 and withdraw it in v5.0, we can simply change the config file - we don't have to change every deprecation:
|
|
|
|
For v4:
|
|
```
|
|
"groups": {
|
|
"old_shadow_features": { "action": "warn", "suffix": "Certain properties of shadow will be withdrawn in InSpec v5.0" }
|
|
}
|
|
```
|
|
|
|
Now, a warning (fed through `Inspec::Log.warn`) will appear each time the property is accessed, but it will otherwise behave normally.
|
|
|
|
For v5, you have some choices as to how to harden the deprecation. `fail_control` will fail any control the deprecation is used in; while `exit` will exit the inspec run entirely.
|
|
|
|
For v5:
|
|
```
|
|
"groups": {
|
|
"old_shadow_features": { "action": "exit", "suffix": "Certain properties of shadow were deprecated in v4 and have now been removed in v5." }
|
|
}
|
|
```
|
|
|
|
Again, no need to update the deprecation calls; though in v6 it might make sense to remove the old code entirely.
|
|
|
|
### Groups
|
|
|
|
When you make a deprecation message, you add it to a group. InSpec will read the file `$INSPEC_INSTALL_ROOT/etc/deprecation.json` to determine the known groups - you may add to that file at any time.
|
|
|
|
If you make a deprecation using a group that is unknown, InSpec will by default treat it as a warning. You can change that behavior by setting the "unknown_group_action" top-level property to any of the valid actions.
|
|
|
|
There are no restrictions on the number or the naming of groups; you can have as many or as few as needed.
|
|
|
|
### Message Assembly
|
|
|
|
For all actions except `ignore`, a message is assembled, consisting of:
|
|
|
|
* The string 'DEPRECATION'
|
|
* The value of the `prefix` field of the group, if any
|
|
* The specific message provided by the deprecation declaration
|
|
* The value of the `suffix` field of the group, if any
|
|
* If possible, the string '(used at ' followed by a `path/file.rb:lineno` to help the user locate the deprecation in *their code*.
|
|
|
|
### Actions
|
|
|
|
#### exit
|
|
|
|
Issues an ERROR via `Inspec::Log.error` with the assembled message, then immediately exits the process via Inspec::UI. The reporters are not executed. By default, the exit code will be 3; but you can set a different code using the `exit_status` property of the group in the config file.
|
|
|
|
#### fail_control
|
|
|
|
Checks to see if the code is being called within a control block; if so, raises a FailedResource exception with the assembled message, which causes the control to fail in the reporter.
|
|
|
|
If the code is outside a control, the `warn` action is triggered instead.
|
|
|
|
#### ignore
|
|
|
|
Does nothing; this is very useful for staging deprecations - you can have the deprecations in place, then enable them later.
|
|
|
|
#### warn
|
|
|
|
Issues a WARN to the `Inspec::Log.warn` facility with the assembled message.
|