From a1f0dbf42825f293386042fd759147882b49880d Mon Sep 17 00:00:00 2001 From: Chris Wuest Date: Sat, 13 Apr 2013 22:53:26 -0500 Subject: [PATCH] Implement rescue mode support for Rackspace Create real and mock rescue and unrescue methods for Rackspace compute V2 Create tests for rescue and unrescue methods --- lib/fog/rackspace/compute_v2.rb | 2 + lib/fog/rackspace/models/compute_v2/server.rb | 39 ++++++++++++++++++ .../requests/compute_v2/rescue_server.rb | 41 +++++++++++++++++++ .../requests/compute_v2/unrescue_server.rb | 40 ++++++++++++++++++ .../models/compute_v2/server_tests.rb | 12 ++++++ .../requests/compute_v2/server_tests.rb | 10 +++++ 6 files changed, 144 insertions(+) create mode 100644 lib/fog/rackspace/requests/compute_v2/rescue_server.rb create mode 100644 lib/fog/rackspace/requests/compute_v2/unrescue_server.rb diff --git a/lib/fog/rackspace/compute_v2.rb b/lib/fog/rackspace/compute_v2.rb index 113765c09..e32f06f48 100644 --- a/lib/fog/rackspace/compute_v2.rb +++ b/lib/fog/rackspace/compute_v2.rb @@ -66,6 +66,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 d7a928984..bc8f22a95 100644 --- a/lib/fog/rackspace/models/compute_v2/server.rb +++ b/lib/fog/rackspace/models/compute_v2/server.rb @@ -451,6 +451,45 @@ 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) + self.state = RESCUE + 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..e2fb8ddeb --- /dev/null +++ b/lib/fog/rackspace/requests/compute_v2/rescue_server.rb @@ -0,0 +1,41 @@ +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" + response(:status => 200) + 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 49f260d14..bda2b08b4 100644 --- a/tests/rackspace/models/compute_v2/server_tests.rb +++ b/tests/rackspace/models/compute_v2/server_tests.rb @@ -139,6 +139,18 @@ Shindo.tests('Fog::Compute::RackspaceV2 | server', ['rackspace']) do @instance.revert_resize end + @instance.wait_for(timeout=1500) { ready? } + tests('#rescue').succeeds do + @instance.rescue + returns('RESCUE') { @instance.state } + end + + @instance.wait_for(timeout=1500) { ready?('RESCUE') } + sleep 60 unless Fog.mocking? + 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..4ba4a4cb3 100644 --- a/tests/rackspace/requests/compute_v2/server_tests.rb +++ b/tests/rackspace/requests/compute_v2/server_tests.rb @@ -124,6 +124,16 @@ Shindo.tests('Fog::Compute::RackspaceV2 | server_tests', ['rackspace']) do end wait_for_server_state(service, server_id, 'ACTIVE', 'ERROR') + tests('#rescue_server').succeeds 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