しばらくして、リクエストに署名するための署名バージョン4を使用して、awsの予約済みrdsインスタンスを返す必要なすべての機能を備えたクラスを構築することができました。コードは次のとおりです。
#!/usr/local/bin/ruby
require 'rubygems'
require 'net/http'
require 'net/https'
require 'time'
require 'hmac'
require 'hmac-sha2'
require 'base64'
require 'cgi'
class AWSGetSignatureV4
def initialize(aws_key,aws_secretpwd)
@regions=['ap-northeast-1', 'ap-southeast-1', 'eu-west-1', 'us-east-1', 'us-west-1', 'us-west-2', 'sa-east-1']
@rds_list={}
@inst_list={}
@rds_reserves={}
@inst_reserves={}
@aws_key=aws_key
@aws_secret=aws_secretpwd
@canonical_uri="/\n"
@request_type="GET\n"
@request_version='2012-04-23'
@request_headers={
'Host' => ''
}
end
def form_request(requestname, zone)
canonical_request_full(requestname, zone)
form_string_to_sign(zone)
form_signature(requestname, zone)
form_request_url(requestname, zone)
end
def get_data(requestname, zone)
form_request(requestname, zone)
http = Net::HTTP.new(@https_addr, "443")
http.use_ssl = true
headers = { 'Host' => "#{@https_addr}" }
@request_data=""
retval = http.get(@url_to_use, headers) do |chunk|
@request_data+=chunk
end
puts(retval.code)
puts(@request_data)
end
def get_service_type(requestname)
if requestname == 'DescribeReservedDBInstances'
@service_type="rds"
else
raise "No such request type."
end
end
def form_time_values()
@timenowz=Time.now.utc.iso8601
@time_use_now=@timenowz.gsub(/-|:/, '')
@date_to_use=@time_use_now.gsub(/T.*$/,'')
end
def init_param_values(requestname)
@init_params = {
'Action' => requestname,
'Version' => @request_version
}
end
def other_param_values(zone)
@other_params = {
'X-Amz-Algorithm' => 'AWS4-HMAC-SHA256',
'X-Amz-Credential' => @aws_key+"/#{@date_to_use}/#{zone}/#{@service_type}/aws4_request",
'X-Amz-Date' => @time_use_now,
'X-Amz-SignedHeaders' => 'Host'
}
end
def form_canonical_query_string(requestname, zone)
@querystringz = @init_params.sort.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&')+"&"+@other_params.sort.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&')
end
def modify_request_headers(requestname, zone)
@request_headers['Host']="#{@service_type}.#{zone}.amazonaws.com"
end
def form_headers()
@queryheaderz = "host:#{@request_headers['Host']}"
@signed_headerz =@request_headers.sort.collect { |key, value| key.to_s.downcase }.join(';')
@canonical_headerz =@request_headers.sort.collect { |key, value| [CGI.escape(key.to_s.downcase), CGI.escape(value.to_s)].join(':') }.join("\n")
end
def form_payload_data()
@payload=@init_params.sort.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&')
@hex_sign_string=Digest::SHA256.digest("").unpack('H*').first
if @request_type == "GET\n"
@hex_sign_string=Digest::SHA256.digest("").unpack('H*').first
elsif @request_type == "POST\n"
@hex_sign_string=Digest::SHA256.digest(@payload).unpack('H*').first
end
end
def canonical_request_full(requestname, zone)
form_time_values()
get_service_type(requestname)
init_param_values(requestname)
other_param_values(zone)
modify_request_headers(requestname, zone)
form_canonical_query_string(requestname, zone)
form_headers()
form_payload_data()
@canonical_request=@request_type+@canonical_uri+@querystringz+"\n"+@canonical_headerz+"\n\n"+@signed_headerz+"\n"+@hex_sign_string
end
def form_string_to_sign(zone)
hex_sign_sts=Digest::SHA256.digest(@canonical_request).unpack('H*').first
@string_to_sign="#{@other_params['X-Amz-Algorithm']}\n#{@other_params['X-Amz-Date']}\n#{@date_to_use}/#{zone}/#{@service_type}/aws4_request\n#{hex_sign_sts}"
end
def form_signature(requestname, zone)
@kdatez = OpenSSL::HMAC.digest('sha256', "AWS4" + @aws_secret, @date_to_use)
@kregionz = OpenSSL::HMAC.digest('sha256', @kdatez, zone)
@kservicez = OpenSSL::HMAC.digest('sha256', @kregionz, "#{@service_type}")
@ksigningz = OpenSSL::HMAC.digest('sha256', @kservicez, "aws4_request")
@signaturez = OpenSSL::HMAC.digest('sha256', @ksigningz, @string_to_sign)
@other_params['X-Amz-Signature']=@signaturez.unpack('H*').first
end
def form_request_url(requestname, zone)
@url_to_use = @init_params.sort.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&')+"&"+@other_params.sort.collect { |key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join('=') }.join('&')
if requestname == 'DescribeReservedDBInstances'
@url_to_use="/?"+@url_to_use
@https_addr="#{@service_type}.#{zone}.amazonaws.com"
@url_to_use_full="https://#{@service_type}.#{zone}.amazonaws.com/?"+@url_to_use
end
end
end
billing_obj=AWSGetSignatureV4.new("AWS_KEY","AWS_SECRET")
billing_obj.get_data("DescribeReservedDBInstances", 'us-east-1')