vectra 0.0.3 → 0.1.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 +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
|