mirror of
https://github.com/inspec/inspec
synced 2024-11-14 08:57:11 +00:00
Merge pull request #161 from chef/bugfix-profile
Merged change 5ce5796b-e97e-4826-a9de-9848865207af From review branch bugfix-profile into master Signed-off-by: chartmann <chartmann@chef.io>
This commit is contained in:
commit
6ddc45446d
9 changed files with 114 additions and 40 deletions
|
@ -27,17 +27,17 @@ module Inspec
|
|||
description
|
||||
version
|
||||
}.each do |name|
|
||||
define_method name do |arg|
|
||||
params[name] = arg
|
||||
define_method name.to_sym do |arg|
|
||||
params[name.to_sym] = arg
|
||||
end
|
||||
end
|
||||
|
||||
def supports(sth, version = nil)
|
||||
params['supports'] ||= []
|
||||
params['supports'].push(
|
||||
params[:supports] ||= []
|
||||
params[:supports].push(
|
||||
{
|
||||
'os' => sth,
|
||||
'version' => version,
|
||||
os: sth,
|
||||
version: version,
|
||||
},
|
||||
)
|
||||
end
|
||||
|
@ -45,20 +45,20 @@ module Inspec
|
|||
def valid?
|
||||
is_valid = true
|
||||
%w{ name title version summary }.each do |field|
|
||||
next unless params[field].nil?
|
||||
@log.error("Missing profile #{field} in metadata.rb")
|
||||
next unless params[field.to_sym].nil?
|
||||
@logger.error("Missing profile #{field} in metadata.rb")
|
||||
is_valid = false
|
||||
end
|
||||
%w{ maintainer copyright }.each do |field|
|
||||
next unless params[field].nil?
|
||||
@log.warn("Missing profile #{field} in metadata.rb")
|
||||
next unless params[field.to_sym].nil?
|
||||
@logger.warn("Missing profile #{field} in metadata.rb")
|
||||
is_valid = false
|
||||
end
|
||||
is_valid && @missing_methods.empty?
|
||||
end
|
||||
|
||||
def method_missing(sth, *args)
|
||||
@log.warn "metadata.rb doesn't support: #{sth} #{args}"
|
||||
@logger.warn "metadata.rb doesn't support: #{sth} #{args}"
|
||||
@missing_methods.push(sth)
|
||||
end
|
||||
|
||||
|
@ -72,7 +72,7 @@ module Inspec
|
|||
|
||||
res = Metadata.new(logger)
|
||||
res.instance_eval(File.read(path), path, 1)
|
||||
res.dict['name'] = profile_id.to_s unless profile_id.to_s.empty?
|
||||
res.params[:name] = profile_id.to_s unless profile_id.to_s.empty?
|
||||
res
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,8 @@ require 'inspec/metadata'
|
|||
module Inspec
|
||||
class Profile
|
||||
def self.from_path(path, options = nil)
|
||||
opt = options.dup || {}
|
||||
opt = {}
|
||||
options.each { |k, v| opt[k.to_sym] = v } unless options.nil?
|
||||
opt[:path] = path
|
||||
Profile.new(opt)
|
||||
end
|
||||
|
@ -18,9 +19,9 @@ module Inspec
|
|||
|
||||
def initialize(options = nil)
|
||||
@options = options || {}
|
||||
@profile_id = options[:id] || nil
|
||||
@params = {}
|
||||
@logger = options.delete(:logger) || Logger.new(nil)
|
||||
@profile_id = options.delete(:profile_id)
|
||||
@logger = options[:logger] || Logger.new(nil)
|
||||
|
||||
@path = @options[:path]
|
||||
fail 'Cannot read an empty path.' if @path.nil? || @path.empty?
|
||||
|
@ -29,14 +30,16 @@ module Inspec
|
|||
@metadata = read_metadata
|
||||
@params = @metadata.params unless @metadata.nil?
|
||||
|
||||
@params['rules'] = rules = {}
|
||||
@params[:rules] = rules = {}
|
||||
@runner = Runner.new(
|
||||
id: @profile_id,
|
||||
backend: :mock,
|
||||
)
|
||||
@runner.add_tests([@path])
|
||||
@runner.rules.each do |id, rule|
|
||||
rules[id] = {
|
||||
file = rule.instance_variable_get(:@__file)
|
||||
rules[file] ||= {}
|
||||
rules[file][id] = {
|
||||
title: rule.title,
|
||||
desc: rule.desc,
|
||||
impact: rule.impact,
|
||||
|
@ -49,17 +52,21 @@ module Inspec
|
|||
def info
|
||||
res = @params.dup
|
||||
rules = {}
|
||||
res['rules'].each do |id, rule|
|
||||
next if id.to_s.empty?
|
||||
|
||||
data = rule.dup
|
||||
data.delete(:checks)
|
||||
data[:impact] ||= 0.5
|
||||
data[:impact] = 1.0 if data[:impact] > 1.0
|
||||
data[:impact] = 0.0 if data[:impact] < 0.0
|
||||
rules[id] = data
|
||||
res[:rules].each do |gid, group|
|
||||
next if gid.to_s.empty?
|
||||
path = gid.sub(File.join(@path, ''), '')
|
||||
rules[path] = { title: '', rules: {} }
|
||||
group.each do |id, rule|
|
||||
next if id.to_s.empty?
|
||||
data = rule.dup
|
||||
data.delete(:checks)
|
||||
data[:impact] ||= 0.5
|
||||
data[:impact] = 1.0 if data[:impact] > 1.0
|
||||
data[:impact] = 0.0 if data[:impact] < 0.0
|
||||
rules[path][:rules][id] = data
|
||||
end
|
||||
end
|
||||
res['rules'] = rules
|
||||
res[:rules] = rules
|
||||
res
|
||||
end
|
||||
|
||||
|
@ -81,26 +88,26 @@ module Inspec
|
|||
|
||||
@logger.info "Checking profile in #{@path}"
|
||||
|
||||
if @params['name'].to_s.empty?
|
||||
if @params[:name].to_s.empty?
|
||||
error.call('No profile name defined')
|
||||
elsif !(@params['name'].to_s =~ %r{^\S+\/\S+$})
|
||||
elsif !(@params[:name].to_s =~ %r{^\S+\/\S+$})
|
||||
error.call('Profile name must be defined as: OWNER/ID')
|
||||
end
|
||||
|
||||
warn.call('No version defined') if @params['version'].to_s.empty?
|
||||
warn.call('No title defined') if @params['title'].to_s.empty?
|
||||
warn.call('No maintainer defined') if @params['maintainer'].to_s.empty?
|
||||
warn.call('No supports defined') if @params['supports'].empty?
|
||||
warn.call('No version defined') if @params[:name].to_s.empty?
|
||||
warn.call('No title defined') if @params[:name].to_s.empty?
|
||||
warn.call('No maintainer defined') if @params[:name].to_s.empty?
|
||||
warn.call('No supports defined') if @params[:name].empty?
|
||||
@logger.info 'Metadata OK.' if no_warnings
|
||||
|
||||
no_warnings = true
|
||||
if @params['rules'].empty?
|
||||
if @params[:name].empty?
|
||||
warn.call('No rules were found.')
|
||||
else
|
||||
@logger.debug "Found #{@params['rules'].length} rules."
|
||||
@logger.debug "Found #{@params[:name].length} rules."
|
||||
end
|
||||
|
||||
@params['rules'].each do |id, rule|
|
||||
@params[:name].each do |id, rule|
|
||||
error.call('Avoid rules with empty IDs') if id.nil? or id.empty?
|
||||
warn.call("Rule #{id} has no title") if rule[:title].to_s.empty?
|
||||
warn.call("Rule #{id} has no description") if rule[:desc].to_s.empty?
|
||||
|
|
|
@ -27,6 +27,7 @@ module Inspec
|
|||
end
|
||||
|
||||
def load(content, source = nil, line = nil)
|
||||
@current_file = source
|
||||
@profile_context.instance_eval(content, source || 'unknown', line || 1)
|
||||
end
|
||||
|
||||
|
@ -37,6 +38,7 @@ module Inspec
|
|||
|
||||
def register_rule(r)
|
||||
# get the full ID
|
||||
r.instance_variable_set(:@__file, @current_file)
|
||||
full_id = Inspec::Rule.full_id(@profile_id, r)
|
||||
if full_id.nil?
|
||||
# TODO: error
|
||||
|
|
|
@ -26,8 +26,15 @@ module Inspec
|
|||
|
||||
def example_group
|
||||
that = self
|
||||
outer_clr = calls[0][3]
|
||||
RSpec::Core::ExampleGroup.describe(that.value, caller: outer_clr) do
|
||||
|
||||
opts = { 'caller' => calls[0][3] }
|
||||
if !calls[0][3].nil? && !calls[0][3].empty? &&
|
||||
(m = calls[0][3][0].match(/^([^:]*):(\d+):/))
|
||||
opts['file_path'] = m[0]
|
||||
opts['line_number'] = m[1]
|
||||
end
|
||||
|
||||
RSpec::Core::ExampleGroup.describe(that.value, opts) do
|
||||
that.calls.each do |method, args, block, clr|
|
||||
it(nil, caller: clr) do
|
||||
x = expect(that.value, &that.block).method(method)
|
||||
|
|
|
@ -83,17 +83,24 @@ module Inspec
|
|||
private
|
||||
|
||||
def get_check_example(method_name, arg, block)
|
||||
opts = {}
|
||||
if !block.nil? && block.respond_to?(:source_location)
|
||||
file_path, line = block.source_location
|
||||
opts['file_path'] = file_path
|
||||
opts['line_number'] = line
|
||||
end
|
||||
|
||||
if !arg.empty? &&
|
||||
arg[0].respond_to?(:resource_skipped) &&
|
||||
!arg[0].resource_skipped.nil?
|
||||
return RSpec::Core::ExampleGroup.describe(*arg) do
|
||||
return RSpec::Core::ExampleGroup.describe(*arg, opts) do
|
||||
it arg[0].resource_skipped
|
||||
end
|
||||
else
|
||||
# add the resource
|
||||
case method_name
|
||||
when 'describe'
|
||||
return RSpec::Core::ExampleGroup.describe(*arg, &block)
|
||||
return RSpec::Core::ExampleGroup.describe(*arg, opts, &block)
|
||||
when 'expect'
|
||||
return block.example_group
|
||||
else
|
||||
|
|
|
@ -15,6 +15,7 @@ end
|
|||
|
||||
require 'inspec/resource'
|
||||
require 'inspec/backend'
|
||||
require 'inspec/profile'
|
||||
|
||||
class MockLoader
|
||||
# pass the os identifier to emulate a specific operating system
|
||||
|
|
0
test/unit/mock/profiles/empty/metadata.rb
Normal file
0
test/unit/mock/profiles/empty/metadata.rb
Normal file
1
test/unit/mock/profiles/metadata/metadata.rb
Normal file
1
test/unit/mock/profiles/metadata/metadata.rb
Normal file
|
@ -0,0 +1 @@
|
|||
name 'metadata profile'
|
49
test/unit/profile_test.rb
Normal file
49
test/unit/profile_test.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
# encoding: utf-8
|
||||
# author: Christoph Hartmann
|
||||
# author: Dominik Richter
|
||||
|
||||
require 'helper'
|
||||
|
||||
def load_profile(name)
|
||||
pwd = File.dirname(__FILE__)
|
||||
Inspec::Profile.from_path("#{pwd}/mock/profiles/#{name}")
|
||||
end
|
||||
|
||||
describe Inspec::Profile do
|
||||
before {
|
||||
# mock up the profile runner
|
||||
# TODO: try to take the real profile runner here;
|
||||
# currently it's stopped at test runner conflicts
|
||||
class Inspec::Profile::Runner
|
||||
def initialize(opts) end
|
||||
def add_tests(tests) end
|
||||
def rules
|
||||
{}
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
describe 'with empty profile' do
|
||||
let(:profile) { load_profile('empty') }
|
||||
|
||||
it 'has no metadata' do
|
||||
profile.params[:name].must_be_nil
|
||||
end
|
||||
|
||||
it 'has no rules' do
|
||||
profile.params[:rules].must_equal({})
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with normal metadata in profile' do
|
||||
let(:profile) { load_profile('metadata') }
|
||||
|
||||
it 'has metadata' do
|
||||
profile.params[:name].must_equal 'metadata profile'
|
||||
end
|
||||
|
||||
it 'has no rules' do
|
||||
profile.params[:rules].must_equal({})
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue