介绍
在 DigitalOcean API 的第二版中,发生的每个事件都会创建 一个“动作”对象 。 这些既可以作为过去发生的事件的记录,也可以作为检查正在进行的事件进度的一种方式。 从创建新的 Droplet 到将图像传输到新区域,Action 对象将为您提供有关事件的有用信息。
本文将解释 Action 对象,并展示如何通过 DropletKit,DigitalOcean API 的官方 Ruby gem 在实践中使用它们。
先决条件
本文假设您对 DigitalOcean API 有基本的了解。 要了解有关 API 的更多信息,包括如何获取完成本教程所需的访问令牌,请参阅以下资源:
了解动作对象
使用 API 发起事件时,会在响应中返回一个 Action 对象。 此对象将包含有关事件的信息,包括其状态、启动和完成时间的时间戳以及关联的资源类型和 ID。 例如,如果我们在哪里拍摄 ID 为 3164450 的 Droplet 的快照:
curl -X POST -H 'Content-Type: application/json' \
-H 'Authorization: Bearer '$TOKEN'' \
-d '{"type":"snapshot","name":"Nifty New Snapshot"}' \
"https://api.digitalocean.com/v2/droplets/3164450/actions"
我们会收到以下回复:
{
"action": {
"id": 36805022,
"status": "in-progress",
"type": "snapshot",
"started_at": "2014-11-14T16:34:39Z",
"completed_at": null,
"resource_id": 3164450,
"resource_type": "droplet",
"region": "nyc3"
}
}
请注意,resource_type 是 droplet 而 resource_id 是液滴的 ID。 status 是 in-progress。 一旦事件结束,这将变为 completed。 为了检查操作的状态,您可以直接查询该操作的 API。
curl -X GET -H 'Content-Type: application/json' \
-H 'Authorization: Bearer '$TOKEN'' \
"https://api.digitalocean.com/v2/actions/36805022"
这将返回请求的操作对象:
{
"action": {
"id": 36805022,
"status": "completed",
"type": "snapshot",
"started_at": "2014-11-14T16:34:39Z",
"completed_at": "2014-11-14T16:38:52Z",
"resource_id": 3164450,
"resource_type": "droplet",
"region": "nyc3"
}
}
注意现在 status 是 completed,completed_at 和 started_at 都有一个时间戳。
您还可以在 /actions 端点访问 在您的帐户上执行的所有操作 的完整历史记录。
curl -X GET -H 'Content-Type: application/json' \
-H 'Authorization: Bearer '$TOKEN'' \
"https://api.digitalocean.com/v2/actions"
在实践中使用动作对象
虽然列出所有 Action 对象可能对审计您的历史记录很有趣,但实际上您将主要使用此端点来检查进程的状态。 对于这些示例,我们将使用 droplet_kit、DigitalOcean API 的官方 Ruby gem。 它可以安装:
gem install droplet_kit
首先,通过运行命令 irb 进入 Ruby shell,然后导入 droplet_kit gem 并使用您的 API 令牌设置您的客户端:
irb(main):> require 'droplet_kit' => true irb(main):> client = DropletKit::Client.new(access_token: DO_TOKEN)
一些行动取决于其他行动首先被采取。 例如,尝试拍摄仍处于开机状态的 Droplet 的快照将导致错误。 必须关闭 Droplet 才能拍摄快照。
irb(main):> client.droplet_actions.snapshot(droplet_id: 4143310, name: 'Snapshot Name')
=> "{\"id\":\"unprocessable_entity\",\"message\":\"Droplet is currently on. Please power it off to run this event.\"}"
尝试在启动关闭操作后立即拍摄快照也会导致相同的错误,因为您必须确保关闭操作已完成,然后才能拍摄快照。 操作不能排队。
irb(main):> client.droplet_actions.shutdown(droplet_id: 4143310)
=> <DropletKit::Action {:@id=>43918785, :@status=>"in-progress", :@type=>"shutdown", :@started_at=>"2015-02-16T21:22:35Z", :@completed_at=>nil, :@resource_id=>4143310, :@resource_type=>"droplet", :@region=>"nyc3"}>
irb(main):> client.droplet_actions.snapshot(droplet_id: 4143310, name: 'Snapshot Name')
=> "{\"id\":\"unprocessable_entity\",\"message\":\"Droplet is currently on. Please power it off to run this event.\"}"
与上面的 curl 示例类似,droplet_kit 也返回 Action 对象以响应成功启动的事件。 它可以作为普通的 Ruby 对象访问。 将响应保存到变量中将允许您直接访问其属性:
irb(main):> snapshot = client.droplet_actions.snapshot(droplet_id: 4143310, name: 'Snapshot Name')
=> "{\"id\":\"unprocessable_entity\",\"message\":\"Droplet is currently on. Please power it off to run this event.\"}"
irb(main):> shutdown = client.droplet_actions.shutdown(droplet_id: 4143310)
=> <DropletKit::Action {:@id=>43919195, :@status=>"in-progress", :@type=>"shutdown", :@started_at=>"2015-02-16T21:32:03Z", :@completed_at=>nil, :@resource_id=>4143310, :@resource_type=>"droplet", :@region=>"nyc3"}>
irb(main):> shutdown.status
=> "in-progress"
irb(main):> shutdown.id
=> 43919195
然后,您可以检查操作的状态:
irb(main):> action = client.actions.find(id: shutdown.id)
=> <DropletKit::Action {:@id=>43919195, :@status=>"completed", :@type=>"shutdown", :@started_at=>"2015-02-16T21:32:03Z", :@completed_at=>"2015-02-16T21:32:07Z", :@resource_id=>4143310, :@resource_type=>"droplet", :@region=>"nyc3"}>
irb(main):> action.status
=> "completed"
我们可以在 Ruby 中使用 until 循环来检查一个动作的进度,直到它完成:
res = client.droplet_actions.shutdown(droplet_id: id)
until res.status == "completed"
res = client.actions.find(id: res.id)
sleep(2)
end
把它们放在一起
下面的这个 Ruby 脚本是一个如何在实践中检查操作状态的示例。 它关闭 droplet 并使用上方的 while 循环来确保在继续之前操作已完成。 关闭操作完成后,它将拍摄液滴的快照。
#!/usr/bin/env ruby
require 'droplet_kit'
require 'json'
token = ENV['DO_TOKEN']
client = DropletKit::Client.new(access_token: token)
droplet_id = ARGV[0]
snapshot_name = ARGV[1] || Time.now.strftime("%b. %d, %Y - %H:%M:%S %Z")
def power_off(client, id)
res = client.droplet_actions.shutdown(droplet_id: id)
until res.status == "completed"
res = client.actions.find(id: res.id)
sleep(2)
end
puts " * Action status: #{res.status}"
rescue NoMethodError
puts JSON.parse(res)['message']
end
def take_snapshot(client, id, name)
res = client.droplet_actions.snapshot(droplet_id: id, name: name)
puts " * Action status: #{res.status}"
rescue NameError
puts JSON.parse(res)['message']
end
unless droplet_id.nil?
puts "Powering off droplet..."
power_off(client, droplet_id)
sleep(2)
puts "Taking snapshot..."
take_snapshot(client, droplet_id, snapshot_name)
else
puts "Power off and snapshot a droplet. Requires a droplet ID and optionally a snapshot name."
puts "Usage: #{$0} droplet_id ['snapshot name']"
end
如果将此脚本保存为名为 snapshot.rb 的文件(或从 this GitHub Gist 下载),则可以从命令行运行它,如下所示:
DO_TOKEN=YOUR_DO_API_TOKEN ruby snapshot.rb 12345 "My Snapshot"
请注意,为了使用该脚本,您必须将 API 令牌导出为名称为 DO_TOKEN 的环境变量。 该脚本采用两个参数,即 droplet 的 ID 和可选的快照名称。 如果您不提供名称,则将是日期和时间。
结论
操作项是 DigitialOcean API 的重要组成部分。 使用它们来检查操作的状态是使用 API 时实施的重要最佳实践。 既然您了解了如何使用它们,您就可以继续使用更复杂的 API 用例,例如:
查看 DigitalOcean 开发者门户 了解更多主题。