inspec/lib/verify/profiles.rb

124 lines
3.4 KiB
Ruby
Raw Normal View History

# encoding: utf-8
# copyright: 2015, Dominik Richter
2015-10-06 16:55:44 +00:00
# author: Dominik Richter
# author: Christoph Hartmann
# license: All rights reserved
2015-10-06 16:55:44 +00:00
require 'verify/specfile'
require 'vulcano/log'
module Vulcano
# Handle Vulcano Profiles
class Profiles
attr_reader :profiles
2015-09-03 18:43:58 +00:00
def initialize(opts = {})
@profiles = {}
@profile_id = opts[:id]
@log = Log.new(opts)
end
2015-09-03 18:43:58 +00:00
def add_folder(f)
2015-09-05 14:07:54 +00:00
path = File.expand_path(f)
if File.directory? path
add_specs_in_folder path
else
@log.error "Path is not a folder: #{path}"
end
self
end
2015-09-03 18:43:58 +00:00
def valid_folder?(f)
2015-09-05 14:07:54 +00:00
path = File.expand_path(f)
if !File.directory? path
return @log.error "This is not a folder: #{path}"
else
2015-09-03 21:18:28 +00:00
@log.ok 'Valid directory'
end
metadata = Metadata.for_path(path, @profile_id)
2015-09-03 21:18:28 +00:00
@log.ok 'vmetadata.rb' unless metadata.nil? or !metadata.valid?
specs = Dir["#{path}/spec/*_spec.rb"]
if specs.empty?
@log.warn "No tests found in #{path}"
end
2015-09-05 14:07:54 +00:00
specs.each { |s| valid_spec? s, metadata }
end
2015-09-03 18:43:58 +00:00
def valid_spec?(f, metadata)
2015-09-05 14:07:54 +00:00
return @log.error "Can't find spec file #{f}" unless File.file? f
# Load the spec file
specs = SpecFile.from_file(f, metadata)
valid = validate_spec_file(specs)
return unless valid && specs.instance_variable_get(:@invalid_calls).empty?
@log.ok "Valid spec file in #{f} with #{meta['rules'].length} rules"
end
private
def validate_spec_file(specs, invalid) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
valid = true
# helper for printing violations
invalid = lambda {|type, msg|
2015-09-05 14:07:54 +00:00
@log.send type, "#{msg} (#{File.basename f})"
valid = false if type == :error
}
# find all errors during parsing
specs.errors.each do |err|
2015-09-25 17:46:46 +00:00
invalid.call(:error, err)
end
# detect missing metadata
meta = specs.metadata
if meta['title'].nil?
2015-09-25 17:46:46 +00:00
invalid.call(:warn, 'Missing title in spec file')
end
if meta['copyright'].nil?
2015-09-25 17:46:46 +00:00
invalid.call(:warn, 'Missing copyright in spec file')
end
# detect empty rules
unless meta['rules'][''].nil?
2015-09-25 17:46:46 +00:00
invalid.call(:error, 'Please configure IDs for all rules.')
end
2015-09-25 17:46:46 +00:00
meta['rules'].each do |k, v|
if v['impact'].nil?
2015-09-25 17:46:46 +00:00
invalid.call(:error, "Missing impact for rule #{k}")
else
2015-09-25 17:46:46 +00:00
invalid.call(:error, "Impact cannot be larger than 1.0 for rule #{k}") if v['impact'] > 1.0
invalid.call(:error, "Impact cannot be less than 0.0 for rule #{k}") if v['impact'] < 0.0
end
2015-09-25 17:46:46 +00:00
invalid.call(:warn, "Missing title for rule #{k}") if v['title'].nil?
invalid.call(:warn, "Missing description for rule #{k}") if v['desc'].nil?
end
valid
end
2015-09-03 18:43:58 +00:00
def add_specs_in_folder(path)
allrules = {}
meta = Metadata.for_path(path, @profile_id, @log)
Dir["#{path}/spec/*_spec.rb"].each do |specfile|
2015-09-05 14:07:54 +00:00
rel_path = specfile.sub(File.join(path, ''), '')
specs = SpecFile.from_file(specfile, meta)
allrules[rel_path] = sanitize_specfile_json(specs.metadata)
end
meta.dict['rules'] = allrules
@profiles = meta.dict
end
2015-09-03 18:43:58 +00:00
def sanitize_specfile_json(j)
2015-09-05 14:07:54 +00:00
j['rules'].each do |k, v|
v['title'] = k if v['title'].nil?
2015-09-05 14:07:54 +00:00
v['desc'] = '' if v['desc'].nil?
v['impact'] = 0.5 if v['impact'].nil?
end
j
end
end
end