sophos-sg-rest 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 +11 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +23 -0
- data/README.md +45 -0
- data/Rakefile +12 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/sophos/sg/rest.rb +20 -0
- data/lib/sophos/sg/rest/client.rb +169 -0
- data/lib/sophos/sg/rest/error.rb +23 -0
- data/lib/sophos/sg/rest/http.rb +32 -0
- data/lib/sophos/sg/rest/version.rb +11 -0
- data/sophos-sg-rest.gemspec +25 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 26bb2c7c244e7f80415bc403a98b8302d3ce28a4
|
4
|
+
data.tar.gz: 0191dd7f080ee7691a4716961bf88aa709495814
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 33b41a4f63203df664153d0dfb0088ece1510170399e8ae0b1a3deb4403e58554951a79cb8ca5ff37b0cda8793b53637c51a7d97808fc17a0cfd1a3c8f4db61b
|
7
|
+
data.tar.gz: 3212d13c0169435c78cd839d536436c736044866b04726e38a48d0ba0f75e80cec1687dbf9178878fcc7625ebf581c123e182f0bc603e4df849ef87f0d12990e
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
sophos-sg-rest
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.6
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright 2016 Sophos Limited. All rights reserved.
|
2
|
+
|
3
|
+
Sophos is a registered trademark of Sophos Limited and Sophos Group. All other
|
4
|
+
product and company names mentioned are trademarks or registered trademarks of
|
5
|
+
their respective owners.
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
9
|
+
in the Software without restriction, including without limitation the rights
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
12
|
+
furnished to do so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
15
|
+
copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Sophos::SG::REST
|
2
|
+
|
3
|
+
This gem implements a simple client for the REST API of SOPHOS SG UTM. The client
|
4
|
+
will help building [Chef](https://www.chef.io/), [Puppet](https://puppet.com/)
|
5
|
+
or other integration and provisioning scripts.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'sophos-sg-rest'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself using:
|
20
|
+
|
21
|
+
$ gem install sophos-sg-rest
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Simple example on how to get started:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'sophos/sg/rest'
|
29
|
+
client = described_class.new('https://<user>:<pass>@<host>/api/',
|
30
|
+
fingerprint: 'F3:D3:C6:C2:01:93:4A:BC:87:C4:07:8D:10:5A:59:F3:B0:B0:3C:XX')
|
31
|
+
hosts = client.objects('network/host')
|
32
|
+
```
|
33
|
+
|
34
|
+
More documentation can be found at [rubydoc](http://www.rubydoc.info/gems/sophos-sg-rest)
|
35
|
+
|
36
|
+
## Development
|
37
|
+
|
38
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
39
|
+
|
40
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
41
|
+
|
42
|
+
## Contributing
|
43
|
+
|
44
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/sophos-iaas/ruby-sophos-sg-rest.
|
45
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
task :default => :spec
|
5
|
+
|
6
|
+
desc "Run specs"
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
desc "Run specs on jenkins"
|
10
|
+
RSpec::Core::RakeTask.new(:jenkins) do |t|
|
11
|
+
t.rspec_opts = '--format RspecJunitFormatter --out rspec.xml'
|
12
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "sophos/sg/rest"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# Copyright 2016 Sophos Technology GmbH. All rights reserved.
|
2
|
+
# See the LICENSE.txt file for details.
|
3
|
+
# Authors: Vincent Landgraf
|
4
|
+
|
5
|
+
require 'net/http'
|
6
|
+
require 'json'
|
7
|
+
require 'ostruct'
|
8
|
+
require 'openssl'
|
9
|
+
|
10
|
+
require "sophos/sg/rest/version"
|
11
|
+
|
12
|
+
module Sophos
|
13
|
+
module SG
|
14
|
+
module REST
|
15
|
+
autoload :HTTP, "sophos/sg/rest/http"
|
16
|
+
autoload :Error, "sophos/sg/rest/error"
|
17
|
+
autoload :Client, "sophos/sg/rest/client"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# Copyright 2016 Sophos Technology GmbH. All rights reserved.
|
2
|
+
# See the LICENSE.txt file for details.
|
3
|
+
# Authors: Vincent Landgraf
|
4
|
+
|
5
|
+
class Sophos::SG::REST::Client
|
6
|
+
HEADER_USER_AGENT = "#{self} (#{Sophos::SG::REST::VERSION})".freeze
|
7
|
+
HEADER_ACCEPT = 'application/json'.freeze
|
8
|
+
HEADER_CONTENT_TYPE = 'Content-Type'.freeze
|
9
|
+
HEADER_ERR_ACK = 'X-Restd-Err-Ack'.freeze
|
10
|
+
HEADER_SESSION = 'X-Restd-Session'.freeze
|
11
|
+
HEADER_INSERT = 'X-Restd-Insert'.freeze
|
12
|
+
HEADER_LOCK_OVERRIDE = 'X-Restd-Lock-Override'.freeze
|
13
|
+
DEFAULT_HEADERS = {
|
14
|
+
'Accept' => HEADER_ACCEPT,
|
15
|
+
'User-Agent' => HEADER_USER_AGENT
|
16
|
+
}.freeze
|
17
|
+
attr_reader :http, :url
|
18
|
+
|
19
|
+
def initialize(url, options = {})
|
20
|
+
@http = Sophos::SG::REST::HTTP.new(url, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def logger=(logger)
|
24
|
+
@http.set_debug_output(logger)
|
25
|
+
end
|
26
|
+
|
27
|
+
def objects(type)
|
28
|
+
get path_objects(type)
|
29
|
+
end
|
30
|
+
|
31
|
+
def object(type, ref)
|
32
|
+
get path_object(type, ref)
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_object(type, attributes, insert = nil)
|
36
|
+
post path_objects(type), attributes, insert
|
37
|
+
end
|
38
|
+
|
39
|
+
def patch_object(type, ref, attributes)
|
40
|
+
patch path_object(type, ref), attributes
|
41
|
+
end
|
42
|
+
|
43
|
+
def update_object(type, attributes, insert = nil)
|
44
|
+
h = attributes.to_h
|
45
|
+
ref = h['_ref'] || h[:_ref]
|
46
|
+
raise ArgumentError, "Object _ref must be set! #{h.inspect}" if ref.nil?
|
47
|
+
put path_object(type, ref), h, insert
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroy_object(type, ref = nil)
|
51
|
+
# if ref is not passed, assume object or hash
|
52
|
+
if ref.nil?
|
53
|
+
if type.is_a? Hash
|
54
|
+
ref = type['_ref'] || type[:_ref]
|
55
|
+
type = type['_type'] || type[:_type]
|
56
|
+
elsif type.respond_to?(:_type) && type.respond_to?(:_ref)
|
57
|
+
ref = type._ref
|
58
|
+
type = type._type
|
59
|
+
else
|
60
|
+
raise ArgumentError, 'type must be a string, hash or object with ' \
|
61
|
+
' _ref and _type defined'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
delete path_object(type, ref)
|
66
|
+
end
|
67
|
+
|
68
|
+
def nodes
|
69
|
+
get nodes_path
|
70
|
+
end
|
71
|
+
|
72
|
+
def update_nodes(hash)
|
73
|
+
patch nodes_path, hash
|
74
|
+
end
|
75
|
+
|
76
|
+
def node(id)
|
77
|
+
get nodes_path(id)
|
78
|
+
end
|
79
|
+
|
80
|
+
def update_node(id, value)
|
81
|
+
put nodes_path(id), value
|
82
|
+
end
|
83
|
+
|
84
|
+
def nodes_path(id = nil)
|
85
|
+
base = File.join(@http.url.path, 'nodes') + '/'
|
86
|
+
base = File.join(base, id) if id
|
87
|
+
base
|
88
|
+
end
|
89
|
+
|
90
|
+
def path_object(type, ref)
|
91
|
+
File.join(@http.url.path, 'objects', type, ref)
|
92
|
+
end
|
93
|
+
|
94
|
+
def path_objects(type)
|
95
|
+
File.join(@http.url.path, 'objects', type) + '/'
|
96
|
+
end
|
97
|
+
|
98
|
+
def get(path)
|
99
|
+
do_json_request('GET', path)
|
100
|
+
end
|
101
|
+
|
102
|
+
def post(path, data, insert = nil)
|
103
|
+
do_json_request('POST', path, data) do |req|
|
104
|
+
req[HEADER_CONTENT_TYPE] = HEADER_ACCEPT
|
105
|
+
req[HEADER_INSERT] = insert if insert
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def put(path, data, insert = nil)
|
110
|
+
do_json_request('PUT', path, data) do |req|
|
111
|
+
req[HEADER_CONTENT_TYPE] = HEADER_ACCEPT
|
112
|
+
req[HEADER_INSERT] = insert if insert
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def patch(path, data)
|
117
|
+
do_json_request('PATCH', path, data) do |req|
|
118
|
+
req[HEADER_CONTENT_TYPE] = HEADER_ACCEPT
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def delete(path)
|
123
|
+
do_json_request('DELETE', path) do |req|
|
124
|
+
req[HEADER_ERR_ACK] = 'all'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def do_json_request(method, path, body = nil)
|
129
|
+
body = json_encode(body) unless body.nil?
|
130
|
+
req = request(method, path, body)
|
131
|
+
yield req if block_given?
|
132
|
+
response = @http.request(req)
|
133
|
+
decode_json(response, req)
|
134
|
+
end
|
135
|
+
|
136
|
+
def request(method, path, body = nil)
|
137
|
+
req = Net::HTTPGenericRequest.new(method, !body.nil?, true, path, DEFAULT_HEADERS)
|
138
|
+
req.basic_auth @http.url.user, @http.url.password
|
139
|
+
req.body = body
|
140
|
+
req
|
141
|
+
end
|
142
|
+
|
143
|
+
def json_encode(data)
|
144
|
+
data.to_json
|
145
|
+
end
|
146
|
+
|
147
|
+
def decode_json(response, req)
|
148
|
+
body = nil
|
149
|
+
|
150
|
+
if response.body && response.body != ''
|
151
|
+
# rubys JSON parse is unable to parse scalar values (number, string,
|
152
|
+
# bool, ...) directly, because of this it needs to be wrapped before
|
153
|
+
body = JSON.parse('[' + response.body + ']').first
|
154
|
+
if body.is_a?(Array) && body.any? && body.first.is_a?(Hash)
|
155
|
+
body = body.map { |i| OpenStruct.new(i) }
|
156
|
+
elsif body.is_a? Hash
|
157
|
+
body = OpenStruct.new(body)
|
158
|
+
else
|
159
|
+
body
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
if response.code.to_i >= 400
|
164
|
+
raise Sophos::SG::REST::Error.new(req, response, body)
|
165
|
+
end
|
166
|
+
|
167
|
+
body
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Copyright 2016 Sophos Technology GmbH. All rights reserved.
|
2
|
+
# See the LICENSE.txt file for details.
|
3
|
+
# Authors: Vincent Landgraf
|
4
|
+
|
5
|
+
class Sophos::SG::REST::Error < StandardError
|
6
|
+
attr_reader :request, :response, :body
|
7
|
+
|
8
|
+
def initialize(request, response, body)
|
9
|
+
@request = request
|
10
|
+
@response = response
|
11
|
+
@body = body
|
12
|
+
|
13
|
+
message = response.message
|
14
|
+
message << ": #{errors.first.name}" if errors.any?
|
15
|
+
reqdesc = "#{request.method} #{request.path} -> #{response.code}"
|
16
|
+
|
17
|
+
super "UTM: #{message} (#{reqdesc})"
|
18
|
+
end
|
19
|
+
|
20
|
+
def errors
|
21
|
+
body.is_a?(Array) ? body : []
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright 2016 Sophos Technology GmbH. All rights reserved.
|
2
|
+
# See the LICENSE.txt file for details.
|
3
|
+
# Authors: Vincent Landgraf
|
4
|
+
|
5
|
+
class Sophos::SG::REST::HTTP < Net::HTTP
|
6
|
+
attr_reader :url
|
7
|
+
|
8
|
+
def initialize(url, options = {})
|
9
|
+
@url = URI(url)
|
10
|
+
super(@url.host, @url.port)
|
11
|
+
if @url.scheme == 'https'
|
12
|
+
self.use_ssl = true
|
13
|
+
self.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
14
|
+
self.verify_callback = lambda do |preverify_ok, ssl_context|
|
15
|
+
if options[:fingerprint]
|
16
|
+
# check if the fingerprint is matching (don't respect the chain)
|
17
|
+
fingerprint = options[:fingerprint].gsub(/\s|:/, '').downcase
|
18
|
+
ssl_context.chain.each do |cert|
|
19
|
+
if fingerprint == OpenSSL::Digest::SHA1.new(cert.to_der).to_s
|
20
|
+
return true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
false
|
24
|
+
else
|
25
|
+
# if the certificate is valid and no fingerprint is passed the
|
26
|
+
# certificate chain result is determining
|
27
|
+
preverify_ok
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sophos/sg/rest/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'sophos-sg-rest'
|
8
|
+
spec.version = Sophos::SG::REST::VERSION
|
9
|
+
spec.authors = ['Vincent Landgraf']
|
10
|
+
spec.email = ['sophos-iaas-oss@sophos.com']
|
11
|
+
spec.licenses = ['MIT', 'SOPHOS proprietary']
|
12
|
+
|
13
|
+
spec.summary = %q{SOPHOS SG UTM Series - REST API Client Library}
|
14
|
+
spec.homepage = "https://github.com/sophos-iaas/ruby-sophos-sg-rest"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = 'exe'
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'rspec', '~> 3.4'
|
24
|
+
spec.add_development_dependency 'simplecov', '~> 0.12'
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sophos-sg-rest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vincent Landgraf
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.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: '3.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.12'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- sophos-iaas-oss@sophos.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".ruby-gemset"
|
79
|
+
- ".ruby-version"
|
80
|
+
- Gemfile
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- bin/console
|
85
|
+
- bin/setup
|
86
|
+
- lib/sophos/sg/rest.rb
|
87
|
+
- lib/sophos/sg/rest/client.rb
|
88
|
+
- lib/sophos/sg/rest/error.rb
|
89
|
+
- lib/sophos/sg/rest/http.rb
|
90
|
+
- lib/sophos/sg/rest/version.rb
|
91
|
+
- sophos-sg-rest.gemspec
|
92
|
+
homepage: https://github.com/sophos-iaas/ruby-sophos-sg-rest
|
93
|
+
licenses:
|
94
|
+
- MIT
|
95
|
+
- SOPHOS proprietary
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.4.8
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: SOPHOS SG UTM Series - REST API Client Library
|
117
|
+
test_files: []
|