diff options
-rw-r--r-- | lib/chef/audit.rb | 21 | ||||
-rw-r--r-- | lib/chef/audit/controls.rb | 120 | ||||
-rw-r--r-- | lib/chef/audit/runner.rb | 62 | ||||
-rw-r--r-- | lib/chef/client.rb | 2 | ||||
-rw-r--r-- | lib/chef/dsl/audit.rb | 4 | ||||
-rw-r--r-- | lib/chef/run_context.rb | 4 |
6 files changed, 65 insertions, 148 deletions
diff --git a/lib/chef/audit.rb b/lib/chef/audit.rb deleted file mode 100644 index 1c28e7ea75..0000000000 --- a/lib/chef/audit.rb +++ /dev/null @@ -1,21 +0,0 @@ -# -# Author:: Claire McQuin (<claire@getchef.com>) -# Copyright:: Copyright (c) 2014 Chef Software, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/dsl/audit' -require 'chef/audit/controls' -require 'chef/audit/runner' diff --git a/lib/chef/audit/controls.rb b/lib/chef/audit/controls.rb deleted file mode 100644 index 61e01b70f2..0000000000 --- a/lib/chef/audit/controls.rb +++ /dev/null @@ -1,120 +0,0 @@ -# -# Author:: Claire McQuin (<claire@getchef.com>) -# Copyright:: Copyright (c) 2014 Chef Software, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'chef/audit/audit_event_proxy' - -class Chef - class Audit - class Controls - - attr_reader :run_context - private :run_context - - ::RSpec::Core::ExampleGroup.define_example_group_method :control - ::RSpec::Core::ExampleGroup.define_example_group_method :__controls__ - - def initialize(run_context, *args, &block) - # To avoid cross-contamination between the configuration in our and other - # spec/spec_helper.rb files and the configuration for audits, we give - # each `controls` group its own RSpec. The files required here manipulate - # RSpec's global configuration, so we wait to load them. - # - # Additionally, name conflicts emerged between Chef's `package` and - # Serverspec's `package`. Requiring serverspec in here eliminates those - # namespace conflict. - # - # TODO: Once we have specs written for audit-mode, I'd like to play with - # which files can be moved around. I'm concerned about how much overhead - # we introduce by sequestering RSpec by `controls` group instead of in - # a common class or shared module. - require 'rspec' - require 'rspec/its' - require 'serverspec/matcher' - require 'serverspec/helper' - require 'serverspec/subject' - require 'specinfra' - - @run_context = run_context - configure - world.register(RSpec::Core::ExampleGroup.__controls__(*args, &block)) - end - - def run - # The first parameter passed to RSpec::Core::Runner.new - # is an instance of RSpec::Core::ConfigurationOptions, which is - # responsible for processing command line options passed through rspec. - # This then gets merged with the configuration. We'll just communicate - # directly with the Configuration here. - RSpec::Core::Runner.new(nil, configuration, world).run_specs(world.ordered_example_groups) - end - - private - def configuration - RSpec.configuration - end - - def world - RSpec.world - end - - # Sets up where output and error streams should stream to, adds formatters - # for people-friendly output of audit results and json for reporting. Also - # configures expectation frameworks. - def configure - # We're setting the output stream, but that will only be used for error situations - # Our formatter forwards events to the Chef event message bus - # TODO so some testing to see if these output to a log file - we probably need - # to register these before any formatters are added. - configuration.output_stream = Chef::Config[:log_location] - configuration.error_stream = Chef::Config[:log_location] - - add_formatters - disable_should_syntax - configure_specinfra - end - - def add_formatters - configuration.add_formatter(RSpec::Core::Formatters::DocumentationFormatter) - configuration.add_formatter(Chef::Audit::AuditEventProxy) - Chef::Audit::AuditEventProxy.events = run_context.events - end - - # Explicitly disable :should syntax. - # - # :should is deprecated in RSpec 3 and we have chosen to explicitly disable it - # in audits. If :should is used in an audit, the audit will fail with error - # message "undefined method `:should`" rather than issue a deprecation warning. - # - # This can be removed when :should is fully removed from RSpec. - def disable_should_syntax - RSpec.configure do |config| - config.expect_with :rspec do |c| - c.syntax = :expect - end - end - end - - def configure_specinfra - # TODO: We may need to change this based on operating system (there is a - # powershell backend) or roll our own. - Specinfra.configuration.backend = :exec - end - - end - end -end diff --git a/lib/chef/audit/runner.rb b/lib/chef/audit/runner.rb index bd8774b9c5..a150336569 100644 --- a/lib/chef/audit/runner.rb +++ b/lib/chef/audit/runner.rb @@ -30,8 +30,68 @@ class Chef end def run - run_context.controls_groups.each { |ctls_grp| ctls_grp.run } + setup + register_controls + runner = RSpec::Core::Runner.new(nil) + runner.run_specs(RSpec.world.ordered_example_groups) end + + private + def setup + require_deps + set_streams + add_formatters + disable_should_syntax + configure_specinfra + add_example_group_methods + end + + def register_controls + run_context.controls.each do |name, group| + ctl_grp = RSpec::Core::ExampleGroup.__controls__(*group[:args], &group[:block]) + RSpec.world.register(ctl_grp) + end + end + + def require_deps + require 'rspec' + require 'rspec/its' + require 'specinfra' + require 'serverspec/helper' + require 'serverspec/matcher' + require 'serverspec/subject' + require 'chef/audit/audit_event_proxy' + require 'chef/audit/rspec_formatter' + end + + def set_streams + RSpec.configuration.output_stream = Chef::Config[:log_location] + RSpec.configuration.error_stream = Chef::Config[:log_location] + end + + def add_formatters + RSpec.configuration.add_formatter(Chef::Audit::AuditEventProxy) + RSpec.configuration.add_formatter(Chef::Audit::RspecFormatter) + Chef::Audit::AuditEventProxy.events = run_context.events + end + + def disable_should_syntax + RSpec.configure do |config| + config.expect_with :rspec do |c| + c.syntax = :expect + end + end + end + + def configure_specinfra + Specinfra.configuration.backend = :exec + end + + def add_example_group_methods + RSpec::Core::ExampleGroup.define_example_group_method :__controls__ + RSpec::Core::ExampleGroup.define_example_group_method :control + end + end end end diff --git a/lib/chef/client.rb b/lib/chef/client.rb index c7ddded1ff..9e1d2dc207 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -25,7 +25,7 @@ require 'chef/log' require 'chef/rest' require 'chef/api_client' require 'chef/api_client/registration' -require 'chef/audit' +require 'chef/audit/runner' require 'chef/node' require 'chef/role' require 'chef/file_cache' diff --git a/lib/chef/dsl/audit.rb b/lib/chef/dsl/audit.rb index 520a667cd4..44c0c56fac 100644 --- a/lib/chef/dsl/audit.rb +++ b/lib/chef/dsl/audit.rb @@ -16,8 +16,6 @@ # limitations under the License. # -require 'rspec/core' - class Chef module DSL module Audit @@ -29,7 +27,7 @@ class Chef name = args[0] raise AuditNameMissing if name.nil? || name.empty? - run_context.controls_groups << Chef::Audit::Controls.new(run_context, args, &block) + run_context.controls[:name] = { :args => args, :block => block } end end diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb index 8f7296822c..a724789d3c 100644 --- a/lib/chef/run_context.rb +++ b/lib/chef/run_context.rb @@ -51,7 +51,7 @@ class Chef attr_accessor :resource_collection # The list of control groups to execute during the audit phase - attr_accessor :controls_groups + attr_accessor :controls # A Hash containing the immediate notifications triggered by resources # during the converge phase of the chef run. @@ -76,7 +76,7 @@ class Chef @node = node @cookbook_collection = cookbook_collection @resource_collection = Chef::ResourceCollection.new - @controls_groups = [] + @controls = {} @immediate_notification_collection = Hash.new {|h,k| h[k] = []} @delayed_notification_collection = Hash.new {|h,k| h[k] = []} @definitions = Hash.new |