servicenow 0.0.3 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 298f78b3a26493a3777a78e81e730c8a674bdafe
4
- data.tar.gz: dd1bbacad809a0442d66b4df78803b4133749519
3
+ metadata.gz: 00356f2950314c1456d77d963cb5828d4cc69064
4
+ data.tar.gz: 3b8f22017986499337f689fa139e8324779fa1b3
5
5
  SHA512:
6
- metadata.gz: 99a13ad7f276f737f6a0a86496c7e3795f526af3e826a68eedf5ac69c75e69459a30fc38814f005d1cbdbd051540ebd4f98fdd347dc03495c106a893ea8fa5e3
7
- data.tar.gz: 9feb14e6dc5ca1fd9fc071e869fee803a77317352e370484848f317a57229339c84d05da32e4ff5a28b809c3fee04dfc1ce94da1b05559a0924ecc5cca32cdec
6
+ metadata.gz: fae82088eec99a3e88b28fa4926d0dbbff263865fc9a04002a460e42b412116c7fb46844cda3a3357efc0b7526dae3f2eaef9a938d2f0d7ef73569d7e37b047c
7
+ data.tar.gz: a7da86f05ac070fa8c368c742e4fed7684bb8b6e3c9ab152be5dfbe07669593de4411c4c30972aa8d8380ec084afc5a9365024ba3045e58762fb44a5ea7654ee
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ .ruby-version
1
2
  /.bundle/
2
3
  /.yardoc
3
4
  /Gemfile.lock
@@ -0,0 +1,23 @@
1
+ ## 1.0.0
2
+
3
+ ### breaking changes
4
+
5
+ * Servicenow::Client#snow_base_url is renamed
6
+ Servicenow::Client#snow_api_base_url for consistency with other variables
7
+ * Logger is moved from Servicenow::Client to Servicenow; passing logger to
8
+ Client has no effect
9
+ * renamed Servicenow::Client#submit_change to Servicenow::Client#create_change
10
+
11
+ ### other changes
12
+
13
+ * moved configuration to the module level
14
+ * added methods to post work notes to a Change
15
+ * added methods to start and stop a Change
16
+ * Servicenow.logger by default logs to STDOUT, INFO level. A future improvement
17
+ will attempt to mask passwords
18
+ * basic tests
19
+
20
+ ## 0.0.3
21
+
22
+ ## 0.0.2
23
+
data/Gemfile CHANGED
@@ -8,6 +8,11 @@ gem 'httpi'
8
8
  gem 'json'
9
9
 
10
10
  group :development, :test do
11
+ gem 'guard'
12
+ gem 'guard-bundler'
13
+ gem 'guard-minitest'
11
14
  gem 'minitest'
15
+ gem 'minitest-rg'
12
16
  gem 'rake'
17
+ gem 'yard'
13
18
  end
@@ -0,0 +1,15 @@
1
+ guard :bundler do
2
+ watch 'Gemfile'
3
+ end
4
+
5
+ guard :minitest do
6
+ watch(%r{^test/(.*/)?test_.+\.rb$})
7
+ watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
8
+ watch(%r{^test/test_helper\.rb$}) { 'test' }
9
+
10
+ # with Minitest::Spec
11
+ # watch(%r{^spec/(.*)_spec\.rb$})
12
+ # watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
13
+ # watch(%r{^spec/spec_helper\.rb$}) { 'spec' }
14
+
15
+ end
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
+ t.test_files = FileList['test/**/*_test.rb']
8
8
  end
9
9
 
10
10
  task :default => :test
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "servicenow"
3
+ require 'bundler/setup'
4
+ require 'servicenow'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "servicenow"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start(__FILE__)
@@ -2,4 +2,56 @@ require 'servicenow/version'
2
2
  require 'servicenow/client'
3
3
  require 'servicenow/change'
4
4
 
5
- module Servicenow; end
5
+ module Servicenow
6
+
7
+ @logger = nil
8
+ @configuration = nil
9
+
10
+ class BaseError < StandardError; end
11
+ class MissingParameterError < BaseError; end
12
+
13
+
14
+ # Set up Servicenow config
15
+ #
16
+ # @example Set up with username. Password and URL would come from environemnt
17
+ # Servicenow.configure do |config|
18
+ # config.username = 'foo'
19
+ # end
20
+ #
21
+ # @yieldparam config [Servicenow::Configuration]
22
+ def self.configure(&block)
23
+ if @configuration.nil?
24
+ @configuration = OpenStruct.new({})
25
+ end
26
+ yield @configuration
27
+ end
28
+
29
+
30
+ # @return [Servicenow::Configuration]
31
+ def self.configuration
32
+ if @configuration.nil?
33
+ @configuration = OpenStruct.new({})
34
+ end
35
+ @configuration
36
+ end
37
+
38
+
39
+ # @param [Logger] new_logger new logger for module
40
+ #
41
+ # @return [Logger]
42
+ def self.logger=(new_logger)
43
+ @logger = new_logger
44
+ end
45
+
46
+
47
+ # @todo filter password
48
+ #
49
+ # @return [Logger] the module logger
50
+ def self.logger
51
+ if @logger.nil?
52
+ @logger = Logger.new(STDOUT)
53
+ end
54
+ @logger
55
+ end
56
+
57
+ end
@@ -2,7 +2,93 @@ require 'ostruct'
2
2
 
3
3
  module Servicenow
4
4
 
5
- class Change < OpenStruct; end
5
+ class Change < OpenStruct
6
+
7
+ @_client = nil
8
+
9
+ # @param [String] notes the notes to post
10
+ #
11
+ # @return [Servicenow::Change] the change
12
+ def add_work_notes(notes)
13
+ url = format('%s/change_request/%s', client.snow_table_url, sys_id)
14
+
15
+ query = {
16
+ work_notes: notes
17
+ }
18
+
19
+ response = client.send_request(url, query, :patch)
20
+ change
21
+ end
22
+
23
+
24
+ #
25
+ # @return [Servicenow::Change] the change
26
+ def start
27
+ url = format('%s/change_request/%s', client.snow_table_url, sys_id)
28
+
29
+ query = {
30
+ state: states['work in progress']
31
+ }
32
+
33
+ response = client.send_request(url, query, :patch)
34
+ change
35
+ end
36
+
37
+
38
+ # @return [Servicenow::Change] the change
39
+ def end_change
40
+ url = format('%s/change_request/%s', client.snow_table_url, sys_id)
41
+
42
+ query = {
43
+ state: states['work complete'],
44
+ u_completion_code: completion_codes['success']
45
+ }
46
+
47
+ response = client.send_request(url, query, :patch)
48
+ change
49
+ end
50
+
51
+
52
+ # This is a convenience method only. It cannot be used to reload a Change
53
+ # *in place* but only to return a new copy of the same Change from the
54
+ # server
55
+ #
56
+ # @return [Servicenow::Change] a refreshed copy of this Change
57
+ def reload
58
+ client.get_change(number)
59
+ end
60
+
61
+
62
+
63
+ private
64
+
65
+
66
+ def client
67
+ if @_client.nil?
68
+ @_client = Servicenow::Client.new
69
+ end
70
+ @_client
71
+ end
72
+
73
+
74
+ def states
75
+ {
76
+ 'open' => 1,
77
+ 'work in progress' => 2,
78
+ 'work complete' => 11,
79
+ 'work incomplete' => 4,
80
+ 'waiting on user' => -5,
81
+ }
82
+ end
83
+
84
+
85
+ def completion_codes
86
+ {
87
+ 'success' => 11
88
+ }
89
+ end
90
+
91
+ end
92
+
6
93
 
7
-
8
94
  end
@@ -6,29 +6,39 @@ module Servicenow
6
6
 
7
7
  class Client
8
8
 
9
- @@logger = nil
10
- attr_reader :snow_base_url
11
-
9
+ attr_reader :snow_api_base_url, :snow_table_url
10
+
11
+ # Initialization parameters for username, password and URL are normally
12
+ # set in the module configuration. They can also be passed here, or
13
+ # set in the environment. The precedence is ENV > params > module config
14
+ #
15
+ # @param [Hash] params initialization parameters
16
+ #
17
+ # @option params [String] :username ServiceNow API username
18
+ # @option params [String] :password ServiceNow API password
19
+ # @option params [String] :base_url ServiceNow API URL
20
+ #
21
+ # @return [Servicenow::Client] new client
12
22
  def initialize(params={})
13
- @snow_api_username = ENV.fetch('SNOW_API_USERNAME')
14
- @snow_api_password = ENV.fetch('SNOW_API_PASSWORD')
15
- @snow_base_url = ENV.fetch('SNOW_API_BASE_URL')
16
- @snow_table_url = format('%s/%s', @snow_base_url, 'table')
23
+ @snow_api_username = ENV.fetch('SNOW_API_USERNAME', params.delete(:username))
24
+ @snow_api_password = ENV.fetch('SNOW_API_PASSWORD', params.delete(:password))
25
+ @snow_api_base_url = ENV.fetch('SNOW_API_BASE_URL', params.delete(:url))
17
26
 
18
- if params[:logger]
19
- @@logger = params.delete(:logger)
20
- else
21
- @@logger = Logger.new(STDOUT)
22
- end
23
- end
27
+ @snow_api_username ||= Servicenow.configuration.username
28
+ @snow_api_password ||= Servicenow.configuration.password
29
+ @snow_api_base_url ||= Servicenow.configuration.base_url
24
30
 
31
+ raise MissingParameterError, 'ServiceNow API Username not set' if @snow_api_username.nil?
32
+ raise MissingParameterError, 'ServiceNow API Password not set' if @snow_api_password.nil?
33
+ raise MissingParameterError, 'ServiceNow API Base URL not set' if @snow_api_base_url.nil?
25
34
 
26
- # TODO: filter password
27
- def logger
28
- @@logger
35
+ @snow_table_url = format('%s/%s', @snow_api_base_url, 'table')
29
36
  end
37
+
30
38
 
31
-
39
+ # @param [String] user_id uses LIKE query to match for substring in u_cr_requester field
40
+ #
41
+ # @return [Array<Servicenow::Change>]
32
42
  def get_changes_by_user(user_id)
33
43
  url = format('%s/change_request', @snow_table_url)
34
44
  query = {
@@ -43,6 +53,11 @@ module Servicenow
43
53
  end
44
54
 
45
55
 
56
+ # @param [String] encodedquery a ServiceNow encoded query
57
+ # @param [int] limit limit results, default 10
58
+ # @param [int] page page of results, default 1
59
+ #
60
+ # @return [Array<Servicenow::Change>]
46
61
  def get_changes_by_query(encodedquery, limit=10, page=1)
47
62
  url = format('%s/change_request', @snow_table_url)
48
63
  query = {
@@ -52,13 +67,16 @@ module Servicenow
52
67
  }
53
68
 
54
69
  response = send_request(url, query)
55
- logger.debug response
56
-
70
+ Servicenow.logger.debug response
71
+
57
72
  obj = JSON.parse response.body
58
73
  obj['result'].collect{ |c| Change.new(c) }
59
74
  end
60
75
 
61
76
 
77
+ # @param [String] number Change number
78
+ #
79
+ # @return [Servicenow::Change]
62
80
  def get_change(number)
63
81
  url = format('%s/change_request', @snow_table_url)
64
82
  query = {
@@ -73,7 +91,10 @@ module Servicenow
73
91
  end
74
92
 
75
93
 
76
- def submit_change(data={})
94
+ # @param [Hash] data the data to use for Change creation
95
+ #
96
+ # @return [Servicenow::Change]
97
+ def create_change(data={})
77
98
  url = format('%s/change_request', @snow_table_url)
78
99
  query = {}
79
100
  query.merge(data)
@@ -88,12 +109,16 @@ module Servicenow
88
109
  end
89
110
 
90
111
 
91
- private
112
+ # protected
92
113
 
93
114
 
94
115
  def send_request(url, query, method=:get)
95
116
  request = HTTPI::Request.new(url)
96
- request.query = query
117
+ if %i[ patch put ].include? method
118
+ request.body = query.to_json
119
+ else
120
+ request.query = query
121
+ end
97
122
  request.auth.basic(@snow_api_username, @snow_api_password)
98
123
  request.headers['Accept'] = 'application/json'
99
124
  request.headers['Content-Type'] = 'application/json'
@@ -0,0 +1,7 @@
1
+ require 'ostruct'
2
+
3
+ module Servicenow
4
+
5
+ class Client < OpenStruct; end
6
+
7
+ end
@@ -1,3 +1,3 @@
1
1
  module Servicenow
2
- VERSION = '0.0.3'
2
+ VERSION = '1.0.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: servicenow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - rubyisbeautiful
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-10 00:00:00.000000000 Z
11
+ date: 2017-10-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This REST API client for ServiceNow is a work in progress
14
14
  email:
@@ -19,7 +19,9 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - ".gitignore"
21
21
  - ".travis.yml"
22
+ - CHANGELOG.md
22
23
  - Gemfile
24
+ - Guardfile
23
25
  - LICENSE.txt
24
26
  - README.md
25
27
  - Rakefile
@@ -28,6 +30,7 @@ files:
28
30
  - lib/servicenow.rb
29
31
  - lib/servicenow/change.rb
30
32
  - lib/servicenow/client.rb
33
+ - lib/servicenow/configuration.rb
31
34
  - lib/servicenow/version.rb
32
35
  - servicenow.gemspec
33
36
  homepage: https://github.com/rubyisbeautiful/servicenow