summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaire McQuin <claire@getchef.com>2015-07-14 10:08:02 -0700
committerClaire McQuin <claire@getchef.com>2015-07-24 09:57:14 -0700
commit6819498a6cec34f48611b92aa1a1998c5587b12c (patch)
treeb1c1c36a920decbc427d75fe02b64e67ae13b896
parent008d187f572e35a025e68476d3bb449eb7dd3db2 (diff)
downloadohai-6819498a6cec34f48611b92aa1a1998c5587b12c.tar.gz
Load workstation config
-rw-r--r--CHANGELOG.md2
-rw-r--r--DOC_CHANGES.md10
-rw-r--r--lib/ohai/application.rb20
-rw-r--r--spec/functional/application_spec.rb154
-rw-r--r--spec/unit/application_spec.rb68
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' }