如何使用和理解动作对象和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_typedropletresource_id 是液滴的 ID。 statusin-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"
  }
}

注意现在 statuscompletedcompleted_atstarted_at 都有一个时间戳。

您还可以在 /actions 端点访问 在您的帐户上执行的所有操作 的完整历史记录。

curl -X GET -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer '$TOKEN'' \
    "https://api.digitalocean.com/v2/actions"

在实践中使用动作对象

虽然列出所有 Action 对象可能对审计您的历史记录很有趣,但实际上您将主要使用此端点来检查进程的状态。 对于这些示例,我们将使用 droplet_kitDigitalOcean 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 开发者门户 了解更多主题。