brpm_content_framework 0.1.55

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 (77) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +38 -0
  3. data/.travis.yml +17 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +21 -0
  6. data/README.md +308 -0
  7. data/Rakefile +23 -0
  8. data/TO_BE_MIGRATED.txt +9 -0
  9. data/architecture.png +0 -0
  10. data/automations/direct_execute.meta +10 -0
  11. data/automations/direct_execute.rb +10 -0
  12. data/automations/install_module.meta +10 -0
  13. data/automations/install_module.rb +13 -0
  14. data/bin/brpm_install +30 -0
  15. data/bin/brpm_uninstall +30 -0
  16. data/bin/event_handler +63 -0
  17. data/bin/webhook_receiver +49 -0
  18. data/brpm_content.gemspec +31 -0
  19. data/config.yml +8 -0
  20. data/infrastructure/.bashrc +6 -0
  21. data/infrastructure/.brpm +2 -0
  22. data/infrastructure/config/customer_include.rb +26 -0
  23. data/infrastructure/config/server.yml +3 -0
  24. data/infrastructure/log.html +39 -0
  25. data/infrastructure/scripts/backup_database.sh +19 -0
  26. data/infrastructure/scripts/ddns.sh +10 -0
  27. data/infrastructure/scripts/install_brpm.sh +63 -0
  28. data/infrastructure/scripts/maintenance.sh +4 -0
  29. data/infrastructure/scripts/patch_brpm.sh +90 -0
  30. data/infrastructure/scripts/restore_database.sh +33 -0
  31. data/infrastructure/scripts/run_event_handler.cmd +19 -0
  32. data/infrastructure/scripts/run_event_handler.sh +20 -0
  33. data/infrastructure/scripts/run_webhook_receiver.cmd +15 -0
  34. data/infrastructure/scripts/run_webhook_receiver.sh +15 -0
  35. data/infrastructure/silent_install_options_4.6.txt +93 -0
  36. data/infrastructure/silent_install_options_upgrade_4.6.txt +92 -0
  37. data/infrastructure/smtp_settings.rb +42 -0
  38. data/lib/brpm_auto.rb +358 -0
  39. data/lib/brpm_script_executor.rb +80 -0
  40. data/lib/logging/brpm_logger.rb +39 -0
  41. data/lib/logging/logger_base.rb +36 -0
  42. data/lib/logging/simple_logger.rb +27 -0
  43. data/lib/module_installer.rb +483 -0
  44. data/lib/params/all_params.rb +80 -0
  45. data/lib/params/integration_settings.rb +27 -0
  46. data/lib/params/params.rb +174 -0
  47. data/lib/params/params_base.rb +81 -0
  48. data/lib/params/request_params.rb +38 -0
  49. data/lib/rest_api.rb +155 -0
  50. data/lib/semaphore.rb +79 -0
  51. data/lib/utilities.rb +317 -0
  52. data/lib/version_control/git.rb +192 -0
  53. data/lib/version_control/svn.rb +221 -0
  54. data/lib/write_to.rb +1 -0
  55. data/tests/all_params_spec.rb +116 -0
  56. data/tests/brpm_auto_spec.rb +84 -0
  57. data/tests/customer_include/config/customer_include.rb +10 -0
  58. data/tests/customer_include/config/server.yml +3 -0
  59. data/tests/customer_include_spec.rb +29 -0
  60. data/tests/gemspec_spec.rb +11 -0
  61. data/tests/module_installer_spec.rb +46 -0
  62. data/tests/params_spec.rb +172 -0
  63. data/tests/request_params_spec.rb +86 -0
  64. data/tests/server_yaml_spec.rb +19 -0
  65. data/tests/spec_helper.rb +64 -0
  66. data/to_be_migrated/brpm_framework.rb +88 -0
  67. data/to_be_migrated/customer_include_default.rb +25 -0
  68. data/to_be_migrated/local_jirb.rb +15 -0
  69. data/to_be_migrated/resource_framework.rb +211 -0
  70. data/transport/dispatch_baa.rb +355 -0
  71. data/transport/dispatch_base.rb +345 -0
  72. data/transport/dispatch_nsh.rb +248 -0
  73. data/transport/dispatch_ssh.rb +154 -0
  74. data/transport/transport_baa.rb +1095 -0
  75. data/transport/transport_nsh.rb +359 -0
  76. data/transport/transport_ssh.rb +220 -0
  77. metadata +204 -0
data/lib/utilities.rb ADDED
@@ -0,0 +1,317 @@
1
+ module Utilities
2
+
3
+ EXIT_CODE_FAILURE = 'Exit_Code_Failure'
4
+ Windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) unless defined?(Windows)
5
+
6
+ # Returns the dos path from a standard path
7
+ #
8
+ # ==== Attributes
9
+ #
10
+ # * +source_path+ - path in standard "/" format
11
+ # * +drive_letter+ - base drive letter if not included in path (defaults to C)
12
+ #
13
+ # ==== Returns
14
+ #
15
+ # * dos compatible path
16
+ #
17
+ def dos_path(source_path, drive_letter = "C")
18
+ path = ""
19
+ return source_path.gsub("/", "\\") if source_path.include?(":\\")
20
+ path_array = source_path.split("/")
21
+ if path_array[1].length == 1 # drive letter
22
+ path = "#{path_array[1]}:\\"
23
+ path += path_array[2..-1].join("\\")
24
+ else
25
+ path = "#{drive_letter}:\\"
26
+ path += path_array[1..-1].join("\\")
27
+ end
28
+ path
29
+ end
30
+
31
+ # Executes a command via shell
32
+ #
33
+ # ==== Attributes
34
+ #
35
+ # * +command+ - command to execute on command line
36
+ # ==== Returns
37
+ #
38
+ # * command_run hash {stdout => <results>, stderr => any errors, pid => process id, status => exit_code}
39
+ def execute_shell(command, sensitive_data = nil)
40
+ escaped_command = command.gsub("\\", "\\\\")
41
+
42
+ loggable_command = BrpmAuto.privatize(escaped_command, sensitive_data)
43
+ BrpmAuto.log "Executing '#{loggable_command}'..."
44
+
45
+ cmd_result = {"stdout" => "","stderr" => "", "pid" => "", "status" => 1}
46
+
47
+ output_dir = File.join(BrpmAuto.params.output_dir,"#{precision_timestamp}")
48
+ errfile = "#{output_dir}_stderr.txt"
49
+ complete_command = "#{escaped_command} 2>#{errfile}" unless Windows
50
+ fil = File.open(errfile, "w+")
51
+ fil.close
52
+
53
+ begin
54
+ cmd_result["stdout"] = `#{complete_command}`
55
+ status = $?
56
+ cmd_result["pid"] = status.pid
57
+ cmd_result["status"] = status.to_i
58
+
59
+ fil = File.open(errfile)
60
+ stderr = fil.read
61
+ fil.close
62
+
63
+ if stderr.length > 2
64
+ BrpmAuto.log "Command generated an error: #{stderr}"
65
+ cmd_result["stderr"] = stderr
66
+ end
67
+ rescue Exception => e
68
+ BrpmAuto.log "Command generated an error: #{e.message}"
69
+ BrpmAuto.log "Back trace:\n#{e.backtrace}"
70
+
71
+ cmd_result["status"] = -1
72
+ cmd_result["stderr"] = "ERROR\n#{e.message}"
73
+ end
74
+
75
+ File.delete(errfile)
76
+
77
+ cmd_result
78
+ end
79
+
80
+ # Returns a timestamp to the thousanth of a second
81
+ #
82
+ # ==== Returns
83
+ #
84
+ # string timestamp 20140921153010456
85
+ #
86
+ def precision_timestamp
87
+ Time.now.strftime("%Y%m%d%H%M%S%L")
88
+ end
89
+
90
+ # Provides a simple failsafe for working with hash options
91
+ # returns "" if the option doesn't exist or is blank
92
+ # ==== Attributes
93
+ #
94
+ # * +options+ - the hash
95
+ # * +key+ - key to find in options
96
+ # * +default_value+ - if entered will be returned if the option doesn't exist or is blank
97
+ def get_option(options, key, default_value = "")
98
+ result = options.has_key?(key) ? options[key] : nil
99
+ result = default_value if result.nil? || result == ""
100
+ result
101
+ end
102
+
103
+ # Throws an error if an option is missing
104
+ # great for checking if properties exist
105
+ #
106
+ # ==== Attributes
107
+ #
108
+ # * +options+ - the options hash
109
+ # * +key+ - key to find
110
+ def required_option(options, key)
111
+ result = get_option(options, key)
112
+ raise ArgumentError, "Missing required option: #{key}" if result == ""
113
+ result
114
+ end
115
+
116
+ # Splits the server and path from an nsh path
117
+ # returns same path if no server prepended
118
+ # ==== Attributes
119
+ #
120
+ # * +path+ - nsh path
121
+ # ==== Returns
122
+ #
123
+ # array [server, path] server is blank if not present
124
+ #
125
+ def split_nsh_path(path)
126
+ result = ["",path]
127
+ result[0] = path.split("/")[2] if path.start_with?("//")
128
+ result[1] = "/#{path.split("/")[3..-1].join("/")}" if path.start_with?("//")
129
+ result
130
+ end
131
+
132
+ # Reads the Shebang in a shell script
133
+ # Supports deep format which can include wrapper information
134
+ # ==== Attributes
135
+ #
136
+ # * +os_platform+ - windows or linux
137
+ # * +action_txt+ - the body of the shell script (action)
138
+ # ==== Returns
139
+ #
140
+ # shebang hash e.g. {"ext" => ".bat", "cmd" => "cmd /c", "shebang" => "#![.bat]cmd /c "}
141
+ #
142
+ def read_shebang(os_platform, action_txt)
143
+ if os_platform.downcase =~ /win/
144
+ result = {"ext" => ".bat", "cmd" => "cmd /c", "shebang" => ""}
145
+ else
146
+ result = {"ext" => ".sh", "cmd" => "/bin/bash ", "shebang" => ""}
147
+ end
148
+ if action_txt.include?("#![") # Custom shebang
149
+ shebang = action_txt.scan(/\#\!.*/).first
150
+ result["shebang"] = shebang
151
+ items = shebang.scan(/\#\!\[.*\]/)
152
+ if items.size > 0
153
+ ext = items[0].gsub("#![","").gsub("]","")
154
+ result["ext"] = ext if ext.start_with?(".")
155
+ result["cmd"] = shebang.gsub(items[0],"").strip
156
+ else
157
+ result["cmd"] = shebang
158
+ end
159
+ elsif action_txt.include?("#!/") # Basic shebang
160
+ result["shebang"] = "standard"
161
+ else # no shebang
162
+ result["shebang"] = "none"
163
+ end
164
+ result
165
+ end
166
+
167
+ # Takes the command result from run command and build a pretty display
168
+ #
169
+ # ==== Attributes
170
+ #
171
+ # * +cmd_result+ - the command result hash
172
+ # ==== Returns
173
+ #
174
+ # * formatted text
175
+ def display_result(cmd_result)
176
+ result = "Process: #{cmd_result["pid"]}\nSTDOUT:\n#{cmd_result["stdout"]}\n"
177
+ result = "STDERR:\n #{cmd_result["stderr"]}\n#{result}" if cmd_result["stderr"].length > 2
178
+ result += "#{EXIT_CODE_FAILURE} Command returned: #{cmd_result["status"]}" if cmd_result["status"] != 0
179
+ result
180
+ end
181
+
182
+ # Looks for terms in the results and builds an exit message
183
+ # returns status message with "Command_Failed if the status fails"
184
+ # ==== Attributes
185
+ # * +results+ - the text to analyze for success
186
+ # * +success_terms+ - the term or terms (use | or & for and and or with multiple terms)
187
+ # * +fail_now+ - if set to true will throw an error if a term is not found
188
+ # ==== Returns
189
+ # * +text+ - summary of success terms
190
+ #
191
+ def verify_success_terms(results, success_terms, fail_now = false, quiet = false)
192
+ results.split("\n").each{|line| exit_status = line if line.start_with?("EXIT_CODE:") }
193
+ if success_terms != ""
194
+ exit_status = []
195
+ c_type = success_terms.include?("|") ? "or" : "and"
196
+ success = [success_terms] if !success_terms.include?("|") || !success_terms.include?("&")
197
+ success = success_terms.split("|") if success_terms.include?("|")
198
+ success = success_terms.split("&") if success_terms.include?("&")
199
+ success.each do |term|
200
+ if results.include?(term)
201
+ exit_status << "Success - found term: #{term}"
202
+ else
203
+ exit_status << "Command_Failed: term not found: #{term}"
204
+ end
205
+ end
206
+ status = exit_status.join(", ")
207
+ status.gsub!("Command_Failed:", "") if status.include?("Success") if c_type == "or"
208
+ else
209
+ status = "Success (because nothing was tested)"
210
+ end
211
+ log status unless quiet
212
+ raise "ERROR: success term not found" if fail_now && status.include?("Command_Failed")
213
+ status
214
+ end
215
+
216
+ # Checks/Creates a staging directory
217
+ #
218
+ # ==== Attributes
219
+ #
220
+ # * +force+ - forces creation of the path if it doesnt exist
221
+ # ==== Returns
222
+ #
223
+ # staging path or ERROR_ if force is false and path does not exist
224
+ #
225
+ def get_staging_dir(version, force = false)
226
+ staging_path = defined?(RPM_STAGING_PATH) ? RPM_STAGING_PATH : File.join(BrpmAuto.all_params["SS_automation_results_dir"],"staging")
227
+ pattern = File.join(staging_path, "#{Time.now.year.to_s}", path_safe(get_param("SS_application")), path_safe(get_param("SS_component")), path_safe(version))
228
+ if force
229
+ FileUtils.mkdir_p(pattern)
230
+ else
231
+ return pattern if File.exist?(pattern) # Cannot stage the same files twice
232
+ return "ERROR_#{pattern}"
233
+ end
234
+ pattern
235
+ end
236
+
237
+ # Returns a version of the string safe for a filname or path
238
+ def path_safe(txt)
239
+ txt.gsub(" ", "_").gsub(/\,|\[|\]/,"")
240
+ end
241
+
242
+ # DEPRECATED - use substitute_tokens instead (token has the format rpm{MY_TOKEN} instead of $${MY_TOKEN} to avid interference with shell variables)
243
+ def get_keyword_items(script_content = nil)
244
+ result = {}
245
+ content = script_content unless script_content.nil?
246
+ content = File.open(BrpmAuto.all_params["SS_script_file"]).read if script_content.nil?
247
+ KEYWORD_SWITCHES.each do |keyword|
248
+ reg = /\$\$\{#{keyword}\=.*\}\$\$/
249
+ items = content.scan(reg)
250
+ items.each do |item|
251
+ result[keyword] = item.gsub("$${#{keyword}=","").gsub("}$$","").chomp("\"").gsub(/^\"/,"")
252
+ end
253
+ end
254
+ result
255
+ end
256
+
257
+ def windows?
258
+ Windows
259
+ end
260
+
261
+ def privatize(expression, sensitive_data = BrpmAuto.params.private_params.values)
262
+ unless sensitive_data.nil? or sensitive_data.empty?
263
+ sensitive_data = [sensitive_data] if sensitive_data.kind_of?(String)
264
+
265
+ sensitive_data.each do |sensitive_string|
266
+ expression = expression.gsub(sensitive_string, "********")
267
+ end
268
+ end
269
+
270
+ expression
271
+ end
272
+
273
+ def substitute_tokens(expression, params = nil)
274
+ return expression if expression.nil? || !expression.kind_of?(String)
275
+
276
+ searchable_params = params || @all_params
277
+
278
+ found_token = expression.match('rpm{[^{}]*}')
279
+ while ! found_token.nil? do
280
+ raise "Property #{found_token[0][4..-2]} doesn't exist" if searchable_params[found_token[0][4..-2]].nil?
281
+ expression = expression.sub(found_token[0],searchable_params[found_token[0][4..-2]])
282
+ found_token = expression.match('rpm{[^{}]*}')
283
+ end
284
+ return expression
285
+ end
286
+
287
+ def first_defined(first, second)
288
+ if first and ! first.empty?
289
+ return first
290
+ else
291
+ return second
292
+ end
293
+ end
294
+
295
+ private
296
+
297
+ #TODO: still needed? the framework's error handling should take care of this already
298
+ def exit_code_failure
299
+ return "" if Windows
300
+ size_ = EXIT_CODE_FAILURE.size
301
+ exit_code_failure_first_part = EXIT_CODE_FAILURE[0..3]
302
+ exit_code_failure_second_part = EXIT_CODE_FAILURE[4..size_]
303
+ BrpmAuto.all_params['ignore_exit_codes'] == 'yes' ?
304
+ '' :
305
+ "; if [ $? -ne 0 ]; then first_part=#{exit_code_failure_first_part}; echo \"${first_part}#{exit_code_failure_second_part}\"; fi;"
306
+ end
307
+
308
+ def url_encode(name)
309
+ name.gsub(" ","%20").gsub("/","%2F").gsub("?","%3F")
310
+ end
311
+
312
+ def touch_file(file_path)
313
+ fil = File.open(file_path,"w+")
314
+ fil.close
315
+ file_path
316
+ end
317
+ end
@@ -0,0 +1,192 @@
1
+ require 'uri'
2
+
3
+ # Base class for working with Git
4
+ class Git
5
+
6
+ # Initializes an instance of the class
7
+ #
8
+ # ==== Attributes
9
+ #
10
+ # * +git+ - path to the git executable
11
+ # * +options+ - hash of options includes:
12
+ # url - url for svn repository
13
+ # base_path - path for the local repository
14
+ # username - repository user username
15
+ # password - repository user password
16
+ # verbose - true for verbose output
17
+ # repository - name of remote git repository (default = origin)
18
+ # artifact_path - path in repository for artifacts (default = .)
19
+ # branch - scm branch (default = master)
20
+ # simulate - simulate command - echo it (default = false)
21
+ # output_file - file for logging results (default = step output file)
22
+ #
23
+ def initialize(git, options, compat_options = {})
24
+ self.extend Utilities
25
+ if options.has_key?("SS_output_dir")
26
+ BrpmAuto.log "Load for this class has changed, no longer necessary to send params as 2nd argument"
27
+ options = compat_options
28
+ end
29
+ @url = get_option(options,"url")
30
+ @base_path = get_option(options,"base_path")
31
+ user = get_option(options,"username")
32
+ password = get_option(options,"password")
33
+ @verbose = get_option(options,"verbose", false)
34
+ @artifact_path = get_option(options,"artifact_path")
35
+ @simulate = get_option(options,"simulate", false)
36
+ update_repo_info(options)
37
+ if user != "" && password != ""
38
+ @credential = " --username #{user} --password #{password}"
39
+ else
40
+ @credential = ""
41
+ end
42
+ super(params)
43
+ @git = git
44
+ end
45
+
46
+ # Updates repository info from options
47
+ #
48
+ # ==== Attributes
49
+ #
50
+ # * +options+ - hash of options, keys [repository, branch]
51
+ # ==== Returns
52
+ #
53
+ # * command output
54
+ def update_repo_info(options)
55
+ @repo = get_option(options,"repository","origin")
56
+ @branch = get_option(options,"branch","master")
57
+ end
58
+
59
+ # Performs a GIT checkout or initialize repository
60
+ #
61
+ # ==== Attributes
62
+ #
63
+ # * +init+ - true to initilize the checkout and local repo
64
+ # * +options+ - hash of options, keys [repository, branch, revision, tag]
65
+ # ==== Returns
66
+ #
67
+ # * command output
68
+ def checkout(init = false, options = {})
69
+ update_repo_info(options)
70
+ if init
71
+ cmd = "#{@git} clone #{@url} #{@credential}"
72
+ process_cmd(cmd)
73
+ cmd = "#{@git} checkout #{@branch}"
74
+ else
75
+ revision = get_option(options,"revision")
76
+ tag = get_option(options,"tag")
77
+ if revision != ""
78
+ cmd = "#{@git} checkout #{revision}"
79
+ elsif tag != ""
80
+ cmd = "#{@git} checkout tags/#{tag}"
81
+ else
82
+ cmd = "#{@git} pull #{@repo} #{@branch}"
83
+ end
84
+ end
85
+ process_cmd(cmd)
86
+ end
87
+
88
+ # Performs an GIT commit
89
+ #
90
+ # ==== Attributes
91
+ #
92
+ # * +message+ - commit string
93
+ # * +options+ - hash of options, keys [repository, branch, push_to_repository]
94
+ # ==== Returns
95
+ #
96
+ # * command output
97
+ def commit(message = "Automation pushed changes", options = {})
98
+ update_repo_info(options)
99
+ push_to_repo = get_option(options,"push_to_repository", true)
100
+ cmd = "#{@git} commit -a -m \"#{message}\""
101
+ result = process_cmd(cmd)
102
+ cmd = "#{@git} push #{repo} #{branch}" if push_to_repo
103
+ result += process_cmd if push_to_repo
104
+ result
105
+ end
106
+
107
+ # Performs an git tag
108
+ #
109
+ # ==== Attributes
110
+ #
111
+ # * +tag_name+ - name for tag
112
+ # * +message+ - message to add to tag
113
+ # * +options+ - hash of options, keys [repository, branch, push_to_repository, tag_path]
114
+ #
115
+ # ==== Returns
116
+ #
117
+ # * command output
118
+ def tag(tag_name, message, options = {})
119
+ update_repo_info(options)
120
+ tag_path = get_option(options,"push_to_repository", true)
121
+ push_to_repo = get_option(options,"tag_path")
122
+ cmd = "#{@git} tag -a #{tag_path} -m \"#{message}\""
123
+ result = process_cmd(cmd)
124
+ cmd = "#{@git} push #{repo} #{branch}" if push_to_repo
125
+ result += process_cmd if push_to_repo
126
+ result
127
+ end
128
+
129
+ # Performs an svn statud
130
+ #
131
+ # ==== Returns
132
+ #
133
+ # * command output
134
+ def status
135
+ process_cmd "#{@git} status"
136
+ end
137
+
138
+ # Adds any new files in the local repo to the git commit list
139
+ # note: you need to commit after adding files
140
+ #
141
+ # ==== Attributes
142
+ #
143
+ # * +exclude_regex+ - regex to filter add files (file !=~ filter)
144
+ #
145
+ # ==== Returns
146
+ #
147
+ # * command output
148
+ def add_files(exclude_regex = "")
149
+ result = status
150
+ lines = result.split("\n")
151
+ ipos = lines.index("Untracked files:")
152
+ unless ipos.nil?
153
+ files = lines[(ipos + 2)..-3]
154
+ files.each do |item|
155
+ unless File.basename.start_with?(".")
156
+ cmd = "#{@git} add #{item}"
157
+ if exclude == ""
158
+ result += process_cmd(cmd)
159
+ else
160
+ result += process_cmd(cmd) unless file =~ /#{exclude}/
161
+ end
162
+ end
163
+ end
164
+ end
165
+ result += status
166
+ result
167
+ end
168
+
169
+ private
170
+
171
+ def process_cmd(cmd)
172
+ goto_base
173
+ res = execute_shell(cmd) unless @simulate
174
+ BrpmAuto.log cmd if @verbose || @simulate
175
+ @simulate ? "ok" : display_result(res)
176
+ end
177
+
178
+ def goto_base
179
+ @pwd = FileUtils.pwd
180
+ goto_path = @base_path
181
+ FileUtils.cd(goto_path, :verbose => true) if @verbose
182
+ FileUtils.cd(goto_path) unless @verbose
183
+ end
184
+
185
+ def git_errors?(output)
186
+ svn_terms = ["403 Forbidden", "SSL error code", "moorrreee"]
187
+ found = output.scan(/#{svn_terms.join("|")}/)
188
+ found.size > 0
189
+ end
190
+
191
+ end
192
+