ぶていのログでぶログ

思い出したが吉日

RubyでOpenStack APIを扱うYaoとyao-yrbの紹介

この記事はペパボアドベントカレンダー2019の1日目の記事です。 今年も残り1ヶ月。早いものです。


ペパボでは、OpenStackを使ってプライベートクラウドを構築しています。 OpenStackを運用するうえで、APIを利用して情報を取得したり、インスタンスを作成したり、削除したりしています。 ・・・まぁ対応したAPIがない場合は、DBを直接修正するのですがそれはまた別の機会に。

OpenStack APIへのアクセスにはいろいろな方法があり、OpenStackプロジェクトが出しているopenstackclientを利用するのが一番簡単です。 openstackclientはCLIで提供されているので、シェルスクリプトを駆使すればざまざまなことを自動化することはできるのですが、複雑なことをしようとするととても煩雑になります。 openstackclientが内部的に利用している、各OpenStackプロジェクトのライブラリを利用すればPythonで記述することができるのですが、ペパボにはRubyistが多く在籍している会社ですし、RubyでもOpenStack APIを利用したい! そんなこんなで、絶賛開発中&利用中のRuby向けOpenStack APIライブラリの Yao を紹介したいと思います。

github.com

fog-openstackclient

RubyでOpenStack APIというか各クラウドのAPIを利用するためのライブラリとしてはfogが有名だと思います。 fogにもOpenStack APIを利用するためのプラグインが存在します。

github.com

実はペパボでも昔はfogを使っていたのですが、当時のfogは依存関係がかなり多く例えばOpenStack APIとは関係ない部分の依存が壊れて利用できなくなるみたいなことがありました*1. そこで、OpenStack APIに絞ったライブラリがほしいということでできたのがYaoだったりします。

Yaoの使い方

実際にYaoの使い方を紹介します。 まずはともあれYaoをインストールしましょう。

$ gem install yao

require "yao" したあとは、 Yao.configure で各パラメータを初期化します。 初期化に利用する環境変数はopenstackclientに倣って OS_** にしておくと便利だと思います。

require "yao"

Yao.configure do
  auth_url             ENV['OS_AUTH_URL']
  tenant_name          ENV['OS_TENANT_NAME']
  username             ENV['OS_USERNAME']
  password             ENV['OS_PASSWORD']
  region_name          ENV['OS_REGION_NAME']
  identity_api_version ENV['OS_IDENTITY_API_VERSION']
  user_domain_name     ENV['OS_USER_DOMAIN_NAME']
  project_domain_name  ENV['OS_PROJECT_DOMAIN_NAME']

  # クライアント証明書を利用する場合には設定する
  client_cert          ENV['OS_CERT']
  client_key           ENV['OS_KEY']
end

初期化が終わったら、あとは利用したいリソースのクラスメソッドを呼び出すだけです。 例えば、サーバ一覧を取得したい場合は以下のようにします。

Yao::Server.list #=> Array<Yao::Server>

メソッドとOpenStack APIとの関連性

Yao::Server.list は実際にはどのOpenStack APIを呼んでいるのでしょうか? 答えは Compute APIのList Servers Detailedです*2。 YaoはOpenStak APIのエンドポイントにリクエストを投げて、帰ってきたJSONレスポンスをRubyオブジェクトに変換しています。 例えば、このAPIのレスポンスには name という属性が含まれていて、ここにはサーバの名前が含まれています。

Yao::Server.list.first.name #=> サーバの名前

OpenStack APIでは、リクエスト時にパラメータでフィルタをかけたりすることができます。 先のList Servers Detailedリクエストであれば、例えば、all_tenants というパラメータが存在します。 このパラメータがtrueの場合でかつadmin権限を持つアカウントであれば、すべてのインスタンスを取得することができます*3all_tenants=true をつけてリクエストするには以下のようにします。

Yao::Server.list(all_tenants:true)

CRUD

OpenStack APIでは各エントリポイントにPOST/GET/PUT/DELETEメソッドを送ることでCRUD操作ができます。 Yaoでもそれぞれに対応したメソッドが生えています。

  • create
  • get(list)
  • update
  • destroy
# サーバを立てる
server_params = {
 # パラメータを設定
}
server = Yao::Server.create(server_params)

# サーバ情報を取得
Yao::Server.get(server.id)

# サーバ情報を更新
server_new_params = {
   # 更新したいパラメータを設定
}
Yao::Server.update(server.id, server_new_params)

# サーバの削除
Yao::Server.destroy(server.id)

Yaoで扱えるリソースの一覧

上記ではサーバの一覧でしたが、他にも扱えるリソースは多くあります。 各リソースとOpenStack APIとの関連付けは以下の通りです。

  • Compute API
    • Yao::Aggregates
    • Yao::ComputeServices
    • Yao::Flavor
    • Yao::Host
    • Yao::Hypervisor
    • Yao::Keypair
    • Yao::Server
  • Networking API
    • Yao::FloatingIP
    • Yao::Network
    • Yao::NetworkingAgents
    • Yao::Port
    • Yao::Router
    • Yao::SecurityGroup
    • Yao::SecurityGroupRule
    • Yao::Subnet
  • Identity API v3
    • Yao::Project
    • Yao::Role
    • Yao::RoleAssignment
    • Yao::User
  • Identity API v2.0
    • Yao::Tenant
  • Image Service API
    • Yao::Image
  • Block Storage API
    • Yao::Volume
    • Yao::VolumeType
  • Octavia (LoadBalancer) API
    • Yao::LoadBalancer
    • Yao::LoadBalancerHealthMonitor
    • Yao::LoadBalancerListener
    • Yao::LoadBalancerPool
    • Yao::LoadBalancerPoolMember
  • Metering API
    • meter.rb
    • old_sample.rb
    • resource.rb
    • sample.rb

Yaoを簡単に試せるyao-yrb

ここまでYaoについて紹介しました。 実際にYaoを使おうと思ったとしても簡単ではあるもののコードを書かないと行けなかったり、またどういうレスポンスが実際に返ってくるのかを試したいことがあります。 そこで、yao-yrbというツールを作ったのであわせて紹介します。

rubygems.org

このツールはYaoの初期化処理を行ったあとpry*4を起動します インタープリタ形式なので1行実行したあとに何が返ってくるか確認しながらコードを書くことができます。 以下は実際に実行した画面です。

f:id:buty4649:20191201190315p:plain
yao-yrbの実行画面

また、yao-yrbにはスクリプト実行機能もあるので、openstackclientとシェルスクリプトを使って行っていた複雑な処理をRubyで書くことができます。

$ cat server_count.yrb 
#!/usr/bin/env yrb
# vim: ft=ruby

puts Yao::Server.list.count

$ chmod +x server_count.yrb 
$ ./server_count.yrb 
133

おわり

以上が、Yaoとyao-yrbの紹介となります。 Yaoを使うことで、Rubyで簡単にOpenStack APIにアクセスできます。 また、yao-yrbを使うことでより便利にYaoを使うことができるのでせひ使っていただければと思います。 Yaoはまだまだ開発中のライブラリなので、足りない機能がぜひPullRequestを投げていただければと思います。

*1:現在は、各クラウドごとに別れているようなので改善されたのかな。試していないのでわからないです。

*2:少し前まではList Servers(/servers)だったのですが、List Serer Detailedのほうが情報量が多いこともありYaoでは置き換えられました https://github.com/yaocloud/yao/pull/127

*3:Compute API側の制限で一回に取得できる上限は1000

*4:ちなみに、最初はirbでした。yao + irbでyrbだったのであった・・・