1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

Merge pull request #2460 from maestrodev/google-operations

[google] Implement operation model
This commit is contained in:
Nat Welch 2013-12-06 15:20:59 -08:00
commit 216cf26899
14 changed files with 270 additions and 43 deletions

View file

@ -29,13 +29,16 @@ module Fog
request :get_network
request :get_zone
request :get_snapshot
request :get_global_operation
request :get_zone_operation
request :delete_disk
request :delete_firewall
request :delete_image
request :delete_network
request :delete_operation
request :delete_server
request :delete_global_operation
request :delete_zone_operation
request :insert_disk
request :insert_firewall
@ -59,6 +62,9 @@ module Fog
model :disk
collection :disks
model :operation
collection :operations
model :snapshot
collection :snapshots
@ -73,10 +79,10 @@ module Fog
@api_version = 'v1beta16'
end
def build_excon_response(body)
def build_excon_response(body, status=200)
response = Excon::Response.new
response.body = body
if response.body["error"]
if response.body and response.body["error"]
response.status = response.body["error"]["code"]
msg = response.body["error"]["errors"].map{|error| error["message"]}.join(", ")
case response.status
@ -86,7 +92,7 @@ module Fog
raise Fog::Errors::Error.new(msg)
end
else
response.status = 200
response.status = status
end
response
end
@ -763,7 +769,8 @@ module Fog
}
end,
:images => {},
:disks => {}
:disks => {},
:operations => {}
}
end
end
@ -782,6 +789,9 @@ module Fog
self.class.data(api_version).delete(@project)
end
def random_operation
"operation-#{Fog::Mock.random_numbers(13)}-#{Fog::Mock.random_hex(13)}-#{Fog::Mock.random_hex(8)}"
end
end
class Real
@ -842,7 +852,7 @@ module Fog
# result = Google::APIClient::Result
# returns Excon::Response
def build_response(result)
build_excon_response(Fog::JSON.decode(result.body))
build_excon_response(result.body.nil? ? nil : Fog::JSON.decode(result.body), result.status)
end
end

View file

@ -38,7 +38,13 @@ module Fog
def destroy
requires :name, :zone_name
service.delete_disk(name, zone_name)
operation = service.delete_disk(name, zone_name)
# wait until "RUNNING" or "DONE" to ensure the operation doesn't fail, raises exception on error
Fog.wait_for do
operation = service.get_zone_operation(zone_name, operation.body["name"])
operation.body["status"] != "PENDING"
end
operation
end
def zone

View file

@ -0,0 +1,42 @@
require 'fog/core/model'
module Fog
module Compute
class Google
class Operation < Fog::Model
identity :name
attribute :kind, :aliases => 'kind'
attribute :id, :aliases => 'id'
attribute :creation_timestamp, :aliases => 'creationTimestamp'
attribute :zone_name, :aliases => 'zone'
attribute :status, :aliases => 'status'
attribute :self_link, :aliases => 'selfLink'
def ready?
self.status == DONE_STATE
end
def pending?
self.status == PENDING_STATE
end
def reload
requires :identity
data = collection.get(identity, zone)
new_attributes = data.attributes
merge_attributes(new_attributes)
self
end
PENDING_STATE = "PENDING"
RUNNING_STATE = "RUNNING"
DONE_STATE = "DONE"
end
end
end
end

View file

@ -0,0 +1,26 @@
require 'fog/core/collection'
require 'fog/google/models/compute/operation'
module Fog
module Compute
class Google
class Operations < Fog::Collection
model Fog::Compute::Google::Operation
def get(identity, zone=nil)
if zone.nil?
response = service.get_global_operation(identity)
else
response = service.get_zone_operation(zone, identity)
end
return nil if response.nil?
new(response.body)
end
end
end
end
end

View file

@ -30,7 +30,13 @@ module Fog
def destroy
requires :name, :zone
service.delete_server(name, zone)
operation = service.delete_server(name, zone)
# wait until "RUNNING" or "DONE" to ensure the operation doesn't fail, raises exception on error
Fog.wait_for do
operation = service.get_zone_operation(zone_name, operation.body["name"])
operation.body["status"] != "PENDING"
end
operation
end
def image

View file

@ -6,23 +6,26 @@ module Fog
def delete_disk(disk_name, zone_name)
get_disk(disk_name, zone_name)
self.data[:disks].delete disk_name
build_response(:body => {
operation = self.random_operation
self.data[:operations][operation] = {
"kind" => "compute#operation",
"id" => "7145812689701515415",
"name" => "operation-1385125998242-4ebc3c7173e70-11e1ad0b",
"id" => Fog::Mock.random_numbers(19).to_s,
"name" => operation,
"zone" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}",
"operationType" => "delete",
"targetLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/disks/#{disk_name}",
"targetId" => "6817095360746367667",
"status" => "PENDING",
"targetId" => self.data[:disks][disk_name]["id"],
"status" => Fog::Compute::Google::Operation::PENDING_STATE,
"user" => "123456789012-qwertyuiopasdfghjkl1234567890qwe@developer.gserviceaccount.com",
"progress" => 0,
"insertTime" => Time.now.iso8601,
"startTime" => Time.now.iso8601,
"selfLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/operations/operation-1385125998242-4ebc3c7173e70-11e1ad0b"
})
"selfLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/operations/#{operation}"
}
self.data[:disks].delete disk_name
build_response(:body => self.data[:operations][operation])
end
end

View file

@ -0,0 +1,29 @@
module Fog
module Compute
class Google
class Mock
def delete_global_operation(operation)
Fog::Mock.not_implemented
end
end
class Real
# https://developers.google.com/compute/docs/reference/latest/globalOperations
def delete_global_operation(operation)
api_method = @compute.global_operations.delete
parameters = {
'project' => @project,
'operation' => operation
}
result = self.build_result(api_method, parameters)
response = self.build_response(result)
end
end
end
end
end

View file

@ -28,21 +28,25 @@ module Fog
server = self.data[:servers][server_name]
server["status"] = "STOPPED"
server["mock-deletionTimestamp"] = Time.now.iso8601
build_response(:body => {
operation = self.random_operation
self.data[:operations][operation] = {
"kind" => "compute#operation",
"id" => "10035781241131638365",
"name" => "operation-1380213292196-4e74bf2fbc3c1-ae707d47",
"id" => Fog::Mock.random_numbers(19).to_s,
"name" => operation,
"zone" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}",
"operationType" => "delete",
"targetLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/instances/#{server_name}",
"targetId" => "14544909043643897380",
"status" => "PENDING",
"targetId" => self.data[:servers][server_name]["id"],
"status" => Fog::Compute::Google::Operation::PENDING_STATE,
"user" => "123456789012-qwertyuiopasdfghjkl1234567890qwe@developer.gserviceaccount.com",
"progress" => 0,
"insertTime" => Time.now.iso8601,
"startTime" => Time.now.iso8601,
"selfLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/operations/operation-1380213292196-4e74bf2fbc3c1-ae707d47"
})
"selfLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/operations/#{operation}"
}
build_response(:body => self.data[:operations][operation])
end
end

View file

@ -0,0 +1,33 @@
module Fog
module Compute
class Google
class Mock
def delete_zone_operation(zone, operation)
Fog::Mock.not_implemented
end
end
class Real
# https://developers.google.com/compute/docs/reference/latest/zoneOperations
def delete_zone_operation(zone_name, operation)
if zone_name.start_with? 'http'
zone_name = zone_name.split('/')[-1]
end
api_method = @compute.zone_operations.delete
parameters = {
'project' => @project,
'zone' => zone_name,
'operation' => operation
}
result = self.build_result(api_method, parameters)
response = self.build_response(result)
end
end
end
end
end

View file

@ -4,27 +4,26 @@ module Fog
class Mock
def delete_operation(operation_name)
def get_global_operation(operation)
Fog::Mock.not_implemented
end
end
class Real
# https://developers.google.com/compute/docs/reference/latest/globalOperations
def delete_operation(operation_name)
api_method = @compute.operations.delete
def get_global_operation(operation)
api_method = @compute.global_operations.get
parameters = {
'project' => @project,
'operation' => operation_name
'operation' => operation
}
result = self.build_result(api_method, parameters)
response = self.build_response(result)
end
end
end
end
end

View file

@ -0,0 +1,58 @@
module Fog
module Compute
class Google
class Mock
def get_zone_operation(zone_name, operation)
operation = self.data[:operations][operation]
if operation
case operation["status"]
when Fog::Compute::Google::Operation::PENDING_STATE
operation["status"] = Fog::Compute::Google::Operation::RUNNING_STATE
operation["progress"] = 50
else
operation["status"] = Fog::Compute::Google::Operation::DONE_STATE
operation["progress"] = 100
end
else
operation = {
"error" => {
"errors" => [
{
"domain" => "global",
"reason" => "notFound",
"message" => "The resource 'projects/#{project}/zones/#{zone_name}/operations/#{operation}' was not found"
}
],
"code" => 404,
"message" => "The resource 'projects/#{project}/zones/#{zone_name}/operations/#{operation}' was not found"
}
}
end
build_response(:body => operation)
end
end
class Real
# https://developers.google.com/compute/docs/reference/latest/zoneOperations
def get_zone_operation(zone_name, operation)
if zone_name.start_with? 'http'
zone_name = zone_name.split('/')[-1]
end
api_method = @compute.zone_operations.get
parameters = {
'project' => @project,
'zone' => zone_name,
'operation' => operation
}
result = self.build_result(api_method, parameters)
response = self.build_response(result)
end
end
end
end
end

View file

@ -16,9 +16,10 @@ module Fog
end
get_zone(zone_name)
id = Fog::Mock.random_numbers(19).to_s
self.data[:disks][disk_name] = {
"kind" => "compute#disk",
"id" => Fog::Mock.random_numbers(19),
"id" => id,
"creationTimestamp" => Time.now.iso8601,
"zone" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}",
"status" => "READY",
@ -27,20 +28,24 @@ module Fog
"selfLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/disks/#{disk_name}"
}
build_response(:body => {
operation = self.random_operation
self.data[:operations][operation] = {
"kind" => "compute#operation",
"id" => "12498846269172327286",
"name" => "operation-1385124218076-4ebc35cfbe9f1-476486c5",
"id" => Fog::Mock.random_numbers(19).to_s,
"name" => operation,
"zone" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}",
"operationType" => "insert",
"targetLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/disks/#{disk_name}",
"status" => "PENDING",
"targetId" => id,
"status" => Fog::Compute::Google::Operation::PENDING_STATE,
"user" => "123456789012-qwertyuiopasdfghjkl1234567890qwe@developer.gserviceaccount.com",
"progress" => 0,
"insertTime" => Time.now.iso8601,
"startTime" => Time.now.iso8601,
"selfLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/operations/operation-1385124218076-4ebc35cfbe9f1-476486c5"
})
"selfLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/operations/#{operation}"
}
build_response(:body => self.data[:operations][operation])
end
end

View file

@ -37,9 +37,10 @@ module Fog
end
get_zone(zone_name)
id = Fog::Mock.random_numbers(19).to_s
self.data[:servers][server_name] = {
"kind" => "compute#instance",
"id" => Fog::Mock.random_numbers(19),
"id" => id,
"creationTimestamp" => Time.now.iso8601,
"zone" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}",
"status" => "PROVISIONING",
@ -85,20 +86,24 @@ module Fog
"selfLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/instances/#{server_name}"
}
build_response(:body => {
operation = self.random_operation
self.data[:operations][operation] = {
"kind" => "compute#operation",
"id" => "4639689000254420481",
"name" => "operation-1380213292196-4e74bf2fbc3c1-ae707d47",
"id" => Fog::Mock.random_numbers(19).to_s,
"name" => operation,
"zone" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}",
"operationType" => "insert",
"targetLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/instances/#{server_name}",
"status" => "PENDING",
"targetId" => id,
"status" => Fog::Compute::Google::Operation::PENDING_STATE,
"user" => "123456789012-qwertyuiopasdfghjkl1234567890qwe@developer.gserviceaccount.com",
"progress" => 0,
"insertTime" => Time.now.iso8601,
"startTime" => Time.now.iso8601,
"selfLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/operations/operation-1380213292196-4e74bf2fbc3c1-ae707d47"
})
"selfLink" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/zones/#{zone_name}/operations/#{operation}"
}
build_response(:body => self.data[:operations][operation])
end
end

View file

@ -11,6 +11,7 @@ module Fog
end
class Real
# https://developers.google.com/compute/docs/reference/latest/zoneOperations
def list_zone_operations(zone)
api_method = @compute.zone_operations.list