とりあえず、Fog::Compute.new あたりをエントリポイントとして掘削開始。
基本的に
@compute = Fog::Compute.new(
:provider => 'CloudStack',
みたいなことすれば Fog::Compute::Cloudstack::Real なオブジェクトが作られる、というざっくり理解を前提にすれば良いのか、それともこのあたりもきっちり掘っとく必要があるのか悩む。
つうか、fog/lib/fog/cloudstack/core.rb に
extend Fog::Provider
という記述を見つけたのですがこれは一体何でしょ。extend って include とはちょっと違う mix-in の方法なのか。とは言え、Fog::Provider なモジュールの定義が見当たらない。
む、以前掘削してたナニを見るに lib/fog/compute.rb を見てるんですが、ここには if な条件分岐は無いですね。以前掘削した以下な記録では
:provider なソレを元に条件分岐してた模様。
つうか最新見てるのが悪いのかもしれませんが、lib/fog/core の中に何も無い。あ、でも lib/fog/cloudstack/compute.rb の定義の先頭らへんが以下になってて
module Fog
module Compute
class Cloudstack < Fog::Service
Fog::Service (これも定義が無い) の属性というかメソドを呼び出してます。
request_path 'fog/cloudstack/requests/compute'
これ使え、ってことなのかどうか。Fog::Service のソースも行方知れず。
とりあえず
@compute = Fog::Compute.new(
:provider => 'CloudStack',
で
class Real
def initialize(options={})
なコンストラクタが呼ばれる、ってことにしておきます。
で、Fog::Compute::Cloudstack には以下なメソド呼び出しがはいってて
request :extract_template
これも Fog::Service なメソドで request な属性の配列に引数を push (で良いのかな) してます。この配列に格納されてるシンボルで API 発行、というあたりを掘っておく必要がある、って思っていたのですがこれはこれでどうにもならない感があります。
む
というか、こないだ追加した extract_template.rb 見てみるに Service の request ってメソドでシンボルを配列に追加しておいて以下を追加してます。
module Fog
module Compute
class Cloudstack
class Real
# Extracts a template.
#
# {CloudStack API Reference}[http://http://download.cloud.com/releases/3.0.0/api_3.0.0/user/extractTemplate.html]
def extract_template(options={})
options.merge!(
'command' => 'extractTemplate'
)
request(options)
end
end # Real
command に API なソレを追加して request を呼んでますね。この中では詳細略で
response = issue_request(params,headers)
これも Service なメソドなのかな。や、fog 固有だった。でもざっくりで以下なカンジ。凄く抽象化されてます。
def issue_request(params={},headers={},method='GET',expects=200)
begin
@connection.request({
:query => params,
:headers => headers,
:method => method,
:expects => expects
})
@connection はコンストラクタで作っている Fog::XML::Connection のインスタンスです。これ、SAXParserConnection のサブクラスなのか。
まとめ
だらだら掘ってても時間が勿体無いので以下に纏めおよび備忘を。
- Fog::Service とかの記述が無いのでありかを探す
- Fog::Compute::Cloudstack は Fog::Service のサブクラス
- 他の Provider な実装も Fog::Service のサブクラスになっているはず
- Fog::Service#request_path で定義されてる i/f の位置を指定して request メソドを使って i/f を登録
- 登録した i/f はファイル名、クラス名、登録した hash は全部同じ名前になってます
- 実際の API の名前 (?) はメソドの中で command に渡す文字列
- ややこしいんですが、各 API な i/f から呼び出される request は Fog::Compute::Cloudstack::Real#request になります
- Cloudstack で通信に使われている道具は SAXParserConnection
テストに関する記述については PR がパスしていないので保留。なんとなく NG な予感がしているのですがリプが付かないのでどうにもならない。