splunk-client 0.5.1 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in splunk-client.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ splunk-client (0.5.3)
5
+ nokogiri
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.1.3)
11
+ json (1.7.3)
12
+ multi_json (1.3.5)
13
+ nokogiri (1.5.2)
14
+ rake (0.9.2.2)
15
+ rspec (2.10.0)
16
+ rspec-core (~> 2.10.0)
17
+ rspec-expectations (~> 2.10.0)
18
+ rspec-mocks (~> 2.10.0)
19
+ rspec-core (2.10.0)
20
+ rspec-expectations (2.10.0)
21
+ diff-lcs (~> 1.1.3)
22
+ rspec-mocks (2.10.1)
23
+ simplecov (0.6.4)
24
+ multi_json (~> 1.0)
25
+ simplecov-html (~> 0.5.3)
26
+ simplecov-html (0.5.3)
27
+ simplecov-rcov (0.2.3)
28
+ simplecov (>= 0.4.1)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ json
35
+ rake
36
+ rspec
37
+ simplecov-rcov
38
+ splunk-client!
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # SplunkClient
2
+
3
+ Ruby library for dealing with Splunk searches and results using the Splunk REST API.
4
+
5
+ ## Installation
6
+
7
+ gem install splunk-client
8
+
9
+ ## Usage
10
+
11
+ Creating and using a client is easy:
12
+
13
+ require 'splunk-client.rb'
14
+
15
+ # Create the client
16
+ splunk = SplunkClient.new("username", "password", "hostname")
17
+
18
+ # Create the Search
19
+ search = splunk.search("test_search")
20
+
21
+ # Wait for the Splunk search to complete
22
+ search.wait # Blocks until the search returns
23
+
24
+ #Print the raw XML results
25
+ puts search.results
26
+
27
+ #Print the time and host of each result
28
+ search.parsedResults.each do |result|
29
+ puts result.host + " : " + result.time
30
+ end
31
+
32
+ ## Tips
33
+
34
+ * Want to spawn multiple jobs without blocking on each? Use `search.complete?` to poll for job status.
35
+
36
+ * Looking for more or less results? Use `search.results(maxResults)` to control how much is returned. (A value of 0 returns all results (this is the default.))
37
+
38
+ * Access Splunk fields in results via method calls
39
+ `result = search.parsedResults`
40
+ `puts result[0].fieldName`
41
+
42
+ ## Revision History
43
+
44
+ #### 0.6
45
+ * Added two new objects: SplunkResults and SplunkResult for to support:
46
+ * Accessing Splunk fields via method calls
47
+ `search.parsedResults.each {|result| puts result.$$FIELD_NAME$$}`
48
+
49
+ #### 0.5
50
+ WARNING: Compatibility with prior versions will break as SplunkClient no longer returns a sid. It now returns a SplunkJob object.
51
+
52
+ * Separated SplunkClient and SplunkJob into two separate objects.
53
+
54
+ #### 0.1
55
+ * Initial Release
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ desc "Run specs"
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
8
+ # Put spec opts in a file named .rspec in root
9
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.6
data/lib/splunk-client.rb CHANGED
@@ -1,93 +1,3 @@
1
1
  # Author:: Christopher Brito (cbrito@gmail.com)
2
2
  # Original Repo:: https://github.com/cbrito/splunk-client
3
-
4
- require 'net/https'
5
- require 'cgi'
6
- require 'rubygems'
7
- require 'nokogiri'
8
-
9
- class SplunkJob
10
- attr_reader :jobId
11
-
12
- def initialize(jobId, clientPointer)
13
- @jobId = jobId
14
- @client = clientPointer #SplunkClient object pointer
15
- end
16
-
17
- def wait
18
- wait_for_results
19
- end
20
-
21
- def wait_for_results
22
- # Wait for the Splunk search to complete
23
- while (@client.get_search_status(@jobId).to_i == 0)
24
- sleep 2
25
- end
26
- end
27
-
28
- def complete?
29
- # Return status of job
30
- @client.get_search_status(@jobId).to_i == 0
31
- end
32
-
33
- def results(maxResults=0)
34
- # Return search results
35
- @client.get_search_results(@jobId, maxResults)
36
- end
37
-
38
- end #class SplunkJob
39
-
40
- class SplunkClient
41
-
42
- def initialize(username, password, host, port=8089)
43
- @USER=username; @PASS=password; @HOST=host; @PORT=port
44
-
45
- @SESSION_KEY = { 'authorization' => "Splunk #{get_session_key}" }
46
- end
47
-
48
- def create_search(search)
49
- # Returns a SplunkJob
50
- xml = splunk_post_request("/services/search/jobs",
51
- "search=#{CGI::escape("search #{search}")}",
52
- @SESSION_KEY)
53
-
54
- @doc = Nokogiri::Slop(xml)
55
-
56
- return SplunkJob.new(@doc.xpath("//sid").text, self)
57
- end
58
-
59
- def get_search_status(sid)
60
- xml = splunk_get_request("/services/search/jobs/#{sid}")
61
- @doc = Nokogiri::Slop(xml)
62
- return @doc.xpath("//s:key[@name='isDone']").text
63
- end
64
-
65
- def get_search_results(sid, maxResults=0)
66
- splunk_get_request("/services/search/jobs/#{sid}/results?count=#{maxResults}")
67
- end
68
-
69
- private ###############################################################################
70
-
71
- def splunk_http_request
72
- http = Net::HTTP.new(@HOST, @PORT)
73
- http.use_ssl = true
74
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
75
- return http
76
- end
77
-
78
- def splunk_get_request(path)
79
- splunk_http_request.get(path, @SESSION_KEY).body
80
- end
81
-
82
- def splunk_post_request(path, data=nil, headers=nil)
83
- splunk_http_request.post(path,data,headers).body
84
- end
85
-
86
- def get_session_key
87
- xml = splunk_post_request("/services/auth/login",
88
- "username=#{@USER}&password=#{@PASS}")
89
- @doc = Nokogiri::Slop(xml)
90
- return @doc.xpath("//sessionKey").text
91
- end
92
-
93
- end #class SplunkClient
3
+ require File.expand_path File.join(File.dirname(__FILE__), 'splunk_client/splunk_client')
@@ -0,0 +1,76 @@
1
+ # Author:: Christopher Brito (cbrito@gmail.com)
2
+ # Original Repo:: https://github.com/cbrito/splunk-client
3
+
4
+ require 'net/https'
5
+ require 'cgi'
6
+ require 'rubygems'
7
+ require 'nokogiri'
8
+ require File.expand_path File.join(File.dirname(__FILE__), 'splunk_job')
9
+
10
+ class SplunkClient
11
+
12
+ def initialize(username, password, host, port=8089)
13
+ @USER=username; @PASS=password; @HOST=host; @PORT=port
14
+
15
+ @SESSION_KEY = { 'authorization' => "Splunk #{get_session_key}" }
16
+ end
17
+
18
+ def search(search)
19
+ create_search(search)
20
+ end
21
+
22
+ def create_search(search)
23
+ # Returns a SplunkJob
24
+ xml = splunk_post_request("/services/search/jobs",
25
+ "search=#{CGI::escape("search #{search}")}",
26
+ @SESSION_KEY)
27
+
28
+ @doc = Nokogiri::Slop(xml)
29
+
30
+ return SplunkJob.new(@doc.xpath("//sid").text, self)
31
+ end
32
+
33
+ def get_search_status(sid)
34
+ xml = splunk_get_request("/services/search/jobs/#{sid}")
35
+ @doc = Nokogiri::Slop(xml)
36
+ return @doc.xpath("//s:key[@name='isDone']").text
37
+ end
38
+
39
+ def get_search_results(sid, maxResults=0, mode=nil)
40
+ url = "/services/search/jobs/#{sid}/results?count=#{maxResults}"
41
+ url += "&output_mode=#{mode}" unless mode.nil?
42
+ splunk_get_request(url)
43
+ end
44
+
45
+ def control_job(sid, action)
46
+ xml = splunk_post_request("/services/search/jobs/#{sid}/control",
47
+ "action=#{CGI::escape(action)}",
48
+ @SESSION_KEY)
49
+ @doc = Nokogiri::Slop(xml)
50
+ end
51
+
52
+ private ###############################################################################
53
+
54
+ def splunk_http_request
55
+ http = Net::HTTP.new(@HOST, @PORT)
56
+ http.use_ssl = true
57
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
58
+ return http
59
+ end
60
+
61
+ def splunk_get_request(path)
62
+ splunk_http_request.get(path, @SESSION_KEY).body
63
+ end
64
+
65
+ def splunk_post_request(path, data=nil, headers=nil)
66
+ splunk_http_request.post(path,data,headers).body
67
+ end
68
+
69
+ def get_session_key
70
+ xml = splunk_post_request("/services/auth/login",
71
+ "username=#{@USER}&password=#{@PASS}")
72
+ @doc = Nokogiri::Slop(xml)
73
+ return @doc.xpath("//sessionKey").text
74
+ end
75
+
76
+ end #class SplunkClient
@@ -0,0 +1,43 @@
1
+ # Author:: Christopher Brito (cbrito@gmail.com)
2
+ # Original Repo:: https://github.com/cbrito/splunk-client
3
+
4
+ require File.expand_path File.join(File.dirname(__FILE__), 'splunk_results')
5
+
6
+
7
+ class SplunkJob
8
+ attr_reader :jobId
9
+
10
+ def initialize(jobId, clientPointer)
11
+ @jobId = jobId
12
+ @client = clientPointer #SplunkClient object pointer
13
+ end
14
+
15
+ def wait
16
+ wait_for_results
17
+ end
18
+
19
+ def wait_for_results
20
+ # Wait for the Splunk search to complete
21
+ sleep 1 until complete?
22
+ end
23
+
24
+ def complete?
25
+ # Return status of job
26
+ @client.get_search_status(@jobId).to_i == 1
27
+ end
28
+
29
+ def results(maxResults=0, mode=nil)
30
+ # Return search results
31
+ @client.get_search_results(@jobId, maxResults, mode)
32
+ end
33
+
34
+ def cancel
35
+ @client.control_job(@jobId, 'cancel')
36
+ end
37
+
38
+ def parsedResults
39
+ # Return a SplunkResults object with methods for the result fields
40
+ SplunkResults.new(results).results
41
+ end
42
+
43
+ end #class SplunkJob
@@ -0,0 +1,34 @@
1
+ # Author:: Christopher Brito (cbrito@gmail.com)
2
+ # Original Repo:: https://github.com/cbrito/splunk-client
3
+
4
+ # Simplify the calling of single result data from xpaths into an object
5
+ # http://stackoverflow.com/questions/2240535/how-do-i-use-hash-keys-as-methods-on-a-class
6
+ class SplunkResult
7
+
8
+ def initialize(nokogiriNode)
9
+ @result = nokogiriNode
10
+ end
11
+
12
+ # Ex: splunkResult.time => nokogiriNode.result.field("[@k=\"_time\"]").value.text
13
+ def time
14
+ @result.field("[@k=\"_time\"]").value.text
15
+ end
16
+
17
+ # Ex: splunkResult.sourceIp => nokogiriNode.result.field("[@k=\"sourceIp\"]").value.text
18
+ def method_missing(name, *args, &blk)
19
+ if args.empty? && blk.nil? && @result.field("[@k=\"#{name}\"]")
20
+ @result.field("[@k=\"#{name}\"]").value.text
21
+ else
22
+ super
23
+ end
24
+ end
25
+
26
+ def respond_to?(name)
27
+ begin
28
+ unless @result.field("[@k=\"#{name}\"]").nil? then true else super end
29
+ rescue NoMethodError
30
+ super
31
+ end
32
+ end
33
+
34
+ end #class SplunkResult
@@ -0,0 +1,29 @@
1
+ # Author:: Christopher Brito (cbrito@gmail.com)
2
+ # Original Repo:: https://github.com/cbrito/splunk-client
3
+
4
+ require 'rubygems'
5
+ require 'nokogiri'
6
+ require File.expand_path File.join(File.dirname(__FILE__), 'splunk_result')
7
+
8
+ # Simplify the calling of single result data from xpaths into an objects
9
+ class SplunkResults
10
+ attr_reader :results
11
+
12
+ def initialize(rawResults)
13
+ nokoResults = Nokogiri::Slop(rawResults)
14
+ @results = Array.new
15
+
16
+ if nokoResults.results.result.respond_to?("length")
17
+ # Multiple Results, build array
18
+ nokoResults.results.result.each do |resultObj|
19
+ @results.push SplunkResult.new(resultObj)
20
+ end
21
+ else
22
+ # Single results object
23
+ @results.push Splunkresults.new(nokoResults.results.result)
24
+ end
25
+
26
+ return @results
27
+ end
28
+
29
+ end #class SplunkResults
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'simplecov'
3
+ require 'simplecov-rcov'
4
+ class SimpleCov::Formatter::MergedFormatter
5
+ def format(result)
6
+ SimpleCov::Formatter::HTMLFormatter.new.format(result)
7
+ SimpleCov::Formatter::RcovFormatter.new.format(result)
8
+ end
9
+ end
10
+ SimpleCov.formatter = SimpleCov::Formatter::MergedFormatter
11
+ SimpleCov.start
12
+ require 'rspec/autorun'
13
+
14
+ require 'json'
15
+ require File.expand_path File.join(File.dirname(__FILE__), '../lib/splunk-client')
@@ -0,0 +1,58 @@
1
+ require File.expand_path File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe SplunkClient do
4
+
5
+ before :each do
6
+ @user = ENV['SPLUNK_USER']
7
+ @pass = ENV['SPLUNK_PASSWD']
8
+ @host = ENV['SPLUNK_HOST']
9
+ @splunk_client = SplunkClient.new(@user, @pass, @host)
10
+ end
11
+
12
+ context "initialization" do
13
+
14
+ it "creates a session key" do
15
+ splunk_client = @splunk_client
16
+ splunk_client.should_not be(nil)
17
+ splunk_client.send(:get_session_key).should_not be(nil)
18
+ end
19
+
20
+ end
21
+
22
+ context "searching" do
23
+
24
+ it "creates a search job and returns results" do
25
+ splunk_client = @splunk_client
26
+ splunk_client.should_not be(nil)
27
+ search = 'source="/var/log/messages" "kernel" earliest=-10m'
28
+ job = splunk_client.search(search)
29
+ job.should_not be(nil)
30
+ job.wait
31
+ job.results(0, 'json')
32
+ job.cancel
33
+ end
34
+
35
+ end
36
+
37
+ context "parsing_results" do
38
+ it "uses the parsedResults 'host' method of a SplunkJob" do
39
+ splunk_client = @splunk_client
40
+ splunk_client.should_not be(nil)
41
+ search = 'source="/var/log/messages" "kernel" earliest=-10m'
42
+ job = splunk_client.search(search)
43
+ job.should_not be(nil)
44
+ job.wait
45
+ results = job.parsedResults
46
+
47
+ # Test the auto generated methods
48
+ results.each do |result|
49
+ result.respond_to?("time").should be(true)
50
+ result.respond_to?("host").should be(true)
51
+ result.time.should_not be(nil)
52
+ result.host.should_not be(nil)
53
+ end
54
+
55
+ end
56
+ end
57
+
58
+ end
metadata CHANGED
@@ -1,78 +1,139 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: splunk-client
3
- version: !ruby/object:Gem::Version
4
- hash: 9
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.6'
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 5
9
- - 1
10
- version: 0.5.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Christopher Brito
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-04-24 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-05-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: nokogiri
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
32
22
  type: :runtime
33
- version_requirements: *id001
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: simplecov-rcov
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: json
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
34
94
  description: Simple Ruby library for interfacing with Splunk's REST API.
35
- email: cbrito@gmail.com
95
+ email:
96
+ - cbrito@gmail.com
36
97
  executables: []
37
-
38
98
  extensions: []
39
-
40
99
  extra_rdoc_files: []
41
-
42
- files:
100
+ files:
43
101
  - lib/splunk-client.rb
102
+ - lib/splunk_client/splunk_client.rb
103
+ - lib/splunk_client/splunk_job.rb
104
+ - lib/splunk_client/splunk_result.rb
105
+ - lib/splunk_client/splunk_results.rb
106
+ - spec/spec_helper.rb
107
+ - spec/splunk_client_spec.rb
108
+ - VERSION
109
+ - README.md
110
+ - Rakefile
111
+ - Gemfile
112
+ - Gemfile.lock
44
113
  homepage: http://github.com/cbrito/splunk-client
45
114
  licenses: []
46
-
47
115
  post_install_message:
48
116
  rdoc_options: []
49
-
50
- require_paths:
117
+ require_paths:
51
118
  - lib
52
- required_ruby_version: !ruby/object:Gem::Requirement
119
+ required_ruby_version: !ruby/object:Gem::Requirement
53
120
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- hash: 3
58
- segments:
59
- - 0
60
- version: "0"
61
- required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
126
  none: false
63
- requirements:
64
- - - ">="
65
- - !ruby/object:Gem::Version
66
- hash: 3
67
- segments:
68
- - 0
69
- version: "0"
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
70
131
  requirements: []
71
-
72
132
  rubyforge_project:
73
- rubygems_version: 1.8.15
133
+ rubygems_version: 1.8.24
74
134
  signing_key:
75
135
  specification_version: 3
76
136
  summary: Ruby Library for interfacing with Splunk's REST API
77
- test_files: []
78
-
137
+ test_files:
138
+ - spec/spec_helper.rb
139
+ - spec/splunk_client_spec.rb