Merge remote-tracking branch 'upstream/develop' into development

This commit is contained in:
Alfonso Juan Dillera
2013-09-03 11:37:16 +08:00
14 changed files with 503 additions and 579 deletions

View File

@@ -3,7 +3,6 @@ require 'active_support/inflector'
require 'faraday' require 'faraday'
require "aviator/version" require "aviator/version"
require "aviator/core/dsl"
require "aviator/core/request" require "aviator/core/request"
require "aviator/core/response" require "aviator/core/response"
require "aviator/core/service" require "aviator/core/service"

View File

@@ -1,37 +0,0 @@
module Aviator
class << self
def define_request(request_name, &block)
class_obj = Class.new(Request, &block)
build_or_get_request_class(
Aviator,
class_obj,
class_obj.provider,
class_obj.service,
class_obj.api_version,
class_obj.endpoint_type,
request_name
)
end
private
def build_or_get_request_class(base, obj, *hierarchy)
const_name = hierarchy.shift.to_s.camelize
const = if base.const_defined?(const_name)
base.const_get(const_name)
else
base.const_set(const_name, (hierarchy.empty? ? obj : Module.new))
end
hierarchy.empty? ? const : build_or_get_request_class(const, obj, *hierarchy)
end
end # class << self
end # module Aviator

View File

@@ -1,5 +1,40 @@
module Aviator module Aviator
class << self
def define_request(request_name, &block)
class_obj = Class.new(Request, &block)
set_class_name(
Aviator,
class_obj,
class_obj.provider,
class_obj.service,
class_obj.api_version,
class_obj.endpoint_type,
request_name
)
end
private
def set_class_name(base, obj, *hierarchy)
const_name = hierarchy.shift.to_s.camelize
const = if base.const_defined?(const_name)
base.const_get(const_name)
else
base.const_set(const_name, (hierarchy.empty? ? obj : Module.new))
end
hierarchy.empty? ? const : set_class_name(const, obj, *hierarchy)
end
end # class << self
class Request class Request
class ApiVersionNotDefinedError < StandardError class ApiVersionNotDefinedError < StandardError
@@ -40,31 +75,16 @@ module Aviator
end end
def api_version
self.class.api_version
end
def body? def body?
self.class.body? self.class.body?
end end
def endpoint_type
self.class.endpoint_type
end
def headers? def headers?
self.class.headers? self.class.headers?
end end
def http_method
self.class.http_method
end
def links def links
self.class.links self.class.links
end end
@@ -80,11 +100,6 @@ module Aviator
end end
def querystring?
self.class.querystring?
end
def required_params def required_params
self.class.required_params self.class.required_params
end end
@@ -100,6 +115,11 @@ module Aviator
end end
def querystring?
self.class.querystring?
end
def url? def url?
self.class.url? self.class.url?
end end
@@ -123,22 +143,8 @@ module Aviator
# within the class and because they don't change between instances anyway. # within the class and because they don't change between instances anyway.
class << self class << self
def anonymous
@anonymous = true
end
def anonymous? def anonymous?
@anonymous == true respond_to?(:anonymous) && anonymous == true
end
def api_version(value=nil)
if value
@api_version = value
else
@api_version
end
end end
@@ -147,34 +153,11 @@ module Aviator
end end
def endpoint_type(value=nil)
if value
@endpoint_type = value
else
@endpoint_type
end
end
def headers? def headers?
instance_methods.include? :headers instance_methods.include? :headers
end end
def http_method(value=nil)
if value
@http_method = value
else
@http_method
end
end
def link_to(rel, href)
links << { rel: rel, href: href }
end
def links def links
@links ||= [] @links ||= []
end end
@@ -191,15 +174,6 @@ module Aviator
end end
def provider(value=nil)
if value
@provider = value
else
@provider
end
end
def optional_params def optional_params
@optional_params ||= [] @optional_params ||= []
end end
@@ -215,15 +189,6 @@ module Aviator
end end
def service(value=nil)
if value
@service = value
else
@service
end
end
def url? def url?
instance_methods.include? :url instance_methods.include? :url
end end
@@ -231,13 +196,27 @@ module Aviator
private private
def required_param(param_name)
required_params << param_name unless required_params.include?(param_name) def link(rel, href)
links << { rel: rel, href: href }
end end
def optional_param(param_name) def meta(attr_name, attr_value)
optional_params << param_name unless optional_params.include?(param_name) define_singleton_method(attr_name) do
attr_value
end
define_method(attr_name) do
self.class.send(attr_name)
end
end
def param(param_name, opts={})
opts = opts.with_indifferent_access
list = (opts[:required] == false ? optional_params : required_params)
list << param_name unless optional_params.include?(param_name)
end end
end end

View File

@@ -1,25 +1,38 @@
Aviator.define_request :list_images do Aviator.define_request :list_images do
provider :openstack meta :provider, :openstack
service :compute meta :service, :compute
api_version :v2 meta :api_version, :v2
endpoint_type :public meta :endpoint_type, :public
http_method :get link 'documentation',
link_to 'documentation',
'http://docs.openstack.org/api/openstack-compute/2/content/List_Images-d1e4435.html' 'http://docs.openstack.org/api/openstack-compute/2/content/List_Images-d1e4435.html'
optional_param :details param :details, required: false
optional_param :server param :server, required: false
optional_param :name param :name, required: false
optional_param :status param :status, required: false
optional_param 'changes-since' param 'changes-since', required: false
optional_param :marker param :marker, required: false
optional_param :limit param :limit, required: false
optional_param :type param :type, required: false
def headers
h = {}
unless self.anonymous?
h['X-Auth-Token'] = session_data[:access][:token][:id]
end
h
end
def http_method
:get
end
def url def url
service_spec = session_data[:access][:serviceCatalog].find{|s| s[:type] == 'compute' } service_spec = session_data[:access][:serviceCatalog].find{|s| s[:type] == 'compute' }
@@ -38,15 +51,4 @@ Aviator.define_request :list_images do
str str
end end
def headers
h = {}
unless self.anonymous?
h['X-Auth-Token'] = session_data[:access][:token][:id]
end
h
end
end end

View File

@@ -1,23 +1,29 @@
Aviator.define_request :create_tenant do module Aviator
provider :openstack define_request :create_tenant do
service :identity
api_version :v2
endpoint_type :admin
http_method :post meta :provider, :openstack
meta :service, :identity
meta :api_version, :v2
meta :endpoint_type, :admin
link_to 'documentation', link 'documentation',
'http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_addTenant_v2.0_tenants_.html' 'http://docs.openstack.org/api/openstack-identity-service/2.0/content/'
required_param :name
required_param :description
required_param :enabled
def url param :name, required: true
service_spec = session_data[:access][:serviceCatalog].find{|s| s[:type] == 'identity' } param :description, required: true
"#{ service_spec[:endpoints][0][:adminURL] }/tenants" param :enabled, required: true
def body
{
tenant: {
name: params[:name],
description: params[:description],
enabled: params[:enabled]
}
}
end end
@@ -32,14 +38,16 @@ Aviator.define_request :create_tenant do
end end
def body def http_method
{ :post
tenant: { end
name: params[:name],
description: params[:description],
enabled: params[:enabled] def url
} service_spec = session_data[:access][:serviceCatalog].find{|s| s[:type] == 'identity' }
} "#{ service_spec[:endpoints][0][:adminURL] }/tenants"
end
end end
end end

View File

@@ -1,20 +1,37 @@
Aviator.define_request :list_tenants do module Aviator
provider :openstack define_request :list_tenants do
service :identity
api_version :v2
endpoint_type :admin
http_method :get meta :provider, :openstack
meta :service, :identity
meta :api_version, :v2
meta :endpoint_type, :admin
link_to 'documentation', link 'documentation',
'http://docs.openstack.org/api/openstack-identity-service/2.0/content/GET_listTenants_v2.0_tenants_Tenant_Operations.html' 'http://docs.openstack.org/api/openstack-identity-service/2.0/content/GET_listTenants_v2.0_tenants_Tenant_Operations.html'
link_to 'documentation bug', link 'documentation bug',
'https://bugs.launchpad.net/keystone/+bug/1218601' 'https://bugs.launchpad.net/keystone/+bug/1218601'
optional_param :marker
optional_param :limit param :marker, required: false
param :limit, required: false
def headers
h = {}
unless self.anonymous?
h['X-Auth-Token'] = session_data[:access][:token][:id]
end
h
end
def http_method
:get
end
def url def url
@@ -32,15 +49,6 @@ Aviator.define_request :list_tenants do
str str
end end
def headers
h = {}
unless self.anonymous?
h['X-Auth-Token'] = session_data[:access][:token][:id]
end
h
end end
end end

View File

@@ -1,38 +1,25 @@
Aviator.define_request :create_token do module Aviator
anonymous define_request :create_token do
provider :openstack meta :anonymous, true
service :identity meta :provider, :openstack
api_version :v2 meta :service, :identity
endpoint_type :public meta :api_version, :v2
meta :endpoint_type, :public
http_method :post link 'documentation',
link_to 'documentation',
'http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_.html' 'http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_.html'
link_to 'documentation bug', link 'documentation bug',
'https://bugs.launchpad.net/keystone/+bug/1208607' 'https://bugs.launchpad.net/keystone/+bug/1208607'
optional_param :username param :username, required: false
optional_param :password param :password, required: false
optional_param :tokenId param :tokenId, required: false
param :tenantName, required: false
optional_param :tenantName param :tenantId, required: false
optional_param :tenantId
# TODO: Add logic for when session_data is actually an OpenStack
# authentication response body and not auth bootstrap information
def url
url = session_data[:auth_service][:host_uri]
url += '/v2.0' if (URI(url).path =~ /^\/?\w+/).nil?
url += "/tokens"
url
end
def body def body
@@ -61,4 +48,20 @@ Aviator.define_request :create_token do
p p
end end
def http_method
:post
end
def url
url = session_data[:auth_service][:host_uri]
url += '/v2.0' if (URI(url).path =~ /^\/?\w+/).nil?
url += "/tokens"
url
end
end
end end

View File

@@ -1,21 +1,21 @@
Aviator.define_request :list_tenants do module Aviator
provider :openstack define_request :list_tenants do
service :identity
api_version :v2
endpoint_type :public
http_method :get meta :provider, :openstack
meta :service, :identity
meta :api_version, :v2
meta :endpoint_type, :public
link_to 'documentation', link 'documentation',
'http://docs.openstack.org/api/openstack-identity-service/2.0/content/GET_listTenants_v2.0_tokens_tenants_.html' 'http://docs.openstack.org/api/openstack-identity-service/2.0/content/GET_listTenants_v2.0_tokens_tenants_.html'
link_to 'documentation bug', link 'documentation bug',
'https://bugs.launchpad.net/keystone/+bug/1218601' 'https://bugs.launchpad.net/keystone/+bug/1218601'
optional_param :marker param :marker, required: false
optional_param :limit param :limit, required: false
def url def url
@@ -44,4 +44,11 @@ Aviator.define_request :list_tenants do
h h
end end
def http_method
:get
end
end
end end

83
test.rb
View File

@@ -1,83 +0,0 @@
require 'pry'
require 'active_support/inflector'
module Aviator
class << self
def define_request(request_name, &block)
class_obj = Class.new(Object, &block)
build_or_get_request_class(
Aviator,
class_obj,
class_obj.provider,
class_obj.service,
class_obj.api_version,
class_obj.endpoint_type,
request_name
)
end
private
def build_or_get_request_class(base, obj, *hierarchy)
const_name = hierarchy.shift.to_s.classify
const = if base.const_defined?(const_name)
base.const_get(const_name)
else
base.const_set(const_name, (hierarchy.empty? ? obj : Module.new))
end
hierarchy.empty? ? const : build_or_get_request_class(const, obj, *hierarchy)
end
end # class << self
end # module Aviator
test1 = Aviator.define_request :test1 do
def self.provider
:openstack
end
def self.service
:identity
end
def self.api_version
:v2
end
def self.endpoint_type
:admin
end
end
test2 = Aviator.define_request :test2 do
def self.provider
:openstack
end
def self.service
:identity
end
def self.api_version
:v3
end
def self.endpoint_type
:admin
end
end
binding.pry

View File

@@ -8,13 +8,13 @@ class Aviator::Test
it 'raises an error when a required param is not provided' do it 'raises an error when a required param is not provided' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
required_param :someparamname param :someparamname, required: true
end end
initializer = lambda { klass.new } the_method = lambda { klass.new }
initializer.must_raise ArgumentError the_method.must_raise ArgumentError
error = initializer.call rescue $! error = the_method.call rescue $!
error.message.wont_be_nil error.message.wont_be_nil
error.message.must_include "someparamname" error.message.must_include "someparamname"
@@ -23,11 +23,9 @@ class Aviator::Test
it 'does not raise any error when the required param is provided' do it 'does not raise any error when the required param is provided' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
required_param :someparamname param :someparamname, required: true
end end
# obj = klass.new({ someparamname: 'someparamvalue' })
obj = klass.new do |params| obj = klass.new do |params|
params.someparamname = 'something' params.someparamname = 'something'
end end
@@ -47,7 +45,7 @@ class Aviator::Test
it 'returns true if specified as such' do it 'returns true if specified as such' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
anonymous meta :anonymous, true
end end
klass.anonymous?.must_equal true klass.anonymous?.must_equal true
@@ -67,7 +65,7 @@ class Aviator::Test
it 'returns true if specified as such' do it 'returns true if specified as such' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
anonymous meta :anonymous, true
end end
klass.new.anonymous?.must_equal true klass.new.anonymous?.must_equal true
@@ -80,7 +78,7 @@ class Aviator::Test
it 'returns the api version' do it 'returns the api version' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
api_version :v2 meta :api_version, :v2
end end
klass.api_version.must_equal :v2 klass.api_version.must_equal :v2
@@ -93,7 +91,7 @@ class Aviator::Test
it 'returns the api version' do it 'returns the api version' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
api_version :v2 meta :api_version, :v2
end end
klass.new.api_version.must_equal :v2 klass.new.api_version.must_equal :v2
@@ -146,7 +144,7 @@ class Aviator::Test
it 'returns the endpoint type' do it 'returns the endpoint type' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
endpoint_type :public meta :endpoint_type, :public
end end
klass.endpoint_type.must_equal :public klass.endpoint_type.must_equal :public
@@ -159,23 +157,10 @@ class Aviator::Test
it 'returns the endpoint type' do it 'returns the endpoint type' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
endpoint_type :public meta :endpoint_type, :whatever
end end
klass.new.endpoint_type.must_equal :public klass.new.endpoint_type.must_equal :whatever
end
end
describe '::http_method' do
it 'returns the http method if it is defined' do
klass = Class.new(Aviator::Request) do
http_method :post
end
klass.http_method.must_equal :post
end end
end end
@@ -185,7 +170,7 @@ class Aviator::Test
it 'returns the http method if it is defined' do it 'returns the http method if it is defined' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
http_method :post def http_method; :post; end
end end
klass.new.http_method.must_equal :post klass.new.http_method.must_equal :post
@@ -194,14 +179,14 @@ class Aviator::Test
end end
describe '::link_to' do describe '::link' do
it 'adds a link to Request::links' do it 'adds a link to Request::links' do
rel = 'documentation' rel = 'documentation'
href = 'http://x.y.z' href = 'http://x.y.z'
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
link_to rel, href link rel, href
end end
expected = [ expected = [
@@ -215,10 +200,10 @@ class Aviator::Test
end end
describe '::optional_param' do describe '::param' do
it 'is a private class method' do it 'is a private class method' do
private_method = lambda { Aviator::Request.optional_param } private_method = lambda { Aviator::Request.param }
private_method.must_raise NoMethodError private_method.must_raise NoMethodError
error = private_method.call rescue $! error = private_method.call rescue $!
@@ -234,7 +219,7 @@ class Aviator::Test
it 'returns an array' do it 'returns an array' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
optional_param :whatever param :whatever, required: false
end end
klass.optional_params.must_equal [:whatever] klass.optional_params.must_equal [:whatever]
@@ -247,7 +232,7 @@ class Aviator::Test
it 'returns an array' do it 'returns an array' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
optional_param :whatever param :whatever, required: false
end end
klass.new.optional_params.must_equal [:whatever] klass.new.optional_params.must_equal [:whatever]
@@ -256,26 +241,11 @@ class Aviator::Test
end end
describe '::required_param' do
it 'is a private class method' do
private_method = lambda { Aviator::Request.required_param }
private_method.must_raise NoMethodError
error = private_method.call rescue $!
error.message.wont_be_nil
error.message.must_include "private method"
end
end
describe '::required_params' do describe '::required_params' do
it 'returns an array' do it 'returns an array' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
required_param :whatever param :whatever, required: true
end end
klass.required_params.must_equal [:whatever] klass.required_params.must_equal [:whatever]
@@ -288,10 +258,15 @@ class Aviator::Test
it 'returns an array' do it 'returns an array' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
required_param :whatever param :whatever, required: true
end end
klass.required_params.must_equal [:whatever] request = klass.new do |params|
params[:whatever] = 'something'
end
request.required_params.must_equal [:whatever]
end end
end end
@@ -299,14 +274,14 @@ class Aviator::Test
describe '::url?' do describe '::url?' do
it 'returns false if the path method is not defined' do it 'returns false if the url method is not defined' do
klass = Class.new(Aviator::Request) klass = Class.new(Aviator::Request)
klass.url?.must_equal false klass.url?.must_equal false
end end
it 'returns true if the path method is defined' do it 'returns true if the url method is defined' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
def url; end def url; end
end end
@@ -317,16 +292,16 @@ class Aviator::Test
end end
describe '#path?' do describe '#url?' do
it 'returns false if the path method is not defined' do it 'returns false if the url method is not defined' do
klass = Class.new(Aviator::Request) klass = Class.new(Aviator::Request)
klass.new.url?.must_equal false klass.new.url?.must_equal false
end end
it 'returns true if the path method is defined' do it 'returns true if the url method is defined' do
klass = Class.new(Aviator::Request) do klass = Class.new(Aviator::Request) do
def url; end def url; end
end end

View File

@@ -69,7 +69,7 @@ class Aviator::Test
validate :http_method do validate :http_method do
klass.http_method.must_equal :get create_request.http_method.must_equal :get
end end

View File

@@ -86,7 +86,7 @@ class Aviator::Test
validate :http_method do validate :http_method do
klass.http_method.must_equal :post create_request.http_method.must_equal :post
end end

View File

@@ -57,7 +57,7 @@ class Aviator::Test
validate :http_method do validate :http_method do
klass.http_method.must_equal :post create_request.http_method.must_equal :post
end end

View File

@@ -0,0 +1,63 @@
---
http_interactions:
- request:
method: post
uri: <HOST_URI>:5000/v2.0/tokens
body:
encoding: UTF-8
string: ! '{"auth":{"passwordCredentials":{"username":"admin","password":"<PASSWORD>"},"tenantName":"admin"}}'
headers:
Content-Type:
- application/json
User-Agent:
- Faraday v0.8.8
response:
status:
code: 200
message:
headers:
vary:
- X-Auth-Token
content-type:
- application/json
content-length:
- '2648'
date:
- Wed, 04 Sep 2013 12:55:30 GMT
connection:
- close
body:
encoding: US-ASCII
string: ! '{"access": {"token": {"issued_at": "2013-09-04T12:55:30.584559",
"expires": "2013-09-05T12:55:30Z", "id": "1cd6ba534d94447f9420b372869447ac",
"tenant": {"description": null, "enabled": true, "id": "3cab25130620477b8b03f1bfa8741603",
"name": "admin"}}, "serviceCatalog": [{"endpoints": [{"adminURL": "http://192.168.56.11:8774/v2/3cab25130620477b8b03f1bfa8741603",
"region": "RegionOne", "internalURL": "http://192.168.56.11:8774/v2/3cab25130620477b8b03f1bfa8741603",
"id": "3b72a66bf2f0491bb8dba827cade0d48", "publicURL": "http://192.168.56.11:8774/v2/3cab25130620477b8b03f1bfa8741603"}],
"endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL":
"http://192.168.56.11:3333", "region": "RegionOne", "internalURL": "http://192.168.56.11:3333",
"id": "482f749b370c40eab8788d6d0bc47f48", "publicURL": "http://192.168.56.11:3333"}],
"endpoints_links": [], "type": "s3", "name": "s3"}, {"endpoints": [{"adminURL":
"http://192.168.56.11:9292", "region": "RegionOne", "internalURL": "http://192.168.56.11:9292",
"id": "0cd5d5d5a0c24721a0392b47c89e3640", "publicURL": "http://192.168.56.11:9292"}],
"endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL":
"http://192.168.56.11:8777", "region": "RegionOne", "internalURL": "http://192.168.56.11:8777",
"id": "4eb4edec1d2647bfb8ba4f9a5757169d", "publicURL": "http://192.168.56.11:8777"}],
"endpoints_links": [], "type": "metering", "name": "ceilometer"}, {"endpoints":
[{"adminURL": "http://192.168.56.11:8776/v1/3cab25130620477b8b03f1bfa8741603",
"region": "RegionOne", "internalURL": "http://192.168.56.11:8776/v1/3cab25130620477b8b03f1bfa8741603",
"id": "009e8a41953d439f845b2a0c0dc28b73", "publicURL": "http://192.168.56.11:8776/v1/3cab25130620477b8b03f1bfa8741603"}],
"endpoints_links": [], "type": "volume", "name": "cinder"}, {"endpoints":
[{"adminURL": "http://192.168.56.11:8773/services/Admin", "region": "RegionOne",
"internalURL": "http://192.168.56.11:8773/services/Cloud", "id": "6820836ec6834548bf7b54da0271dded",
"publicURL": "http://192.168.56.11:8773/services/Cloud"}], "endpoints_links":
[], "type": "ec2", "name": "ec2"}, {"endpoints": [{"adminURL": "http://192.168.56.11:35357/v2.0",
"region": "RegionOne", "internalURL": "http://192.168.56.11:5000/v2.0", "id":
"24a95f51f67949e784971e97463ee4d8", "publicURL": "http://192.168.56.11:5000/v2.0"}],
"endpoints_links": [], "type": "identity", "name": "keystone"}], "user": {"username":
"admin", "roles_links": [], "id": "cbbcc4f7aef6435fa2da7e5f0b2f1e97", "roles":
[{"name": "admin"}], "name": "admin"}, "metadata": {"is_admin": 0, "roles":
["01a81f2dbb3441f1aaa8fe68a7c6f546"]}}}'
http_version:
recorded_at: Mon, 02 Sep 2013 08:56:17 GMT
recorded_with: VCR 2.5.0