right_link 5.9.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.
Files changed (199) hide show
  1. data/actors/agent_manager.rb +88 -0
  2. data/actors/instance_scheduler.rb +321 -0
  3. data/actors/instance_services.rb +64 -0
  4. data/actors/instance_setup.rb +567 -0
  5. data/bin/cloud +25 -0
  6. data/bin/cook_runner +44 -0
  7. data/bin/deploy +120 -0
  8. data/bin/enroll +385 -0
  9. data/bin/rad +32 -0
  10. data/bin/rchk +29 -0
  11. data/bin/rnac +39 -0
  12. data/bin/rs_connect +33 -0
  13. data/bin/rs_log_level +31 -0
  14. data/bin/rs_ohai +28 -0
  15. data/bin/rs_reenroll +31 -0
  16. data/bin/rs_run_recipe +34 -0
  17. data/bin/rs_run_right_script +34 -0
  18. data/bin/rs_shutdown +33 -0
  19. data/bin/rs_tag +33 -0
  20. data/bin/rs_thunk +33 -0
  21. data/bin/rstat +31 -0
  22. data/bin/system +16 -0
  23. data/ext/Rakefile +18 -0
  24. data/init/config.yml +5 -0
  25. data/init/init.rb +79 -0
  26. data/lib/chef/ohai_setup.rb +51 -0
  27. data/lib/chef/plugins/cloud.rb +91 -0
  28. data/lib/chef/plugins/cloudstack.rb +23 -0
  29. data/lib/chef/plugins/ec2.rb +23 -0
  30. data/lib/chef/plugins/linux/block_device2.rb +24 -0
  31. data/lib/chef/plugins/rackspace.rb +23 -0
  32. data/lib/chef/plugins/rightscale.rb +125 -0
  33. data/lib/chef/plugins/windows/network.rb +114 -0
  34. data/lib/chef/plugins.rb +74 -0
  35. data/lib/chef/providers/dns_dnsmadeeasy_provider.rb +81 -0
  36. data/lib/chef/providers/dns_resource.rb +100 -0
  37. data/lib/chef/providers/executable_schedule_provider.rb +70 -0
  38. data/lib/chef/providers/executable_schedule_resource.rb +144 -0
  39. data/lib/chef/providers/remote_recipe_provider.rb +86 -0
  40. data/lib/chef/providers/remote_recipe_resource.rb +101 -0
  41. data/lib/chef/providers/right_link_tag_provider.rb +73 -0
  42. data/lib/chef/providers/right_link_tag_resource.rb +59 -0
  43. data/lib/chef/providers/right_script_provider.rb +190 -0
  44. data/lib/chef/providers/right_script_resource.rb +113 -0
  45. data/lib/chef/providers/rs_shutdown_provider.rb +75 -0
  46. data/lib/chef/providers/rs_shutdown_resource.rb +55 -0
  47. data/lib/chef/providers/server_collection_provider.rb +66 -0
  48. data/lib/chef/providers/server_collection_resource.rb +93 -0
  49. data/lib/chef/providers/windows/powershell_provider.rb +151 -0
  50. data/lib/chef/providers/windows/powershell_resource.rb +111 -0
  51. data/lib/chef/providers/windows/unsupported_provider.rb +51 -0
  52. data/lib/chef/right_providers.rb +55 -0
  53. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ChefNodeCmdlet.csproj +104 -0
  54. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ChefNodeCmdlet.dll-Help.xml +141 -0
  55. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/Exceptions.cs +182 -0
  56. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetChefNodeCommand.cs +58 -0
  57. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetChefNodeRequest.cs +46 -0
  58. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetChefNodeResponse.cs +45 -0
  59. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetCurrentResourceCommand.cs +58 -0
  60. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetCurrentResourceRequest.cs +46 -0
  61. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetCurrentResourceResponse.cs +45 -0
  62. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNewResourceCommand.cs +58 -0
  63. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNewResourceRequest.cs +46 -0
  64. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNewResourceResponse.cs +45 -0
  65. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNextActionCommand.cs +178 -0
  66. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNextActionRequest.cs +67 -0
  67. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNextActionResponse.cs +58 -0
  68. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNodeValueCommandBase.cs +142 -0
  69. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNodeValueRequestBase.cs +64 -0
  70. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNodeValueResponseBase.cs +69 -0
  71. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/JsonTransport.cs +110 -0
  72. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/PipeClient.cs +158 -0
  73. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/PipeServer.cs +142 -0
  74. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/Properties/AssemblyInfo.cs +16 -0
  75. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ProtocolConstants.cs +55 -0
  76. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ProtocolUtilities.cs +77 -0
  77. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ReadMe.txt +53 -0
  78. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetChefNodeCommand.cs +59 -0
  79. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetChefNodeRequest.cs +46 -0
  80. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetChefNodeResponse.cs +58 -0
  81. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetCurrentResourceCommand.cs +59 -0
  82. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetCurrentResourceRequest.cs +46 -0
  83. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetCurrentResourceResponse.cs +40 -0
  84. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNewResourceCommand.cs +59 -0
  85. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNewResourceRequest.cs +46 -0
  86. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNewResourceResponse.cs +40 -0
  87. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNodeValueCommandBase.cs +293 -0
  88. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNodeValueRequestBase.cs +75 -0
  89. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNodeValueResponseBase.cs +45 -0
  90. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/Transport.cs +91 -0
  91. data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet.sln +35 -0
  92. data/lib/chef/windows/ChefNodeCmdlet/TestChefNodeCmdlet/Program.cs +374 -0
  93. data/lib/chef/windows/ChefNodeCmdlet/TestChefNodeCmdlet/Properties/AssemblyInfo.cs +16 -0
  94. data/lib/chef/windows/ChefNodeCmdlet/TestChefNodeCmdlet/TestChefNodeCmdlet.csproj +65 -0
  95. data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/Program.cs +136 -0
  96. data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/Properties/AssemblyInfo.cs +36 -0
  97. data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/ReadMe.txt +46 -0
  98. data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/TestNextActionCmdlet.csproj +68 -0
  99. data/lib/chef/windows/bin/Newtonsoft.Json.dll +0 -0
  100. data/lib/chef/windows/chef_node_server.rb +463 -0
  101. data/lib/chef/windows/dynamic_powershell_provider.rb +296 -0
  102. data/lib/chef/windows/pipe_server.rb +283 -0
  103. data/lib/chef/windows/powershell_host.rb +285 -0
  104. data/lib/chef/windows/powershell_pipe_server.rb +136 -0
  105. data/lib/chef/windows/powershell_provider_base.rb +92 -0
  106. data/lib/chef/windows/scripts/run_loop.ps1 +105 -0
  107. data/lib/clouds/cloud.rb +557 -0
  108. data/lib/clouds/cloud_factory.rb +250 -0
  109. data/lib/clouds/cloud_utilities.rb +244 -0
  110. data/lib/clouds/clouds/azure.rb +106 -0
  111. data/lib/clouds/clouds/cloudstack.rb +114 -0
  112. data/lib/clouds/clouds/ec2.rb +113 -0
  113. data/lib/clouds/clouds/eucalyptus.rb +46 -0
  114. data/lib/clouds/clouds/google.rb +102 -0
  115. data/lib/clouds/clouds/none.rb +76 -0
  116. data/lib/clouds/clouds/openstack.rb +30 -0
  117. data/lib/clouds/clouds/rackspace-ng.rb +54 -0
  118. data/lib/clouds/clouds/rackspace.rb +78 -0
  119. data/lib/clouds/clouds/softlayer.rb +91 -0
  120. data/lib/clouds/metadata_formatter.rb +108 -0
  121. data/lib/clouds/metadata_provider.rb +128 -0
  122. data/lib/clouds/metadata_source.rb +87 -0
  123. data/lib/clouds/metadata_sources/certificate_metadata_source.rb +207 -0
  124. data/lib/clouds/metadata_sources/config_drive_metadata_source.rb +129 -0
  125. data/lib/clouds/metadata_sources/file_metadata_source.rb +74 -0
  126. data/lib/clouds/metadata_sources/http_metadata_source.rb +277 -0
  127. data/lib/clouds/metadata_sources/selective_metadata_source.rb +122 -0
  128. data/lib/clouds/metadata_tree_climber.rb +144 -0
  129. data/lib/clouds/metadata_writer.rb +155 -0
  130. data/lib/clouds/metadata_writers/dictionary_metadata_writer.rb +72 -0
  131. data/lib/clouds/metadata_writers/ruby_metadata_writer.rb +76 -0
  132. data/lib/clouds/metadata_writers/shell_metadata_writer.rb +121 -0
  133. data/lib/clouds/register_clouds.rb +34 -0
  134. data/lib/clouds.rb +32 -0
  135. data/lib/gem_dependencies.rb +83 -0
  136. data/lib/git_hooks/commit-msg.rb +7 -0
  137. data/lib/instance/agent_config.rb +168 -0
  138. data/lib/instance/agent_watcher.rb +233 -0
  139. data/lib/instance/audit_cook_stub.rb +104 -0
  140. data/lib/instance/audit_proxy.rb +247 -0
  141. data/lib/instance/bundle_queue.rb +104 -0
  142. data/lib/instance/cook/agent_connection.rb +109 -0
  143. data/lib/instance/cook/audit_logger.rb +165 -0
  144. data/lib/instance/cook/audit_stub.rb +142 -0
  145. data/lib/instance/cook/ca-bundle.crt +2794 -0
  146. data/lib/instance/cook/chef_state.rb +211 -0
  147. data/lib/instance/cook/cook.rb +306 -0
  148. data/lib/instance/cook/cook_state.rb +298 -0
  149. data/lib/instance/cook/cookbook_path_mapping.rb +66 -0
  150. data/lib/instance/cook/cookbook_repo_retriever.rb +190 -0
  151. data/lib/instance/cook/executable_sequence.rb +765 -0
  152. data/lib/instance/cook/external_parameter_gatherer.rb +190 -0
  153. data/lib/instance/cook/repose_downloader.rb +349 -0
  154. data/lib/instance/cook/shutdown_request_proxy.rb +121 -0
  155. data/lib/instance/cook.rb +41 -0
  156. data/lib/instance/downloader.rb +208 -0
  157. data/lib/instance/duplicable.rb +67 -0
  158. data/lib/instance/exceptions.rb +49 -0
  159. data/lib/instance/executable_sequence_proxy.rb +278 -0
  160. data/lib/instance/instance_commands.rb +577 -0
  161. data/lib/instance/instance_state.rb +633 -0
  162. data/lib/instance/json_utilities.rb +102 -0
  163. data/lib/instance/login_manager.rb +533 -0
  164. data/lib/instance/login_user_manager.rb +522 -0
  165. data/lib/instance/message_encoder.rb +118 -0
  166. data/lib/instance/multi_thread_bundle_queue.rb +232 -0
  167. data/lib/instance/operation_context.rb +60 -0
  168. data/lib/instance/options_bag.rb +65 -0
  169. data/lib/instance/payload_formatter.rb +46 -0
  170. data/lib/instance/policy.rb +53 -0
  171. data/lib/instance/policy_audit.rb +100 -0
  172. data/lib/instance/policy_manager.rb +146 -0
  173. data/lib/instance/reenroll_manager.rb +104 -0
  174. data/lib/instance/right_scripts_cookbook.rb +181 -0
  175. data/lib/instance/shutdown_request.rb +221 -0
  176. data/lib/instance/single_thread_bundle_queue.rb +189 -0
  177. data/lib/instance/volume_management.rb +450 -0
  178. data/lib/instance.rb +50 -0
  179. data/lib/repo_conf_generators/apt_conf_generators.rb +106 -0
  180. data/lib/repo_conf_generators/gem_conf_generators.rb +80 -0
  181. data/lib/repo_conf_generators/rightscale_conf_generators.rb +254 -0
  182. data/lib/repo_conf_generators/rightscale_key.pub +17 -0
  183. data/lib/repo_conf_generators/yum_conf_generators.rb +225 -0
  184. data/lib/repo_conf_generators.rb +30 -0
  185. data/lib/run_shell.rb +28 -0
  186. data/scripts/agent_checker.rb +571 -0
  187. data/scripts/agent_controller.rb +247 -0
  188. data/scripts/agent_deployer.rb +148 -0
  189. data/scripts/bundle_runner.rb +336 -0
  190. data/scripts/cloud_controller.rb +176 -0
  191. data/scripts/log_level_manager.rb +142 -0
  192. data/scripts/ohai_runner.rb +33 -0
  193. data/scripts/reenroller.rb +193 -0
  194. data/scripts/server_importer.rb +293 -0
  195. data/scripts/shutdown_client.rb +183 -0
  196. data/scripts/system_configurator.rb +367 -0
  197. data/scripts/tagger.rb +381 -0
  198. data/scripts/thunker.rb +356 -0
  199. metadata +418 -0
@@ -0,0 +1,336 @@
1
+ # === Synopsis:
2
+ # RightScale Bundle Runner (rs_run_right_script/rs_run_recipe) - (c) 2009-2011 RightScale Inc
3
+ #
4
+ # rs_run_right_script and rs_run_recipe are command line tools that allow
5
+ # running RightScripts and recipes respectively from within an instance
6
+ #
7
+ # === Examples:
8
+ # Run recipe with id 12:
9
+ # rs_run_recipe -i 12
10
+ # rs_run_recipe --identity 12
11
+ #
12
+ # Run recipe 'nginx' using given JSON attributes file:
13
+ # rs_run_recipe -n nginx -j attribs.js
14
+ # rs_run_recipe --name nginx --json attribs.js
15
+ #
16
+ # Run RightScript with id 14 and override input 'APPLICATION' with value
17
+ # 'Mephisto':
18
+ # rs_run_right_script -i 14 -p APPLICATION=text:Mephisto
19
+ # rs_run_right_script --identity 14 --parameter APPLICATION=text:Mephisto
20
+ #
21
+ # === Usage:
22
+ # rs_run_recipe --identity, -i ID [--json, -j JSON_FILE] [--verbose, -v]
23
+ # rs_run_recipe --name, -n NAME [--json, -j JSON_FILE]
24
+ # [--recipient_tags, -r TAG_LIST]
25
+ # [--scope, -s SCOPE] [--verbose, -v]
26
+ # rs_run_right_script --identity, -i ID [--parameter, -p NAME=type:VALUE]*
27
+ # [--verbose, -v]
28
+ # rs_run_right_script --name, -n NAME [--parameter, -p NAME=type:VALUE]*
29
+ # [--recipient_tags, -r TAG_LIST]
30
+ # [--scope, -s SCOPE] [--verbose, -v]
31
+ #
32
+ # * Can appear multiple times
33
+ #
34
+ # Options:
35
+ # --identity, -i ID RightScript or ServerTemplateChefRecipe id
36
+ # --name, -n NAME RightScript or Chef recipe name (overridden by id)
37
+ # --json, -j JSON_FILE JSON file name for JSON to be merged into
38
+ # attributes before running recipe
39
+ # --parameter,
40
+ # -p NAME=TYPE:VALUE Define or override RightScript input
41
+ # Note: Only applies to run_right_script
42
+ # --thread, Schedule the operation on a specific thread name
43
+ # -t THREAD for concurrent execution. Thread names must begin
44
+ # with a letter and can consist only of lower-case
45
+ # alphabetic characters, digits, and the underscore
46
+ # character.
47
+ # --policy, Audits for the executable to be run will be grouped under
48
+ # -P POLICY the given policy name. All detail will be logged on the instance,
49
+ # but limited detail will be audited.
50
+ # --audit_period Specifies the period of time that should pass between audits
51
+ # -a PERIOD_IN_SECONDS
52
+ # --recipient_tags, Tags for selecting which instances are to receive
53
+ # request with the TAG_LIST being quoted if it
54
+ # -r TAG_LIST contains spaces
55
+ # --scope, -s SCOPE Scope for selecting tagged recipients: single or
56
+ # all (default all)
57
+ # --cfg-dir, -c DIR Set directory containing configuration for all
58
+ # agents
59
+ # --verbose, -v Display progress information
60
+ # --help: Display help
61
+ # --version: Display version information
62
+ #
63
+ # Note: Partially specified option names are accepted if not ambiguous.
64
+
65
+ require 'rubygems'
66
+ require 'trollop'
67
+ require 'right_agent'
68
+ require 'right_agent/scripts/usage'
69
+ require 'right_agent/scripts/common_parser'
70
+ require 'right_agent/core_payload_types'
71
+
72
+ module RightScale
73
+
74
+ class BundleRunner
75
+
76
+ # Default number of seconds to wait for command response
77
+ DEFAULT_TIMEOUT = 20
78
+
79
+ # Run recipe or RightScript (that is, schedule it)
80
+ #
81
+ # === Parameters
82
+ # options(Hash):: Hash of options as defined in +parse_args+
83
+ #
84
+ # === Block
85
+ # If a block is given, it should take one argument corresponding to the
86
+ # reply sent back by the agent
87
+ #
88
+ # === Return
89
+ # true:: If everything went smoothly
90
+ # false:: If something terrible happened
91
+ def run(options, &callback)
92
+ fail('Missing identity or name argument', true) unless options[:id] || options[:name]
93
+ if options[:thread] && (options[:thread] !~ RightScale::AgentConfig.valid_thread_name)
94
+ fail("Invalid thread name #{options[:thread]}", true)
95
+ end
96
+ echo(options)
97
+ cmd = { :options => to_forwarder_options(options) }
98
+ cmd[:name] = options[:bundle_type] == :right_script ? 'run_right_script' : 'run_recipe'
99
+ AgentConfig.cfg_dir = options[:cfg_dir]
100
+ config_options = AgentConfig.agent_options('instance')
101
+ listen_port = config_options[:listen_port]
102
+ fail('Could not retrieve listen port', false) unless listen_port
103
+ command_serializer = Serializer.new
104
+ client = CommandClient.new(listen_port, config_options[:cookie])
105
+
106
+ exit_code = true
107
+ callback ||= lambda do |r|
108
+ response = OperationResult.from_results(command_serializer.load(r)) rescue nil
109
+ if r == 'OK'
110
+ puts "Request sent successfully"
111
+ elsif response.respond_to?(:success?) && response.success?
112
+ puts "Request processed successfully"
113
+ else
114
+ puts "Failed to process request: #{(response.respond_to?(:content) && response.content) || '<unknown error>'}"
115
+ exit_code = false
116
+ end
117
+ end
118
+
119
+ begin
120
+ timeout = options[:timeout] || DEFAULT_TIMEOUT
121
+ client.send_command(cmd, options[:verbose], timeout) { |r| callback.call(r) }
122
+ rescue Exception => e
123
+ fail(e.message)
124
+ end
125
+ exit_code
126
+ rescue SystemExit => e
127
+ raise e
128
+ rescue Exception => e
129
+ fail(e)
130
+ end
131
+
132
+ # Echo what is being requested
133
+ #
134
+ # === Parameters
135
+ # options(Hash):: Options specified
136
+ #
137
+ # === Return
138
+ # true:: Always return true
139
+ def echo(options)
140
+ type = options[:bundle_type] == :right_script ? "RightScript" : "recipe"
141
+ which = options[:id] ? "with ID #{options[:id].inspect}" : "named #{options[:name].inspect}"
142
+ scope = options[:scope] == :all ? "'all' servers" : "a 'single' server"
143
+ where = options[:tags] ? "on #{scope} with tags #{options[:tags].inspect}" : "locally on this server"
144
+ using = ""
145
+ if options[:parameters] && !options[:parameters].empty?
146
+ using = " using parameters #{options[:parameters].inspect}"
147
+ end
148
+ if options[:json]
149
+ using += !using.empty? && options[:json_file] ? " and " : " using "
150
+ using += "options from JSON file #{options[:json_file].inspect}"
151
+ end
152
+
153
+ if options[:thread]
154
+ thread = " on thread #{options[:thread]}"
155
+ else
156
+ thread = ""
157
+ end
158
+
159
+ if options[:policy]
160
+ policy = " auditing on policy #{options[:policy]}"
161
+ else
162
+ policy = ""
163
+ end
164
+ puts "Requesting to execute the #{type} #{which} #{where}#{using}#{thread}#{policy}"
165
+ true
166
+ end
167
+
168
+ # Create options hash from command line arguments
169
+ #
170
+ # === Return
171
+ # options(Hash):: Hash of options as defined by the command line
172
+ def parse_args(arguments=ARGV)
173
+ options = { :attributes => {}, :parameters => {}, :verbose => false }
174
+
175
+ parser = Trollop::Parser.new do
176
+ opt :id, "", :type => String, :long => "--identity", :short => "-i"
177
+ opt :name, "", :type => String
178
+ opt :parameter, "", :type => :string, :multi => true, :short => "-p"
179
+ opt :thread, "", :type => String
180
+ opt :json_file, "", :type => String, :short => "-j", :long => "--json"
181
+ opt :tags, "", :type => String, :short => "-r", :long => "--recipient_tags"
182
+ opt :scope, "", :type => String, :default => "all"
183
+ opt :cfg_dir, "", :type => String
184
+ opt :policy, "", :type => String, :short => "-P"
185
+ opt :audit_period, "", :type => :int, :long => "--audit_period"
186
+ opt :verbose
187
+ version ""
188
+ end
189
+
190
+ begin
191
+ options.merge!(parser.parse(arguments))
192
+ options.delete(:name) if options[:id]
193
+ if options[:parameter]
194
+ options.delete(:parameter).each do |p|
195
+ name, value = p.split('=', 2)
196
+ if name && value && value.include?(':')
197
+ options[:parameters][name] = value
198
+ else
199
+ fail("Invalid parameter definition '#{p}', should be of the form 'name=type:value'")
200
+ end
201
+ end
202
+ end
203
+
204
+ if options[:json_file]
205
+ fail("Invalid JSON filename '#{options[:json_file]}'") unless File.file?(options[:json_file])
206
+ begin
207
+ options[:json] = IO.read(options[:json_file])
208
+ rescue Exception => e
209
+ fail("Invalid JSON content: #{e}")
210
+ end
211
+ end
212
+
213
+ options[:tags] = options[:tags].split if options[:tags]
214
+
215
+ if options[:scope]
216
+ if options[:scope] == 'single'
217
+ options[:scope] = :any
218
+ elsif options[:scope] == 'all'
219
+ options[:scope] = :all
220
+ else
221
+ fail("Invalid scope definition '#{options[:scope]}', should be either 'single' or 'all'")
222
+ end
223
+ end
224
+ options
225
+ rescue Trollop::HelpNeeded
226
+ puts Usage.scan(__FILE__)
227
+ exit
228
+ rescue Trollop::VersionNeeded
229
+ puts version
230
+ succeed
231
+ rescue Exception => e
232
+ puts e.message + "\nUse --help for additional information"
233
+ exit(1)
234
+ end
235
+ end
236
+
237
+ protected
238
+
239
+ # Print error on console and exit abnormally
240
+ #
241
+ # === Parameter
242
+ # reason(String|Exception):: Error message or exception, default to nil (no message printed)
243
+ # print_usage(Boolean):: Whether script usage should be printed, default to false
244
+ #
245
+ # === Return
246
+ # R.I.P. does not return
247
+ def fail(reason=nil, print_usage=false)
248
+ case reason
249
+ when Errno::EACCES
250
+ STDERR.puts "** #{reason.message}"
251
+ STDERR.puts "** Try elevating privilege (sudo/runas) before invoking this command."
252
+ code = 2
253
+ when Exception
254
+ STDERR.puts "** #{reason.message}"
255
+ code = 1
256
+ else
257
+ STDERR.puts "** #{reason}" if reason
258
+ code = 1
259
+ end
260
+
261
+ puts Usage.scan(__FILE__) if print_usage
262
+ exit(code)
263
+ end
264
+
265
+ # Map arguments options into forwarder actor compatible options
266
+ #
267
+ # === Parameters
268
+ # options(Hash):: Arguments options
269
+ #
270
+ # === Return
271
+ # result(Hash):: Forwarder actor compatible options hash
272
+ def to_forwarder_options(options)
273
+ result = {}
274
+ if options[:tags]
275
+ result[:tags] = options[:tags]
276
+ result[:selector] = options[:scope]
277
+ end
278
+ if options[:thread]
279
+ result[:thread] = options[:thread]
280
+ end
281
+ if options[:policy]
282
+ result[:policy] = options[:policy]
283
+ end
284
+ if options[:audit_period]
285
+ result[:audit_period] = options[:audit_period]
286
+ end
287
+ if options[:bundle_type] == :right_script
288
+ result[:right_script_id] = options[:id] if options[:id]
289
+ result[:right_script] = options[:name] if options[:name] && !options[:id]
290
+ result[:arguments] = options[:parameters] unless options[:parameters].empty?
291
+ else
292
+ result[:recipe_id] = options[:id] if options[:id]
293
+ result[:recipe] = options[:name] if options[:name] && !options[:id]
294
+ result[:json] = options[:json]
295
+ end
296
+ result
297
+ end
298
+
299
+ # Version information
300
+ #
301
+ # === Return
302
+ # (String):: Version information
303
+ def version
304
+ gemspec = eval(File.read(File.join(File.dirname(__FILE__), '..', 'right_link.gemspec')))
305
+ "rs_run_right_script & rs_run_recipe #{gemspec.version} - RightLink's bundle runner (c) 2011 RightScale"
306
+ end
307
+
308
+ def succeed
309
+ exit(0)
310
+ end
311
+
312
+ end # BundleRunner
313
+
314
+ end # RightScale
315
+
316
+ #
317
+ # Copyright (c) 2009-2011 RightScale Inc
318
+ #
319
+ # Permission is hereby granted, free of charge, to any person obtaining
320
+ # a copy of this software and associated documentation files (the
321
+ # "Software"), to deal in the Software without restriction, including
322
+ # without limitation the rights to use, copy, modify, merge, publish,
323
+ # distribute, sublicense, and/or sell copies of the Software, and to
324
+ # permit persons to whom the Software is furnished to do so, subject to
325
+ # the following conditions:
326
+ #
327
+ # The above copyright notice and this permission notice shall be
328
+ # included in all copies or substantial portions of the Software.
329
+ #
330
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
331
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
332
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
333
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
334
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
335
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
336
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,176 @@
1
+ # === Synopsis:
2
+ # RightScale Cloud Controller (cloud) - Copyright (c) 2011 by RightScale Inc
3
+ #
4
+ # cloud is a command line tool which invokes cloud-specific actions
5
+ #
6
+ # === Examples:
7
+ # Write cloud and user metadata to cache directory using default cloud:
8
+ # cloud --action=write_metadata
9
+ #
10
+ # Write user metadata only to cache directory using named ec2 cloud:
11
+ # cloud --name=ec2 --action=write_user_metadata
12
+ #
13
+ # Read default cloud user metadata in dictionary format (metadata is output):
14
+ # cloud --action=read_user_metadata
15
+ # --parameters=dictionary_metadata_writer
16
+ #
17
+ # === Usage:
18
+ # cloud [options]
19
+ #
20
+ # options:
21
+ # --action, -a Action to perform (required, see below for details).
22
+ # --name, -n Cloud to use instead of attempting to determine a
23
+ # default cloud.
24
+ # --parameters, -p Parameters passed to cloud action as either a single
25
+ # string argument or as a square-bracketed array in
26
+ # JSON format for multiple arguments.
27
+ # --only-if, -o Ignores unknown cloud actions instead of printing an
28
+ # error.
29
+
30
+ require 'rubygems'
31
+ require 'json'
32
+ require 'logger'
33
+ require 'trollop'
34
+ require 'fileutils'
35
+ require 'right_agent'
36
+ require 'right_agent/scripts/usage'
37
+
38
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'instance', 'agent_config'))
39
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'clouds', 'register_clouds'))
40
+
41
+ module RightScale
42
+
43
+ class CloudController
44
+
45
+ # Convenience wrapper
46
+ def self.run
47
+ controller = CloudController.new
48
+ controller.control(controller.parse_args)
49
+ rescue Errno::EACCES => e
50
+ STDERR.puts e.message
51
+ STDERR.puts "Try elevating privilege (sudo/runas) before invoking this command."
52
+ exit(2)
53
+ rescue SystemExit => e
54
+ raise e
55
+ rescue Exception => e
56
+ $stderr.puts "ERROR: #{e.message}"
57
+ exit 1
58
+ end
59
+
60
+ # Undecorated formatter to support legacy console output
61
+ class PlainLoggerFormatter < Logger::Formatter
62
+ def call(severity, time, program_name, message)
63
+ return message + "\n"
64
+ end
65
+ end
66
+
67
+ # Parse arguments and run
68
+ def control(options)
69
+ fail("No action specified on the command line.") unless options[:action]
70
+ name = options[:name]
71
+ parameters = options[:parameters] || []
72
+ only_if = options[:only_if]
73
+ verbose = options[:verbose]
74
+
75
+ # support either single or a comma-delimited list of actions to execute
76
+ # sequentially (e.g. "--action clear_state,wait_for_instance_ready,write_user_metadata")
77
+ # (because we need to split bootstrap actions up in Windows case).
78
+ actions = options[:action].to_s.split(',').inject([]) do |result, action|
79
+ unless (action = action.strip).empty?
80
+ action = action.to_sym
81
+ case action
82
+ when :bootstrap
83
+ # bootstrap is shorthand for all standard actions performed on boot
84
+ result += [:clear_state, :wait_for_instance_ready, :write_cloud_metadata, :write_user_metadata, :wait_for_eip]
85
+ only_if = true
86
+ else
87
+ result << action
88
+ end
89
+ end
90
+ result
91
+ end
92
+
93
+ cloud = CloudFactory.instance.create(name, :logger => default_logger(verbose))
94
+
95
+ actions.each do |action|
96
+ if cloud.respond_to?(action)
97
+ # Expect most methods to return ActionResult, but a cloud can expose any
98
+ # custom method so we can't assume return type
99
+ result = cloud.send(action, *parameters)
100
+ $stderr.puts result.error if result.respond_to?(:error) && result.error
101
+ $stdout.puts result.output if verbose && result.respond_to?(:output) && result.output
102
+
103
+ if result.respond_to?(:exitstatus) && (result.exitstatus != 0)
104
+ raise StandardError, "Action #{action} failed with status #{result.exitstatus}"
105
+ end
106
+ elsif only_if
107
+ next
108
+ else
109
+ raise ArgumentError, "ERROR: Unknown cloud action: #{action}"
110
+ end
111
+ end
112
+ end
113
+
114
+ # Parse arguments
115
+ def parse_args
116
+ parser = Trollop::Parser.new do
117
+ opt :name, "", :default => CloudFactory::UNKNOWN_CLOUD_NAME.to_s
118
+ opt :action, "", :type => :string
119
+ opt :only_if
120
+ opt :parameters, "",:type => :string
121
+ opt :quiet # note that :quiet is deprecated (use -v instead) because Trollop cannot easily support inverse flags that default to true
122
+ opt :verbose
123
+ end
124
+ begin
125
+ options = parser.parse
126
+ if options[:parameters_given]
127
+ if options[:parameters].start_with?("[")
128
+ options[:parameters] = JSON.parse(options[:parameters])
129
+ else
130
+ options[:parameters] = [options[:parameters]]
131
+ end
132
+ end
133
+ options
134
+ rescue Trollop::HelpNeeded
135
+ puts Usage.scan(__FILE__)
136
+ exit 0
137
+ end
138
+ end
139
+
140
+ # Default logger for printing to console
141
+ def default_logger(verbose)
142
+ if verbose
143
+ logger = Logger.new(STDOUT)
144
+ logger.level = Logger::INFO
145
+ logger.formatter = PlainLoggerFormatter.new
146
+ else
147
+ logger = RightScale::Log
148
+ end
149
+ return logger
150
+ end
151
+
152
+ end # CloudController
153
+
154
+ end # RightScale
155
+
156
+ #
157
+ # Copyright (c) 2011 RightScale Inc
158
+ #
159
+ # Permission is hereby granted, free of charge, to any person obtaining
160
+ # a copy of this software and associated documentation files (the
161
+ # "Software"), to deal in the Software without restriction, including
162
+ # without limitation the rights to use, copy, modify, merge, publish,
163
+ # distribute, sublicense, and/or sell copies of the Software, and to
164
+ # permit persons to whom the Software is furnished to do so, subject to
165
+ # the following conditions:
166
+ #
167
+ # The above copyright notice and this permission notice shall be
168
+ # included in all copies or substantial portions of the Software.
169
+ #
170
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
171
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
172
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
173
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
174
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
175
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
176
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,142 @@
1
+ # === Synopsis:
2
+ # RightScale Log Level Manager (rs_log_level) - (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Log level manager allows setting and retrieving the RightLink agent
5
+ # log level.
6
+ #
7
+ # === Examples:
8
+ # Retrieve log level:
9
+ # rs_log_level
10
+ #
11
+ # Set log level to debug:
12
+ # rs_log_level --log-level debug
13
+ # rs_log_level -l debug
14
+ #
15
+ # === Usage
16
+ # rs_set_log_level [--log-level, -l debug|info|warn|error|fatal]
17
+ #
18
+ # Options:
19
+ # --log-level, -l LVL Set log level of RightLink agent
20
+ # --verbose, -v Display debug information
21
+ # --help: Display help
22
+ # --version: Display version information
23
+ #
24
+ # No options prints the current RightLink agent log level
25
+ #
26
+
27
+ require 'right_agent/scripts/log_level_manager'
28
+ require 'trollop'
29
+
30
+ module RightScale
31
+
32
+ class RightLinkLogLevelManager < LogLevelManager
33
+
34
+ # Convenience wrapper for creating and running log level manager
35
+ #
36
+ # === Return
37
+ # true:: Always return true
38
+ def self.run
39
+ m = RightLinkLogLevelManager.new
40
+
41
+ options = m.parse_args
42
+ m.manage(options)
43
+
44
+ if options[:level] =~ /debug/i && !RightScale::Platform.windows?
45
+ puts
46
+ puts "NOTE: RightLink is now logging with syslog severity 'debug', but your system"
47
+ puts " log daemon may discard these messages. If debug messages do not appear,"
48
+ puts " review your syslog configuration and restart the daemon."
49
+ end
50
+ rescue Errno::EACCES => e
51
+ write_error(e.message)
52
+ write_error("Try elevating privilege (sudo/runas) before invoking this command.")
53
+ exit(2)
54
+ end
55
+
56
+ # Create options hash from command line arguments
57
+ #
58
+ # === Return
59
+ # options(Hash):: Hash of options as defined by the command line
60
+ def parse_args
61
+ options = { :agent_name => 'instance', :verbose => false }
62
+
63
+ parser = Trollop::Parser.new do
64
+ opt :level, "", :type => String, :long => "--log-level", :short => "-l"
65
+ opt :verbose
66
+ version ""
67
+ end
68
+
69
+ begin
70
+ options.merge!(parser.parse)
71
+ if options[:level]
72
+ fail("Invalig log level '#{options[:level]}'") unless AgentManager::LEVELS.include?(options[:level].to_sym)
73
+ end
74
+ options
75
+ rescue Trollop::HelpNeeded
76
+ write_output(Usage.scan(__FILE__))
77
+ exit
78
+ rescue Trollop::VersionNeeded
79
+ write_output(version)
80
+ succeed
81
+ rescue SystemExit => e
82
+ raise e
83
+ rescue Exception => e
84
+ write_output(e.message + "\nUse --help for additional information")
85
+ exit(1)
86
+ end
87
+ end
88
+
89
+ protected
90
+ # Writes to STDOUT (and a placeholder for spec mocking).
91
+ #
92
+ # === Parameters
93
+ # @param [String] message to write
94
+ def write_output(message)
95
+ STDOUT.puts(message)
96
+ end
97
+
98
+ # Writes to STDERR (and a placeholder for spec mocking).
99
+ #
100
+ # === Parameters
101
+ # @param [String] message to write
102
+ def write_error(message)
103
+ STDERR.puts(message)
104
+ end
105
+
106
+ # Version information
107
+ #
108
+ # === Return
109
+ # (String):: Version information
110
+ def version
111
+ gemspec = eval(File.read(File.join(File.dirname(__FILE__), '..', 'right_link.gemspec')))
112
+ "rs_log_level #{gemspec.version} - RightLink's log level (c) 2011 RightScale"
113
+ end
114
+
115
+ def succeed
116
+ exit(0)
117
+ end
118
+
119
+ end
120
+ end
121
+
122
+ #
123
+ # Copyright (c) 2009-2011 RightScale Inc
124
+ #
125
+ # Permission is hereby granted, free of charge, to any person obtaining
126
+ # a copy of this software and associated documentation files (the
127
+ # "Software"), to deal in the Software without restriction, including
128
+ # without limitation the rights to use, copy, modify, merge, publish,
129
+ # distribute, sublicense, and/or sell copies of the Software, and to
130
+ # permit persons to whom the Software is furnished to do so, subject to
131
+ # the following conditions:
132
+ #
133
+ # The above copyright notice and this permission notice shall be
134
+ # included in all copies or substantial portions of the Software.
135
+ #
136
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
137
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
138
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
139
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
140
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
141
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
142
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,33 @@
1
+ # === Synopsis:
2
+ # RightScale Ohai Runner - Copyright (c) 2012 by RightScale Inc
3
+ #
4
+ # runs Ohai in the RightScale environment
5
+ #
6
+ # === Examples:
7
+ #
8
+ # === Usage:
9
+ # rs_ohai [ohai node name]
10
+ #
11
+
12
+ require 'rubygems'
13
+ require 'right_agent'
14
+ require 'right_agent/scripts/usage'
15
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'chef', 'ohai_setup')
16
+ require 'ohai/application'
17
+ if RightScale::Platform.windows?
18
+ require 'ruby-wmi'
19
+ end
20
+
21
+ module RightScale
22
+ class OhaiRunner
23
+ # Activates RightScale environment before running ohai
24
+ #
25
+ # === Return
26
+ # true:: Always return true
27
+ def run
28
+ RightScale::OhaiSetup.configure_ohai
29
+ Ohai::Application.new.run
30
+ true
31
+ end
32
+ end
33
+ end