ace-client 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rspec", "~> 2.8.0"
10
+ gem "rdoc", "~> 3.12"
11
+ gem "bundler", "~> 1.0"
12
+ gem "jeweler", "~> 1.8.7"
13
+ gem "rcov", ">= 0"
14
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 tily
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,106 @@
1
+ # ACE (Amazon Compatible Environment) Client
2
+
3
+ ## Synopsis
4
+
5
+ Simple ACE (Amazon Compatible Environment) client for debugging and testing.
6
+ On ACE, see [Transcend Computing | Amazon Compatible Environment](http://www.transcendcomputing.com/features/amazon-compatible-environment/).
7
+
8
+ ## Background
9
+
10
+ On the view of API testing, AWS SDK is too complicated and not easy to fall back to lower levels like creating signature and sending requests.
11
+ Also, it validates parameters on the client side, and we can not test server-side validation.
12
+ ace-client solves this problem, and provide simple interface to test ACE environments.
13
+
14
+ ## Features
15
+
16
+ * no client-side validation
17
+ * no dynamic API exception (both success and error response is returned as raw response)
18
+
19
+ ## Usage
20
+
21
+ ### Good Old Query + Sig2 Client
22
+
23
+ RDS:
24
+
25
+ require 'ace-client'
26
+
27
+ rds = AceClient::Query2.new(
28
+ :endpoint => 'rds.ap-northeast-1.amazonaws.com',
29
+ :access_key_id => ENV['AWS_ACCESS_KEY_ID'],
30
+ :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
31
+ )
32
+ res = rds.action('DescribeDBEngineVersions', 'MaxRecords' => '20')
33
+ p res['DescribeDBEngineVersionsResponse']['DescribeDBEngineVersionsResult']['DBEngineVersions']['DBEngineVersion'].first
34
+ # => {"DBParameterGroupFamily"=>"mysql5.1", "Engine"=>"mysql", "DBEngineDescription"=>"MySQL Community Edition", "EngineVersion"=>"5.1.50", "DBEngineVersionDescription"=>"MySQL 5.1.50"}
35
+
36
+ SQS:
37
+
38
+ require 'ace-client'
39
+
40
+ sqs = AceClient::Query2.new(
41
+ :endpoint => 'sqs.ap-northeast-1.amazonaws.com',
42
+ :version => '2012-11-05',
43
+ :access_key_id => ENV['AWS_ACCESS_KEY_ID'],
44
+ :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
45
+ )
46
+ p sqs.action('CreateQueue', 'QueueName' => 'queue001')
47
+ # => #<HTTParty::Response:0x163e5308 parsed_response={"CreateQueueResponse"=>{"CreateQueueResult"=>{"QueueUrl"=>"https://sqs.ap-northeast-1.amazonaws.com/370162190418/queue001"}, "ResponseMetadata"=>{"RequestId"=>"66640219-a36d-54d8-8c56-491a1f19fa2c"}}}, @response=#<Net::HTTPOK 200 OK readbody=true>, @headers={"server"=>["Server"], "date"=>["Mon, 18 Nov 2013 06:56:52 GMT"], "content-type"=>["text/xml"], "content-length"=>["333"], "connection"=>["close"], "x-amzn-requestid"=>["66640219-a36d-54d8-8c56-491a1f19fa2c"]}>
48
+
49
+ ### Query + Sig4 Client
50
+
51
+ (coming soon)
52
+
53
+ ### JSON + Sig4 Client
54
+
55
+ (coming soon)
56
+
57
+ ### Setting HTTP Proxy
58
+
59
+ Construct your client with :http_proxy option (Proxy user and password is not currently supported.)
60
+
61
+ sqs = AceClient::Query2.new(
62
+ :endpoint => 'sqs.ap-northeast-1.amazonaws.com',
63
+ :access_key_id => ENV['AWS_ACCESS_KEY_ID'],
64
+ :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'],
65
+ :http_proxy => 'http://example.com:8080'
66
+ )
67
+ p rdb.action('ListQueues')
68
+
69
+ ### GET/POST Support
70
+
71
+ you can specify your http method with :http_method option (Default is :post).
72
+
73
+ sqs = AceClient::Query2.new(
74
+ :http_method => :get,
75
+ :endpoint => 'sqs.ap-northeast-1.amazonaws.com',
76
+ :access_key_id => ENV['AWS_ACCESS_KEY_ID'],
77
+ :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'],
78
+ :http_proxy => 'http://example.com:8080'
79
+ )
80
+ p sqs.action('ListQueues')
81
+
82
+ ### Getting Last Response Info
83
+
84
+ sqs = AceClient::Query2.new(
85
+ :endpoint => 'sqs.ap-northeast-1.amazonaws.com',
86
+ :access_key_id => ENV['AWS_ACCESS_KEY_ID'],
87
+ :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
88
+ )
89
+ p sqs.action('ListQueues')
90
+ p sqs.last_response # currently HTTParty::Response object
91
+ p sqs.last_response_time # returned in seconds (Float object)
92
+
93
+ ## TODO
94
+
95
+ * user agent support
96
+ * query + sig4 support
97
+ * json + sig4 support
98
+ * dry run mode (for genarating signatures)
99
+ * logging
100
+ * human readable 'Sample Request & Response' format
101
+ * masking access_key_id and signature
102
+ * handle redirects
103
+ * socket/connection timeout configuration
104
+ * rewrite query and header before/after genrating signature (maybe hook-like interface)
105
+
106
+ ## Copyright
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "ace-client"
18
+ gem.homepage = "http://github.com/tily/ace-client"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Simple ACE(Amazon Compatible Environment) Client}
21
+ gem.description = %Q{Simple ACE(Amazon Compatible Environment) Client}
22
+ gem.email = "tily05@gmail.com"
23
+ gem.authors = ["tily"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rdoc/task'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "ace-client #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,7 @@
1
+ require 'ace-client/base'
2
+ require 'ace-client/query2'
3
+ require 'ace-client/query4'
4
+
5
+ module AceClient
6
+ VERSION = File.read(File.dirname(__FILE__) + '/../VERSION').chomp
7
+ end
@@ -0,0 +1,42 @@
1
+ require 'httparty'
2
+ require 'uri'
3
+
4
+ module AceClient
5
+ class Base
6
+ include HTTParty
7
+
8
+ attr_accessor :access_key_id
9
+ attr_accessor :secret_access_key
10
+ attr_accessor :endpoint
11
+ attr_accessor :http_proxy
12
+ attr_accessor :http_method
13
+ attr_accessor :use_ssl
14
+ attr_accessor :last_response_time
15
+
16
+ def initialize(options)
17
+ @access_key_id = options[:access_key_id]
18
+ @secret_access_key = options[:secret_access_key]
19
+ @endpoint = options[:endpoint]
20
+ @http_proxy = options[:http_proxy]
21
+ @http_method = options[:http_method] || :post
22
+ @use_ssl = options[:use_ssl] || true
23
+ @version = options[:version]
24
+ @path = options[:path] || '/'
25
+ set_http_proxy
26
+ end
27
+
28
+ def set_http_proxy
29
+ if @http_proxy
30
+ uri = URI.parse(@http_proxy)
31
+ self.class.http_proxy(uri.scheme + '://' + uri.host, uri.port)
32
+ end
33
+ end
34
+
35
+ def record_response
36
+ start_time = Time.now
37
+ @last_response = yield
38
+ @last_response_time = Time.now - start_time
39
+ @last_response
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,65 @@
1
+ require 'openssl'
2
+ require 'cgi'
3
+
4
+ module AceClient
5
+ class Query2 < Base
6
+ attr_accessor :http_method
7
+ attr_accessor :signature_method # TODO: HMAC-SHA256 or HMAC-SHA1
8
+
9
+ format :xml
10
+ #debug_output $stderr
11
+
12
+ def initialize(options={})
13
+ super(options)
14
+ @signature_method = options[:signature_method] || 'HmacSHA256'
15
+ end
16
+
17
+ def action(action, params={})
18
+ params.update('Action' => action)
19
+ execute(params)
20
+ end
21
+
22
+ def execute(params={})
23
+ @params = params
24
+ @params.update(
25
+ 'SignatureVersion' => '2',
26
+ 'SignatureMethod' => @signature_method,
27
+ 'AWSAccessKeyId' => @access_key_id,
28
+ 'Timestamp' => Time.now.getutc.iso8601.sub(/Z/, sprintf(".%03dZ",(Time.now.getutc.usec/1000)))
29
+ )
30
+ @params['Version'] = @version if @version
31
+ @params['Signature'] = create_signature
32
+
33
+ response = record_response do
34
+ response = self.class.send(
35
+ http_method,
36
+ endpoint_url,
37
+ :headers => {'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8', 'User-Agent' => 'ace-client v0.0.1'},
38
+ :query => @params
39
+ )
40
+ end
41
+ response
42
+ end
43
+
44
+ def endpoint_url
45
+ protocol = use_ssl ? 'https' : 'http'
46
+ protocol + '://' + endpoint
47
+ end
48
+
49
+ def create_signature
50
+ digest = OpenSSL::Digest::Digest.new(@signature_method.downcase.gsub(/hmac/, ''))
51
+ Base64.encode64(OpenSSL::HMAC.digest(digest, secret_access_key, string_to_sign)).strip
52
+ end
53
+
54
+ def string_to_sign
55
+ p [@http_method.to_s.upcase, @endpoint, @path, canonical_query_string].join("\n")
56
+ [@http_method.to_s.upcase, @endpoint, @path, canonical_query_string].join("\n")
57
+ end
58
+
59
+ def canonical_query_string
60
+ @params.sort.collect { |param|
61
+ "#{CGI::escape(param[0])}=#{CGI::escape(param[1])}"
62
+ }.join("&").gsub('+', '%20').gsub('%7E', '~')
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,5 @@
1
+ module AceClient
2
+ class Query4 < Base
3
+ # not implemented yet
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "AceClient" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'ace-client'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ace-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - tily
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-11-18 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &57501080 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.8.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *57501080
25
+ - !ruby/object:Gem::Dependency
26
+ name: rdoc
27
+ requirement: &57500260 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '3.12'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *57500260
36
+ - !ruby/object:Gem::Dependency
37
+ name: bundler
38
+ requirement: &57499240 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '1.0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *57499240
47
+ - !ruby/object:Gem::Dependency
48
+ name: jeweler
49
+ requirement: &57495300 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.8.7
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *57495300
58
+ - !ruby/object:Gem::Dependency
59
+ name: rcov
60
+ requirement: &57493560 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *57493560
69
+ description: Simple ACE(Amazon Compatible Environment) Client
70
+ email: tily05@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files:
74
+ - LICENSE.txt
75
+ - README.md
76
+ files:
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - VERSION
82
+ - lib/ace-client.rb
83
+ - lib/ace-client/base.rb
84
+ - lib/ace-client/query2.rb
85
+ - lib/ace-client/query4.rb
86
+ - spec/ace-client_spec.rb
87
+ - spec/spec_helper.rb
88
+ homepage: http://github.com/tily/ace-client
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ segments:
102
+ - 0
103
+ hash: 4298272965098336729
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 1.8.13
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: Simple ACE(Amazon Compatible Environment) Client
116
+ test_files: []