vectra 0.0.3 → 0.1.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 +30 -13
- data/lib/vectra.rb +1 -1
- data/lib/vectra/api.rb +33 -30
- data/lib/vectra/detections.rb +15 -8
- data/lib/vectra/hosts.rb +15 -8
- data/lib/vectra/rules.rb +2 -2
- data/lib/vectra/sensors.rb +1 -1
- data/lib/vectra/version.rb +1 -1
- data/spec/vectra/vectra_spec.rb +15 -5
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53de84b919e4f477a7dacbe8066df6d7ba62f457
|
4
|
+
data.tar.gz: c3a59be8da5e83badb23f3a034a2fccae4d8044b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35ba198580d653156a267523b8ae48fd8da81179fd39f49ac14a9fffabaff6a9444a0042ffb09603004688140661ba584a160a21179735f98e77dc28399cc12d
|
7
|
+
data.tar.gz: 4c0a5c10633dbfd9acd06c794d5c9aad9d1d88210a8663287e6586085f44539f2a51e34717c6763df3ca80b16c9bff54f12715efee78c0e67db2a48babebddae
|
data/README.md
CHANGED
@@ -14,30 +14,47 @@ gem install vectra
|
|
14
14
|
|
15
15
|
Basic Block Configuration:
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
```ruby
|
18
|
+
Vectra.configure do |config|
|
19
|
+
config.endpoint = @endpoint_url
|
20
|
+
config.username = @username
|
21
|
+
config.password = @password
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
**endpoint** should be your Vectra box URL, no need to add the `/api` suffix. If you include it, it won't break things either.
|
22
26
|
|
23
27
|
## Detections
|
24
28
|
|
25
|
-
|
29
|
+
To get all detections, use `#all`:
|
26
30
|
|
27
|
-
|
31
|
+
```ruby
|
32
|
+
Vectra::Detections.all
|
33
|
+
```
|
28
34
|
|
29
|
-
|
35
|
+
You can also get a detection by ID or by referencing the detection URL:
|
30
36
|
|
37
|
+
```ruby
|
38
|
+
Vectra::Detections.get(1)
|
39
|
+
Vectra::Detections.get('https://vectra/detection/1')
|
40
|
+
```
|
31
41
|
|
32
42
|
## Hosts
|
33
43
|
|
34
|
-
|
44
|
+
Do not use `::Hosts.all` if you are in production. This will be very costly if you have more than 5,000 discovered hosts.
|
45
|
+
|
46
|
+
Instead, pass a Host ID or URL:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
Vectra::Hosts.get(1)
|
50
|
+
```
|
35
51
|
|
36
|
-
|
52
|
+
## Notes
|
37
53
|
|
38
|
-
|
54
|
+
Vectra uses a `next` parameter in their responses for pagination. Default pagination is `50`. This API client will follow the `next` pages.
|
39
55
|
|
56
|
+
Currently, all responses which contain arrays (hosts and detections) will be sorted in ASC order by ID.
|
40
57
|
|
41
|
-
|
58
|
+
## Credit
|
42
59
|
|
43
|
-
|
60
|
+
[Mike Mackintosh](http://www.mikemackintosh.com)
|
data/lib/vectra.rb
CHANGED
data/lib/vectra/api.rb
CHANGED
@@ -1,48 +1,51 @@
|
|
1
1
|
module Vectra
|
2
|
-
class
|
2
|
+
class API
|
3
3
|
class InvalidResponse < RuntimeError ; end
|
4
|
+
|
5
|
+
include HTTParty
|
4
6
|
|
5
|
-
|
7
|
+
def self.pull(url)
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
# Set the endpoint
|
10
|
+
unless Vectra::Config.endpoint.include? "/api"
|
11
|
+
Vectra::Config.endpoint = "#{Vectra::Config.endpoint}/api"
|
12
|
+
end
|
13
|
+
base_uri Vectra::Config.endpoint
|
14
|
+
|
15
|
+
# Right now, they don't support signed Certs
|
16
|
+
default_options.update(verify: false)
|
9
17
|
|
18
|
+
# Set basic auth
|
19
|
+
default_options.update(basic_auth: {username: Vectra::Config.username, password: Vectra::Config.password})
|
20
|
+
|
21
|
+
# Default the result set
|
22
|
+
results = []
|
23
|
+
|
10
24
|
# Send the request
|
11
|
-
response =
|
12
|
-
"#{url}#{args}?page_size=100000",
|
13
|
-
:verify => false, # Vectra doesnt accept real certs yet
|
14
|
-
:basic_auth => {
|
15
|
-
:username => Vectra::Config.username,
|
16
|
-
:password => Vectra::Config.password
|
17
|
-
})
|
25
|
+
response = get(url)
|
18
26
|
|
27
|
+
# Check the response
|
19
28
|
if !response.code.eql?(200)
|
20
|
-
raise Vectra::
|
29
|
+
raise Vectra::API::InvalidResponse, "Invalid Response Received"
|
21
30
|
end
|
22
31
|
|
23
|
-
#
|
24
|
-
response
|
32
|
+
#response = response.response_parse
|
33
|
+
if response.parsed_response.has_key? "next"
|
34
|
+
unless response.parsed_response["next"].nil?
|
35
|
+
results.concat(self.pull(response.parsed_response["next"]))
|
36
|
+
end
|
37
|
+
end
|
25
38
|
|
26
|
-
#
|
27
|
-
if
|
28
|
-
|
29
|
-
response['results'].map{|r| results.push(r)}
|
39
|
+
# Merge the results into results
|
40
|
+
if response.parsed_response.has_key? "results"
|
41
|
+
results.concat(response.parsed_response["results"])
|
30
42
|
else
|
31
|
-
|
43
|
+
return response.parsed_response
|
32
44
|
end
|
33
45
|
|
34
|
-
#
|
35
|
-
|
36
|
-
# puts self.send(response['next']).inspect
|
37
|
-
#end
|
38
|
-
|
39
|
-
results
|
40
|
-
|
41
|
-
end
|
46
|
+
# Sort the results and spit them out
|
47
|
+
results.sort!{|a,b| a['id']<=>b['id']}
|
42
48
|
|
43
|
-
def self.request(args="", decode=true)
|
44
|
-
r = self.send("#{Vectra::Config.endpoint}#{self.target}", args, decode)
|
45
|
-
r
|
46
49
|
end
|
47
50
|
|
48
51
|
end
|
data/lib/vectra/detections.rb
CHANGED
@@ -1,18 +1,25 @@
|
|
1
1
|
module Vectra
|
2
|
-
class Detections
|
2
|
+
class Detections
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
def self.target
|
7
|
-
"detections?page_size=50000"
|
8
|
-
end
|
4
|
+
attr_accessor :target
|
5
|
+
@target = "/detections"
|
9
6
|
|
10
7
|
def self.all
|
11
|
-
|
8
|
+
Vectra::API.pull(@target)
|
12
9
|
end
|
13
10
|
|
11
|
+
def each
|
12
|
+
self.all.each do |host|
|
13
|
+
yield host
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
14
17
|
def self.get(id)
|
15
|
-
|
18
|
+
unless id.is_a? Integer
|
19
|
+
id = id.split("/").last
|
20
|
+
end
|
21
|
+
|
22
|
+
Vectra::API.pull("#{@target}/#{id}")
|
16
23
|
end
|
17
24
|
|
18
25
|
end
|
data/lib/vectra/hosts.rb
CHANGED
@@ -1,18 +1,25 @@
|
|
1
1
|
module Vectra
|
2
|
-
class Hosts
|
2
|
+
class Hosts
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
def self.target
|
7
|
-
"hosts?page_size=50000"
|
8
|
-
end
|
4
|
+
attr_accessor :target
|
5
|
+
@target = "/hosts"
|
9
6
|
|
10
7
|
def self.all
|
11
|
-
|
8
|
+
Vectra::API.pull(@target)
|
12
9
|
end
|
13
10
|
|
11
|
+
def each
|
12
|
+
self.all.each do |host|
|
13
|
+
yield host
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
14
17
|
def self.get(id)
|
15
|
-
|
18
|
+
unless id.is_a? Integer
|
19
|
+
id = id.split("/").last
|
20
|
+
end
|
21
|
+
|
22
|
+
Vectra::API.pull("#{@target}/#{id}")
|
16
23
|
end
|
17
24
|
|
18
25
|
end
|
data/lib/vectra/rules.rb
CHANGED
data/lib/vectra/sensors.rb
CHANGED
data/lib/vectra/version.rb
CHANGED
data/spec/vectra/vectra_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
2
|
|
3
|
-
describe Vectra::
|
3
|
+
describe Vectra::API, 'Configure' do
|
4
4
|
include_context "shared environment"
|
5
5
|
|
6
6
|
it 'configures correctly' do
|
@@ -11,12 +11,18 @@ describe Vectra::Api, 'Configure' do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
# This WILL be costly
|
15
|
+
#it 'gets all hosts' do
|
16
|
+
# hosts = Vectra::Hosts.all
|
17
|
+
# puts hosts.count
|
18
|
+
#end
|
17
19
|
|
18
20
|
it 'gets host by id' do
|
19
|
-
puts Vectra::Hosts.get(1)
|
21
|
+
puts Vectra::Hosts.get(1).inspect
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'gets host by link' do
|
25
|
+
puts Vectra::Hosts.get("http://blah/api/hosts/1").inspect
|
20
26
|
end
|
21
27
|
|
22
28
|
it 'gets all detections' do
|
@@ -27,4 +33,8 @@ describe Vectra::Api, 'Configure' do
|
|
27
33
|
puts Vectra::Detections.get(95)
|
28
34
|
end
|
29
35
|
|
36
|
+
it 'gets detection by id' do
|
37
|
+
puts Vectra::Detections.get("http://blah/api/detections/2").inspect
|
38
|
+
end
|
39
|
+
|
30
40
|
end
|