sumo-search 1.0.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/sumo-search.png)](http://badge.fury.io/rb/sumo-search) [![Build Status](https://travis-ci.org/swipely/sumo.svg?branch=add-fog-style-credential-loading)](https://travis-ci.org/swipely/sumo) [![Code Climate](https://codeclimate.com/github/swipely/sumo.png)](https://codeclimate.com/github/swipely/sumo) [![Dependency Status](https://gemnasium.com/swipely/sumo-search.svg)](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
|