samanage 1.9.33 → 2.0.03
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/Gemfile.lock +24 -26
- data/changelog.md +13 -0
- data/lib/samanage.rb +2 -1
- data/lib/samanage/api.rb +140 -144
- data/lib/samanage/api/attachments.rb +21 -0
- data/lib/samanage/api/category.rb +24 -19
- data/lib/samanage/api/changes.rb +59 -0
- data/lib/samanage/api/comments.rb +13 -13
- data/lib/samanage/api/contracts.rb +51 -47
- data/lib/samanage/api/custom_fields.rb +23 -19
- data/lib/samanage/api/custom_forms.rb +42 -38
- data/lib/samanage/api/departments.rb +25 -22
- data/lib/samanage/api/groups.rb +43 -39
- data/lib/samanage/api/hardwares.rb +57 -53
- data/lib/samanage/api/incidents.rb +60 -51
- data/lib/samanage/api/mobiles.rb +50 -46
- data/lib/samanage/api/other_assets.rb +47 -43
- data/lib/samanage/api/requester.rb +7 -7
- data/lib/samanage/api/sites.rb +27 -23
- data/lib/samanage/api/users.rb +58 -54
- data/lib/samanage/api/utils.rb +0 -19
- data/lib/samanage/error.rb +20 -20
- data/lib/samanage/url_builder.rb +53 -53
- data/lib/samanage/version.rb +2 -2
- data/samanage.gemspec +2 -2
- data/sample_file.txt +1 -0
- data/spec/api/samanage_attachment_spec.rb +14 -0
- data/spec/api/samanage_category_spec.rb +24 -24
- data/spec/api/samanage_change_spec.rb +98 -0
- data/spec/api/samanage_comments_spec.rb +25 -32
- data/spec/api/samanage_contract_spec.rb +62 -68
- data/spec/api/samanage_custom_field_spec.rb +12 -12
- data/spec/api/samanage_custom_form_spec.rb +24 -24
- data/spec/api/samanage_department_spec.rb +35 -36
- data/spec/api/samanage_group_spec.rb +59 -59
- data/spec/api/samanage_hardware_spec.rb +80 -85
- data/spec/api/samanage_incident_spec.rb +99 -103
- data/spec/api/samanage_mobile_spec.rb +70 -74
- data/spec/api/samanage_other_asset_spec.rb +72 -76
- data/spec/api/samanage_site_spec.rb +45 -45
- data/spec/api/samanage_user_spec.rb +117 -100
- data/spec/api/samanage_util_spec.rb +4 -9
- data/spec/samanage_api_spec.rb +48 -48
- data/spec/samanage_category_spec.rb +21 -28
- data/spec/samanage_url_builder_spec.rb +15 -15
- metadata +15 -11
- data/lib/data/gd-class2-root.crt +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d50b17cbf967d11c283e611f81604dbaa706a2e
|
4
|
+
data.tar.gz: 431c0c26fbceb0b2f7ad044b94437ca36c00fd11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff9a40bd713209bb3f37b22bf7b6ff93b7a57e3074e92e9c27e0b21c27f127061b9865d3da7b2c8de2dedbe3feafdee7948cc304238416c677c2512815136e2d
|
7
|
+
data.tar.gz: cdd09ce93a1200a5335dadbc0997792f0e8a93f07fa72abe188fd2063fb9f2e2ae7067334ce8ac4a3a716b5910371269b490827bdd407b59011f0b767320fdc0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
GEM
|
2
2
|
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
|
-
coderay (1.1.
|
4
|
+
coderay (1.1.2)
|
5
5
|
diff-lcs (1.3)
|
6
|
-
ffi (1.9.
|
6
|
+
ffi (1.9.23)
|
7
7
|
formatador (0.2.5)
|
8
|
-
guard (2.14.
|
8
|
+
guard (2.14.2)
|
9
9
|
formatador (>= 0.2.4)
|
10
10
|
listen (>= 2.7, < 4.0)
|
11
|
-
lumberjack (
|
11
|
+
lumberjack (>= 1.0.12, < 2.0)
|
12
12
|
nenv (~> 0.1)
|
13
13
|
notiffany (~> 0.0)
|
14
14
|
pry (>= 0.9.12)
|
@@ -19,50 +19,48 @@ GEM
|
|
19
19
|
guard (~> 2.1)
|
20
20
|
guard-compat (~> 1.1)
|
21
21
|
rspec (>= 2.99.0, < 4.0)
|
22
|
-
httparty (0.15.
|
22
|
+
httparty (0.15.7)
|
23
23
|
multi_xml (>= 0.5.2)
|
24
24
|
listen (3.1.5)
|
25
25
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
26
26
|
rb-inotify (~> 0.9, >= 0.9.7)
|
27
27
|
ruby_dep (~> 1.2)
|
28
28
|
lumberjack (1.0.12)
|
29
|
-
method_source (0.
|
29
|
+
method_source (0.9.0)
|
30
30
|
multi_xml (0.6.0)
|
31
31
|
nenv (0.3.0)
|
32
32
|
notiffany (0.1.1)
|
33
33
|
nenv (~> 0.1)
|
34
34
|
shellany (~> 0.0)
|
35
|
-
pry (0.
|
35
|
+
pry (0.11.3)
|
36
36
|
coderay (~> 1.1.0)
|
37
|
-
method_source (~> 0.
|
38
|
-
|
39
|
-
rb-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
rspec-
|
44
|
-
rspec-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
rspec-expectations (3.6.0)
|
37
|
+
method_source (~> 0.9.0)
|
38
|
+
rb-fsevent (0.10.2)
|
39
|
+
rb-inotify (0.9.10)
|
40
|
+
ffi (>= 0.5.0, < 2)
|
41
|
+
rspec (3.7.0)
|
42
|
+
rspec-core (~> 3.7.0)
|
43
|
+
rspec-expectations (~> 3.7.0)
|
44
|
+
rspec-mocks (~> 3.7.0)
|
45
|
+
rspec-core (3.7.1)
|
46
|
+
rspec-support (~> 3.7.0)
|
47
|
+
rspec-expectations (3.7.0)
|
49
48
|
diff-lcs (>= 1.2.0, < 2.0)
|
50
|
-
rspec-support (~> 3.
|
51
|
-
rspec-mocks (3.
|
49
|
+
rspec-support (~> 3.7.0)
|
50
|
+
rspec-mocks (3.7.0)
|
52
51
|
diff-lcs (>= 1.2.0, < 2.0)
|
53
|
-
rspec-support (~> 3.
|
54
|
-
rspec-support (3.
|
52
|
+
rspec-support (~> 3.7.0)
|
53
|
+
rspec-support (3.7.1)
|
55
54
|
ruby_dep (1.5.0)
|
56
55
|
shellany (0.0.1)
|
57
|
-
|
58
|
-
thor (0.19.4)
|
56
|
+
thor (0.20.0)
|
59
57
|
|
60
58
|
PLATFORMS
|
61
59
|
ruby
|
62
60
|
|
63
61
|
DEPENDENCIES
|
64
62
|
guard-rspec
|
65
|
-
httparty
|
63
|
+
httparty (= 0.15.7)
|
66
64
|
rspec
|
67
65
|
|
68
66
|
BUNDLED WITH
|
data/changelog.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# 2.0.03
|
2
|
+
- Bugfix for custom fields (fix httparty version)
|
3
|
+
|
4
|
+
# 2.0.0
|
5
|
+
- Support for responding to blocks in all paginated collection methods
|
6
|
+
- Added Changes (itsm)
|
7
|
+
|
8
|
+
# 1.9.35
|
9
|
+
- Solve warnings
|
10
|
+
|
11
|
+
# 1.9.34
|
12
|
+
- Solve warnings
|
13
|
+
|
1
14
|
# 1.9.33
|
2
15
|
- Using new cert
|
3
16
|
|
data/lib/samanage.rb
CHANGED
@@ -2,7 +2,9 @@ $LOAD_PATH << File.dirname(__FILE__)
|
|
2
2
|
require 'httparty'
|
3
3
|
|
4
4
|
require 'samanage/api'
|
5
|
+
require 'samanage/api/attachments'
|
5
6
|
require 'samanage/api/category'
|
7
|
+
require 'samanage/api/changes'
|
6
8
|
require 'samanage/api/contracts'
|
7
9
|
require 'samanage/api/comments'
|
8
10
|
require 'samanage/api/custom_fields'
|
@@ -23,5 +25,4 @@ require 'samanage/url_builder'
|
|
23
25
|
require 'samanage/version'
|
24
26
|
|
25
27
|
module Samanage
|
26
|
-
|
27
28
|
end
|
data/lib/samanage/api.rb
CHANGED
@@ -1,156 +1,152 @@
|
|
1
1
|
require 'open-uri'
|
2
2
|
module Samanage
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
3
|
+
class Api
|
4
|
+
include HTTParty
|
5
|
+
MAX_RETRIES = 3
|
6
|
+
PATHS = {
|
7
|
+
category: 'categories.json',
|
8
|
+
contract: 'contracts.json',
|
9
|
+
change: 'changes.json',
|
10
|
+
custom_fields: 'custom_fields.json',
|
11
|
+
custom_forms: 'custom_forms.json',
|
12
|
+
department: 'departments.json',
|
13
|
+
group: 'groups.json',
|
14
|
+
hardware: 'hardwares.json',
|
15
|
+
incident: 'incidents.json',
|
16
|
+
mobile: 'mobiles.json',
|
17
|
+
other_asset: 'other_assets.json',
|
18
|
+
site: 'sites.json',
|
19
|
+
user: 'users.json',
|
20
|
+
}
|
21
|
+
attr_accessor :datacenter, :content_type, :base_url, :token, :custom_forms, :authorized, :admins, :max_retries
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
23
|
+
# Development mode forces authorization & pre-populates admins and custom forms / fields
|
24
|
+
# datacenter should equal 'eu' or blank
|
25
|
+
def initialize(token: , datacenter: nil, development_mode: false, max_retries: MAX_RETRIES)
|
26
|
+
self.token = token
|
27
|
+
if !datacenter.nil? && datacenter.to_s.downcase != 'eu'
|
28
|
+
datacenter = nil
|
29
|
+
end
|
30
|
+
self.datacenter ||= datacenter.to_s.downcase
|
31
|
+
self.base_url = "https://api#{self.datacenter.to_s.downcase}.samanage.com/"
|
32
|
+
self.content_type = 'json'
|
33
|
+
self.admins = []
|
34
|
+
self.max_retries = max_retries
|
35
|
+
if development_mode
|
36
|
+
if self.authorized? != true
|
37
|
+
self.authorize
|
38
|
+
end
|
39
|
+
self.custom_forms = self.organize_forms
|
40
|
+
self.admins = self.list_admins
|
41
|
+
end
|
42
|
+
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
def authorized?
|
45
|
+
self.authorized
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
puts 'Disabling Local SSL Verification'
|
54
|
-
self.execute(path: 'api.json', ssl_fix: true)
|
55
|
-
self.authorized = true
|
56
|
-
end
|
48
|
+
# Check token against api.json
|
49
|
+
def authorize
|
50
|
+
self.execute(path: 'api.json')
|
51
|
+
self.authorized = true
|
52
|
+
end
|
57
53
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
54
|
+
# Calling execute without a method defaults to GET
|
55
|
+
def execute(http_method: 'get', path: nil, payload: nil, verbose: nil, headers: {})
|
56
|
+
if payload.class == String
|
57
|
+
begin
|
58
|
+
payload = JSON.parse(payload)
|
59
|
+
rescue => e
|
60
|
+
puts "Invalid JSON: #{payload.inspect}"
|
61
|
+
raise Samanage::Error.new(error: e, response: nil)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
token = token ||= self.token
|
65
|
+
unless verbose.nil?
|
66
|
+
verbose = '?layout=long'
|
67
|
+
end
|
72
68
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
69
|
+
headers = headers.merge({
|
70
|
+
'Accept' => "application/vnd.samanage.v2.0+#{self.content_type}#{verbose}",
|
71
|
+
'Content-type' => "application/#{self.content_type}",
|
72
|
+
'X-Samanage-Authorization' => 'Bearer ' + self.token
|
73
|
+
})
|
74
|
+
@options = {
|
75
|
+
headers: headers,
|
76
|
+
payload: payload
|
77
|
+
}
|
78
|
+
full_path = self.base_url + path
|
79
|
+
retries = 0
|
80
|
+
begin
|
81
|
+
case http_method.to_s.downcase
|
82
|
+
when 'get'
|
83
|
+
api_call = self.class.get(full_path, headers: headers)
|
84
|
+
when 'post'
|
85
|
+
api_call = self.class.post(full_path, query: payload, headers: headers)
|
86
|
+
when 'put'
|
87
|
+
api_call = self.class.put(full_path, query: payload, headers: headers)
|
88
|
+
when 'delete'
|
89
|
+
api_call = self.class.delete(full_path, query: payload, headers: headers)
|
90
|
+
else
|
91
|
+
raise Samanage::Error.new(response: {response: 'Unknown HTTP method'})
|
92
|
+
end
|
93
|
+
rescue Errno::ECONNREFUSED, Net::OpenTimeout, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError => e
|
94
|
+
puts "Error:[#{e.class}] #{e} - Retry: #{retries}/#{self.max_retries}"
|
95
|
+
sleep 3
|
96
|
+
retries += 1
|
97
|
+
retry if retries < self.max_retries
|
98
|
+
error = e
|
99
|
+
response = e.class
|
100
|
+
raise Samanage::InvalidRequest.new(error: error, response: response)
|
101
|
+
end
|
106
102
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
103
|
+
response = Hash.new
|
104
|
+
response[:code] = api_call.code.to_i
|
105
|
+
response[:json] = api_call.body
|
106
|
+
response[:response] = api_call
|
107
|
+
response[:headers] = api_call.headers
|
108
|
+
response[:total_pages] = api_call.headers['X-Total-Pages'].to_i
|
109
|
+
response[:total_pages] = 1 if response[:total_pages] == 0
|
110
|
+
response[:total_count] = api_call.headers['X-Total-Count'].to_i
|
115
111
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
112
|
+
# Error cases
|
113
|
+
case response[:code]
|
114
|
+
when 200..201
|
115
|
+
begin
|
116
|
+
response[:data] = JSON.parse(api_call.body)
|
117
|
+
rescue JSON::ParserError => e
|
118
|
+
response[:data] = api_call.body
|
119
|
+
puts "** Warning **#{e.class}"
|
120
|
+
puts e
|
121
|
+
end
|
122
|
+
response
|
123
|
+
when 401
|
124
|
+
response[:data] = api_call.body
|
125
|
+
error = response[:response]
|
126
|
+
self.authorized = false
|
127
|
+
raise Samanage::AuthorizationError.new(error: error,response: response)
|
128
|
+
when 404
|
129
|
+
response[:data] = api_call.body
|
130
|
+
error = response[:response]
|
131
|
+
raise Samanage::NotFound.new(error: error, response: response)
|
132
|
+
when 422
|
133
|
+
response[:data] = api_call.body
|
134
|
+
error = response[:response]
|
135
|
+
raise Samanage::InvalidRequest.new(error: error, response: response)
|
136
|
+
else
|
137
|
+
response[:data] = api_call.body
|
138
|
+
error = response[:response]
|
139
|
+
raise Samanage::InvalidRequest.new(error: error, response: response)
|
140
|
+
end
|
141
|
+
end
|
146
142
|
|
147
143
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
144
|
+
# Return all admins in the account
|
145
|
+
def list_admins
|
146
|
+
admin_role_id = self.execute(path: 'roles.json')[:data].select{|role| role['name'] == 'Administrator'}.first['id']
|
147
|
+
self.admins.push(
|
148
|
+
self.execute(path: "users.json?role=#{admin_role_id}")[:data].map{|u| u['email']}
|
149
|
+
).flatten
|
150
|
+
end
|
151
|
+
end
|
156
152
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Samanage
|
2
|
+
class Api
|
3
|
+
def download_attachment(attachment: {}, filename: nil, path: nil)
|
4
|
+
attachable_type = attachment['attachable_type']
|
5
|
+
attachable_id = attachment['attachable_id'].to_s
|
6
|
+
filename = filename || attachment['filename']
|
7
|
+
url = attachment['url']
|
8
|
+
|
9
|
+
file_path = path ? path : File.join(Dir.pwd,attachable_type,attachable_id)
|
10
|
+
unless File.directory?(file_path)
|
11
|
+
FileUtils.mkpath(file_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
exact_path = File.join(file_path,filename)
|
15
|
+
downloaded_attachment = open(exact_path, "wb+") do |file|
|
16
|
+
file << open(url).read
|
17
|
+
end
|
18
|
+
downloaded_attachment
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|