Class: AliyunGreen::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/aliyun_green/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Client

Returns a new instance of Client.



11
12
13
14
15
16
17
# File 'lib/aliyun_green/client.rb', line 11

def initialize(config)
  self.endpoint = config[:endpoint]
  self.api_version = config[:api_version]
  self.access_key_id = config[:access_key_id]
  self.access_key_secret = config[:access_key_secret]
  self.enable_internal = config[:enable_internal]
end

Instance Attribute Details

#access_key_idObject

Returns the value of attribute access_key_id.



9
10
11
# File 'lib/aliyun_green/client.rb', line 9

def access_key_id
  @access_key_id
end

#access_key_secretObject

Returns the value of attribute access_key_secret.



9
10
11
# File 'lib/aliyun_green/client.rb', line 9

def access_key_secret
  @access_key_secret
end

#api_versionObject

Returns the value of attribute api_version.



9
10
11
# File 'lib/aliyun_green/client.rb', line 9

def api_version
  @api_version
end

#enable_internalObject

Returns the value of attribute enable_internal.



9
10
11
# File 'lib/aliyun_green/client.rb', line 9

def enable_internal
  @enable_internal
end

#endpointObject

Returns the value of attribute endpoint.



9
10
11
# File 'lib/aliyun_green/client.rb', line 9

def endpoint
  @endpoint
end

Instance Method Details

#authorization(string_to_sign) ⇒ Object



62
63
64
# File 'lib/aliyun_green/client.rb', line 62

def authorization(string_to_sign)
  "acs #{self.access_key_id}:#{signature(string_to_sign)}"
end

#canonicalized_headers(headers) ⇒ Object



52
53
54
55
# File 'lib/aliyun_green/client.rb', line 52

def canonicalized_headers(headers)
  headers.keys.select { |key| key.to_s.start_with? "x-acs-" }
    .sort.map { |key| "#{key}:#{headers[key].strip}\n" }.join
end

#canonicalized_resource(uri, query_hash = {}) ⇒ Object



57
58
59
60
# File 'lib/aliyun_green/client.rb', line 57

def canonicalized_resource(uri, query_hash = {})
  query_string = query_hash.sort.map { |key, value| "#{key}=#{value}" }.join("&")
  query_string.empty? ? uri : "#{uri}?#{query_string}"
end

#default_headersObject



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/aliyun_green/client.rb', line 70

def default_headers
  default_headers = {
    "accept" => "application/json",
    "content-type" => "application/json",
    "date" => Time.now.httpdate,
    "host" => get_host(self.endpoint),
    "x-acs-version" => self.api_version,
    "x-acs-signature-nonce" => SecureRandom.hex(16),
    "x-acs-signature-version" => "1.0",
    "x-acs-signature-method" => "HMAC-SHA1",
  }
  default_headers
end

#get_host(endpoint) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/aliyun_green/client.rb', line 84

def get_host(endpoint)
  externals = {
    "cn-shanghai" => "green.cn-shanghai.aliyuncs.com",
    "cn-beijing" => "green.cn-beijing.aliyuncs.com",
    "cn-shenzhen" => "green.cn-shenzhen.aliyuncs.com",
    "ap-southeast-1" => "green.ap-southeast-1.aliyuncs.com",
  }
  internals = {
    "cn-shanghai" => "green-vpc.cn-shanghai.aliyuncs.com",
    "cn-beijing" => "green-vpc.cn-beijing.aliyuncs.com",
    "cn-shenzhen" => "green-vpc.cn-shenzhen.aliyuncs.com",
    "ap-southeast-1" => "green-vpc.ap-southeast-1.aliyuncs.com",
  }
  if self.enable_internal
    internals[endpoint]
  else
    externals[endpoint]
  end
end

#post(uri, payload, params = {}) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/aliyun_green/client.rb', line 19

def post(uri, payload, params = {})
  url = "https://#{get_host(self.endpoint)}#{uri}"

  mix_headers = default_headers
  request_body = payload.to_json

  mix_headers["content-md5"] = Digest::MD5.base64digest request_body
  mix_headers["content-length"] = request_body.length.to_s

  string2sign = string_to_sign(uri, mix_headers, params)
  mix_headers.merge!(authorization: authorization(string2sign))

  response = HTTPX.with(headers: mix_headers).post(url, body: payload.to_json)

  r = JSON.parse(response)

  raise AliyunGreen::Error::SignatureDoesNotMatchError if r["Code"] == "SignatureDoesNotMatch"
  raise AliyunGreen::Error::ClientError.new(r["msg"], r["code"]) if r["code"] != 200

  r
end

#signature(string_to_sign) ⇒ Object



66
67
68
# File 'lib/aliyun_green/client.rb', line 66

def signature(string_to_sign)
  Base64.encode64(OpenSSL::HMAC.digest("sha1", self.access_key_secret, string_to_sign)).strip
end

#string_to_sign(uri, headers, query = {}) ⇒ Object



41
42
43
44
45
46
47
48
49
50
# File 'lib/aliyun_green/client.rb', line 41

def string_to_sign(uri, headers, query = {})
  header_string = [
    "POST",
    headers["accept"],
    headers["content-md5"] || "",
    headers["content-type"] || "",
    headers["date"],
  ].join("\n")
  "#{header_string}\n#{canonicalized_headers(headers)}#{canonicalized_resource(uri, query)}"
end