snow_sync 1.9.4 → 2.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 +4 -4
- data/README.md +10 -2
- data/lib/snow_sync/sync_util.rb +93 -17
- data/lib/snow_sync/version.rb +1 -1
- data/spec/spec_helper.rb +3 -0
- data/spec/sync_util_spec.rb +23 -31
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7426da92a88133f622c76eb1fd0a2ac246f67ba9
|
4
|
+
data.tar.gz: 3ef9f116203a9f13fc26c2e512f4a73b6af058a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0887c2e29d65bd236f512528cfcd6628377e543f9fb4662bfaed7d5b8319a543a117a53b4322bdc78166c2c37309837798eb47809fd023592009c1258eb09092
|
7
|
+
data.tar.gz: a89f50a0dc4463a229c85f76d894b416de3d1641fc9555459a6c54ca12ca9c19c1bee113d11e5e4ceb2555cb845468090264ab5b823288f381c2ceba957934f1
|
data/README.md
CHANGED
@@ -44,13 +44,17 @@ bundle install
|
|
44
44
|
cd /lib/snow_sync
|
45
45
|
```
|
46
46
|
|
47
|
-
* Setup the
|
47
|
+
* Setup the configurations in the configs.yml
|
48
|
+
* Configurations path is <path>/gems/snow_sync-<version>/lib/snow_sync/
|
48
49
|
* Append /api/now/table/ to the base_url
|
49
50
|
|
50
51
|
```bash
|
51
52
|
guard -i
|
52
53
|
```
|
53
54
|
|
55
|
+
Note: if the sync directory is deleted after a previous sync, reset the credential configs in the configs.yml so they can be re-encrypted
|
56
|
+
|
57
|
+
|
54
58
|
## Running the Tests
|
55
59
|
|
56
60
|
```bash
|
@@ -59,12 +63,16 @@ cd <path>/gems/snow_sync-<version>
|
|
59
63
|
|
60
64
|
* Create a test_configs.yml file
|
61
65
|
* Create a test record in the instance (ex: a test script include)
|
62
|
-
* Setup the test
|
66
|
+
* Setup the test configurations in the test_configs.yml
|
67
|
+
* Configurations path is <path>/gems/snow_sync-<version>/
|
68
|
+
* Append /api/now/table/ to the base_url
|
63
69
|
|
64
70
|
```ruby
|
65
71
|
rspec spec/sync_util_spec.rb
|
66
72
|
```
|
67
73
|
|
74
|
+
Note: if the sync directory is deleted after a previous sync, reset the credential configs in the test_configs.yml so they can be re-encrypted
|
75
|
+
|
68
76
|
## License
|
69
77
|
|
70
78
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/lib/snow_sync/sync_util.rb
CHANGED
@@ -9,14 +9,22 @@ module SnowSync
|
|
9
9
|
require 'rest-client'
|
10
10
|
require "yaml"
|
11
11
|
|
12
|
-
attr_accessor :configs, :logger
|
12
|
+
attr_accessor :cf, :configs, :logger
|
13
|
+
|
14
|
+
# creates utility object
|
15
|
+
# initializes encapsulated data
|
16
|
+
# opts {string}: optional configuration
|
13
17
|
|
14
18
|
def initialize(opts = nil)
|
15
|
-
opts.nil? ?
|
16
|
-
@configs = YAML::load_file(
|
19
|
+
opts.nil? ? @cf = "configs.yml" : @cf = "test_configs.yml"
|
20
|
+
@configs = YAML::load_file(@cf)
|
17
21
|
@logger = Logger.new(STDERR)
|
18
22
|
end
|
19
23
|
|
24
|
+
# creates directory if directory doesn't exist
|
25
|
+
# name {string}: required directory name
|
26
|
+
# &block {object}: optional directory path
|
27
|
+
|
20
28
|
def create_directory(name, &block)
|
21
29
|
yield block if block_given?
|
22
30
|
unless File.directory?(name)
|
@@ -25,6 +33,12 @@ module SnowSync
|
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
36
|
+
# creates a js file
|
37
|
+
# logs out the file created
|
38
|
+
# name {string}: required file name
|
39
|
+
# json {object}: required json object
|
40
|
+
# &block {object}: optional file path
|
41
|
+
|
28
42
|
def create_file(name, json, &block)
|
29
43
|
yield if block_given?
|
30
44
|
File.open("#{name}.js", "w") do |f|
|
@@ -33,24 +47,65 @@ module SnowSync
|
|
33
47
|
end
|
34
48
|
end
|
35
49
|
|
50
|
+
# checks required configurations
|
51
|
+
# raises an exception when required configs aren't found
|
52
|
+
|
36
53
|
def check_required_configs
|
37
|
-
|
54
|
+
conf_path = File.directory?(@configs["conf_path"])
|
55
|
+
missing_credentials = @configs["creds"].values.any? do |e|
|
38
56
|
e.nil?
|
39
57
|
end
|
40
58
|
keys = @configs["table_map"].keys
|
41
59
|
keys.each do |key|
|
42
|
-
|
60
|
+
# set as instance variable to reference outside block
|
61
|
+
@missing_table_map = @configs["table_map"][key].values.any? do |e|
|
43
62
|
e.nil?
|
44
63
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
64
|
+
end
|
65
|
+
if missing_credentials or @missing_table_map or !conf_path
|
66
|
+
raise "EXCEPTION: Required configs missing in configs.yml. " \
|
67
|
+
"Please check the configuration path, credentials or table to sync."
|
68
|
+
else
|
69
|
+
@configs
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# encrypts the configured credentials based on
|
74
|
+
# whether a previous sync setup has occurred
|
75
|
+
|
76
|
+
def encrypt_credentials
|
77
|
+
previous_sync = File.directory?("sync")
|
78
|
+
# sets up the configs object
|
79
|
+
configs_path = @configs["conf_path"] + @cf
|
80
|
+
configs = YAML::load_file(configs_path)
|
81
|
+
if previous_sync
|
82
|
+
# local configuration changes
|
83
|
+
configs = YAML::load_file(configs_path)
|
84
|
+
user = Base64.strict_decode64(@configs["creds"]["user"])
|
85
|
+
pass = Base64.strict_decode64(@configs["creds"]["pass"])
|
86
|
+
userb64 = Base64.strict_encode64(user)
|
87
|
+
passb64 = Base64.strict_encode64(pass)
|
88
|
+
configs["creds"]["user"] = userb64
|
89
|
+
configs["creds"]["pass"] = passb64
|
90
|
+
File.open(configs_path, 'w') { |f| YAML::dump(configs, f) }
|
91
|
+
# object state configuration changes
|
92
|
+
@configs["creds"]["user"] = userb64
|
93
|
+
@configs["creds"]["pass"] = passb64
|
94
|
+
else
|
95
|
+
# local configuration changes
|
96
|
+
userb64 = Base64.strict_encode64(@configs["creds"]["user"])
|
97
|
+
passb64 = Base64.strict_encode64(@configs["creds"]["pass"])
|
98
|
+
configs["creds"]["user"] = userb64
|
99
|
+
configs["creds"]["pass"] = passb64
|
100
|
+
File.open(configs_path, 'w') { |f| YAML::dump(configs, f) }
|
101
|
+
# object state configuration changes
|
102
|
+
@configs["creds"]["user"] = userb64
|
103
|
+
@configs["creds"]["pass"] = passb64
|
51
104
|
end
|
52
105
|
end
|
53
106
|
|
107
|
+
# requests, retrieves, sets up the js script file locally
|
108
|
+
|
54
109
|
def setup_sync_directories
|
55
110
|
@configs["table_map"].each do |key, value|
|
56
111
|
directory_name = "sync"
|
@@ -59,12 +114,12 @@ module SnowSync
|
|
59
114
|
sub_directory_name = key
|
60
115
|
create_directory(sub_directory_name, &path)
|
61
116
|
begin
|
62
|
-
user = @configs["creds"]["user"]
|
63
|
-
pass = @configs["creds"]["pass"]
|
117
|
+
user = Base64.strict_decode64(@configs["creds"]["user"])
|
118
|
+
pass = Base64.strict_decode64(@configs["creds"]["pass"])
|
64
119
|
response = RestClient.get(
|
65
120
|
"#{@configs['base_url']}#{value["table"]}?sysparm_query=sys_id%3D" +
|
66
121
|
"#{value["sysid"]}%5Ename%3D#{value["name"]}",
|
67
|
-
{:authorization => "#{"Basic " + Base64.strict_encode64("#{user}:#{pass}")}",
|
122
|
+
{:authorization => "#{"Basic " + Base64.strict_encode64("#{user}:#{pass}")}",
|
68
123
|
:accept => "application/json"})
|
69
124
|
path = proc { FileUtils.cd(sub_directory_name) }
|
70
125
|
@configs[value["table"] + "_response"] = JSON.parse(response)["result"][0]
|
@@ -78,12 +133,18 @@ module SnowSync
|
|
78
133
|
end
|
79
134
|
end
|
80
135
|
|
136
|
+
# classify's a local js file name
|
137
|
+
# file {string}: js file path
|
138
|
+
|
81
139
|
def classify(file)
|
82
140
|
file = file.split("/").last.split(".").first.camelcase
|
83
141
|
file[0] = file[0].capitalize
|
84
|
-
|
142
|
+
file
|
85
143
|
end
|
86
144
|
|
145
|
+
# returns the configured SN table hash
|
146
|
+
# file {string}: js file path
|
147
|
+
|
87
148
|
def table_lookup(file)
|
88
149
|
@configs["table_map"].select do |key, value|
|
89
150
|
if value["name"].eql?(classify(file))
|
@@ -92,6 +153,11 @@ module SnowSync
|
|
92
153
|
end
|
93
154
|
end
|
94
155
|
|
156
|
+
# replaces the encapsulated table reponse value
|
157
|
+
# with the current js file updates
|
158
|
+
# file {string}: js file path
|
159
|
+
# table_hash {hash}: configured SN table hash
|
160
|
+
|
95
161
|
def merge_update(file, table_hash)
|
96
162
|
FileUtils.cd(file.split("/")[0..1].join("/"))
|
97
163
|
script_body = File.open(file.split("/").last).read
|
@@ -99,19 +165,29 @@ module SnowSync
|
|
99
165
|
FileUtils.cd("../..")
|
100
166
|
end
|
101
167
|
|
168
|
+
# start sync process
|
169
|
+
# check required configurations
|
170
|
+
# encrypt configured credentials
|
171
|
+
# retrieve and set up the script file locally
|
172
|
+
|
102
173
|
def start_sync
|
103
174
|
check_required_configs
|
175
|
+
encrypt_credentials
|
104
176
|
setup_sync_directories
|
105
177
|
end
|
106
178
|
|
179
|
+
# merges all js file changes
|
180
|
+
# updates SN instance with the js file changes
|
181
|
+
# files {array}: array of js file paths
|
182
|
+
|
107
183
|
def push_modifications(files)
|
108
184
|
files.each do |file|
|
109
185
|
file.downcase!
|
110
186
|
table_hash = table_lookup(file)
|
111
187
|
merge_update(file, table_hash)
|
112
188
|
begin
|
113
|
-
user = @configs["creds"]["user"]
|
114
|
-
pass = @configs["creds"]["pass"]
|
189
|
+
user = Base64.strict_decode64(@configs["creds"]["user"])
|
190
|
+
pass = Base64.strict_decode64(@configs["creds"]["pass"])
|
115
191
|
request_body_map = {
|
116
192
|
table_hash["field"].to_sym => @configs[table_hash["table"] + "_response"]
|
117
193
|
}
|
data/lib/snow_sync/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -5,6 +5,9 @@ RSpec.configure do |config|
|
|
5
5
|
require "json"
|
6
6
|
require_relative "../lib/snow_sync/sync_util.rb"
|
7
7
|
|
8
|
+
@util = SnowSync::SyncUtil.new(opts = "test")
|
9
|
+
@util.encrypt_credentials
|
10
|
+
|
8
11
|
config.expect_with :rspec do |expectations|
|
9
12
|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
10
13
|
end
|
data/spec/sync_util_spec.rb
CHANGED
@@ -1,20 +1,5 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
def setup_test_config
|
4
|
-
util.configs["base_url"] = "<base url>"
|
5
|
-
util.configs["creds"]["user"] = "<username>"
|
6
|
-
util.configs["creds"]["pass"] = "<password>"
|
7
|
-
util.configs["table_map"]["script_include"]["name"] = "<js class or script name>"
|
8
|
-
util.configs["table_map"]["script_include"]["table"] = "<table>"
|
9
|
-
util.configs["table_map"]["script_include"]["sysid"] = "<sys id>"
|
10
|
-
util.configs["table_map"]["script_include"]["field"] = "<field>"
|
11
|
-
end
|
12
|
-
|
13
|
-
def setup_test_directory
|
14
|
-
FileUtils.mkdir_p("sync")
|
15
|
-
FileUtils.mkdir_p("sync/test_sub_dir")
|
16
|
-
end
|
17
|
-
|
18
3
|
## --> unit tests
|
19
4
|
describe "utility object" do
|
20
5
|
|
@@ -67,7 +52,8 @@ describe "create_file" do
|
|
67
52
|
end
|
68
53
|
|
69
54
|
it "should create a file" do
|
70
|
-
|
55
|
+
FileUtils.mkdir_p("sync")
|
56
|
+
FileUtils.mkdir_p("sync/test_sub_dir")
|
71
57
|
json = { "property" => "value" }
|
72
58
|
name = "TestClass".snakecase
|
73
59
|
path = proc do
|
@@ -85,18 +71,29 @@ describe "check_required_configs" do
|
|
85
71
|
|
86
72
|
let :util do
|
87
73
|
SnowSync::SyncUtil.new(opts = "test")
|
88
|
-
end
|
74
|
+
end
|
89
75
|
|
90
|
-
it "should raise an exception when there
|
91
|
-
|
92
|
-
util.
|
93
|
-
|
76
|
+
it "should raise an exception when there is no config path" do
|
77
|
+
util.configs["conf_path"] = "test/bad/path"
|
78
|
+
expect{util.check_required_configs}.to raise_error(/Please check the configuration path, credentials or table to sync/)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should raise an exception when there is no username" do
|
82
|
+
util.configs["creds"]["user"] = nil
|
83
|
+
expect{util.check_required_configs}.to raise_error(/Please check the configuration path, credentials or table to sync/)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should raise an exception when there is no password" do
|
87
|
+
util.configs["creds"]["pass"] = nil
|
88
|
+
expect{util.check_required_configs}.to raise_error(/Please check the configuration path, credentials or table to sync/)
|
94
89
|
end
|
95
90
|
|
96
91
|
it "should raise an exception when there are no tables mapped" do
|
97
|
-
|
98
|
-
|
99
|
-
|
92
|
+
tables = util.configs["table_map"].keys
|
93
|
+
tables.each do |table|
|
94
|
+
util.configs["table_map"][table]["table"] = nil
|
95
|
+
expect{util.check_required_configs}.to raise_error(/Please check the configuration path, credentials or table to sync/)
|
96
|
+
end
|
100
97
|
end
|
101
98
|
|
102
99
|
end
|
@@ -122,7 +119,6 @@ describe "table_lookup" do
|
|
122
119
|
end
|
123
120
|
|
124
121
|
it "should return configured SN table" do
|
125
|
-
setup_test_config
|
126
122
|
table_map = util.table_lookup("sync/script_include/test_class.js")
|
127
123
|
expect(table_map.keys).to eq ["name", "table", "sysid", "field"]
|
128
124
|
expect(table_map["table"]).to eq "sys_script_include"
|
@@ -136,10 +132,9 @@ describe "merge_update" do
|
|
136
132
|
SnowSync::SyncUtil.new(opts = "test")
|
137
133
|
end
|
138
134
|
|
139
|
-
#merge_update
|
140
135
|
it "should merge updated script with the configs object" do
|
141
|
-
|
142
|
-
|
136
|
+
FileUtils.mkdir_p("sync")
|
137
|
+
FileUtils.mkdir_p("sync/test_sub_dir")
|
143
138
|
json = { "property" => "value - with update" }
|
144
139
|
name = "TestClass".snakecase
|
145
140
|
path = proc do
|
@@ -163,7 +158,6 @@ describe "setup_sync_directories" do
|
|
163
158
|
end
|
164
159
|
|
165
160
|
it "should setup and synchronize field from the SN instance" do
|
166
|
-
setup_test_config
|
167
161
|
util.setup_sync_directories
|
168
162
|
file = File.open("sync/script_include/test_class.js")
|
169
163
|
expect(file.is_a?(Object)).to eq true
|
@@ -179,7 +173,6 @@ describe "push_modifications" do
|
|
179
173
|
end
|
180
174
|
|
181
175
|
it "should push modifications to a configured instance" do
|
182
|
-
setup_test_config
|
183
176
|
util.setup_sync_directories
|
184
177
|
file = File.open("sync/script_include/test_class.js", "r+")
|
185
178
|
lines = file.readlines
|
@@ -196,7 +189,6 @@ describe "push_modifications" do
|
|
196
189
|
lines = file.readlines
|
197
190
|
file.close
|
198
191
|
expect(lines[0]).to eq "// test comment -\n"
|
199
|
-
FileUtils.rm_rf("sync")
|
200
192
|
end
|
201
193
|
|
202
194
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snow_sync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Wallace
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|