right_agent 0.5.1

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 (147) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +78 -0
  3. data/Rakefile +86 -0
  4. data/lib/right_agent.rb +66 -0
  5. data/lib/right_agent/actor.rb +163 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +189 -0
  8. data/lib/right_agent/agent.rb +735 -0
  9. data/lib/right_agent/agent_config.rb +403 -0
  10. data/lib/right_agent/agent_identity.rb +209 -0
  11. data/lib/right_agent/agent_tags_manager.rb +213 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/broker_client.rb +683 -0
  14. data/lib/right_agent/command.rb +30 -0
  15. data/lib/right_agent/command/agent_manager_commands.rb +134 -0
  16. data/lib/right_agent/command/command_client.rb +136 -0
  17. data/lib/right_agent/command/command_constants.rb +42 -0
  18. data/lib/right_agent/command/command_io.rb +128 -0
  19. data/lib/right_agent/command/command_parser.rb +87 -0
  20. data/lib/right_agent/command/command_runner.rb +105 -0
  21. data/lib/right_agent/command/command_serializer.rb +63 -0
  22. data/lib/right_agent/console.rb +65 -0
  23. data/lib/right_agent/core_payload_types.rb +42 -0
  24. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  25. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  26. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  27. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  28. data/lib/right_agent/core_payload_types/dev_repositories.rb +90 -0
  29. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  30. data/lib/right_agent/core_payload_types/executable_bundle.rb +138 -0
  31. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  32. data/lib/right_agent/core_payload_types/login_user.rb +62 -0
  33. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  34. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +60 -0
  35. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  36. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  37. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +73 -0
  38. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  39. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  40. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  41. data/lib/right_agent/daemonize.rb +35 -0
  42. data/lib/right_agent/dispatcher.rb +348 -0
  43. data/lib/right_agent/enrollment_result.rb +217 -0
  44. data/lib/right_agent/exceptions.rb +30 -0
  45. data/lib/right_agent/ha_broker_client.rb +1278 -0
  46. data/lib/right_agent/idempotent_request.rb +140 -0
  47. data/lib/right_agent/log.rb +418 -0
  48. data/lib/right_agent/monkey_patches.rb +29 -0
  49. data/lib/right_agent/monkey_patches/amqp_patch.rb +274 -0
  50. data/lib/right_agent/monkey_patches/ruby_patch.rb +49 -0
  51. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  52. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  53. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  54. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  55. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  56. data/lib/right_agent/monkey_patches/ruby_patch/singleton_patch.rb +46 -0
  57. data/lib/right_agent/monkey_patches/ruby_patch/string_patch.rb +107 -0
  58. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +90 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  64. data/lib/right_agent/multiplexer.rb +91 -0
  65. data/lib/right_agent/operation_result.rb +270 -0
  66. data/lib/right_agent/packets.rb +637 -0
  67. data/lib/right_agent/payload_formatter.rb +104 -0
  68. data/lib/right_agent/pid_file.rb +159 -0
  69. data/lib/right_agent/platform.rb +319 -0
  70. data/lib/right_agent/platform/darwin.rb +227 -0
  71. data/lib/right_agent/platform/linux.rb +268 -0
  72. data/lib/right_agent/platform/windows.rb +1204 -0
  73. data/lib/right_agent/scripts/agent_controller.rb +522 -0
  74. data/lib/right_agent/scripts/agent_deployer.rb +379 -0
  75. data/lib/right_agent/scripts/common_parser.rb +153 -0
  76. data/lib/right_agent/scripts/log_level_manager.rb +193 -0
  77. data/lib/right_agent/scripts/stats_manager.rb +256 -0
  78. data/lib/right_agent/scripts/usage.rb +58 -0
  79. data/lib/right_agent/secure_identity.rb +92 -0
  80. data/lib/right_agent/security.rb +32 -0
  81. data/lib/right_agent/security/cached_certificate_store_proxy.rb +63 -0
  82. data/lib/right_agent/security/certificate.rb +102 -0
  83. data/lib/right_agent/security/certificate_cache.rb +89 -0
  84. data/lib/right_agent/security/distinguished_name.rb +56 -0
  85. data/lib/right_agent/security/encrypted_document.rb +84 -0
  86. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  87. data/lib/right_agent/security/signature.rb +86 -0
  88. data/lib/right_agent/security/static_certificate_store.rb +69 -0
  89. data/lib/right_agent/sender.rb +937 -0
  90. data/lib/right_agent/serialize.rb +29 -0
  91. data/lib/right_agent/serialize/message_pack.rb +102 -0
  92. data/lib/right_agent/serialize/secure_serializer.rb +131 -0
  93. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  94. data/lib/right_agent/serialize/serializable.rb +135 -0
  95. data/lib/right_agent/serialize/serializer.rb +149 -0
  96. data/lib/right_agent/stats_helper.rb +731 -0
  97. data/lib/right_agent/subprocess.rb +38 -0
  98. data/lib/right_agent/tracer.rb +124 -0
  99. data/right_agent.gemspec +60 -0
  100. data/spec/actor_registry_spec.rb +81 -0
  101. data/spec/actor_spec.rb +99 -0
  102. data/spec/agent_config_spec.rb +226 -0
  103. data/spec/agent_identity_spec.rb +75 -0
  104. data/spec/agent_spec.rb +571 -0
  105. data/spec/broker_client_spec.rb +961 -0
  106. data/spec/command/agent_manager_commands_spec.rb +51 -0
  107. data/spec/command/command_io_spec.rb +93 -0
  108. data/spec/command/command_parser_spec.rb +79 -0
  109. data/spec/command/command_runner_spec.rb +72 -0
  110. data/spec/command/command_serializer_spec.rb +51 -0
  111. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  112. data/spec/core_payload_types/executable_bundle_spec.rb +59 -0
  113. data/spec/core_payload_types/login_user_spec.rb +98 -0
  114. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  115. data/spec/core_payload_types/spec_helper.rb +23 -0
  116. data/spec/dispatcher_spec.rb +372 -0
  117. data/spec/enrollment_result_spec.rb +53 -0
  118. data/spec/ha_broker_client_spec.rb +1673 -0
  119. data/spec/idempotent_request_spec.rb +136 -0
  120. data/spec/log_spec.rb +177 -0
  121. data/spec/monkey_patches/amqp_patch_spec.rb +100 -0
  122. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  123. data/spec/monkey_patches/string_patch_spec.rb +99 -0
  124. data/spec/multiplexer_spec.rb +48 -0
  125. data/spec/operation_result_spec.rb +171 -0
  126. data/spec/packets_spec.rb +418 -0
  127. data/spec/platform/platform_spec.rb +60 -0
  128. data/spec/results_mock.rb +45 -0
  129. data/spec/secure_identity_spec.rb +50 -0
  130. data/spec/security/cached_certificate_store_proxy_spec.rb +56 -0
  131. data/spec/security/certificate_cache_spec.rb +71 -0
  132. data/spec/security/certificate_spec.rb +49 -0
  133. data/spec/security/distinguished_name_spec.rb +46 -0
  134. data/spec/security/encrypted_document_spec.rb +55 -0
  135. data/spec/security/rsa_key_pair_spec.rb +55 -0
  136. data/spec/security/signature_spec.rb +66 -0
  137. data/spec/security/static_certificate_store_spec.rb +52 -0
  138. data/spec/sender_spec.rb +887 -0
  139. data/spec/serialize/message_pack_spec.rb +131 -0
  140. data/spec/serialize/secure_serializer_spec.rb +102 -0
  141. data/spec/serialize/serializable_spec.rb +90 -0
  142. data/spec/serialize/serializer_spec.rb +174 -0
  143. data/spec/spec.opts +2 -0
  144. data/spec/spec_helper.rb +77 -0
  145. data/spec/stats_helper_spec.rb +681 -0
  146. data/spec/tracer_spec.rb +114 -0
  147. metadata +320 -0
@@ -0,0 +1,379 @@
1
+ # === Synopsis:
2
+ # RightScale RightAgent Deployer (rad) - (c) 2009-2011 RightScale Inc
3
+ #
4
+ # rad is a command line tool for building the configuration file for a RightAgent
5
+ #
6
+ # The configuration file is generated in:
7
+ # <agent name>/config.yml
8
+ # in platform-specific RightAgent configuration directory
9
+ #
10
+ # === Examples:
11
+ # Build configuration for agent named AGENT with default options:
12
+ # rad AGENT
13
+ #
14
+ # Build configuration for agent named AGENT so it uses given AMQP settings:
15
+ # rad AGENT --user USER --pass PASSWORD --vhost VHOST --port PORT --host HOST
16
+ # rad AGENT -u USER -p PASSWORD -v VHOST -P PORT -h HOST
17
+ #
18
+ # === Usage:
19
+ # rad AGENT [options]
20
+ #
21
+ # options:
22
+ # --root-dir, -r DIR Set agent root directory (containing init, actors, and certs subdirectories)
23
+ # --cfg-dir, -c DIR Set directory where generated configuration files for all agents are stored
24
+ # --pid-dir, -z DIR Set directory containing process id file
25
+ # --identity, -i ID Use base id ID to build agent's identity
26
+ # --token, -t TOKEN Use token TOKEN to build agent's identity
27
+ # --prefix, -x PREFIX Use prefix PREFIX to build agent's identity
28
+ # --type TYPE Use agent type TYPE to build agent's' identity,
29
+ # defaults to AGENT with any trailing '_[0-9]+' removed
30
+ # --secure-identity, -S Derive actual token from given TOKEN and ID
31
+ # --url Set agent AMQP connection URL (host, port, user, pass, vhost)
32
+ # --user, -u USER Set agent AMQP username
33
+ # --password, -p PASS Set agent AMQP password
34
+ # --vhost, -v VHOST Set agent AMQP virtual host
35
+ # --host, -h HOST Set AMQP broker host
36
+ # --port, -P PORT Set AMQP broker port
37
+ # --prefetch COUNT Set maximum requests AMQP broker is to prefetch before current is ack'd
38
+ # --http-proxy PROXY Use a proxy for all agent-originated HTTP traffic
39
+ # --http-no-proxy NOPROXY Comma-separated list of proxy exceptions (e.g. metadata server)
40
+ # --time-to-live SEC Set maximum age in seconds before a request times out and is rejected
41
+ # --retry-timeout SEC Set maximum number of seconds to retry request before give up
42
+ # --retry-interval SEC Set number of seconds before initial request retry, increases exponentially
43
+ # --check-interval SEC Set number of seconds between failed connection checks, increases exponentially
44
+ # --ping-interval SEC Set minimum number of seconds since last message receipt for the agent
45
+ # to ping the mapper to check connectivity, 0 means disable ping
46
+ # --reconnect-interval SEC Set number of seconds between broker reconnect attempts
47
+ # --grace-timeout SEC Set number of seconds before graceful termination times out
48
+ # --[no-]dup-check Set whether to check for and reject duplicate requests, .e.g., due to retries
49
+ # --options, -o KEY=VAL Set options that act as final override for any persisted configuration settings
50
+ # --monit, -m Generate monit configuration file
51
+ # --test Build test deployment using default test settings
52
+ # --quiet, -Q Do not produce output
53
+ # --help Display help
54
+
55
+ require 'rubygems'
56
+ require 'optparse'
57
+ require 'fileutils'
58
+ require File.expand_path(File.join(File.dirname(__FILE__), 'usage'))
59
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'right_agent'))
60
+ require File.expand_path(File.join(File.dirname(__FILE__), 'common_parser'))
61
+
62
+ module RightScale
63
+
64
+ class AgentDeployer
65
+
66
+ include CommonParser
67
+
68
+ # Create and run deployer
69
+ #
70
+ # === Return
71
+ # true:: Always return true
72
+ def self.run
73
+ d = AgentDeployer.new
74
+ d.deploy(d.parse_args)
75
+ end
76
+
77
+ # Generate configuration from specified options and the agent's base options
78
+ # and write them to a file
79
+ #
80
+ # === Parameters
81
+ # options(Hash):: Command line options
82
+ #
83
+ # === Return
84
+ # true:: Always return true
85
+ def deploy(options)
86
+ # Initialize directory settings
87
+ AgentConfig.root_dir = options[:root_dir]
88
+ AgentConfig.cfg_dir = options[:cfg_dir]
89
+ AgentConfig.pid_dir = options[:pid_dir]
90
+
91
+ # Configure agent
92
+ cfg = load_init_cfg
93
+ check_agent(options, cfg)
94
+ cfg = configure(options, cfg)
95
+
96
+ # Persist configuration
97
+ persist(options, cfg)
98
+
99
+ # Setup agent monitoring
100
+ monitor(options) if options[:monit]
101
+ true
102
+ end
103
+
104
+ # Create options hash from command line arguments
105
+ #
106
+ # === Return
107
+ # options(Hash):: Parsed options
108
+ def parse_args
109
+ options = {}
110
+ options[:agent_name] = ARGV[0]
111
+ options[:options] = { :secure => true }
112
+ options[:quiet] = false
113
+ fail('No agent specified on the command line', print_usage = true) if options[:agent_name].nil?
114
+
115
+ opts = OptionParser.new do |opts|
116
+ parse_common(opts, options)
117
+ parse_other_args(opts, options)
118
+
119
+ opts.on('-r', '--root-dir DIR') do |d|
120
+ # Allow for more than one
121
+ if options[:root_dir]
122
+ options[:root_dir] = [options[:root_dir]] unless options[:root_dir].is_a?(Array)
123
+ options[:root_dir] << d
124
+ else
125
+ options[:root_dir] = d
126
+ end
127
+ end
128
+
129
+ opts.on('-c', '--cfg-dir DIR') do |d|
130
+ options[:cfg_dir] = d
131
+ end
132
+
133
+ opts.on('-z', '--pid-dir DIR') do |d|
134
+ options[:pid_dir] = d
135
+ end
136
+
137
+ opts.on('-w', '--monit') do
138
+ options[:monit] = true
139
+ end
140
+
141
+ opts.on('-S', '--secure-identity') do
142
+ options[:secure_identity] = true
143
+ end
144
+
145
+ opts.on('--http-proxy PROXY') do |proxy|
146
+ options[:http_proxy] = proxy
147
+ end
148
+
149
+ opts.on('--http-no-proxy NOPROXY') do |no_proxy|
150
+ options[:http_no_proxy] = no_proxy
151
+ end
152
+
153
+ opts.on('--time-to-live SEC') do |sec|
154
+ options[:time_to_live] = sec.to_i
155
+ end
156
+
157
+ opts.on('--retry-timeout SEC') do |sec|
158
+ options[:retry_timeout] = sec.to_i
159
+ end
160
+
161
+ opts.on('--retry-interval SEC') do |sec|
162
+ options[:retry_interval] = sec.to_i
163
+ end
164
+
165
+ opts.on('--check-interval SEC') do |sec|
166
+ options[:check_interval] = sec.to_i
167
+ end
168
+
169
+ opts.on('--ping-interval SEC') do |sec|
170
+ options[:ping_interval] = sec.to_i
171
+ end
172
+
173
+ opts.on('--reconnect-interval SEC') do |sec|
174
+ options[:reconnect_interval] = sec.to_i
175
+ end
176
+
177
+ opts.on('--grace-timeout SEC') do |sec|
178
+ options[:grace_timeout] = sec.to_i
179
+ end
180
+
181
+ opts.on('--[no-]dup-check') do |b|
182
+ options[:dup_check] = b
183
+ end
184
+
185
+ opts.on('--prefetch COUNT') do |count|
186
+ options[:prefetch] = count.to_i
187
+ end
188
+
189
+ opts.on('-o', '--options OPT') do |e|
190
+ fail("Invalid option definition #{e}' (use '=' to separate name and value)") unless e.include?('=')
191
+ key, val = e.split(/=/)
192
+ options[:options][key.gsub('-', '_').to_sym] = val
193
+ end
194
+
195
+ opts.on('-Q', '--quiet') do
196
+ options[:quiet] = true
197
+ end
198
+
199
+ opts.on_tail('--help') do
200
+ puts Usage.scan(__FILE__)
201
+ exit
202
+ end
203
+ end
204
+ begin
205
+ opts.parse!(ARGV)
206
+ rescue Exception => e
207
+ exit 0 if e.is_a?(SystemExit)
208
+ fail(e.message, print_usage = true)
209
+ end
210
+ resolve_identity(options)
211
+ options
212
+ end
213
+
214
+ protected
215
+
216
+ # Parse any other arguments used by agent
217
+ #
218
+ # === Parameters
219
+ # opts(OptionParser):: Options parser with options to be parsed
220
+ # options(Hash):: Storage for options that are parsed
221
+ #
222
+ # === Return
223
+ # true:: Always return true
224
+ def parse_other_args(opts, options)
225
+ true
226
+ end
227
+
228
+ # Load initial configuration for agent, if any
229
+ #
230
+ # === Return
231
+ # cfg(Hash):: Initial agent configuration options
232
+ def load_init_cfg
233
+ cfg = {}
234
+ if (cfg_file = AgentConfig.init_cfg_file) && (cfg_data = YAML.load(IO.read(cfg_file)))
235
+ cfg = SerializationHelper.symbolize_keys(cfg_data) rescue nil
236
+ fail("Cannot read configuration for agent #{cfg_file.inspect}") unless cfg
237
+ end
238
+ cfg
239
+ end
240
+
241
+ # Check agent type consistency and existence of initialization file and actors directory
242
+ #
243
+ # === Parameters
244
+ # options(Hash):: Command line options
245
+ # cfg(Hash):: Initial configuration settings
246
+ #
247
+ # === Return
248
+ # true:: Always return true
249
+ def check_agent(options, cfg)
250
+ identity = options[:identity]
251
+ agent_type = options[:agent_type]
252
+ type = AgentIdentity.parse(identity).agent_type if identity
253
+ fail("Agent type #{agent_type.inspect} and identity #{identity.inspect} are inconsistent") if agent_type != type
254
+ fail("Cannot find agent init.rb file in init directory of #{AgentConfig.root_dir.inspect}") unless AgentConfig.init_file
255
+
256
+ actors = cfg[:actors]
257
+ fail('Agent configuration is missing actors') unless actors && actors.respond_to?(:each)
258
+ actors_dirs = AgentConfig.actors_dirs
259
+ actors.each do |a|
260
+ found = false
261
+ actors_dirs.each { |d| break if found = File.exist?(File.normalize_path(File.join(d, "#{a}.rb"))) }
262
+ fail("Cannot find source for actor #{a.inspect} in #{actors_dirs.inspect}") unless found
263
+ end
264
+ true
265
+ end
266
+
267
+ # Determine configuration settings to be persisted
268
+ #
269
+ # === Parameters
270
+ # options(Hash):: Command line options
271
+ # cfg(Hash):: Initial configuration settings
272
+ #
273
+ # === Return
274
+ # cfg(Hash):: Configuration settings
275
+ def configure(options, cfg)
276
+ cfg[:root_dir] = AgentConfig.root_dir
277
+ cfg[:pid_dir] = AgentConfig.pid_dir
278
+ cfg[:identity] = options[:identity] if options[:identity]
279
+ cfg[:user] = options[:user] if options[:user]
280
+ cfg[:pass] = options[:pass] if options[:pass]
281
+ cfg[:vhost] = options[:vhost] if options[:vhost]
282
+ cfg[:port] = options[:port] if options[:port]
283
+ cfg[:host] = options[:host] if options[:host]
284
+ cfg[:prefetch] = options[:prefetch] || 1
285
+ cfg[:time_to_live] = options[:time_to_live] || 60
286
+ cfg[:retry_timeout] = options[:retry_timeout] || 2 * 60
287
+ cfg[:retry_interval] = options[:retry_interval] || 15
288
+ cfg[:ping_interval] = options[:ping_interval] ||= 4 * 60 * 60
289
+ cfg[:check_interval] = options[:check_interval] if options[:check_interval]
290
+ cfg[:reconnect_interval] = options[:reconnect_interval] if options[:reconnect_interval]
291
+ cfg[:grace_timeout] = options[:grace_timeout] if options[:grace_timeout]
292
+ cfg[:dup_check] = options[:dup_check].nil? ? true : options[:dup_check]
293
+ cfg[:http_proxy] = options[:http_proxy] if options[:http_proxy]
294
+ cfg[:http_no_proxy] = options[:http_no_proxy] if options[:http_no_proxy]
295
+ cfg
296
+ end
297
+
298
+ # Write configuration options to file after applying any overrides
299
+ #
300
+ # === Parameters
301
+ # options(Hash):: Command line options
302
+ # cfg(Hash):: Configurations options with which specified options are to be merged
303
+ #
304
+ # === Return
305
+ # true:: Always return true
306
+ def persist(options, cfg)
307
+ overrides = options[:options]
308
+ overrides.each { |k, v| cfg[k] = v } if overrides
309
+ cfg_file = AgentConfig.store_cfg(options[:agent_name], cfg)
310
+ unless options[:quiet]
311
+ puts "Generated configuration file for #{options[:agent_name]} agent: #{cfg_file}" unless options[:quiet]
312
+ end
313
+ true
314
+ end
315
+
316
+ # Setup agent monitoring
317
+ #
318
+ # === Parameters
319
+ # options(Hash):: Command line options
320
+ #
321
+ # === Return
322
+ # true:: Always return true
323
+ def monitor(options)
324
+ agent_name = options[:agent_name]
325
+ identity = options[:identity]
326
+ pid_file = PidFile.new(identity)
327
+ cfg = <<-EOF
328
+ check process #{agent_name}
329
+ with pidfile \"#{pid_file}\"
330
+ start program \"/opt/rightscale/bin/rnac --start #{agent_name}\"
331
+ stop program \"/opt/rightscale/bin/rnac --stop #{agent_name}\"
332
+ mode manual
333
+ EOF
334
+ cfg_file = File.join(AgentConfig.cfg_dir, agent_name, "#{identity}.conf")
335
+ File.open(cfg_file, 'w') { |f| f.puts(cfg) }
336
+ File.chmod(0600, cfg_file) # monit requires strict perms on this file
337
+ puts " - agent monit config: #{cfg_file}" unless options[:quiet]
338
+ true
339
+ end
340
+
341
+ # Print error on console and exit abnormally
342
+ #
343
+ # === Parameters
344
+ # message(String):: Error message to be displayed
345
+ # print_usage(Boolean):: Whether to display usage information
346
+ #
347
+ # === Return
348
+ # never return
349
+ def fail(message = nil, print_usage = false)
350
+ puts "** #{message}" if message
351
+ puts Usage.scan(__FILE__) if print_usage
352
+ exit(1)
353
+ end
354
+
355
+ end
356
+
357
+ end
358
+
359
+ #
360
+ # Copyright (c) 2009-2011 RightScale Inc
361
+ #
362
+ # Permission is hereby granted, free of charge, to any person obtaining
363
+ # a copy of this software and associated documentation files (the
364
+ # "Software"), to deal in the Software without restriction, including
365
+ # without limitation the rights to use, copy, modify, merge, publish,
366
+ # distribute, sublicense, and/or sell copies of the Software, and to
367
+ # permit persons to whom the Software is furnished to do so, subject to
368
+ # the following conditions:
369
+ #
370
+ # The above copyright notice and this permission notice shall be
371
+ # included in all copies or substantial portions of the Software.
372
+ #
373
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
374
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
375
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
376
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
377
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
378
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
379
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,153 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require 'uri'
24
+ require 'tmpdir'
25
+
26
+ require File.normalize_path(File.join(File.dirname(__FILE__), '..', 'agent_identity'))
27
+
28
+ # Common options parser
29
+ module RightScale
30
+
31
+ module CommonParser
32
+
33
+ # Parse common options between rad and rnac
34
+ #
35
+ # === Parameters
36
+ # opts(OptionParser):: Options parser with options to be parsed
37
+ # options(Hash):: Storage for options that are parsed
38
+ #
39
+ # === Return
40
+ # true:: Always return true
41
+ def parse_common(opts, options)
42
+
43
+ opts.on("--test") do
44
+ options[:user] = 'test'
45
+ options[:pass] = 'testing'
46
+ options[:vhost] = '/right_net'
47
+ options[:test] = true
48
+ options[:pid_dir] = Dir.tmpdir
49
+ options[:base_id] = "#{rand(1000000)}"
50
+ options[:options][:log_dir] = Dir.tmpdir
51
+ end
52
+
53
+ opts.on("-i", "--identity ID") do |id|
54
+ options[:base_id] = id
55
+ end
56
+
57
+ opts.on("-t", "--token TOKEN") do |t|
58
+ options[:token] = t
59
+ end
60
+
61
+ opts.on("-x", "--prefix PREFIX") do |p|
62
+ options[:prefix] = p
63
+ end
64
+
65
+ opts.on("--url URL") do |url|
66
+ uri = URI.parse(url)
67
+ options[:user] = uri.user if uri.user
68
+ options[:pass] = uri.password if uri.password
69
+ options[:host] = uri.host
70
+ options[:port] = uri.port if uri.port
71
+ options[:vhost] = uri.path if (uri.path && !uri.path.empty?)
72
+ end
73
+
74
+ opts.on("-u", "--user USER") do |user|
75
+ options[:user] = user
76
+ end
77
+
78
+ opts.on("-p", "--pass PASSWORD") do |pass|
79
+ options[:pass] = pass
80
+ end
81
+
82
+ opts.on("-v", "--vhost VHOST") do |vhost|
83
+ options[:vhost] = vhost
84
+ end
85
+
86
+ opts.on("-P", "--port PORT") do |port|
87
+ options[:port] = port
88
+ end
89
+
90
+ opts.on("-h", "--host HOST") do |host|
91
+ options[:host] = host
92
+ end
93
+
94
+ opts.on('--type TYPE') do |t|
95
+ options[:agent_type] = t
96
+ end
97
+
98
+ opts.on_tail("--help") do
99
+ puts Usage.scan(__FILE__)
100
+ exit
101
+ end
102
+
103
+ opts.on_tail("--version") do
104
+ puts version
105
+ exit
106
+ end
107
+ true
108
+ end
109
+
110
+ # Generate agent or mapper identity from options
111
+ # Build identity from base_id, token, prefix and agent name
112
+ #
113
+ # === Parameters
114
+ # options(Hash):: Hash containing identity components
115
+ #
116
+ # === Return
117
+ # options(Hash)::
118
+ def resolve_identity(options)
119
+ options[:agent_type] = agent_type(options[:agent_type], options[:agent_name])
120
+ if options[:base_id]
121
+ base_id = options[:base_id].to_i
122
+ if base_id.abs.to_s != options[:base_id]
123
+ puts "** Identity needs to be a positive integer"
124
+ exit(1)
125
+ end
126
+ token = options[:token]
127
+ token = RightScale::SecureIdentity.derive(base_id, options[:token]) if options[:secure_identity]
128
+ options[:identity] = AgentIdentity.new(options[:prefix] || 'rs', options[:agent_type], base_id, token).to_s
129
+ end
130
+ end
131
+
132
+ # Determine agent type
133
+ #
134
+ # === Parameters
135
+ # type(String):: Agent type
136
+ # name(String):: Agent name
137
+ #
138
+ # === Return
139
+ # (String):: Agent type
140
+ def agent_type(type, name)
141
+ unless type
142
+ if name =~ /^(.*)_[0-9]+$/
143
+ type = Regexp.last_match(1)
144
+ else
145
+ type = name || "instance"
146
+ end
147
+ end
148
+ type
149
+ end
150
+
151
+ end # CommonParser
152
+
153
+ end # RightScale