diff options
-rw-r--r-- | lib/chef.rb | 2 | ||||
-rw-r--r-- | lib/chef/chef_class.rb | 6 | ||||
-rw-r--r-- | lib/chef/event_dispatch/dsl.rb | 46 | ||||
-rw-r--r-- | lib/chef/exceptions.rb | 1 | ||||
-rw-r--r-- | spec/unit/chef_class_spec.rb | 23 |
5 files changed, 77 insertions, 1 deletions
diff --git a/lib/chef.rb b/lib/chef.rb index 6bce976439..1a0b802adb 100644 --- a/lib/chef.rb +++ b/lib/chef.rb @@ -31,5 +31,5 @@ require 'chef/daemon' require 'chef/run_status' require 'chef/handler' require 'chef/handler/json_file' - +require 'chef/event_dispatch/dsl' require 'chef/chef_class' diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb index d3f7ee55c7..60dd5efef4 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -43,6 +43,12 @@ class Chef # @return [Chef::RunContext] run_context of the chef-client run attr_reader :run_context + # Adds an event handler with user defined block + def event_handler(&block) + dsl = Chef::EventDispatch::DSL.new + dsl.instance_eval(&block) + end + # Get the array of providers associated with a resource_name for the current node # # @param resource_name [Symbol] name of the resource as a symbol diff --git a/lib/chef/event_dispatch/dsl.rb b/lib/chef/event_dispatch/dsl.rb new file mode 100644 index 0000000000..f61ea90580 --- /dev/null +++ b/lib/chef/event_dispatch/dsl.rb @@ -0,0 +1,46 @@ +# +# Author:: Ranjib Dey (<ranjib@linux.com>) +# Copyright:: Copyright (c) 2015 Ranjib Dey +# 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/event_dispatch/base' +require 'chef/exceptions' +require 'chef/config' + +class Chef + module EventDispatch + class DSL + # Adds a new event handler derived from base handler + # with user defined block against a chef event + # + # @return [Chef::EventDispatch::Base] a base handler object + def on(event_type, &block) + validate!(event_type) + handler = Chef::EventDispatch::Base.new + handler.define_singleton_method(event_type) do |*args| + block.call(args) + end + Chef::Config[:event_handlers] << handler + handler + end + + private + def validate!(event_type) + all_event_types = (Chef::EventDispatch::Base.instance_methods - Object.instance_methods) + raise Chef::Exceptions::UnknownEventType unless all_event_types.include?(event_type) + end + end + end +end diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb index eea6a2f239..0b7b1634ad 100644 --- a/lib/chef/exceptions.rb +++ b/lib/chef/exceptions.rb @@ -91,6 +91,7 @@ class Chef class InvalidResourceReference < RuntimeError; end class ResourceNotFound < RuntimeError; end class VerificationNotFound < RuntimeError; end + class UnknownEventType < ArgumentError; end # Can't find a Resource of this type that is valid on this platform. class NoSuchResourceType < NameError diff --git a/spec/unit/chef_class_spec.rb b/spec/unit/chef_class_spec.rb index 2528246be6..65a637dcbb 100644 --- a/spec/unit/chef_class_spec.rb +++ b/spec/unit/chef_class_spec.rb @@ -88,4 +88,27 @@ describe "Chef class" do expect(Chef.node).to eql(node) end end + + context '#event_handler' do + it 'adds a new handler' do + x = 1 + Chef.event_handler do + on :converge_start do + x = 2 + end + end + expect(Chef::Config[:event_handlers]).to_not be_empty + Chef::Config[:event_handlers].first.send(:converge_start) + expect(x).to eq(2) + end + + it 'raise error if unknown event type is passed' do + expect do + Chef.event_handler do + on :yolo do + end + end + end.to raise_error(Chef::Exceptions::UnknownEventType) + end + end end |