如何使用和理解动作对象和DigitalOceanAPI
介绍
在 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 开发者门户 了解更多主题。