diff --git a/lib/fog/rackspace/compute_v2.rb b/lib/fog/rackspace/compute_v2.rb index c9cdf861f..a69b073d2 100644 --- a/lib/fog/rackspace/compute_v2.rb +++ b/lib/fog/rackspace/compute_v2.rb @@ -67,6 +67,8 @@ module Fog request :resize_server request :confirm_resize_server request :revert_resize_server + request :rescue_server + request :unrescue_server request :list_addresses request :list_addresses_by_network diff --git a/lib/fog/rackspace/models/compute_v2/server.rb b/lib/fog/rackspace/models/compute_v2/server.rb index 2738ddb84..fb7e40b32 100644 --- a/lib/fog/rackspace/models/compute_v2/server.rb +++ b/lib/fog/rackspace/models/compute_v2/server.rb @@ -452,6 +452,44 @@ module Fog true end + # Place existing server into rescue mode, allowing for offline editing of configuration. The original server's disk is attached to a new instance of the same base image for a period of time to facilitate working within rescue mode. The original server will be automatically restored after 90 minutes. + # @return [Boolean] returns true if call to put server in rescue mode reports success + # @raise [Fog::Rackspace::Errors::NotFound] - HTTP 404 + # @raise [Fog::Rackspace::Errors::BadRequest] - HTTP 400 + # @raise [Fog::Rackspace::Errors::InternalServerError] - HTTP 500 + # @raise [Fog::Rackspace::Errors::ServiceError] + # @note Rescue mode is only guaranteed to be active for 90 minutes. + # @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/rescue_mode.html + # @see #unrescue + # + # * Status Transition: + # * ACTIVE -> PREP_RESCUE -> RESCUE + def rescue + requires :identity + data = service.rescue_server(identity) + merge_attributes(data.body) + true + end + + # Remove existing server from rescue mode. + # @return [Boolean] returns true if call to remove server from rescue mode reports success + # @raise [Fog::Rackspace::Errors::NotFound] - HTTP 404 + # @raise [Fog::Rackspace::Errors::BadRequest] - HTTP 400 + # @raise [Fog::Rackspace::Errors::InternalServerError] - HTTP 500 + # @raise [Fog::Rackspace::Errors::ServiceError] + # @note Rescue mode is only guaranteed to be active for 90 minutes. + # @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/exit_rescue_mode.html + # @see #rescue + # + # * Status Transition: + # * PREP_UNRESCUE -> ACTIVE + def unrescue + requires :identity + service.unrescue_server(identity) + self.state = ACTIVE + true + end + # Change admin password # @param [String] password The administrator password. # @return [Boolean] returns true if operation was scheduled diff --git a/lib/fog/rackspace/requests/compute_v2/rescue_server.rb b/lib/fog/rackspace/requests/compute_v2/rescue_server.rb new file mode 100644 index 000000000..0d6769e84 --- /dev/null +++ b/lib/fog/rackspace/requests/compute_v2/rescue_server.rb @@ -0,0 +1,43 @@ +module Fog + module Compute + class RackspaceV2 + class Real + # Puts server into rescue mode + # @param [String] server_id id of server to rescue + # @return [Excon::Response] response + # @raise [Fog::Rackspace::Errors::NotFound] - HTTP 404 + # @raise [Fog::Rackspace::Errors::BadRequest] - HTTP 400 + # @raise [Fog::Rackspace::Errors::InternalServerError] - HTTP 500 + # @raise [Fog::Rackspace::Errors::ServiceError] + # @note Rescue mode is only guaranteed to be active for 90 minutes + # @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/rescue_mode.html + # + # * Status Transition: + # * PREP_RESCUE -> RESCUE + # * PREP_RESCUE -> ACTIVE (on error) + def rescue_server(server_id) + data = { + 'rescue' => nil + } + + request( + :body => Fog::JSON.encode(data), + :expects => [200], + :method => 'POST', + :path => "servers/#{server_id}/action" + ) + end + end + + class Mock + def rescue_server(server_id) + server = self.data[:servers][server_id] + server["status"] = "RESCUE" + admin_pass = Fog::Mock.random_letters(12) + server_response = { 'adminPass' => admin_pass } + response(:status => 200, :body => server_response) + end + end + end + end +end diff --git a/lib/fog/rackspace/requests/compute_v2/unrescue_server.rb b/lib/fog/rackspace/requests/compute_v2/unrescue_server.rb new file mode 100644 index 000000000..29a9bbbd3 --- /dev/null +++ b/lib/fog/rackspace/requests/compute_v2/unrescue_server.rb @@ -0,0 +1,40 @@ +module Fog + module Compute + class RackspaceV2 + class Real + # Take server out of rescue mode + # @param [String] server_id id of server + # @return [Excon::Response] response + # @raise [Fog::Rackspace::Errors::NotFound] - HTTP 404 + # @raise [Fog::Rackspace::Errors::BadRequest] - HTTP 400 + # @raise [Fog::Rackspace::Errors::InternalServerError] - HTTP 500 + # @raise [Fog::Rackspace::Errors::ServiceError] + # @see http://docs.rackspace.com/servers/api/v2/cs-devguide/content/exit_rescue_mode.html + # + # * Status Transition: + # * RESCUE -> PREP_UNRESCUE -> ACTIVE + # * RESCUE -> ERROR (on error) + def unrescue_server(server_id) + data = { + 'unrescue' => nil + } + + request( + :body => Fog::JSON.encode(data), + :expects => [202], + :method => 'POST', + :path => "servers/#{server_id}/action" + ) + end + end + + class Mock + def unrescue_server(server_id) + server = self.data[:servers][server_id] + server["status"] = "ACTIVE" + response(:status => 202) + end + end + end + end +end diff --git a/tests/rackspace/models/compute_v2/server_tests.rb b/tests/rackspace/models/compute_v2/server_tests.rb index acaf558ab..99717d220 100644 --- a/tests/rackspace/models/compute_v2/server_tests.rb +++ b/tests/rackspace/models/compute_v2/server_tests.rb @@ -148,6 +148,16 @@ Shindo.tests('Fog::Compute::RackspaceV2 | server', ['rackspace']) do @instance.revert_resize end + @instance.wait_for(timeout=1500) { ready? } + tests('#rescue').succeeds do + @instance.rescue + end + + @instance.wait_for(timeout=1500) { ready?('RESCUE') } + tests('#unrescue').succeeds do + @instance.unrescue + end + @instance.wait_for(timeout=1500) { ready? } tests('#change_admin_password').succeeds do @instance.change_admin_password('somerandompassword') diff --git a/tests/rackspace/requests/compute_v2/server_tests.rb b/tests/rackspace/requests/compute_v2/server_tests.rb index ed7624b3a..6af4e6a9b 100644 --- a/tests/rackspace/requests/compute_v2/server_tests.rb +++ b/tests/rackspace/requests/compute_v2/server_tests.rb @@ -54,6 +54,9 @@ Shindo.tests('Fog::Compute::RackspaceV2 | server_tests', ['rackspace']) do } } + rescue_server_format = { + 'adminPass' => Fog::Nullable::String + } tests('success') do @@ -124,6 +127,16 @@ Shindo.tests('Fog::Compute::RackspaceV2 | server_tests', ['rackspace']) do end wait_for_server_state(service, server_id, 'ACTIVE', 'ERROR') + tests('#rescue_server').formats(rescue_server_format, false) do + service.rescue_server(server_id) + end + wait_for_server_state(service, server_id, 'RESCUE', 'ACTIVE') + + tests('#unrescue_server').succeeds do + service.unrescue_server(server_id) + end + wait_for_server_state(service, server_id, 'ACTIVE', 'ERROR') + tests('#delete_server').succeeds do service.delete_server(server_id) end