This adds two REST API:
* /instrumentation_listener(s)/<instrumentation_name>
GET /instrumentation_listener/<instrumentation_name>
Gives details about a given instrumentation listener
GET /instrumentation_listeners/unused
Lists all instrumentation listeners loaded in the system
PUT /instrumentation_listener/name
Allows to enable or disable a given instrumentation listener (supports
only pson). The body should be
{"name":"instrumentation_name","pattern":<pattern>,"enabled":true}
* /instrumentation_data/<instrumentation_name>
Only GET is supported. This returns the accumulated data of the given
instrumentation name if the listener supports data aggregation.
This is the only way so far to get access to the instrumentation data.
The data format is specific to the given listener.
Note: actual default auth.conf doesn't allow to interact with these
two indirections.
Signed-off-by: Brice Figureau <[email protected]>
---
lib/puppet/application.rb | 3 +
lib/puppet/indirector/instrumentation_data.rb | 3 +
.../indirector/instrumentation_data/local.rb | 19 +++++++
lib/puppet/indirector/instrumentation_data/rest.rb | 5 ++
lib/puppet/indirector/instrumentation_listener.rb | 3 +
.../indirector/instrumentation_listener/local.rb | 20 +++++++
.../indirector/instrumentation_listener/rest.rb | 5 ++
lib/puppet/util/instrumentation/data.rb | 33 +++++++++++
spec/unit/application_spec.rb | 6 ++
.../indirector/instrumentation_data/local_spec.rb | 52 ++++++++++++++++++
.../indirector/instrumentation_data/rest_spec.rb | 11 ++++
.../instrumentation_listener/local_spec.rb | 58 ++++++++++++++++++++
.../instrumentation_listener/rest_spec.rb | 11 ++++
spec/unit/util/instrumentation/data_spec.rb | 35 ++++++++++++
14 files changed, 264 insertions(+), 0 deletions(-)
create mode 100644 lib/puppet/indirector/instrumentation_data.rb
create mode 100644 lib/puppet/indirector/instrumentation_data/local.rb
create mode 100644 lib/puppet/indirector/instrumentation_data/rest.rb
create mode 100644 lib/puppet/indirector/instrumentation_listener.rb
create mode 100644 lib/puppet/indirector/instrumentation_listener/local.rb
create mode 100644 lib/puppet/indirector/instrumentation_listener/rest.rb
create mode 100644 lib/puppet/util/instrumentation/data.rb
create mode 100644 spec/unit/indirector/instrumentation_data/local_spec.rb
create mode 100644 spec/unit/indirector/instrumentation_data/rest_spec.rb
create mode 100644 spec/unit/indirector/instrumentation_listener/local_spec.rb
create mode 100644 spec/unit/indirector/instrumentation_listener/rest_spec.rb
create mode 100755 spec/unit/util/instrumentation/data_spec.rb
diff --git a/lib/puppet/application.rb b/lib/puppet/application.rb
index 374dc85..31d0dd1 100644
--- a/lib/puppet/application.rb
+++ b/lib/puppet/application.rb
@@ -264,12 +264,15 @@ class Application
end
def initialize(command_line = nil)
+
require 'puppet/util/command_line'
@command_line = command_line || Puppet::Util::CommandLine.new
set_run_mode self.class.run_mode
@options = {}
require 'puppet'
+ require 'puppet/util/instrumentation'
+ Puppet::Util::Instrumentation.init
end
# WARNING: This is a totally scary, frightening, and nasty internal API. We
diff --git a/lib/puppet/indirector/instrumentation_data.rb
b/lib/puppet/indirector/instrumentation_data.rb
new file mode 100644
index 0000000..f1bea33
--- /dev/null
+++ b/lib/puppet/indirector/instrumentation_data.rb
@@ -0,0 +1,3 @@
+# A stub class, so our constants work.
+class Puppet::Indirector::InstrumentationData
+end
diff --git a/lib/puppet/indirector/instrumentation_data/local.rb
b/lib/puppet/indirector/instrumentation_data/local.rb
new file mode 100644
index 0000000..6510d7f
--- /dev/null
+++ b/lib/puppet/indirector/instrumentation_data/local.rb
@@ -0,0 +1,19 @@
+require 'puppet/indirector/instrumentation_data'
+
+class Puppet::Indirector::InstrumentationData::Local < Puppet::Indirector::Code
+ def find(request)
+ model.new(request.key)
+ end
+
+ def search(request)
+ raise Puppet::DevError, "You cannot search for instrumentation data"
+ end
+
+ def save(request)
+ raise Puppet::DevError, "You cannot save instrumentation data"
+ end
+
+ def destroy(request)
+ raise Puppet::DevError, "You cannot remove instrumentation data"
+ end
+end
diff --git a/lib/puppet/indirector/instrumentation_data/rest.rb
b/lib/puppet/indirector/instrumentation_data/rest.rb
new file mode 100644
index 0000000..28b2117
--- /dev/null
+++ b/lib/puppet/indirector/instrumentation_data/rest.rb
@@ -0,0 +1,5 @@
+require 'puppet/indirector/rest'
+require 'puppet/indirector/instrumentation_data'
+
+class Puppet::Indirector::InstrumentationData::Rest < Puppet::Indirector::REST
+end
diff --git a/lib/puppet/indirector/instrumentation_listener.rb
b/lib/puppet/indirector/instrumentation_listener.rb
new file mode 100644
index 0000000..6aaa71c
--- /dev/null
+++ b/lib/puppet/indirector/instrumentation_listener.rb
@@ -0,0 +1,3 @@
+# A stub class, so our constants work.
+class Puppet::Indirector::InstrumentationListener
+end
diff --git a/lib/puppet/indirector/instrumentation_listener/local.rb
b/lib/puppet/indirector/instrumentation_listener/local.rb
new file mode 100644
index 0000000..5b643ad
--- /dev/null
+++ b/lib/puppet/indirector/instrumentation_listener/local.rb
@@ -0,0 +1,20 @@
+require 'puppet/indirector/instrumentation_listener'
+
+class Puppet::Indirector::InstrumentationListener::Local <
Puppet::Indirector::Code
+ def find(request)
+ Puppet::Util::Instrumentation[request.key]
+ end
+
+ def search(request)
+ Puppet::Util::Instrumentation.listeners
+ end
+
+ def save(request)
+ res = request.instance
+ Puppet::Util::Instrumentation[res.name] = res
+ end
+
+ def destroy(request)
+ raise Puppet::DevError, "You cannot remove an Instrumentation Listener"
+ end
+end
diff --git a/lib/puppet/indirector/instrumentation_listener/rest.rb
b/lib/puppet/indirector/instrumentation_listener/rest.rb
new file mode 100644
index 0000000..0bc8122
--- /dev/null
+++ b/lib/puppet/indirector/instrumentation_listener/rest.rb
@@ -0,0 +1,5 @@
+require 'puppet/indirector/instrumentation_listener'
+require 'puppet/indirector/rest'
+
+class Puppet::Indirector::InstrumentationListener::Rest <
Puppet::Indirector::REST
+end
diff --git a/lib/puppet/util/instrumentation/data.rb
b/lib/puppet/util/instrumentation/data.rb
new file mode 100644
index 0000000..8d0b89d
--- /dev/null
+++ b/lib/puppet/util/instrumentation/data.rb
@@ -0,0 +1,33 @@
+require 'puppet/indirector'
+require 'puppet/util/instrumentation'
+
+# This is just a transport class to be used through the instrumentation_data
+# indirection. All the data resides in the real underlying listeners which this
+# class delegates to.
+class Puppet::Util::Instrumentation::Data
+ extend Puppet::Indirector
+
+ indirects :instrumentation_data, :terminus_class => :local
+
+ attr_reader :listener
+
+ def initialize(listener_name)
+ @listener = Puppet::Util::Instrumentation[listener_name]
+ end
+
+ def name
+ @listener.name
+ end
+
+ def to_pson(*args)
+ result = {
+ 'document_type' => "Puppet::Util::Instrumentation::Data",
+ 'data' => { :name => name }.merge(@listener.data)
+ }
+ result.to_pson(*args)
+ end
+
+ def self.from_pson(data)
+ raise "Instrumentation Listeners data are read only"
+ end
+end
diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb
index fc1bbce..0b13cca 100755
--- a/spec/unit/application_spec.rb
+++ b/spec/unit/application_spec.rb
@@ -8,6 +8,7 @@ require 'getoptlong'
describe Puppet::Application do
before do
+ Puppet::Util::Instrumentation.stubs(:init)
@app = Class.new(Puppet::Application).new
@appclass = @app.class
@@ -113,6 +114,11 @@ describe Puppet::Application do
@app.run_command
end
+ it "should initialize the Puppet Instrumentation layer on creation" do
+ Puppet::Util::Instrumentation.expects(:init)
+ Class.new(Puppet::Application).new
+ end
+
describe 'when invoking clear!' do
before :each do
Puppet::Application.run_status = :stop_requested
diff --git a/spec/unit/indirector/instrumentation_data/local_spec.rb
b/spec/unit/indirector/instrumentation_data/local_spec.rb
new file mode 100644
index 0000000..45ca1e0
--- /dev/null
+++ b/spec/unit/indirector/instrumentation_data/local_spec.rb
@@ -0,0 +1,52 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+require 'puppet/util/instrumentation/listener'
+require 'puppet/indirector/instrumentation_data/local'
+
+describe Puppet::Indirector::InstrumentationData::Local do
+ it "should be a subclass of the Code terminus" do
+ Puppet::Indirector::InstrumentationData::Local.superclass.should
equal(Puppet::Indirector::Code)
+ end
+
+ it "should be registered with the configuration store indirection" do
+ indirection =
Puppet::Indirector::Indirection.instance(:instrumentation_data)
+ Puppet::Indirector::InstrumentationData::Local.indirection.should
equal(indirection)
+ end
+
+ it "should have its name set to :local" do
+ Puppet::Indirector::InstrumentationData::Local.name.should == :local
+ end
+end
+
+describe Puppet::Indirector::InstrumentationData::Local do
+ before :each do
+ Puppet::Util::Instrumentation.stubs(:listener)
+ @data = Puppet::Indirector::InstrumentationData::Local.new
+ @name = "me"
+ @request = stub 'request', :key => @name
+ end
+
+ describe "when finding instrumentation data" do
+ it "should return a Instrumentation Data instance matching the key" do
+ end
+ end
+
+ describe "when searching listeners" do
+ it "should raise an error" do
+ lambda { @data.search(@request) }.should raise_error(Puppet::DevError)
+ end
+ end
+
+ describe "when saving listeners" do
+ it "should raise an error" do
+ lambda { @data.save(@request) }.should raise_error(Puppet::DevError)
+ end
+ end
+
+ describe "when destroying listeners" do
+ it "should raise an error" do
+ lambda { @data.destroy(@reques) }.should raise_error(Puppet::DevError)
+ end
+ end
+end
diff --git a/spec/unit/indirector/instrumentation_data/rest_spec.rb
b/spec/unit/indirector/instrumentation_data/rest_spec.rb
new file mode 100644
index 0000000..762667e
--- /dev/null
+++ b/spec/unit/indirector/instrumentation_data/rest_spec.rb
@@ -0,0 +1,11 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+require 'puppet/util/instrumentation/data'
+require 'puppet/indirector/instrumentation_data/rest'
+
+describe Puppet::Indirector::InstrumentationData::Rest do
+ it "should be a subclass of Puppet::Indirector::REST" do
+ Puppet::Indirector::InstrumentationData::Rest.superclass.should
equal(Puppet::Indirector::REST)
+ end
+end
diff --git a/spec/unit/indirector/instrumentation_listener/local_spec.rb
b/spec/unit/indirector/instrumentation_listener/local_spec.rb
new file mode 100644
index 0000000..81bc812
--- /dev/null
+++ b/spec/unit/indirector/instrumentation_listener/local_spec.rb
@@ -0,0 +1,58 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+require 'puppet/util/instrumentation/listener'
+require 'puppet/indirector/instrumentation_listener/local'
+
+describe Puppet::Indirector::InstrumentationListener::Local do
+ it "should be a subclass of the Code terminus" do
+ Puppet::Indirector::InstrumentationListener::Local.superclass.should
equal(Puppet::Indirector::Code)
+ end
+
+ it "should be registered with the configuration store indirection" do
+ indirection =
Puppet::Indirector::Indirection.instance(:instrumentation_listener)
+ Puppet::Indirector::InstrumentationListener::Local.indirection.should
equal(indirection)
+ end
+
+ it "should have its name set to :local" do
+ Puppet::Indirector::InstrumentationListener::Local.name.should == :local
+ end
+end
+
+describe Puppet::Indirector::InstrumentationListener::Local do
+ before :each do
+ Puppet::Util::Instrumentation.stubs(:listener)
+ @listener = Puppet::Indirector::InstrumentationListener::Local.new
+ @name = "me"
+ @request = stub 'request', :key => @name
+ end
+
+ describe "when finding listeners" do
+ it "should return a Instrumentation Listener instance matching the key" do
+ Puppet::Util::Instrumentation.expects(:[]).with("me").returns(:instance)
+ @listener.find(@request).should == :instance
+ end
+ end
+
+ describe "when searching listeners" do
+ it "should return a list of all loaded Instrumentation Listenesrs
irregardless of the given key" do
+ Puppet::Util::Instrumentation.expects(:listeners).returns([:instance1,
:instance2])
+ @listener.search(@request).should == [:instance1, :instance2]
+ end
+ end
+
+ describe "when saving listeners" do
+ it "should set the new listener to the global listener list" do
+ newlistener = stub 'listener', :name => @name
+ @request.stubs(:instance).returns(newlistener)
+ Puppet::Util::Instrumentation.expects(:[]=).with("me", newlistener)
+ @listener.save(@request)
+ end
+ end
+
+ describe "when destroying listeners" do
+ it "should raise an error" do
+ lambda { @listener.destroy(stub 'instance') }.should
raise_error(Puppet::DevError)
+ end
+ end
+end
diff --git a/spec/unit/indirector/instrumentation_listener/rest_spec.rb
b/spec/unit/indirector/instrumentation_listener/rest_spec.rb
new file mode 100644
index 0000000..6355a1c
--- /dev/null
+++ b/spec/unit/indirector/instrumentation_listener/rest_spec.rb
@@ -0,0 +1,11 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+require 'puppet/util/instrumentation/listener'
+require 'puppet/indirector/instrumentation_listener/rest'
+
+describe Puppet::Indirector::InstrumentationListener::Rest do
+ it "should be a subclass of Puppet::Indirector::REST" do
+ Puppet::Indirector::InstrumentationListener::Rest.superclass.should
equal(Puppet::Indirector::REST)
+ end
+end
diff --git a/spec/unit/util/instrumentation/data_spec.rb
b/spec/unit/util/instrumentation/data_spec.rb
new file mode 100755
index 0000000..5e3069e
--- /dev/null
+++ b/spec/unit/util/instrumentation/data_spec.rb
@@ -0,0 +1,35 @@
+#!/usr/bin/env rspec
+
+require 'spec_helper'
+require 'matchers/json'
+require 'puppet/util/instrumentation'
+require 'puppet/util/instrumentation/data'
+
+describe Puppet::Util::Instrumentation::Data do
+ Puppet::Util::Instrumentation::Data
+
+ before(:each) do
+ @listener = stub 'listener', :name => "name"
+ Puppet::Util::Instrumentation.stubs(:[]).with("name").returns(@listener)
+ end
+
+ it "should indirect instrumentation_data" do
+ Puppet::Util::Instrumentation::Data.indirection.name.should ==
:instrumentation_data
+ end
+
+ it "should lookup the corresponding listener" do
+ Puppet::Util::Instrumentation.expects(:[]).with("name").returns(@listener)
+ Puppet::Util::Instrumentation::Data.new("name")
+ end
+
+ it "should return pson data" do
+ data = Puppet::Util::Instrumentation::Data.new("name")
+ @listener.stubs(:data).returns({ :this_is_data => "here also" })
+ data.should set_json_attribute('name').to("name")
+ data.should set_json_attribute('this_is_data').to("here also")
+ end
+
+ it "should raise an error when deserializing from pson" do
+ lambda { Puppet::Util::Instrumentation::Data.from_pson({}) }.should
raise_error
+ end
+end
\ No newline at end of file
--
1.7.5.1
--
You received this message because you are subscribed to the Google Groups
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en.