CFINSPEC-542 Bug fix for profiles with dependent profiles (#6377) (#6435)

* Matching semver using regex to determine profile name without version in dsl logic



* Testing for selecting control using version in require control dsl



* Documentation for using version with profile name when including or selecting controls in a profile



* Commenting in dsl library about logic for fetching version and matching it



* Comment for regex used to fetch version



* Minor improvement for regex variable placement

Signed-off-by: Nikita Mathur <nikita.mathur@chef.io>
Co-authored-by: Nikita Mathur <Nik08@users.noreply.github.com>
This commit is contained in:
Vasundhara Jagdale 2023-02-26 20:37:28 +05:30 committed by GitHub
parent bbf4c7eabe
commit 812001abcc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 4 deletions

View file

@ -404,6 +404,44 @@ As with the prior example, only `baseline-2` and `baseline-4` are executed, but
if `baseline-2` fails, it will report with an impact of `0.5` instead of the
originally-intended `1.0` impact.
## Including or Selecting controls from a profile with same name and different version.
When an inspec profile has dependency on another profile to it's specific version, then the controls can be included or selected by using profile name with version separated by `-`.
Here, the Profile - A has following dependency:
```yaml
name: profile-a
depends:
- name: ssh
git: https://github.com/dev-sec/ssh-baseline.git
tag: 2.6.0
```
And Profile - B has following dependency:
```yaml
name: profile-b
depends:
- name: ssh
git: https://github.com/dev-sec/ssh-baseline.git
tag: 2.7.0
```
Controls of these profiles can be included or required in a profile in a following manner:
```ruby
include_controls "ssh-2.6.0"
include_controls "ssh-2.7.0"
```
OR
```ruby
require_controls "ssh-2.6.0"
require_controls "ssh-2.7.0"
```
## Using Resources from an Included Profile
By default, all of the custom resources from a listed dependency are available

View file

@ -91,13 +91,19 @@ module Inspec::DSL
if profile_version
new_profile_id = "#{profile_id}-#{profile_version}"
else
# This scary regex is used to match version following semantic Versioning (SemVer). Thanks to https://ihateregex.io/expr/semver/
regex_for_semver = /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?/
dependencies.list.keys.each do |key|
# 1. Fetching VERSION from a profile dependency name which is in a format NAME-VERSION.
# 2. Matching original profile dependency name with profile name used with include or require control DSL.
fetching_semver = key.match(regex_for_semver).to_s
unless fetching_semver.nil? || fetching_semver.empty?
profile_id_key = key.split("-#{fetching_semver}")[0]
new_profile_id = key if profile_id_key == profile_id
end
end
end
# If dep profile does not contain a source version, key does not contain a version as well. In that case new_profile_id will be always nil and instead profile_id would be used to fetch profile from dependency list.
profile_id_key = key.split("-")
profile_id_key.pop
new_profile_id = key if profile_id_key.join("-") == profile_id
end
end
dep_entry = new_profile_id ? dependencies.list[new_profile_id] : dependencies.list[profile_id]
if dep_entry.nil?

View file

@ -0,0 +1,3 @@
require_controls "ssh-2.6.0" do
control "sshd-01"
end

View file

@ -0,0 +1,14 @@
name: child-profile-3
title: InSpec Profile
maintainer: The Authors
copyright: The Authors
copyright_email: you@example.com
license: Apache-2.0
summary: An InSpec Compliance Profile
version: 0.1.0
supports:
platform: os
depends:
- name: ssh
git: https://github.com/dev-sec/ssh-baseline.git
tag: 2.6.0

View file

@ -1319,6 +1319,17 @@ EOT
_(run_result.stdout).must_include "sshd-50"
end
end
describe "DSL with version: when profiles are dependent on different versions of same profile" do
let(:profile) { "#{profile_path}/git-fetcher/inheritance/child-profile-3" }
let(:run_result) { run_inspec_process("exec #{profile}") }
it "should evaluate all test controls of all versions correctly" do
skip_windows!
_(run_result.stderr).must_be_empty
_(run_result.stdout).must_include "2.6.0"
_(run_result.stdout).must_include "sshd-01"
end
end
end
if windows?