ace-client 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []