diff options
author | Claire McQuin <claire@getchef.com> | 2015-07-14 10:08:02 -0700 |
---|---|---|
committer | Claire McQuin <claire@getchef.com> | 2015-07-24 09:57:14 -0700 |
commit | 6819498a6cec34f48611b92aa1a1998c5587b12c (patch) | |
tree | b1c1c36a920decbc427d75fe02b64e67ae13b896 | |
parent | 008d187f572e35a025e68476d3bb449eb7dd3db2 (diff) | |
download | ohai-6819498a6cec34f48611b92aa1a1998c5587b12c.tar.gz |
Load workstation config
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | DOC_CHANGES.md | 10 | ||||
-rw-r--r-- | lib/ohai/application.rb | 20 | ||||
-rw-r--r-- | spec/functional/application_spec.rb | 154 | ||||
-rw-r--r-- | spec/unit/application_spec.rb | 68 |
5 files changed, 254 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bf6d901..91f13bda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ Fix Darwin filesystem plugin on newer MacOSX * [**Claire McQuin**](https://github.com/mcquin): Deprecate Ohai::Config in favor of Ohai::Config.ohai. +* [**Claire McQuin**](https://github.com/mcquin): + Load a configuration file while running as an application. ## Release 8.5.0 diff --git a/DOC_CHANGES.md b/DOC_CHANGES.md index 7b832d75..56470c1d 100644 --- a/DOC_CHANGES.md +++ b/DOC_CHANGES.md @@ -20,3 +20,13 @@ subsection of the `client.rb` documentation should be updated to use If there is any mention of the ability to access configuration options via `Ohai::Config`, it should be updated to `Ohai::Config.ohai`. Additionally, it should be mentioned that `Ohai.config` is an alias for `Ohai::Config.ohai`. + +## Load a configuration file while running ohai as an application +You can specify a configuration file for ohai to load while running as an +application. For example, if your configuration file is located at +`~/.chef/config.rb` you can run ohai with that configuration file with +`ohai -c ~/.chef/config.rb`. + +When running ohai as an application and no configuration file is specified +as a command line parameter, ohai will load a configuration file from your +workstation (`config.rb` or `knife.rb`) if one is found. diff --git a/lib/ohai/application.rb b/lib/ohai/application.rb index 4388fdf7..113b9c82 100644 --- a/lib/ohai/application.rb +++ b/lib/ohai/application.rb @@ -15,6 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +require 'chef-config/workstation_config_loader' require 'ohai' require 'ohai/log' require 'mixlib/cli' @@ -22,6 +23,12 @@ require 'mixlib/cli' class Ohai::Application include Mixlib::CLI + option :config_file, + :short => "-c CONFIG", + :long => "--config CONFIG", + :description => "A configuration file to use", + :proc => lambda { |path| File.expand_path(path, Dir.pwd) } + option :directory, :short => "-d DIRECTORY", :long => "--directory DIRECTORY", @@ -74,6 +81,7 @@ class Ohai::Application @attributes = parse_options @attributes = nil if @attributes.empty? + load_workstation_config Ohai::Config.merge_deprecated_config Ohai.config.merge!(config) if Ohai.config[:directory] @@ -112,4 +120,16 @@ class Ohai::Application Process.exit err end end + + private + def load_workstation_config + config_loader = ChefConfig::WorkstationConfigLoader.new( + config[:config_file], Ohai::Log + ) + begin + config_loader.load + rescue ChefConfig::ConfigurationError => config_error + Ohai::Application.fatal!(config_error.message) + end + end end diff --git a/spec/functional/application_spec.rb b/spec/functional/application_spec.rb new file mode 100644 index 00000000..85b938dc --- /dev/null +++ b/spec/functional/application_spec.rb @@ -0,0 +1,154 @@ +# +# Author:: Claire McQuin <claire@chef.io> +# Copyright:: Copyright (c) 2015 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_relative '../spec_helper' + +require 'ohai/application' + +RSpec.describe 'Ohai::Application' do + + let(:app) { Ohai::Application.new } + let(:argv) { [] } + let(:stderr) { StringIO.new } + + before(:each) do + @original_argv = ARGV.dup + ARGV.replace(argv) + end + + after(:each) do + ARGV.replace(@original_argv) + end + + describe '#configure_ohai' do + + let(:config_content) { '' } + let(:config_dir) { Dir.mktmpdir('.chef') } + let(:config_location) { File.join(config_dir, 'config.rb') } + + before(:each) do + File.open(config_location, 'w+') do |f| + f.write(config_content) + end + end + + after(:each) do + FileUtils.rm_rf(config_dir) + end + + context 'when a configuration file is provided as a command line option' do + + let(:argv) { [ '-c', config_location + '.oops' ] } + + context 'and the configuration file does not exist' do + + it 'logs an error and terminates the application' do + expect(STDERR).to receive(:puts).with(/FATAL:/) + expect(Ohai::Log).to receive(:fatal). + with(/Specified config file #{argv[1]} does not exist/) + expect { app.configure_ohai }.to raise_error(SystemExit) + end + end + end + + context 'when a workstation configuration file exists' do + + let(:config_content) { 'ohai.disabled_plugins = [ :Foo, :Baz ]' } + + # env['KNIFE_HOME']/config.rb is the first config file the workstation + # config loader looks for: + # https://github.com/chef/chef/blob/master/chef-config/lib/chef-config/workstation_config_loader.rb#L102 + let(:env) { { 'KNIFE_HOME' => config_dir } } + + before(:each) do + allow_any_instance_of(ChefConfig::WorkstationConfigLoader). + to receive(:env).and_return(env) + end + + it 'loads the workstation configuration file' do + app.configure_ohai + expect(Ohai.config[:disabled_plugins]).to eq([ :Foo, :Baz ]) + end + end + + context 'when the configuration file contains deprecated config options' do + # For the purpose of these tests it doesn't matter if the configuration + # file was specified via command line or discovered on the local + # workstation. It's easier if we pass the configuration file as a cli + # argument (there's less to stub). + + let(:argv) { [ '-c', config_location ] } + + let(:config_content) do + <<-CONFIG +log_location "#{log_location}" +log_level :#{log_level} +Ohai::Config[:disabled_plugins] = #{disabled_plugins} +Ohai::Config[:plugin_path] << "#{plugin_path}" +CONFIG + end + + # config settings + let(:disabled_plugins) { [ :Foo, :Baz ] } + + let(:log_level) { :debug } + + let(:log_location) { 'path/to/log' } + + let(:plugin_path) { '/path/to/plugins' } + + it 'logs warnings for deprecated options and merges with Ohai.config' do + # deprecation warnings for options need to be stubbed in the order + # they are received, in this case it's the order they appear in the + # configuration file. + options = [ :log_location, :log_level, :disabled_plugins, :plugin_path ] + options.each do |option| + expect(Ohai::Log).to receive(:warn). + with(/Ohai::Config\[:#{option}\] is deprecated/) + end + app.configure_ohai + options.each do |option| + if option == :plugin_path + expect(Ohai.config[option]).to include(self.send(option)) + else + expect(Ohai.config[option]).to eq(self.send(option)) + end + end + end + end + + context 'when the configuration file has a syntax error' do + # For the purpose of these tests it doesn't matter if the configuration + # file was specified via command line or discovered on the local + # workstation. It's easier if we pass the configuration file as a cli + # argument (there's less to stub). + + let(:argv) { [ '-c', config_location ] } + + let(:config_content) { 'config_location "blaaaaa' } + + it 'logs an error and terminates the application' do + expect(STDERR).to receive(:puts).with(/FATAL:/) + expect(Ohai::Log).to receive(:fatal). + with(/You have invalid ruby syntax in your config file/) + expect { app.configure_ohai }.to raise_error(SystemExit) + end + end + + end +end diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index 32b6f8e1..4dfdc24d 100644 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -34,12 +34,80 @@ RSpec.describe 'Ohai::Application' do ARGV.replace(@original_argv) end + def stub_fatal!(expected_message) + expect(STDERR).to receive(:puts).with(expected_message) + expect(Ohai::Log).to receive(:fatal).with(expected_message) + end + describe '#configure_ohai' do it 'merges deprecated config settings into the ohai config context' do expect(Ohai::Config).to receive(:merge_deprecated_config) app.configure_ohai end + describe 'loading configuration from a file' do + let(:config_file) { '/local/workstation/config' } + let(:config_loader) { instance_double('ChefConfig::WorkstationConfigLoader') } + + context 'when specified on the command line' do + let(:argv) { [ '-c', config_file ] } + + before(:each) do + if windows? + expect(ChefConfig::WorkstationConfigLoader).to receive(:new). + with("C:#{config_file}", Ohai::Log). + and_return(config_loader) + else + expect(ChefConfig::WorkstationConfigLoader).to receive(:new). + with(config_file, Ohai::Log). + and_return(config_loader) + end + end + + it 'loads the configuration file' do + expect(config_loader).to receive(:path_exists?). + with(config_file). + and_return(true) + expect(config_loader).to receive(:config_location). + and_return(config_file) + expect(Ohai::Config).to receive(:from_file). + with(config_file) + app.configure_ohai + end + + context 'when the configuration file does not exist' do + let(:expected_message) { Regexp.new("#{config_file} does not exist") } + + it 'terminates the application' do + expect(config_loader).to receive(:path_exists?). + with(config_file). + and_return(false) + expect(Ohai::Application).to receive(:fatal!). + with(expected_message). + and_call_original + stub_fatal!(expected_message) + expect { app.configure_ohai }.to raise_error(SystemExit) + end + end + end + + context 'when a local workstation config exists' do + before(:each) do + expect(ChefConfig::WorkstationConfigLoader).to receive(:new). + with(nil, Ohai::Log). + and_return(config_loader) + end + + it 'loads the configuration file' do + expect(config_loader).to receive(:config_location). + and_return(config_file) + expect(Ohai::Config).to receive(:from_file). + with(config_file) + app.configure_ohai + end + end + end + context 'when CLI options are provided' do let(:argv) { [ '-d', directory ] } let(:directory) { '/some/fantastic/plugins' } |