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,577 @@
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
+ module RightScale
24
+
25
+ # Commands exposed by instance agent
26
+ # To add a new command, simply add it to the COMMANDS hash and define its implementation in
27
+ # a method called '<command name>_command'
28
+ class InstanceCommands
29
+
30
+ # List of command names associated with description
31
+ # The commands should be implemented in methods in this class named '<name>_command'
32
+ # where <name> is the name of the command.
33
+ COMMANDS = {
34
+ :list => 'List all available commands with their description',
35
+ :run_recipe => 'Run recipe with id given in options[:id] and optionally JSON given in options[:json]',
36
+ :run_right_script => 'Run RightScript with id given in options[:id] and arguments given in hash options[:arguments] (e.g. { \'application\' => \'text:Mephisto\' })',
37
+ :send_push => 'Send request to one or more remote agents with no response expected',
38
+ :send_persistent_push => 'Send request to one or more remote agents with no response expected with persistence en route',
39
+ :send_retryable_request => 'Send request to a remote agent with a response expected and retry if response times out',
40
+ :send_persistent_request => 'Send request to a remote agent with a response expected with persistence ' +
41
+ 'en route and no retries that would result in it being duplicated',
42
+ :send_idempotent_request => 'Send a request to a remote agent (identified solely by operation), retrying at the' +
43
+ 'application level until the request succeeds or the timeout elapses',
44
+ :set_log_level => 'Set log level to options[:level]',
45
+ :get_log_level => 'Get log level',
46
+ :decommission => 'Run instance decommission bundle synchronously',
47
+ :terminate => 'Terminate agent',
48
+ :get_tags => 'Retrieve instance tags',
49
+ :add_tag => 'Add given tag',
50
+ :remove_tag => 'Remove given tag',
51
+ :query_tags => 'Query for instances with specified tags',
52
+ :audit_create_entry => 'Create a new audit entry',
53
+ :audit_update_status => 'Update last audit title',
54
+ :audit_create_new_section => 'Create new audit section',
55
+ :audit_append_output => 'Append process output to audit',
56
+ :audit_append_info => 'Append info message to audit',
57
+ :audit_append_error => 'Append error message to audit',
58
+ :set_inputs_patch => 'Set inputs patch post execution',
59
+ :check_connectivity => 'Check whether the instance is able to communicate',
60
+ :close_connection => 'Close persistent connection (used for auditing)',
61
+ :stats => 'Get statistics about instance agent operation',
62
+ :get_shutdown_request => 'Gets the requested reboot state.',
63
+ :set_shutdown_request => 'Sets the requested reboot state.'
64
+ }
65
+
66
+ # Build hash of commands associating command names with block
67
+ #
68
+ # === Parameters
69
+ # agent_identity(String):: Serialized instance agent identity
70
+ # scheduler(InstanceScheduler):: Scheduler used by decommission command
71
+ # agent_manager(AgentManager):: Agent manager used by stats command
72
+ #
73
+ # === Return
74
+ # cmds(Hash):: Hash of command blocks keyed by command names
75
+ def self.get(agent_identity, scheduler, agent_manager)
76
+ cmds = {}
77
+ target = new(agent_identity, scheduler, agent_manager)
78
+ COMMANDS.each { |k, _| cmds[k] = lambda { |opts, conn| opts[:conn] = conn; target.send("#{k.to_s}_command", opts) } }
79
+ cmds
80
+ end
81
+
82
+ # Set token id used to send core requests
83
+ #
84
+ # === Parameter
85
+ # agent_identity(String):: Serialized instance agent identity
86
+ # scheduler(InstanceScheduler):: Scheduler used by decommission command
87
+ # agent_manager(AgentManager):: Agent manager used by stats command
88
+ def initialize(agent_identity, scheduler, agent_manager)
89
+ @agent_identity = agent_identity
90
+ @scheduler = scheduler
91
+ @serializer = Serializer.new
92
+ @agent_manager = agent_manager
93
+ end
94
+
95
+ protected
96
+
97
+ # List command implementation
98
+ #
99
+ # === Parameters
100
+ # opts[:conn](EM::Connection):: Connection used to send reply
101
+ #
102
+ # === Return
103
+ # true:: Always return true
104
+ def list_command(opts)
105
+ usage = "Agent exposes the following commands:\n"
106
+ COMMANDS.reject { |k, _| k == :list || k.to_s =~ /test/ }.each do |c|
107
+ c.each { |k, v| usage += " - #{k.to_s}: #{v}\n" }
108
+ end
109
+ CommandIO.instance.reply(opts[:conn], usage)
110
+ end
111
+
112
+ # Run recipe command implementation
113
+ #
114
+ # === Parameters
115
+ # opts[:conn](EM::Connection):: Connection used to send reply
116
+ # opts[:options](Hash):: Pass-through options sent to forwarder or instance_scheduler
117
+ # with a :tags value indicating tag-based routing instead of local execution
118
+ #
119
+ # === Return
120
+ # true:: Always return true
121
+ def run_recipe_command(opts)
122
+ payload = opts[:options] || {}
123
+ target = {}
124
+ target[:tags] = payload.delete(:tags) if payload[:tags]
125
+ target[:scope] = payload.delete(:scope) if payload[:scope]
126
+ target[:selector] = payload.delete(:selector) if payload[:selector]
127
+ if (target[:tags] && !target[:tags].empty?) || target[:scope] || (target[:selector] && target(:selector) == :all)
128
+ send_persistent_push("/instance_scheduler/execute", opts[:conn], payload, target)
129
+ else
130
+ send_persistent_request("/forwarder/schedule_recipe", opts[:conn], payload)
131
+ end
132
+ end
133
+
134
+ # Run RightScript command implementation
135
+ #
136
+ # === Parameters
137
+ # opts[:conn](EM::Connection):: Connection used to send reply
138
+ # opts[:options](Hash):: Pass-through options sent to forwarder or instance_scheduler
139
+ # with a :tags value indicating tag-based routing instead of local execution
140
+ #
141
+ # === Return
142
+ # true:: Always return true
143
+ def run_right_script_command(opts)
144
+ payload = opts[:options] || {}
145
+ target = {}
146
+ target[:tags] = payload.delete(:tags) if payload[:tags]
147
+ target[:scope] = payload.delete(:scope) if payload[:scope]
148
+ target[:selector] = payload.delete(:selector) if payload[:selector]
149
+ if (target[:tags] && !target[:tags].empty?) || target[:scope] || (target[:selector] && target(:selector) == :all)
150
+ send_persistent_push("/instance_scheduler/execute", opts[:conn], payload, target)
151
+ else
152
+ send_persistent_request("/forwarder/schedule_right_script", opts[:conn], payload)
153
+ end
154
+ end
155
+
156
+ # Send a request to one or more targets with no response expected
157
+ #
158
+ # === Parameters
159
+ # opts[:conn](EM::Connection):: Connection used to send reply
160
+ # opts[:type](String):: Request type
161
+ # opts[:payload](String):: Request data, optional
162
+ # opts[:target](String|Hash):: Request target or target selectors, optional
163
+ #
164
+ # === Return
165
+ # true:: Always return true
166
+ def send_push_command(opts)
167
+ send_push(opts[:type], opts[:conn], opts[:payload], opts[:target])
168
+ end
169
+
170
+ # Send a request to one or more targets with no response expected
171
+ # Persist the request en route to reduce the chance of it being lost at the expense of some
172
+ # additional network overhead
173
+ #
174
+ # === Parameters
175
+ # opts[:conn](EM::Connection):: Connection used to send reply
176
+ # opts[:type](String):: Request type
177
+ # opts[:payload](String):: Request data, optional
178
+ # opts[:target](String|Hash):: Request target or target selectors, optional
179
+ #
180
+ # === Return
181
+ # true:: Always return true
182
+ def send_persistent_push_command(opts)
183
+ send_persistent_push(opts[:type], opts[:conn], opts[:payload], opts[:target])
184
+ end
185
+
186
+ # Send a request to a single target with a response expected
187
+ # Automatically retry the request if the response is not received in a reasonable amount of time
188
+ # Timeout the request if a response is not received in time, typically configured to 2 minutes
189
+ # Allow the request to expire per the agent's configured time-to-live, typically 1 minute
190
+ #
191
+ # === Parameters
192
+ # opts[:conn](EM::Connection):: Connection used to send reply
193
+ # opts[:type](String):: Request type
194
+ # opts[:payload](String):: Request data, optional
195
+ # opts[:target](String|Hash):: Request target or target selectors (random pick if multiple), optional
196
+ #
197
+ # === Return
198
+ # true:: Always return true
199
+ def send_retryable_request_command(opts)
200
+ send_retryable_request(opts[:type], opts[:conn], opts[:payload], opts[:target])
201
+ end
202
+
203
+ # Send a request to a single target with a response expected
204
+ # Persist the request en route to reduce the chance of it being lost at the expense of some
205
+ # additional network overhead
206
+ # Never retry the request if there is the possibility of it being duplicated
207
+ #
208
+ # === Parameters
209
+ # opts[:conn](EM::Connection):: Connection used to send reply
210
+ # opts[:type](String):: Request type
211
+ # opts[:payload](String):: Request data, optional
212
+ # opts[:target](String|Hash):: Request target or target selectors (random pick if multiple), optional
213
+ # opts[:options](Hash):: Request options
214
+ #
215
+ # === Return
216
+ # true:: Always return true
217
+ def send_persistent_request_command(opts)
218
+ send_persistent_request(opts[:type], opts[:conn], opts[:payload], opts[:target], opts[:options])
219
+ end
220
+
221
+ # Send a retryable request to a single target with a response expected, retrying multiple times
222
+ # at the application layer in case failures or errors occur.
223
+ #
224
+ # === Parameters
225
+ # opts[:conn](EM::Connection):: Connection used to send reply
226
+ # opts[:type](String):: Request type
227
+ # opts[:payload](String):: Request data, optional
228
+ # opts[:timeout](Integer):: Timeout for idempotent request, -1 or nil for no timeout
229
+ # opts[:options](Hash):: Request options
230
+ #
231
+ # === Return
232
+ # true:: Always return true
233
+ def send_idempotent_request_command(opts)
234
+ send_idempotent_request(opts[:type], opts[:conn], opts[:payload], opts[:options])
235
+ end
236
+
237
+ # Set log level command
238
+ #
239
+ # === Parameters
240
+ # opts[:conn](EM::Connection):: Connection used to send reply
241
+ # opts[:level](Symbol):: One of :debug, :info, :warn, :error or :fatal
242
+ #
243
+ # === Return
244
+ # true:: Always return true
245
+ def set_log_level_command(opts)
246
+ Log.level = opts[:level] if [ :debug, :info, :warn, :error, :fatal ].include?(opts[:level])
247
+ CommandIO.instance.reply(opts[:conn], Log.level)
248
+ end
249
+
250
+ # Get log level command
251
+ #
252
+ # === Parameters
253
+ # opts[:conn](EM::Connection):: Connection used to send reply
254
+ #
255
+ # === Return
256
+ # true:: Always return true
257
+ def get_log_level_command(opts)
258
+ CommandIO.instance.reply(opts[:conn], Log.level)
259
+ end
260
+
261
+ # Decommission command
262
+ #
263
+ # === Parameters
264
+ # opts[:conn](EM::Connection):: Connection used to send reply
265
+ #
266
+ # === Return
267
+ # true:: Always return true
268
+ def decommission_command(opts)
269
+ @scheduler.run_decommission { CommandIO.instance.reply(opts[:conn], 'Decommissioned') }
270
+ end
271
+
272
+ # Terminate command
273
+ #
274
+ # === Parameters
275
+ # opts[:conn](EM::Connection):: Connection used to send reply
276
+ #
277
+ # === Return
278
+ # true:: Always return true
279
+ def terminate_command(opts)
280
+ CommandIO.instance.reply(opts[:conn], 'Terminating')
281
+ @scheduler.terminate
282
+ end
283
+
284
+ # Get tags command
285
+ #
286
+ # === Parameters
287
+ # opts[:conn](EM::Connection):: Connection used to send reply
288
+ #
289
+ # === Return
290
+ # true:: Always return true
291
+ def get_tags_command(opts)
292
+ AgentTagManager.instance.tags { |tags| CommandIO.instance.reply(opts[:conn], tags) }
293
+ end
294
+
295
+ # Add given tag
296
+ #
297
+ # === Parameters
298
+ # opts[:conn](EM::Connection):: Connection used to send reply
299
+ # opts[:tag](String):: Tag to be added
300
+ #
301
+ # === Return
302
+ # true:: Always return true
303
+ def add_tag_command(opts)
304
+ AgentTagManager.instance.add_tags(opts[:tag]) do |raw_response|
305
+ reply = @serializer.dump(raw_response) rescue raw_response
306
+ CommandIO.instance.reply(opts[:conn], reply)
307
+ end
308
+ end
309
+
310
+ # Remove given tag
311
+ #
312
+ # === Parameters
313
+ # opts[:conn](EM::Connection):: Connection used to send reply
314
+ # opts[:tag](String):: Tag to be removed
315
+ #
316
+ # === Return
317
+ # true:: Always return true
318
+ def remove_tag_command(opts)
319
+ AgentTagManager.instance.remove_tags(opts[:tag]) do |raw_response|
320
+ reply = @serializer.dump(raw_response) rescue raw_response
321
+ CommandIO.instance.reply(opts[:conn], reply)
322
+ end
323
+ end
324
+
325
+ # Query for instances with given tags
326
+ #
327
+ # === Parameters
328
+ # opts[:conn](EM::Connection):: Connection used to send reply
329
+ # opts[:tags](String):: Tags to be used in query
330
+ #
331
+ # === Return
332
+ # true:: Always return true
333
+ def query_tags_command(opts)
334
+ AgentTagManager.instance.query_tags_raw(opts[:tags], opts[:agent_ids]) do |raw_response|
335
+ reply = @serializer.dump(raw_response) rescue raw_response
336
+ CommandIO.instance.reply(opts[:conn], reply)
337
+ end
338
+ end
339
+
340
+ # Create an audit entry.
341
+ #
342
+ # === Parameters
343
+ # opts[:conn](EM::Connection):: Connection used to send reply
344
+ # opts[:summary](String):: Initial audit summary; must be present in order to avoid a blank summary!
345
+ # opts[:category](String):: One of the categories enumerated by RightScale::EventCategories
346
+ # opts[:user_email](String):: Optional; email of user who caused the audit event
347
+ #
348
+ # === Return
349
+ # result(RightScale::OperationResult):: result; if successful, payload == an integer audit ID
350
+ def audit_create_entry_command(opts)
351
+ payload = {
352
+ :agent_identity => @agent_identity,
353
+ :summary => opts[:summary],
354
+ :category => opts[:category] || RightScale::EventCategories::NONE,
355
+ :user_email => opts[:user_email],
356
+ :detail => opts[:detail]
357
+ }
358
+
359
+ send_persistent_push('/auditor/create_entry', opts[:conn], payload)
360
+ end
361
+
362
+ # Update audit summary
363
+ #
364
+ # === Parameters
365
+ # opts[:conn](EM::Connection):: Connection used to send reply
366
+ # opts[:title](Hash):: Chef attributes hash
367
+ #
368
+ # === Return
369
+ # true:: Always return true
370
+ def audit_update_status_command(opts)
371
+ AuditCookStub.instance.forward_audit(:update_status, opts[:content], opts[:thread_name], opts[:options])
372
+ CommandIO.instance.reply(opts[:conn], 'OK', close_after_writing=false)
373
+ end
374
+
375
+ # Update audit summary
376
+ #
377
+ # === Parameters
378
+ # opts[:conn](EM::Connection):: Connection used to send reply
379
+ # opts[:title](Hash):: Chef attributes hash
380
+ #
381
+ # === Return
382
+ # true:: Always return true
383
+ def audit_create_new_section_command(opts)
384
+ AuditCookStub.instance.forward_audit(:create_new_section, opts[:content], opts[:thread_name], opts[:options])
385
+ CommandIO.instance.reply(opts[:conn], 'OK', close_after_writing=false)
386
+ end
387
+
388
+ # Update audit summary
389
+ #
390
+ # === Parameters
391
+ # opts[:conn](EM::Connection):: Connection used to send reply
392
+ # opts[:title](Hash):: Chef attributes hash
393
+ #
394
+ # === Return
395
+ # true:: Always return true
396
+ def audit_append_output_command(opts)
397
+ AuditCookStub.instance.forward_audit(:append_output, opts[:content], opts[:thread_name], opts[:options])
398
+ CommandIO.instance.reply(opts[:conn], 'OK', close_after_writing=false)
399
+ end
400
+
401
+ # Update audit summary
402
+ #
403
+ # === Parameters
404
+ # opts[:conn](EM::Connection):: Connection used to send reply
405
+ # opts[:title](Hash):: Chef attributes hash
406
+ #
407
+ # === Return
408
+ # true:: Always return true
409
+ def audit_append_info_command(opts)
410
+ AuditCookStub.instance.forward_audit(:append_info, opts[:content], opts[:thread_name], opts[:options])
411
+ CommandIO.instance.reply(opts[:conn], 'OK', close_after_writing=false)
412
+ end
413
+
414
+ # Update audit summary
415
+ #
416
+ # === Parameters
417
+ # opts[:conn](EM::Connection):: Connection used to send reply
418
+ # opts[:title](Hash):: Chef attributes hash
419
+ #
420
+ # === Return
421
+ # true:: Always return true
422
+ def audit_append_error_command(opts)
423
+ AuditCookStub.instance.forward_audit(:append_error, opts[:content], opts[:thread_name], opts[:options])
424
+ CommandIO.instance.reply(opts[:conn], 'OK', close_after_writing=false)
425
+ end
426
+
427
+ # Update inputs patch to be sent back to core after cook process finishes
428
+ #
429
+ # === Parameters
430
+ # opts[:conn](EM::Connection):: Connection used to send reply
431
+ # opts[:patch](Hash):: Patch to be forwarded to core
432
+ #
433
+ # === Return
434
+ # true:: Always return true
435
+ def set_inputs_patch_command(opts)
436
+ payload = {:agent_identity => @agent_identity, :patch => opts[:patch]}
437
+ send_persistent_push("/updater/update_inputs", opts[:conn], payload)
438
+ CommandIO.instance.reply(opts[:conn], 'OK')
439
+ end
440
+
441
+ # Check whether this instance agent is connected by pinging a mapper
442
+ #
443
+ # === Return
444
+ # true:: Always return true
445
+ def check_connectivity_command(opts)
446
+ send_persistent_request("/mapper/ping", opts[:conn])
447
+ true
448
+ end
449
+
450
+ # Close connection
451
+ def close_connection_command(opts)
452
+ AuditCookStub.instance.close(opts[:thread_name])
453
+ CommandIO.instance.reply(opts[:conn], 'OK')
454
+ end
455
+
456
+ # Helper method to send a request to one or more targets with no response expected
457
+ # See Sender for details
458
+ def send_push(type, conn, payload = nil, target = nil)
459
+ payload ||= {}
460
+ payload[:agent_identity] = @agent_identity
461
+ Sender.instance.send_push(type, payload, target)
462
+ CommandIO.instance.reply(conn, 'OK')
463
+ true
464
+ end
465
+
466
+ # Helper method to send a request to one or more targets with no response expected
467
+ # The request is persisted en route to reduce the chance of it being lost at the expense of some
468
+ # additional network overhead
469
+ # See Sender for details
470
+ def send_persistent_push(type, conn, payload = nil, target = nil)
471
+ payload ||= {}
472
+ payload[:agent_identity] = @agent_identity
473
+ Sender.instance.send_persistent_push(type, payload, target)
474
+ CommandIO.instance.reply(conn, 'OK')
475
+ true
476
+ end
477
+
478
+ # Helper method to send a request to a single target with a response expected
479
+ # The request is retried if the response is not received in a reasonable amount of time
480
+ # The request is timed out if not received in time, typically configured to 2 minutes
481
+ # The request is allowed to expire per the agent's configured time-to-live, typically 1 minute
482
+ # See Sender for details
483
+ def send_retryable_request(type, conn, payload = nil, target = nil)
484
+ payload ||= {}
485
+ payload[:agent_identity] = @agent_identity
486
+ Sender.instance.send_retryable_request(type, payload, target) do |r|
487
+ reply = @serializer.dump(r) rescue '\"Failed to serialize response\"'
488
+ CommandIO.instance.reply(conn, reply)
489
+ end
490
+ true
491
+ end
492
+
493
+ # Helper method to send a request to a single target with a response expected
494
+ # The request is persisted en route to reduce the chance of it being lost at the expense of some
495
+ # additional network overhead
496
+ # The request is never retried if there is the possibility of it being duplicated
497
+ # See Sender for details
498
+ def send_persistent_request(type, conn, payload = nil, target = nil)
499
+ payload ||= {}
500
+ payload[:agent_identity] = @agent_identity
501
+ Sender.instance.send_persistent_request(type, payload, target) do |r|
502
+ reply = @serializer.dump(r) rescue '\"Failed to serialize response\"'
503
+ CommandIO.instance.reply(conn, reply)
504
+ end
505
+ true
506
+ end
507
+
508
+ # Helper method to send a retryable (and therefore idempotent!) request to a single target with a response
509
+ # expected, retrying at the application layer until the request succeeds or the timeout elapses; default
510
+ # timeout is 'forever'.
511
+ #
512
+ # See IdempotentRequest for details
513
+ def send_idempotent_request(type, conn, payload=nil, opts={})
514
+ req = IdempotentRequest.new(type, payload, opts)
515
+
516
+ callback = Proc.new do |content|
517
+ result = OperationResult.success(content)
518
+ reply = @serializer.dump(result) rescue '\"Failed to serialize response\"'
519
+ CommandIO.instance.reply(conn, reply)
520
+ end
521
+
522
+ errback = Proc.new do |content|
523
+ result = OperationResult.error(content)
524
+ reply = @serializer.dump(result) rescue '\"Failed to serialize response\"'
525
+ CommandIO.instance.reply(conn, reply)
526
+ end
527
+
528
+ req.callback(&callback)
529
+ req.errback(&errback)
530
+ req.run
531
+ end
532
+
533
+ # Stats command
534
+ #
535
+ # === Parameters
536
+ # opts[:conn](EM::Connection):: Connection used to send reply
537
+ # opts[:reset](Boolean):: Whether to reset stats
538
+ #
539
+ # === Return
540
+ # true:: Always return true
541
+ def stats_command(opts)
542
+ CommandIO.instance.reply(opts[:conn], JSON.dump(@agent_manager.stats({:reset => opts[:reset]})))
543
+ end
544
+
545
+ # Get shutdown request command
546
+ #
547
+ # === Parameters
548
+ # opts[:conn](EM::Connection):: Connection used to send reply
549
+ #
550
+ # === Return
551
+ # true:: Always return true
552
+ def get_shutdown_request_command(opts)
553
+ shutdown_request = ShutdownRequest.instance
554
+ CommandIO.instance.reply(opts[:conn], { :level => shutdown_request.level, :immediately => shutdown_request.immediately? })
555
+ rescue Exception => e
556
+ CommandIO.instance.reply(opts[:conn], { :error => e.message })
557
+ end
558
+
559
+ # Set reboot timeout command
560
+ #
561
+ # === Parameters
562
+ # opts[:conn](EM::Connection):: Connection used to send reply
563
+ # opts[:level](String):: shutdown request level
564
+ # opts[:immediately](Boolean):: shutdown immediacy or nil
565
+ #
566
+ # === Return
567
+ # true:: Always return true
568
+ def set_shutdown_request_command(opts)
569
+ shutdown_request = ShutdownRequest.submit(opts)
570
+ CommandIO.instance.reply(opts[:conn], { :level => shutdown_request.level, :immediately => shutdown_request.immediately? })
571
+ rescue Exception => e
572
+ CommandIO.instance.reply(opts[:conn], { :error => e.message })
573
+ end
574
+
575
+ end # InstanceCommands
576
+
577
+ end # RightScale