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.
@@ -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
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /rest.log
11
+ /rspec.xml
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1 @@
1
+ sophos-sg-rest
@@ -0,0 +1 @@
1
+ 2.2.6
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sophos-sg-rest.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rspec'
8
+ gem 'rspec_junit_formatter'
9
+ gem 'simplecov'
10
+ gem 'simplecov-cobertura'
11
+ end
@@ -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.
@@ -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
+
@@ -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
@@ -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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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,11 @@
1
+ # Copyright 2016 Sophos Technology GmbH. All rights reserved.
2
+ # See the LICENSE.txt file for details.
3
+ # Authors: Vincent Landgraf
4
+
5
+ module Sophos
6
+ module SG
7
+ module REST
8
+ VERSION = "0.1.0"
9
+ end
10
+ end
11
+ 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: []