sumo-search 1.0.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +19 -0
- data/lib/sumo.rb +2 -1
- data/lib/sumo/cli.rb +16 -3
- data/lib/sumo/client.rb +9 -3
- data/lib/sumo/config.rb +50 -30
- data/lib/sumo/version.rb +2 -2
- data/spec/fixtures/bad-creds +1 -0
- data/spec/fixtures/sumo-creds +3 -1
- data/spec/lib/sumo/client_spec.rb +18 -5
- data/spec/lib/sumo/config_spec.rb +56 -74
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ed2fa4eca034af9b83515cfcee0e1f7f491ea3a
|
4
|
+
data.tar.gz: 75c6c374a0a966aaf3fefcc62d6c6400845003c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7e7ea816310a6c07ccb81e52c8686741c4f99ed100fcce5ec702d7a9f651635cfb3eed35e219a0e4bde7345d7be766ff85967a9885c7fa21862905750ef8ef0
|
7
|
+
data.tar.gz: 33e61f4c901faad6ded980d08acd6a99cf72af45b40accc9f89dbfdeec19b5f81112b855d93691328db931aa2739795bd96feda9a76922db66e1bbe6ac030707
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# sumo-search
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/sumo-search) [](https://travis-ci.org/swipely/sumo) [](https://codeclimate.com/github/swipely/sumo) [](https://gemnasium.com/swipely/sumo-search)
|
4
|
+
|
3
5
|
This gem interfaces with the Sumo Logic [Search Job API](https://github.com/SumoLogic/sumo-api-doc/wiki/search-job-api).
|
4
6
|
It may be used through native Ruby, or via a CLI that has been provided.
|
5
7
|
|
@@ -17,6 +19,23 @@ From your application's `Gemfile`:
|
|
17
19
|
gem 'sumo-search'
|
18
20
|
```
|
19
21
|
|
22
|
+
## Configuration
|
23
|
+
|
24
|
+
Your credentials go into the YAML file `~/.sumo_creds`.
|
25
|
+
An example YAML file is listed below:
|
26
|
+
|
27
|
+
```yaml
|
28
|
+
backend:
|
29
|
+
email: email@test.net
|
30
|
+
password: trustno1
|
31
|
+
default:
|
32
|
+
email: email2@test.net
|
33
|
+
password: test-pass
|
34
|
+
```
|
35
|
+
|
36
|
+
The credentials in the `default` namespace are loaded by default.
|
37
|
+
To change this, set `ENV['SUMO_CREDENTIAL']` to the credential that you would like to load.
|
38
|
+
|
20
39
|
## Ruby Usage
|
21
40
|
|
22
41
|
To create a search job from ruby, the `Sumo.search` method is provided.
|
data/lib/sumo.rb
CHANGED
@@ -2,12 +2,13 @@ require 'base64'
|
|
2
2
|
require 'clamp'
|
3
3
|
require 'excon'
|
4
4
|
require 'json'
|
5
|
+
require 'yaml'
|
5
6
|
|
6
7
|
# This is the top level module for the gem. It is used as a namespace and holds
|
7
8
|
# top-level convenience functions.
|
8
9
|
module Sumo
|
9
10
|
# Define global constants.
|
10
|
-
|
11
|
+
CONFIG_FILE = File.expand_path('~/.sumo_creds').freeze
|
11
12
|
|
12
13
|
# Require sub-modules.
|
13
14
|
require 'sumo/error'
|
data/lib/sumo/cli.rb
CHANGED
@@ -8,17 +8,30 @@ class Sumo::CLI < Clamp::Command
|
|
8
8
|
option ['-r', '--records'], :flag, 'Extract records instead of messages.'
|
9
9
|
option ['-v', '--version'], :flag, 'Print the version.'
|
10
10
|
|
11
|
+
banner <<-EOS.gsub(/^.*\|/, '')
|
12
|
+
|Example
|
13
|
+
|
|
14
|
+
|Search for all of the logs containing 'HealthMetrics' on March 4, 2014,
|
15
|
+
|extracting the message key from the response:
|
16
|
+
|
|
17
|
+
|sumo --query HealthMetrics \\
|
18
|
+
| --from 2014-03-14T00:00:00 \\
|
19
|
+
| --to 2014-03-15T00:00:00 \\
|
20
|
+
| --time-zone EST \\
|
21
|
+
| --extract-key message
|
22
|
+
EOS
|
23
|
+
|
11
24
|
# This method is called when the CLI is run.
|
12
25
|
def execute
|
13
26
|
if version?
|
14
27
|
puts Sumo::VERSION
|
15
28
|
elsif records?
|
16
|
-
search.records.each { |record| puts record }
|
29
|
+
search.records.each { |record| $stdout.puts record }
|
17
30
|
else
|
18
|
-
search.messages.each { |message| puts format_message(message) }
|
31
|
+
search.messages.each { |message| $stdout.puts format_message(message) }
|
19
32
|
end
|
20
33
|
rescue StandardError => ex
|
21
|
-
puts "#{ex.class}: #{ex.message}"
|
34
|
+
$stderr.puts "#{ex.class}: #{ex.message}"
|
22
35
|
exit 1
|
23
36
|
end
|
24
37
|
|
data/lib/sumo/client.rb
CHANGED
@@ -2,14 +2,15 @@
|
|
2
2
|
class Sumo::Client
|
3
3
|
include Sumo::Error
|
4
4
|
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :email, :password, :cookie
|
6
6
|
|
7
7
|
# The error message raised when the result can be parsed from Sumo.
|
8
8
|
DEFAULT_ERROR_MESSAGE = 'Error sending API request'
|
9
9
|
|
10
10
|
# Create a new `Sumo::Client` with the given credentials.
|
11
|
-
def initialize(
|
12
|
-
@
|
11
|
+
def initialize(credentials = Sumo.creds)
|
12
|
+
@email = credentials['email'].freeze
|
13
|
+
@password = credentials['password'].freeze
|
13
14
|
end
|
14
15
|
|
15
16
|
# Send a HTTP request to the server, handling any errors that may occur.
|
@@ -73,6 +74,11 @@ class Sumo::Client
|
|
73
74
|
end
|
74
75
|
private :encoded_creds
|
75
76
|
|
77
|
+
def creds
|
78
|
+
[email, password].join(':')
|
79
|
+
end
|
80
|
+
private :creds
|
81
|
+
|
76
82
|
def connection
|
77
83
|
@connection ||= Excon.new('https://api.sumologic.com')
|
78
84
|
end
|
data/lib/sumo/config.rb
CHANGED
@@ -1,11 +1,5 @@
|
|
1
|
-
# This class contains the logic to find the user's credentials
|
2
|
-
#
|
3
|
-
# configuration file has not been specified, the environment variable is
|
4
|
-
# preferred. If both exist and a config file has been specified, the config
|
5
|
-
# file is preferred.
|
6
|
-
#
|
7
|
-
# The environment varibale is called 'SUMO_CREDS'; the default configuration
|
8
|
-
# file is '~/.sumo_creds'.
|
1
|
+
# This class contains the logic to find the user's credentials from a
|
2
|
+
# configuration file. By default, the file is `~/.sumo_creds`.
|
9
3
|
class Sumo::Config
|
10
4
|
include Sumo::Error
|
11
5
|
|
@@ -13,40 +7,66 @@ class Sumo::Config
|
|
13
7
|
|
14
8
|
# Given an optional `String`, sets and freezes the `@config_file` instance
|
15
9
|
# variable, as long as it's a valid file path.
|
16
|
-
def initialize(config_file = Sumo::
|
10
|
+
def initialize(config_file = Sumo::CONFIG_FILE)
|
17
11
|
@config_file = File.expand_path(config_file).freeze
|
18
12
|
end
|
19
13
|
|
20
|
-
#
|
21
|
-
def
|
22
|
-
|
14
|
+
# Load the credentials, raising an any errors that occur.
|
15
|
+
def load_creds!
|
16
|
+
@creds ||= load_file[cred_key].tap do |creds|
|
17
|
+
raise NoCredsFound, "#{cred_key} not found in #{config_file}" if !creds
|
18
|
+
end
|
23
19
|
end
|
24
20
|
|
25
|
-
#
|
26
|
-
def
|
27
|
-
|
21
|
+
# Load the credentials, returning nil if an error occurs.
|
22
|
+
def load_creds
|
23
|
+
load_creds! rescue nil
|
28
24
|
end
|
29
25
|
|
30
|
-
# Get the credentials from the
|
31
|
-
def
|
32
|
-
|
26
|
+
# Get the credentials from the environment.
|
27
|
+
def cred_key
|
28
|
+
@cred_key = ENV['SUMO_CREDENTIAL'] || 'default'
|
33
29
|
end
|
30
|
+
private :cred_key
|
34
31
|
|
35
|
-
#
|
36
|
-
def
|
37
|
-
|
38
|
-
|
32
|
+
# Get the credentials from the configuration file.
|
33
|
+
def load_file
|
34
|
+
if File.exists?(config_file)
|
35
|
+
parse_file
|
39
36
|
else
|
40
|
-
|
37
|
+
raise NoCredsFound, bad_config_file("#{config_file} does not exist.")
|
41
38
|
end
|
42
39
|
end
|
40
|
+
private :load_file
|
43
41
|
|
44
|
-
#
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
42
|
+
# Parse the configuration file, raising an error if it is invalid YAML.
|
43
|
+
def parse_file
|
44
|
+
YAML.load_file(config_file).tap { |creds| raise unless creds.is_a?(Hash) }
|
45
|
+
rescue
|
46
|
+
raise NoCredsFound, bad_config_file("#{config_file} is not valid YAML.")
|
47
|
+
end
|
48
|
+
private :parse_file
|
49
|
+
|
50
|
+
def bad_config_file(message)
|
51
|
+
<<-EOS.gsub(/^.*\|/, '')
|
52
|
+
|#{message}
|
53
|
+
|
|
54
|
+
|sumo-search now expects its config file (located at #{config_file}) to
|
55
|
+
|be valid YAML. Below is an example of a valid config file:
|
56
|
+
|
|
57
|
+
|backend:
|
58
|
+
| email: backend@example.com
|
59
|
+
| password: trustno1
|
60
|
+
|frontend:
|
61
|
+
| email: frontend@example.com
|
62
|
+
| password: test-pass-1
|
63
|
+
|
|
64
|
+
|By default, the 'default' credential in #{config_file} will be used. To
|
65
|
+
|change this behavior, set the $SUMO_CREDENTIAL environment varibale
|
66
|
+
|to the credential you would like to use. In the above example, setting
|
67
|
+
|$SUMO_CREDENTIAL to 'frontend' would allow you to access the account with
|
68
|
+
|email 'frontend@example.com' and password 'test-pass-1'.
|
69
|
+
EOS
|
51
70
|
end
|
71
|
+
private :bad_config_file
|
52
72
|
end
|
data/lib/sumo/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
test@test.net:trustno1
|
data/spec/fixtures/sumo-creds
CHANGED
@@ -2,13 +2,20 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Sumo::Client do
|
4
4
|
describe '#initialize' do
|
5
|
-
let(:creds) {
|
5
|
+
let(:creds) {
|
6
|
+
{
|
7
|
+
'email' => 'test@test.com',
|
8
|
+
'password' => 'example'
|
9
|
+
}
|
10
|
+
}
|
6
11
|
|
7
12
|
context 'with no arguments' do
|
8
13
|
subject { Sumo::Client.new }
|
9
14
|
before { Sumo.stub(:creds).and_return(creds) }
|
15
|
+
|
10
16
|
it 'sets the default credentials' do
|
11
|
-
subject.
|
17
|
+
subject.email.should == 'test@test.com'
|
18
|
+
subject.password.should == 'example'
|
12
19
|
end
|
13
20
|
end
|
14
21
|
|
@@ -16,7 +23,8 @@ describe Sumo::Client do
|
|
16
23
|
subject { Sumo::Client.new(creds) }
|
17
24
|
|
18
25
|
it 'sets the credentials to that argument' do
|
19
|
-
subject.
|
26
|
+
subject.email.should == 'test@test.com'
|
27
|
+
subject.password.should == 'example'
|
20
28
|
end
|
21
29
|
end
|
22
30
|
end
|
@@ -24,8 +32,13 @@ describe Sumo::Client do
|
|
24
32
|
describe '#request' do
|
25
33
|
let(:connection) { double(:connection) }
|
26
34
|
let(:response) { double(:response) }
|
27
|
-
let(:creds) {
|
28
|
-
|
35
|
+
let(:creds) {
|
36
|
+
{
|
37
|
+
'email' => 'creds@email.com',
|
38
|
+
'password' => 'test'
|
39
|
+
}
|
40
|
+
}
|
41
|
+
let(:encoded) { Base64.encode64('creds@email.com:test').strip }
|
29
42
|
subject { Sumo::Client.new(creds) }
|
30
43
|
before { subject.stub(:connection).and_return(connection) }
|
31
44
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Sumo::Config do
|
3
|
+
describe Sumo::Config, :current do
|
4
4
|
let(:test_config_file) {
|
5
5
|
File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'sumo-creds')
|
6
6
|
}
|
@@ -14,84 +14,35 @@ describe Sumo::Config do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
describe '#file_specified?' do
|
18
|
-
context 'when Sumo::DEFAULT_CONFIG_FILE is not equal to @config_file' do
|
19
|
-
let(:config_file) { '/etc/sumo-creds' }
|
20
|
-
subject { Sumo::Config.new(config_file) }
|
21
|
-
|
22
|
-
it 'returns true' do
|
23
|
-
subject.file_specified?.should be_true
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'when Sumo::DEFAULT_CONFIG_FILE is equal to @config_file' do
|
28
|
-
subject { Sumo::Config.new }
|
29
|
-
|
30
|
-
it 'returns false' do
|
31
|
-
subject.file_specified?.should be_false
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe '#env_creds' do
|
37
|
-
let(:email) { 'test@test.net' }
|
38
|
-
let(:password) { 'trustno1' }
|
39
|
-
let(:creds) { [email, password].join(':') }
|
40
|
-
|
41
|
-
before { ENV['SUMO_CREDS'] = creds }
|
42
|
-
after { ENV['SUMO_CREDS'] = nil }
|
43
|
-
|
44
|
-
it 'retrieves the $SUMO_CREDS environment variable' do
|
45
|
-
subject.env_creds.should == creds
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe '#file_creds' do
|
50
|
-
subject { Sumo::Config.new(config_file) }
|
51
|
-
|
52
|
-
context 'when @config_file is not a file' do
|
53
|
-
let(:config_file) { '/not/a/file' }
|
54
|
-
|
55
|
-
it 'returns nil' do
|
56
|
-
subject.file_creds.should be_nil
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'when @config_file is a file' do
|
61
|
-
let(:config_file) { test_config_file }
|
62
|
-
|
63
|
-
it 'returns the contents of that file' do
|
64
|
-
subject.file_creds.should == File.read(config_file).strip
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
17
|
describe '#load_creds' do
|
70
|
-
|
71
|
-
|
72
|
-
let(:creds) { [email, password].join(':') }
|
18
|
+
context 'when #load_creds! raises an error' do
|
19
|
+
before { subject.stub(:load_creds!).and_raise(Sumo::Error::NoCredsFound) }
|
73
20
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
context 'when a config file is not specified' do
|
78
|
-
it 'prefers the environment variable' do
|
79
|
-
subject.load_creds.should == ENV['SUMO_CREDS']
|
21
|
+
it 'returns nil' do
|
22
|
+
expect(subject.load_creds).to be_nil
|
80
23
|
end
|
81
24
|
end
|
82
25
|
|
83
|
-
context 'when
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
26
|
+
context 'when #load_creds! does not raise an error' do
|
27
|
+
let(:creds) {
|
28
|
+
{
|
29
|
+
:email => 'test@example.com',
|
30
|
+
:password => 'canthackthis'
|
31
|
+
}
|
32
|
+
}
|
33
|
+
before { subject.stub(:load_creds!).and_return(creds) }
|
34
|
+
|
35
|
+
it 'returns its return value' do
|
36
|
+
expect(subject.load_creds).to eq(creds)
|
88
37
|
end
|
89
38
|
end
|
90
39
|
end
|
91
40
|
|
92
41
|
describe '#load_creds!' do
|
93
|
-
|
94
|
-
|
42
|
+
subject { Sumo::Config.new(test_config_file) }
|
43
|
+
|
44
|
+
context 'when the config file does not exist' do
|
45
|
+
before { File.stub(:exists?).and_return(false) }
|
95
46
|
|
96
47
|
it 'raises an error' do
|
97
48
|
expect { subject.load_creds! }
|
@@ -99,12 +50,43 @@ describe Sumo::Config do
|
|
99
50
|
end
|
100
51
|
end
|
101
52
|
|
102
|
-
context 'when the
|
103
|
-
|
104
|
-
|
53
|
+
context 'when the config file does exist' do
|
54
|
+
context 'when the file is not valid YAML' do
|
55
|
+
let(:test_config_file) {
|
56
|
+
File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'bad-creds')
|
57
|
+
}
|
58
|
+
|
59
|
+
it 'raises an error' do
|
60
|
+
expect { subject.load_creds! }
|
61
|
+
.to raise_error(Sumo::Error::NoCredsFound)
|
62
|
+
end
|
63
|
+
end
|
105
64
|
|
106
|
-
|
107
|
-
|
65
|
+
context 'when the file is valid YAML' do
|
66
|
+
context 'but the specified key cannot be found' do
|
67
|
+
before { ENV['SUMO_CREDENTIAL'] = 'does-not-exist' }
|
68
|
+
after { ENV['SUMO_CREDENTIAL'] = nil }
|
69
|
+
|
70
|
+
it 'raises an error' do
|
71
|
+
expect { subject.load_creds! }
|
72
|
+
.to raise_error(Sumo::Error::NoCredsFound)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when the specified key can be found' do
|
77
|
+
let(:expected) {
|
78
|
+
{
|
79
|
+
'email' => 'test@example.com',
|
80
|
+
'password' => 'trustno1'
|
81
|
+
}
|
82
|
+
}
|
83
|
+
before { ENV['SUMO_CREDENTIAL'] = 'engineering' }
|
84
|
+
after { ENV['SUMO_CREDENTIAL'] = nil }
|
85
|
+
|
86
|
+
it 'returns those credentials' do
|
87
|
+
expect(subject.load_creds!).to eq(expected)
|
88
|
+
end
|
89
|
+
end
|
108
90
|
end
|
109
91
|
end
|
110
92
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sumo-search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Swipely, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: excon
|
@@ -145,6 +145,7 @@ files:
|
|
145
145
|
- lib/sumo/error.rb
|
146
146
|
- lib/sumo/search.rb
|
147
147
|
- lib/sumo/version.rb
|
148
|
+
- spec/fixtures/bad-creds
|
148
149
|
- spec/fixtures/sumo-creds
|
149
150
|
- spec/lib/sumo/client_spec.rb
|
150
151
|
- spec/lib/sumo/config_spec.rb
|
@@ -183,6 +184,7 @@ signing_key:
|
|
183
184
|
specification_version: 4
|
184
185
|
summary: A simple REST client for the Sumo Search Job API
|
185
186
|
test_files:
|
187
|
+
- spec/fixtures/bad-creds
|
186
188
|
- spec/fixtures/sumo-creds
|
187
189
|
- spec/lib/sumo/client_spec.rb
|
188
190
|
- spec/lib/sumo/config_spec.rb
|