というのをやるのにはちゃんとパッケージがあります。羽鳥とかキャプテンアメリカとかもauthorに入っているということで使わない理由はありません。
が、人間は理由に隷属する生き物ですが、敢えてそれに抗う愚かさも兼ね備えています。ということで(?)、素のhttrでやったときのメモ。
トークンを発行
ドキュメントはこのへん: https://developers.digitalocean.com/documentation/v2/#authentication
Applications & APIからアクセストークンを発行します。今回はdropletを立てるのでWriteの権限も必要です。
これを、
Authorization: Bearer (トークン)
というヘッダにして投げればAPIを使えます。
リクエストを投げる
ドキュメントはこのへん:https://developers.digitalocean.com/documentation/v2/#create-a-new-droplet
サンプルリクエストによると、dropletをつくるには、こんな感じのJSONを投げないといけないみたいです。
{ "name": "example.com", "region": "nyc3", "size": "512mb", "image": "ubuntu-14-04-x64", "ssh_keys": null, "backups": false, "ipv6": true, "user_data": null, "private_networking": null, "volumes": null }
region
とかimage
とかに指定する値がよくわかりません。この辺はRegionとかImageを列挙するAPIがあるみたいなのでそれを使うことにします。
/v2/regions
/v2/regions
に対してGETリクエストを投げます。
library(httr) library(purrr) token <- "(トークン)" res <- GET("https://api.digitalocean.com/v2/regions", add_headers(`Authorization` = sprintf("Bearer %s", token))) x <- content(res)
結果はこんな感じです。
names(x) #> [1] "regions" "links" "meta" str(x$regions[[1]]) #> List of 5 #> $ name : chr "New York 1" #> $ slug : chr "nyc1" #> $ sizes :List of 9 #> ..$ : chr "512mb" #> ..$ : chr "1gb" #> ..$ : chr "2gb" #> ..$ : chr "4gb" #> ..$ : chr "8gb" #> ..$ : chr "16gb" #> ..$ : chr "32gb" #> ..$ : chr "48gb" #> ..$ : chr "64gb" #> $ features :List of 5 #> ..$ : chr "private_networking" #> ..$ : chr "backups" #> ..$ : chr "ipv6" #> ..$ : chr "metadata" #> ..$ : chr "storage" #> $ available: logi TRUE
sizes
とfeatures
はlistではなくてvectorになってほしいところです。content()
は結果がJSONのときはjsonlite::fromJSON()
を呼んでいて、その引数を渡すことができます。
simplifyVector=TRUE
を指定すると結果を可能な限りdata.frameにしてくれます。
content(res, simplifyVector = TRUE) #> $regions #> name slug sizes features available #> 1 New York 1 nyc1 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata, storage TRUE #> 2 San Francisco 1 sfo1 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata TRUE #> 3 New York 2 nyc2 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata TRUE #> 4 Amsterdam 2 ams2 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata TRUE #> 5 Singapore 1 sgp1 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata TRUE #> 6 London 1 lon1 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata TRUE #> 7 New York 3 nyc3 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata TRUE #> 8 Amsterdam 3 ams3 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata TRUE #> 9 Frankfurt 1 fra1 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata, storage TRUE #> 10 Toronto 1 tor1 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata TRUE #> 11 San Francisco 2 sfo2 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata, storage TRUE #> 12 Bangalore 1 blr1 512mb, 1gb, 2gb, 4gb, 8gb, 16gb, 32gb, 48gb, 64gb private_networking, backups, ipv6, metadata TRUE #> #> $links #> named list() #> #> $meta #> $meta$total #> [1] 12
シンガポールがアジア圏なのでsgp1
を指定すればよさそうです。
/v2/images
イメージも同じ感じでsimplifyVector = TRUE
を指定します。
res <- GET("https://api.digitalocean.com/v2/images", add_headers(`Authorization` = sprintf("Bearer %s", token)), query = list(type = "distribution")) x <- content(res, simplifyVector = TRUE) # FreeBSDのイメージに絞り込み dplyr::filter(x$images, distribution == "FreeBSD") #> id name distribution slug public regions #> 1 10144573 10.1 FreeBSD freebsd-10-1-x64 TRUE nyc1, ams1, sfo1, nyc2, ams2, sgp1, lon1, nyc3, ams3, fra1, tor1, sfo2, blr1 #> 2 18818640 10.3 zfs FreeBSD freebsd-10-3-x64-zfs TRUE nyc1, sfo1, nyc2, ams2, sgp1, lon1, nyc3, ams3, fra1, tor1, sfo2, blr1 #> 3 18848244 10.2 FreeBSD freebsd-10-2-x64 TRUE nyc1, sfo1, nyc2, ams2, sgp1, lon1, nyc3, ams3, fra1, tor1, sfo2, blr1 #> 4 19103923 10.3 FreeBSD freebsd-10-3-x64 TRUE nyc1, sfo1, nyc2, ams2, sgp1, lon1, nyc3, ams3, fra1, tor1, sfo2, blr1 #> created_at min_disk_size type size_gigabytes #> 1 2015-01-20T20:04:34Z 20 snapshot 2.44 #> 2 2016-08-02T02:42:12Z 20 snapshot 0.81 #> 3 2016-08-03T19:11:01Z 20 snapshot 1.05 #> 4 2016-08-16T19:11:09Z 20 snapshot 1.05
/v2/account/keys
登録しているSSH鍵の一覧を表示します。dropletをつくるときは、このSSH鍵のid
かfingerprint
を指定するとのことなのでメモっておきます。
res <- GET("https://api.digitalocean.com/v2/account/keys", add_headers(`Authorization` = sprintf("Bearer %s", token))) x <- content(res, simplifyVector = TRUE) x$ssh_keys$id #> [1] 123456 789012
/v2/droplets
リージョン名とイメージ名がわかったところでいよいよdropletsをつくります。I()
を指定している理由が気になる方はメモ:httrでJSON形式のリクエストを送るときのコツ - Technically, technophobic.を読んでください。
res <- POST( "https://api.digitalocean.com/v2/droplets", add_headers(`Authorization` = sprintf("Bearer %s", token)), encode = "json", body = list( name = "r-test-server", region = "sgp1", size = "4gb", image = "freebsd-10-3-x64", ssh_keys = I(123456), # ssh_keysはarrayで指定するのでI()をつける backups = FALSE, ipv6 = FALSE, user_data = NULL, private_networking = NULL, volumes = NULL ) ) res #> Response [https://api.digitalocean.com/v2/droplets] #> Date: 2016-09-03 02:26 #> Status: 202 #> Content-Type: application/json; charset=utf-8 #> Size: 1.16 kB
できました。res
の中身にはできたdropletの詳細が入っています。
同じURLにGETリクエストを送ると、dropletsの一覧を取得することができます。先ほど指定した名前のdropletができていることがわかります。
res <- GET("https://api.digitalocean.com/v2/droplets", add_headers(`Authorization` = sprintf("Bearer %s", token))) content(res, simplifyVector = TRUE, simplifyDataFrame = FALSE) #> $droplets #> $droplets[[1]] #> $droplets[[1]]$id #> [1] 12345678 #> #> $droplets[[1]]$name #> [1] "r-test-server" #> #> $droplets[[1]]$memory #> [1] 4096 #> #> $droplets[[1]]$vcpus #> [1] 2 #> #> $droplets[[1]]$disk #> [1] 60 #> #> $droplets[[1]]$locked #> [1] FALSE #> #> $droplets[[1]]$status #> [1] "active" #> #> $droplets[[1]]$kernel #> NULL #> #> $droplets[[1]]$created_at #> [1] "2016-09-03T02:26:04Z" #> ...
試しに作っただけのやつなので、消します。dropletの削除には、先ほどのURLの最後にdropletのIDをつけます。
DELETE(sprintf("https://api.digitalocean.com/v2/droplets/%d", 12345678), add_headers(`Authorization` = sprintf("Bearer %s", token))) #> Response [https://api.digitalocean.com/v2/droplets/24586153] #> Date: 2016-09-03 02:36 #> Status: 204 #> Content-Type: <unknown> #> <EMPTY BODY>
あっさり消えました。
まとめ
これでカッとなってRからサーバを立てたいときとかも安心ですね。