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:
commit
216cf26899
14 changed files with 270 additions and 43 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
42
lib/fog/google/models/compute/operation.rb
Normal file
42
lib/fog/google/models/compute/operation.rb
Normal 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
|
26
lib/fog/google/models/compute/operations.rb
Normal file
26
lib/fog/google/models/compute/operations.rb
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
29
lib/fog/google/requests/compute/delete_global_operation.rb
Normal file
29
lib/fog/google/requests/compute/delete_global_operation.rb
Normal 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
|
|
@ -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
|
||||
|
|
33
lib/fog/google/requests/compute/delete_zone_operation.rb
Normal file
33
lib/fog/google/requests/compute/delete_zone_operation.rb
Normal 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
|
|
@ -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
|
58
lib/fog/google/requests/compute/get_zone_operation.rb
Normal file
58
lib/fog/google/requests/compute/get_zone_operation.rb
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue