samanage 1.9.33 → 2.0.03

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +24 -26
  4. data/changelog.md +13 -0
  5. data/lib/samanage.rb +2 -1
  6. data/lib/samanage/api.rb +140 -144
  7. data/lib/samanage/api/attachments.rb +21 -0
  8. data/lib/samanage/api/category.rb +24 -19
  9. data/lib/samanage/api/changes.rb +59 -0
  10. data/lib/samanage/api/comments.rb +13 -13
  11. data/lib/samanage/api/contracts.rb +51 -47
  12. data/lib/samanage/api/custom_fields.rb +23 -19
  13. data/lib/samanage/api/custom_forms.rb +42 -38
  14. data/lib/samanage/api/departments.rb +25 -22
  15. data/lib/samanage/api/groups.rb +43 -39
  16. data/lib/samanage/api/hardwares.rb +57 -53
  17. data/lib/samanage/api/incidents.rb +60 -51
  18. data/lib/samanage/api/mobiles.rb +50 -46
  19. data/lib/samanage/api/other_assets.rb +47 -43
  20. data/lib/samanage/api/requester.rb +7 -7
  21. data/lib/samanage/api/sites.rb +27 -23
  22. data/lib/samanage/api/users.rb +58 -54
  23. data/lib/samanage/api/utils.rb +0 -19
  24. data/lib/samanage/error.rb +20 -20
  25. data/lib/samanage/url_builder.rb +53 -53
  26. data/lib/samanage/version.rb +2 -2
  27. data/samanage.gemspec +2 -2
  28. data/sample_file.txt +1 -0
  29. data/spec/api/samanage_attachment_spec.rb +14 -0
  30. data/spec/api/samanage_category_spec.rb +24 -24
  31. data/spec/api/samanage_change_spec.rb +98 -0
  32. data/spec/api/samanage_comments_spec.rb +25 -32
  33. data/spec/api/samanage_contract_spec.rb +62 -68
  34. data/spec/api/samanage_custom_field_spec.rb +12 -12
  35. data/spec/api/samanage_custom_form_spec.rb +24 -24
  36. data/spec/api/samanage_department_spec.rb +35 -36
  37. data/spec/api/samanage_group_spec.rb +59 -59
  38. data/spec/api/samanage_hardware_spec.rb +80 -85
  39. data/spec/api/samanage_incident_spec.rb +99 -103
  40. data/spec/api/samanage_mobile_spec.rb +70 -74
  41. data/spec/api/samanage_other_asset_spec.rb +72 -76
  42. data/spec/api/samanage_site_spec.rb +45 -45
  43. data/spec/api/samanage_user_spec.rb +117 -100
  44. data/spec/api/samanage_util_spec.rb +4 -9
  45. data/spec/samanage_api_spec.rb +48 -48
  46. data/spec/samanage_category_spec.rb +21 -28
  47. data/spec/samanage_url_builder_spec.rb +15 -15
  48. metadata +15 -11
  49. data/lib/data/gd-class2-root.crt +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb610ead1f5436f3437f5549b2e19ba42c4fc96c
4
- data.tar.gz: 7ae398a40f0356665519c677874b5c0a0fcf288d
3
+ metadata.gz: 1d50b17cbf967d11c283e611f81604dbaa706a2e
4
+ data.tar.gz: 431c0c26fbceb0b2f7ad044b94437ca36c00fd11
5
5
  SHA512:
6
- metadata.gz: fcb4f4bc10aed1358a560e5a2a133a5799cfb1a7e7b8bbe2b0e0aaaa87b2a55fb22bc19cdd36efc367106b52c01f1223cb344f90c2e35b089920a360b984cf6b
7
- data.tar.gz: 8be7ca8d4bc073bfdb95532628c38a17c27314b7c8e65890a17edd2a26130d067855d41398276f30718fbd13d96ac6d055a72188de955c9d54d631119a22007e
6
+ metadata.gz: ff9a40bd713209bb3f37b22bf7b6ff93b7a57e3074e92e9c27e0b21c27f127061b9865d3da7b2c8de2dedbe3feafdee7948cc304238416c677c2512815136e2d
7
+ data.tar.gz: cdd09ce93a1200a5335dadbc0997792f0e8a93f07fa72abe188fd2063fb9f2e2ae7067334ce8ac4a3a716b5910371269b490827bdd407b59011f0b767320fdc0
data/Gemfile CHANGED
@@ -2,8 +2,8 @@ source "https://rubygems.org"
2
2
 
3
3
  gem 'rspec'
4
4
 
5
- gem 'httparty'
5
+ gem 'httparty', '0.15.7'
6
6
 
7
7
  group :development do
8
- gem 'guard-rspec', require: false
8
+ gem 'guard-rspec', require: false
9
9
  end
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- coderay (1.1.1)
4
+ coderay (1.1.2)
5
5
  diff-lcs (1.3)
6
- ffi (1.9.18)
6
+ ffi (1.9.23)
7
7
  formatador (0.2.5)
8
- guard (2.14.1)
8
+ guard (2.14.2)
9
9
  formatador (>= 0.2.4)
10
10
  listen (>= 2.7, < 4.0)
11
- lumberjack (~> 1.0)
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.6)
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.8.2)
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.10.4)
35
+ pry (0.11.3)
36
36
  coderay (~> 1.1.0)
37
- method_source (~> 0.8.1)
38
- slop (~> 3.4)
39
- rb-fsevent (0.9.8)
40
- rb-inotify (0.9.8)
41
- ffi (>= 0.5.0)
42
- rspec (3.6.0)
43
- rspec-core (~> 3.6.0)
44
- rspec-expectations (~> 3.6.0)
45
- rspec-mocks (~> 3.6.0)
46
- rspec-core (3.6.0)
47
- rspec-support (~> 3.6.0)
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.6.0)
51
- rspec-mocks (3.6.0)
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.6.0)
54
- rspec-support (3.6.0)
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
- slop (3.6.0)
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
- class Api
4
- include HTTParty
5
- MAX_RETRIES = 3
6
- PATHS = {
7
- category: 'categories.json',
8
- contract: 'contracts.json',
9
- custom_fields: 'custom_fields.json',
10
- custom_forms: 'custom_forms.json',
11
- department: 'departments.json',
12
- group: 'groups.json',
13
- hardware: 'hardwares.json',
14
- incident: 'incidents.json',
15
- mobile: 'mobiles.json',
16
- other_asset: 'other_assets.json',
17
- site: 'sites.json',
18
- user: 'users.json',
19
- }
20
- ssl_ca_file "#{File.expand_path('..')}/data/gd-class2-root.crt"
21
- attr_accessor :datacenter, :content_type, :base_url, :token, :custom_forms, :authorized, :admins, :max_retries
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
- # 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
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
- def authorized?
45
- self.authorized
46
- end
44
+ def authorized?
45
+ self.authorized
46
+ end
47
47
 
48
- # Check token against api.json
49
- def authorize
50
- self.execute(path: 'api.json')
51
- rescue OpenSSL::SSL::SSLError => e
52
- puts "Raised: #{e} #{e.class}"
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
- # Calling execute without a method defaults to GET
59
- def execute(http_method: 'get', path: nil, payload: nil, verbose: nil, ssl_fix: false)
60
- if payload.class == String
61
- begin
62
- payload = JSON.parse(payload)
63
- rescue => e
64
- puts "Invalid JSON: #{payload.inspect}"
65
- raise Samanage::Error(error: e, response: nil)
66
- end
67
- end
68
- token = token ||= self.token
69
- unless verbose.nil?
70
- verbose = '?layout=long'
71
- end
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
- headers = {
74
- 'Accept' => "application/vnd.samanage.v2.0+#{self.content_type}#{verbose}",
75
- 'Content-type' => "application/#{self.content_type}",
76
- 'X-Samanage-Authorization' => 'Bearer ' + self.token
77
- }
78
- @options = {
79
- headers: headers,
80
- payload: payload
81
- }
82
- full_path = self.base_url + path
83
- retries = 0
84
- begin
85
- case http_method.to_s.downcase
86
- when 'get'
87
- api_call = self.class.get(full_path, headers: headers)
88
- when 'post'
89
- api_call = self.class.post(full_path, query: payload, headers: headers)
90
- when 'put'
91
- api_call = self.class.put(full_path, query: payload, headers: headers)
92
- when 'delete'
93
- api_call = self.class.delete(full_path, query: payload, headers: headers)
94
- else
95
- raise Samanage::Error.new(response: {response: 'Unknown HTTP method'})
96
- end
97
- rescue Errno::ECONNREFUSED, Net::OpenTimeout, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError => e
98
- puts "Error:[#{e.class}] #{e} - Retry: #{retries}/#{self.max_retries}"
99
- sleep 3
100
- retries += 1
101
- retry if retries < self.max_retries
102
- error = e
103
- response = e.class
104
- raise Samanage::InvalidRequest.new(error: error, response: response)
105
- end
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
- response = Hash.new
108
- response[:code] = api_call.code.to_i
109
- response[:json] = api_call.body
110
- response[:response] = api_call
111
- response[:headers] = api_call.headers
112
- response[:total_pages] = api_call.headers['X-Total-Pages'].to_i
113
- response[:total_pages] = 1 if response[:total_pages] == 0
114
- response[:total_count] = api_call.headers['X-Total-Count'].to_i
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
- # Error cases
117
- case response[:code]
118
- when 200..201
119
- begin
120
- response[:data] = JSON.parse(api_call.body)
121
- rescue JSON::ParserError => e
122
- response[:data] = api_call.body
123
- puts "** Warning **#{e.class}"
124
- puts e
125
- end
126
- response
127
- when 401
128
- response[:data] = api_call.body
129
- error = response[:response]
130
- self.authorized = false
131
- raise Samanage::AuthorizationError.new(error: error,response: response)
132
- when 404
133
- response[:data] = api_call.body
134
- error = response[:response]
135
- raise Samanage::NotFound.new(error: error, response: response)
136
- when 422
137
- response[:data] = api_call.body
138
- error = response[:response]
139
- raise Samanage::InvalidRequest.new(error: error, response: response)
140
- else
141
- response[:data] = api_call.body
142
- error = response[:response]
143
- raise Samanage::InvalidRequest.new(error: error, response: response)
144
- end
145
- end
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
- # Return all admins in the account
149
- def list_admins
150
- admin_role_id = self.execute(path: 'roles.json')[:data].select{|role| role['name'] == 'Administrator'}.first['id']
151
- self.admins.push(
152
- self.execute(path: "users.json?role=#{admin_role_id}")[:data].map{|u| u['email']}
153
- ).flatten
154
- end
155
- end
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