cradlepoint 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 +7 -0
- data/.gitignore +20 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +13 -0
- data/cradlepoint.gemspec +27 -0
- data/lib/cradlepoint.rb +73 -0
- data/lib/cradlepoint/account.rb +38 -0
- data/lib/cradlepoint/config.rb +97 -0
- data/lib/cradlepoint/cradlepoint_object.rb +24 -0
- data/lib/cradlepoint/net_device.rb +42 -0
- data/lib/cradlepoint/net_flow.rb +33 -0
- data/lib/cradlepoint/router.rb +100 -0
- data/lib/cradlepoint/version.rb +3 -0
- data/lib/cradlepoint/wlan_survey.rb +18 -0
- data/script/.gitkeep +0 -0
- data/spec/account_spec.rb +62 -0
- data/spec/config_spec.rb +72 -0
- data/spec/cradlepoint_object_spec.rb +23 -0
- data/spec/cradlepoint_spec.rb +37 -0
- data/spec/net_device_spec.rb +49 -0
- data/spec/net_flow_spec.rb +26 -0
- data/spec/router_spec.rb +90 -0
- data/spec/spec_helper.rb +33 -0
- metadata +146 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a39b1ded7fedf95f572b701bc48aa6a8610b49e8
|
4
|
+
data.tar.gz: c74d80eb9a4246dde59bc3ff97a2e0ef7bf1a3a4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ce512a39b670eb5b1eb47ee41f75612882c2577a6460d2168a17df92ef02a6dbc107fa73b1b2e47ee1866c75af42ddfba6fd707e79f258f81d05059909d28f9b
|
7
|
+
data.tar.gz: 426f4d58f1d264c61916fa353d987e487ed4db19b84315c547286aff65602504c933863e0f599ea67ffaf4219350be637b4af9f8c8a04053f14b521025bc657d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 johnotander
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Cradlepoint
|
2
|
+
|
3
|
+
This is a gem that talks to Cradlepoint's Enterprise Cloud Manager \(ECM\).
|
4
|
+
|
5
|
+
In order to use this gem you will need a valid ECM username and password.
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'cradlepoint'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install cradlepoint
|
21
|
+
|
22
|
+
__Note:__ in order to run the tests you will need to do the following:
|
23
|
+
|
24
|
+
# These are required in order to run the tests, you can locate these
|
25
|
+
# details at https://cradlepointecm.com/
|
26
|
+
$ export ECM_USERNAME='<my_username>'
|
27
|
+
$ export ECM_PASSWORD='<my_password>'
|
28
|
+
$ export ECM_ACCOUNT_ID='<my_account_id>'
|
29
|
+
$ export ECM_ROUTER_ID='<my_router_id>'
|
30
|
+
|
31
|
+
# Now you're ready to run the tests.
|
32
|
+
$ rspec
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
Getting router information:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
Cradlepoint::Router.get(my_router_id) # => Router's JSON blob.
|
40
|
+
Cradlepoint::Rouer.index # => All the routers as a JSON array.
|
41
|
+
```
|
42
|
+
|
43
|
+
Getting net device information:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
router = Cradlepoint::NetDevice.new(my_router_id) # => Router object
|
47
|
+
Cradlepoint::NetDevice.new(router).get # => Router's net_device info as JSON blob.
|
48
|
+
```
|
49
|
+
|
50
|
+
## More Information
|
51
|
+
|
52
|
+
http://dev.cradlepoint.com/
|
53
|
+
|
54
|
+
## Contributing
|
55
|
+
|
56
|
+
1. Fork it
|
57
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
58
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
59
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
60
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/cradlepoint.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cradlepoint/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "cradlepoint"
|
8
|
+
spec.version = Cradlepoint::VERSION
|
9
|
+
spec.authors = ["uceem"]
|
10
|
+
spec.email = ["support@uceem.com"]
|
11
|
+
spec.description = %q{Cradlepoint ECM API gem}
|
12
|
+
spec.summary = %q{Cradlepoint ECM API gem}
|
13
|
+
spec.homepage = "https://www.uceem.com"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'rest-client'
|
22
|
+
spec.add_dependency 'json'
|
23
|
+
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "bundler"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
end
|
data/lib/cradlepoint.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'rest-client'
|
3
|
+
|
4
|
+
require 'cradlepoint/version'
|
5
|
+
|
6
|
+
require 'cradlepoint/cradlepoint_object'
|
7
|
+
require 'cradlepoint/account'
|
8
|
+
require 'cradlepoint/net_device'
|
9
|
+
require 'cradlepoint/net_flow'
|
10
|
+
require 'cradlepoint/router'
|
11
|
+
require 'cradlepoint/config'
|
12
|
+
|
13
|
+
module Cradlepoint
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_accessor :username, :password, :account, :base_url
|
17
|
+
end
|
18
|
+
|
19
|
+
@base_url = 'cradlepointecm.com/api/v1'
|
20
|
+
|
21
|
+
def self.make_request(method, url = '', params = {})
|
22
|
+
raise 'You need to call Cradlepoint.authenticate(username, password) first.' unless username and password
|
23
|
+
|
24
|
+
parameters = { format: :json }
|
25
|
+
headers = { accept: :json, content_type: :json }
|
26
|
+
|
27
|
+
response = case method
|
28
|
+
when :get then RestClient.get()
|
29
|
+
when :configs then get_configs
|
30
|
+
else false
|
31
|
+
end
|
32
|
+
|
33
|
+
response ? handle_response(response) : false
|
34
|
+
rescue RestClient::Exception => e
|
35
|
+
return case e.code
|
36
|
+
when 400 then { data: :unavailable }
|
37
|
+
when 401 then { data: :unavailable }
|
38
|
+
when 403 then { data: :unavailable }
|
39
|
+
when 404 then { data: :unavailable }
|
40
|
+
when 500 then { data: :unavailable }
|
41
|
+
else raise(e)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.authenticate(username, password)
|
46
|
+
self.username = username
|
47
|
+
self.password = password
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.url_prepend
|
52
|
+
"https://#{ @username }:#{ @password }@"
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.url_append
|
56
|
+
"?format=json"
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.handle_response(response)
|
60
|
+
begin
|
61
|
+
parsed_response = JSON.parse(response)
|
62
|
+
rescue JSON::ParserError, TypeError
|
63
|
+
raise "Cradlepoint received an invalid json response."
|
64
|
+
end
|
65
|
+
|
66
|
+
case response.code
|
67
|
+
when 200, 302 then parsed_response
|
68
|
+
when 400, 401 then false
|
69
|
+
when 500 then false
|
70
|
+
else false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Cradlepoint
|
2
|
+
class Account < CradlepointObject
|
3
|
+
|
4
|
+
attr_accessor :ecm_id, :data
|
5
|
+
|
6
|
+
def initialize(id = nil)
|
7
|
+
self.ecm_id = id
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.rel_url
|
11
|
+
'/accounts'
|
12
|
+
end
|
13
|
+
|
14
|
+
def rel_url
|
15
|
+
Cradlepoint::Account.rel_url
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.rel_url_with_id(id)
|
19
|
+
"#{ rel_url }/#{ id }/"
|
20
|
+
end
|
21
|
+
|
22
|
+
def rel_url_with_id
|
23
|
+
Cradlepoint::Account.rel_url_with_id(id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def id
|
27
|
+
self.ecm_id ? self.ecm_id : lazy_load_id
|
28
|
+
end
|
29
|
+
|
30
|
+
def lazy_load_id
|
31
|
+
self.data = Cradlepoint.handle_response RestClient.get(build_url(rel_url),
|
32
|
+
content_type: :json,
|
33
|
+
accept: :json)
|
34
|
+
self.ecm_id = self.data['data'][0]['id']
|
35
|
+
self.ecm_id
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Cradlepoint
|
2
|
+
# In order to apply a configuration to the ECM you can simply call
|
3
|
+
# Cradlepoint::Config.update(router), where the router is currently
|
4
|
+
# an ActiveRecord object, this will soon merely require a ruby dictionary
|
5
|
+
# instead.
|
6
|
+
#
|
7
|
+
# When update is called, a few steps must be undergone:
|
8
|
+
# 1. We must facilitate a POST to create a configuration_editor with the ECM API.
|
9
|
+
# 2. We must then perform a PUT of the configuration data to the configuration_editor.
|
10
|
+
# 3. Then we simply DELETE the configuration_editor, the ECM API does the rest.
|
11
|
+
class Config < CradlepointObject
|
12
|
+
|
13
|
+
attr_accessor :id, :router, :config_settings, :config_editor_id, :data
|
14
|
+
|
15
|
+
def initialize(router, config_settings = nil)
|
16
|
+
self.router = router
|
17
|
+
self.config_settings = config_settings
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.rel_url
|
21
|
+
'/configuration_editors/'
|
22
|
+
end
|
23
|
+
|
24
|
+
def rel_url
|
25
|
+
Cradlepoint::Config.rel_url
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.rel_url_with_id(id)
|
29
|
+
"#{ rel_url }#{ id }/"
|
30
|
+
end
|
31
|
+
|
32
|
+
def rel_url_with_id
|
33
|
+
Cradlepoint::Config.rel_url_with_id(id)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.rel_url_from_router(router)
|
37
|
+
"#{ Cradlepoint::Router.rel_url }/#{ router.id }/configuration_manager/"
|
38
|
+
end
|
39
|
+
|
40
|
+
def rel_url_from_router
|
41
|
+
Cradlepoint::Config.rel_url_from_router(router)
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_editor
|
45
|
+
self.data = Cradlepoint.handle_response RestClient.post(build_url(rel_url),
|
46
|
+
router.get_configuration_editor_data.to_json,
|
47
|
+
content_type: :json,
|
48
|
+
accept: :json)
|
49
|
+
self.id = self.data['data']['id']
|
50
|
+
self.data
|
51
|
+
end
|
52
|
+
|
53
|
+
def apply_config_to_editor
|
54
|
+
self.data = Cradlepoint.handle_response RestClient.put(build_url(rel_url_with_id),
|
55
|
+
get_config_data_with_wrapper(config_settings).to_json,
|
56
|
+
content_type: :json,
|
57
|
+
accept: :json)
|
58
|
+
end
|
59
|
+
|
60
|
+
def remove_editor
|
61
|
+
self.data = Cradlepoint.handle_response RestClient.delete(build_url(rel_url_with_id),
|
62
|
+
content_type: :json,
|
63
|
+
accept: :json)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def get_config_data_with_wrapper(config_settings = {})
|
69
|
+
editor_data = router.get_configuration_editor_data
|
70
|
+
editor_data[:resource_uri] = '/api/v1' + rel_url_with_id
|
71
|
+
editor_data[:committed] = true
|
72
|
+
editor_data[:id] = self.id
|
73
|
+
editor_data[:diff_from_default] = [wifi_values_wrapper(config_settings), []]
|
74
|
+
editor_data
|
75
|
+
end
|
76
|
+
|
77
|
+
def wifi_values_wrapper(config_settings)
|
78
|
+
{
|
79
|
+
wlan: {
|
80
|
+
bss: {
|
81
|
+
:'0' => wifi_values(config_settings)
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def wifi_values(config_settings)
|
88
|
+
{
|
89
|
+
system: { ui_activated: true },
|
90
|
+
radius0ip: config_settings[:radius_ip1],
|
91
|
+
radius1ip: config_settings[:radius_ip2],
|
92
|
+
radius0key: config_settings[:shared_secret] || :foobarbaz,
|
93
|
+
ssid: config_settings[:ssid] || '@uceem_ECM'
|
94
|
+
}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Cradlepoint
|
2
|
+
class CradlepointObject
|
3
|
+
|
4
|
+
def self.build_url(rel_url = '/')
|
5
|
+
"#{ Cradlepoint.url_prepend }#{ Cradlepoint.base_url }#{ rel_url }#{ Cradlepoint.url_append }"
|
6
|
+
end
|
7
|
+
|
8
|
+
def build_url(rel_url = '/')
|
9
|
+
CradlepointObject.build_url(rel_url)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.build_new_url(rel_url = '/')
|
13
|
+
"#{ Cradlepoint.url_prepend }#{ Cradlepoint.base_url }#{ rel_url }"
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_new_url(rel_url = '/')
|
17
|
+
CradlepointObject.build_new_url(rel_url)
|
18
|
+
end
|
19
|
+
|
20
|
+
def params
|
21
|
+
{ params: { format: :json } }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Cradlepoint
|
2
|
+
class NetDevice < CradlepointObject
|
3
|
+
|
4
|
+
attr_accessor :id, :router, :data
|
5
|
+
|
6
|
+
def initialize(id = nil, router = nil)
|
7
|
+
self.id = id
|
8
|
+
self.router = router
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.rel_url
|
12
|
+
'/net_devices'
|
13
|
+
end
|
14
|
+
|
15
|
+
def rel_url
|
16
|
+
Cradlepoint::NetDevice.rel_url
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.rel_url_with_id(id)
|
20
|
+
"#{ Cradlepoint::NetDevice.rel_url }/#{ id }"
|
21
|
+
end
|
22
|
+
|
23
|
+
def rel_url_with_id
|
24
|
+
Cradlepoint::NetDevice.rel_url_with_id(id)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.rel_url_from_router(router_id)
|
28
|
+
"/routers/#{ router_id }/net_devices/"
|
29
|
+
end
|
30
|
+
|
31
|
+
def rel_url_from_router
|
32
|
+
Cradlepoint::NetDevice.rel_url_from_router(router.id)
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_all_from_router
|
36
|
+
raise 'You must provide an ECM router' if router.nil?
|
37
|
+
self.data = Cradlepoint.handle_response RestClient.get(build_url(rel_url_from_router),
|
38
|
+
content_type: :json,
|
39
|
+
accept: :json)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Cradlepoint
|
2
|
+
class NetFlow < CradlepointObject
|
3
|
+
|
4
|
+
attr_accessor :mac, :router, :data, :status_data
|
5
|
+
|
6
|
+
def initialize(mac = nil, router = nil)
|
7
|
+
self.mac = mac
|
8
|
+
self.router = router
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.rel_url
|
12
|
+
'/remote'
|
13
|
+
end
|
14
|
+
|
15
|
+
def rel_url
|
16
|
+
Cradlepoint::NetFlow.rel_url
|
17
|
+
end
|
18
|
+
|
19
|
+
def get
|
20
|
+
raise 'You must provide a mac' unless self.mac
|
21
|
+
self.data = Cradlepoint.handle_response RestClient.get(build_new_url(rel_url), params)
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_status
|
25
|
+
raise 'You must provide a mac' unless self.mac
|
26
|
+
self.status_data = Cradlepoint.handle_response RestClient.get(build_new_url("#{ rel_url }/status"), params)
|
27
|
+
end
|
28
|
+
|
29
|
+
def params
|
30
|
+
{ params: { format: :json, mac: self.mac, limit: 1 }, accept: :json, content_type: :json }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Cradlepoint
|
2
|
+
class Router < CradlepointObject
|
3
|
+
|
4
|
+
attr_accessor :id, :data, :ecm_firmware_uri, :ecm_configuration_uri,
|
5
|
+
:ecm_configuration_manager_uri, :ecm_configuration_manager_data
|
6
|
+
|
7
|
+
def initialize(id = nil)
|
8
|
+
self.id = id
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.rel_url
|
12
|
+
'/routers'
|
13
|
+
end
|
14
|
+
|
15
|
+
def rel_url
|
16
|
+
Cradlepoint::Router.rel_url
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.rel_url_with_id(id)
|
20
|
+
"#{ rel_url }/#{ id }/"
|
21
|
+
end
|
22
|
+
|
23
|
+
def rel_url_with_id
|
24
|
+
Cradlepoint::Router.rel_url_with_id(id)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.rel_url_for_configuration_managers(id)
|
28
|
+
"#{ Cradlepoint::Router.rel_url_with_id(id) }/confguration_managers/"
|
29
|
+
end
|
30
|
+
|
31
|
+
def rel_url_for_configuration_managers
|
32
|
+
Cradlepoint::Router.rel_url_with_id(id)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.index
|
36
|
+
Cradlepoint.handle_response RestClient.get(build_url(rel_url))
|
37
|
+
end
|
38
|
+
|
39
|
+
def get
|
40
|
+
check_for_id_or_raise_error
|
41
|
+
self.data = Cradlepoint.handle_response RestClient.get(build_url(rel_url_with_id))
|
42
|
+
end
|
43
|
+
|
44
|
+
def apply_new_config(config_settings = {})
|
45
|
+
config = Cradlepoint::Config.new(self, config_settings)
|
46
|
+
config.create_editor
|
47
|
+
config.apply_config_to_editor
|
48
|
+
config.remove_editor
|
49
|
+
end
|
50
|
+
|
51
|
+
def configuration_manager_data
|
52
|
+
check_for_id_or_raise_error
|
53
|
+
lazy_load_configuration_manager_data unless self.ecm_configuration_manager_data
|
54
|
+
self.ecm_configuration_manager_data
|
55
|
+
end
|
56
|
+
|
57
|
+
def firmware_data
|
58
|
+
check_for_id_or_raise_error
|
59
|
+
Cradlepoint.handle_response RestClient.get(build_url(firmware_uri.split('/api/v1').last)) if firmware_uri
|
60
|
+
end
|
61
|
+
|
62
|
+
def firmware_uri
|
63
|
+
lazy_load_router_data unless self.ecm_firmware_uri
|
64
|
+
self.ecm_firmware_uri
|
65
|
+
end
|
66
|
+
|
67
|
+
def configuration_uri
|
68
|
+
lazy_load_router_data unless self.ecm_configuration_manager_uri
|
69
|
+
lazy_load_configuration_manager_data unless self.ecm_configuration_uri
|
70
|
+
self.ecm_configuration_uri
|
71
|
+
end
|
72
|
+
|
73
|
+
def lazy_load_router_data
|
74
|
+
get # Grab the data from the api.
|
75
|
+
self.ecm_firmware_uri = self.data['data']['actual_firmware']
|
76
|
+
self.ecm_configuration_manager_uri = self.data['data']['configuration_manager']
|
77
|
+
end
|
78
|
+
|
79
|
+
def lazy_load_configuration_manager_data
|
80
|
+
self.ecm_configuration_manager_data = Cradlepoint.handle_response RestClient.get(build_url(rel_url_for_configuration_managers),
|
81
|
+
content_type: :json,
|
82
|
+
accept: :json)
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_configuration_editor_data
|
86
|
+
{
|
87
|
+
account: '/api/v1' + Cradlepoint.account.rel_url_with_id,
|
88
|
+
baseline: configuration_uri,
|
89
|
+
firmware: firmware_uri,
|
90
|
+
router: '/api/v1' + rel_url_with_id
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def check_for_id_or_raise_error
|
97
|
+
raise 'You must provide an ECM router id' if id.nil?
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Cradlepoint
|
2
|
+
class WlanSurvey < CradlepointObject
|
3
|
+
|
4
|
+
attr_accessor :router, :data
|
5
|
+
|
6
|
+
def initialize(router = nil)
|
7
|
+
self.router = router
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.rel_url
|
11
|
+
'/remote/status/wlan/survey'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.get
|
15
|
+
# ...
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/script/.gitkeep
ADDED
File without changes
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cradlepoint::Account do
|
4
|
+
|
5
|
+
context 'without an id' do
|
6
|
+
|
7
|
+
let(:account) { Cradlepoint::Account.new }
|
8
|
+
|
9
|
+
before do
|
10
|
+
authenticate_with_valid_credentials
|
11
|
+
account.id
|
12
|
+
end
|
13
|
+
|
14
|
+
after { logout }
|
15
|
+
|
16
|
+
it 'should lazy load the id' do
|
17
|
+
account.id.should == ACCOUNT_ID
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should also assign the response to the data attribute' do
|
21
|
+
account.data.should be
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with an id' do
|
26
|
+
|
27
|
+
let(:id) { 123 }
|
28
|
+
let(:account) { Cradlepoint::Account.new(id) }
|
29
|
+
|
30
|
+
it 'should return the id' do
|
31
|
+
account.id.should == id
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '.rel_url' do
|
36
|
+
|
37
|
+
let(:rel_url) { '/accounts' }
|
38
|
+
|
39
|
+
it 'should return the proper rel_url from the factory' do
|
40
|
+
Cradlepoint::Account.rel_url.should == rel_url
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should return the proper rel_url' do
|
44
|
+
Cradlepoint::Account.new.rel_url.should == rel_url
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '.rel_url_with_id' do
|
49
|
+
|
50
|
+
let(:id) { 123 }
|
51
|
+
let(:rel_url_with_id) { "/accounts/#{ id }/" }
|
52
|
+
let(:account) { Cradlepoint::Account.new(id) }
|
53
|
+
|
54
|
+
it 'should return the proper rel_url_with_id from the factory' do
|
55
|
+
Cradlepoint::Account.rel_url_with_id(id).should == rel_url_with_id
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should return the proper rel_url_with_id' do
|
59
|
+
account.rel_url_with_id.should == rel_url_with_id
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
=begin
|
4
|
+
describe Cradlepoint::Config do
|
5
|
+
|
6
|
+
let(:router) { Cradlepoint::Router.new(ROUTER_ID) }
|
7
|
+
let(:config) { Cradlepoint::Config.new(router, {}) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
Cradlepoint.account = Cradlepoint::Account.new(ACCOUNT_ID)
|
11
|
+
authenticate_with_valid_credentials
|
12
|
+
end
|
13
|
+
after { logout }
|
14
|
+
|
15
|
+
subject { config }
|
16
|
+
it { should be }
|
17
|
+
it { should respond_to(:id) }
|
18
|
+
it { should respond_to(:data) }
|
19
|
+
it { should respond_to(:router) }
|
20
|
+
it { should respond_to(:config_settings) }
|
21
|
+
it { should respond_to(:config_editor_id) }
|
22
|
+
|
23
|
+
it 'should return the correct rel_url' do
|
24
|
+
config.rel_url.should == '/configuration_editors/'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should return the correct rel_url_with_id' do
|
28
|
+
config.id = 123
|
29
|
+
config.rel_url_with_id.should == '/configuration_editors/123/'
|
30
|
+
config.id = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'configuration patch' do
|
34
|
+
|
35
|
+
describe '.create_editor' do
|
36
|
+
|
37
|
+
before { config.create_editor }
|
38
|
+
after { config.remove_editor }
|
39
|
+
|
40
|
+
it 'should have been successful' do
|
41
|
+
config.id.should be
|
42
|
+
config.data['success'].should be_true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '.apply_config_to_editor' do
|
47
|
+
|
48
|
+
before do
|
49
|
+
config.create_editor
|
50
|
+
config.apply_config_to_editor
|
51
|
+
end
|
52
|
+
after { config.remove_editor }
|
53
|
+
|
54
|
+
it 'should have been successful' do
|
55
|
+
config.data['success'].should be_true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '.remove_editor' do
|
60
|
+
|
61
|
+
before do
|
62
|
+
config.create_editor
|
63
|
+
config.remove_editor
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should have been successful' do
|
67
|
+
config.data['success'].should be_true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
=end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cradlepoint::CradlepointObject do
|
4
|
+
|
5
|
+
let(:factory_cradlepoint_object) { Cradlepoint::CradlepointObject }
|
6
|
+
let(:cradlepoint_object) { Cradlepoint::CradlepointObject.new }
|
7
|
+
|
8
|
+
let(:url) { 'https://:@cradlepointecm.com/api/v1/blah?format=json' }
|
9
|
+
|
10
|
+
context 'factory' do
|
11
|
+
|
12
|
+
it 'should return the correct url' do
|
13
|
+
factory_cradlepoint_object.build_url('/blah').should == url
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'initialized object' do
|
18
|
+
|
19
|
+
it 'should return the correct url' do
|
20
|
+
cradlepoint_object.build_url('/blah').should == url
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cradlepoint do
|
4
|
+
|
5
|
+
let(:cradlepoint) { Cradlepoint }
|
6
|
+
|
7
|
+
subject { cradlepoint }
|
8
|
+
it { should be }
|
9
|
+
it { should respond_to(:username) }
|
10
|
+
it { should respond_to(:password) }
|
11
|
+
|
12
|
+
context 'authentication' do
|
13
|
+
|
14
|
+
it 'should raise an error if you make a request without credentials' do
|
15
|
+
-> { cradlepoint.make_request(:fake) }.should raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with credentials' do
|
19
|
+
|
20
|
+
before { cradlepoint.authenticate(:blah_user, :blah_password) }
|
21
|
+
|
22
|
+
it 'should not raise an error' do
|
23
|
+
-> { cradlepoint.make_request(:fake) }.should_not raise_error
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'make_request' do
|
29
|
+
|
30
|
+
before { authenticate_with_valid_credentials }
|
31
|
+
|
32
|
+
it 'should return the proper credentials' do
|
33
|
+
cradlepoint.username.should == USERNAME
|
34
|
+
cradlepoint.password.should == PASSWORD
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cradlepoint::NetDevice do
|
4
|
+
|
5
|
+
let(:net_device) { Cradlepoint::NetDevice }
|
6
|
+
|
7
|
+
subject { net_device.new }
|
8
|
+
it { should be }
|
9
|
+
it { should respond_to(:id) }
|
10
|
+
it { should respond_to(:data) }
|
11
|
+
it { should respond_to(:router) }
|
12
|
+
|
13
|
+
it 'should provide the proper rel_url' do
|
14
|
+
net_device.rel_url_from_router(123).should == '/routers/123/net_devices/'
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when authenticated' do
|
18
|
+
|
19
|
+
before { authenticate_with_valid_credentials }
|
20
|
+
|
21
|
+
describe '.get_all_from_router' do
|
22
|
+
|
23
|
+
let(:router) { Cradlepoint::Router.new(ROUTER_ID) }
|
24
|
+
let(:device) { net_device.new(nil, router) }
|
25
|
+
|
26
|
+
before { device.get_all_from_router }
|
27
|
+
|
28
|
+
it 'should have been successful' do
|
29
|
+
device.data['success'].should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should raise an error when there is no router' do
|
33
|
+
device_with_no_router = net_device.new
|
34
|
+
-> { device_with_no_router.get_all_from_router }.should raise_error
|
35
|
+
end
|
36
|
+
|
37
|
+
# TODO: Overhaul these to allow them to endure the test of time.
|
38
|
+
# These are brittle, temporary tests to make sure the correct
|
39
|
+
# blob is being returned.
|
40
|
+
it 'should return a blob' do
|
41
|
+
device.data['data'].any?.should be_true
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should be an array' do
|
45
|
+
device.data['data'].is_a?(Array).should be_true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cradlepoint::NetFlow do
|
4
|
+
|
5
|
+
let(:net_flow) { Cradlepoint::NetFlow.new(ROUTER_MAC) }
|
6
|
+
|
7
|
+
before { login }
|
8
|
+
|
9
|
+
describe '.get' do
|
10
|
+
|
11
|
+
let(:net_flow_data) { net_flow.get }
|
12
|
+
|
13
|
+
it 'should return successfully' do
|
14
|
+
net_flow_data['success'].should be_true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.get_status' do
|
19
|
+
|
20
|
+
let(:net_flow_status_data) { net_flow.get_status }
|
21
|
+
|
22
|
+
it 'should return data successfully' do
|
23
|
+
net_flow_status_data['success'].should be_true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/router_spec.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cradlepoint::Router do
|
4
|
+
|
5
|
+
let(:router) { Cradlepoint::Router }
|
6
|
+
|
7
|
+
subject { router }
|
8
|
+
it { should be }
|
9
|
+
|
10
|
+
it 'should provide the proper rel_url' do
|
11
|
+
router.rel_url.should == '/routers'
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should provide the proper rel_url_with_id' do
|
15
|
+
router.rel_url_with_id(123).should == '/routers/123/'
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when authenticated' do
|
19
|
+
|
20
|
+
before { authenticate_with_valid_credentials }
|
21
|
+
|
22
|
+
describe '.get' do
|
23
|
+
|
24
|
+
let(:response) { router.new(ROUTER_ID).get }
|
25
|
+
let(:response_hash) { response['data'] }
|
26
|
+
|
27
|
+
subject { response }
|
28
|
+
it { should be }
|
29
|
+
|
30
|
+
it 'should be successful' do
|
31
|
+
response['success'].should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should raise an error when the id is not provided' do
|
35
|
+
-> { router.get }.should raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should return the correct blob' do
|
39
|
+
response['data'].any?.should be_true
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should have the correct keys' do
|
43
|
+
['full_product_name', 'config_status', 'mac'].all? { |k| response_hash.has_key?(k) }.should be_true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.index' do
|
48
|
+
|
49
|
+
let(:response) { router.index }
|
50
|
+
let(:response_hash) { response['data'].first }
|
51
|
+
|
52
|
+
subject { response }
|
53
|
+
it { should be }
|
54
|
+
|
55
|
+
it 'should be successful' do
|
56
|
+
response['success'].should be_true
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should return the correct blob' do
|
60
|
+
response['data'].any?.should be_true
|
61
|
+
response['data'].is_a?(Array).should be_true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '.get_configuration_manager_data' do
|
66
|
+
|
67
|
+
let(:the_router) { router.new(ROUTER_ID) }
|
68
|
+
|
69
|
+
before { the_router.configuration_manager_data }
|
70
|
+
|
71
|
+
it 'should have gotten the configuration manager data' do
|
72
|
+
the_router.ecm_configuration_manager_data.should be
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '.firmware_data' do
|
77
|
+
|
78
|
+
let(:the_router) { router.new(ROUTER_ID) }
|
79
|
+
|
80
|
+
it 'should have gotten the firmware data' do
|
81
|
+
pending 'Waiting for updates to the firmware on the API side.'
|
82
|
+
the_router.firmware_data['success'].should be_true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '.apply_new_config' do
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'rspec'
|
4
|
+
|
5
|
+
require 'json'
|
6
|
+
require 'rest-client'
|
7
|
+
|
8
|
+
require 'cradlepoint'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.color_enabled = true
|
12
|
+
end
|
13
|
+
|
14
|
+
USERNAME ||= ENV['ECM_USERNAME']
|
15
|
+
PASSWORD ||= ENV['ECM_PASSWORD']
|
16
|
+
ROUTER_ID ||= ENV['ECM_ROUTER_ID']
|
17
|
+
ACCOUNT_ID ||= ENV['ECM_ACCOUNT_ID']
|
18
|
+
ROUTER_MAC ||= ENV['ECM_ROUTER_MAC']
|
19
|
+
|
20
|
+
unless USERNAME and PASSWORD and ROUTER_ID and ACCOUNT_ID
|
21
|
+
raise 'REQUIRED ENV variables: [ECM_USERNAME, ECM_PASSWORD, ECM_ROUTER_ID, ECM_ACCOUNT_ID] in order to run the specs.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def authenticate_with_valid_credentials(username = USERNAME, password = PASSWORD)
|
25
|
+
Cradlepoint.authenticate(username, password)
|
26
|
+
end
|
27
|
+
|
28
|
+
alias :login :authenticate_with_valid_credentials
|
29
|
+
|
30
|
+
def logout
|
31
|
+
Cradlepoint.username = nil
|
32
|
+
Cradlepoint.password = nil
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cradlepoint
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- uceem
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Cradlepoint ECM API gem
|
84
|
+
email:
|
85
|
+
- support@uceem.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- cradlepoint.gemspec
|
96
|
+
- lib/cradlepoint.rb
|
97
|
+
- lib/cradlepoint/account.rb
|
98
|
+
- lib/cradlepoint/config.rb
|
99
|
+
- lib/cradlepoint/cradlepoint_object.rb
|
100
|
+
- lib/cradlepoint/net_device.rb
|
101
|
+
- lib/cradlepoint/net_flow.rb
|
102
|
+
- lib/cradlepoint/router.rb
|
103
|
+
- lib/cradlepoint/version.rb
|
104
|
+
- lib/cradlepoint/wlan_survey.rb
|
105
|
+
- script/.gitkeep
|
106
|
+
- spec/account_spec.rb
|
107
|
+
- spec/config_spec.rb
|
108
|
+
- spec/cradlepoint_object_spec.rb
|
109
|
+
- spec/cradlepoint_spec.rb
|
110
|
+
- spec/net_device_spec.rb
|
111
|
+
- spec/net_flow_spec.rb
|
112
|
+
- spec/router_spec.rb
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
homepage: https://www.uceem.com
|
115
|
+
licenses:
|
116
|
+
- MIT
|
117
|
+
metadata: {}
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
requirements: []
|
133
|
+
rubyforge_project:
|
134
|
+
rubygems_version: 2.0.6
|
135
|
+
signing_key:
|
136
|
+
specification_version: 4
|
137
|
+
summary: Cradlepoint ECM API gem
|
138
|
+
test_files:
|
139
|
+
- spec/account_spec.rb
|
140
|
+
- spec/config_spec.rb
|
141
|
+
- spec/cradlepoint_object_spec.rb
|
142
|
+
- spec/cradlepoint_spec.rb
|
143
|
+
- spec/net_device_spec.rb
|
144
|
+
- spec/net_flow_spec.rb
|
145
|
+
- spec/router_spec.rb
|
146
|
+
- spec/spec_helper.rb
|