snow_sync 1.9.4 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|