Skip to content

Commit

Permalink
Merge pull request #8 from rockuw/master
Browse files Browse the repository at this point in the history
Add STS support
  • Loading branch information
yami committed Dec 7, 2015
2 parents c883b02 + e9abbfe commit ed69306
Show file tree
Hide file tree
Showing 39 changed files with 834 additions and 102 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Change Log

### v0.2.0

- Add aliyun/sts
- OSS::Client support STS

### v0.1.8

- Fix StreamWriter string encoding problem
Expand Down
32 changes: 28 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ AccessKeySecret,在使用Aliyun OSS SDK时需要提供您的这两个信息。

其中`endpoint`是OSS服务的地址,根据节点区域不同,这个地址可能不一样,例如
杭州节点的地址是:`http://oss-cn-hangzhou.aliyuncs.com`,其他节点的地址见:
[节点列表][1]
[节点列表][region-list]

`access_key_id``access_key_secret`是您的服务凭证,在官网的“管理控制
台”上面可以查看。**请妥善保管您的AccessKeySecret,泄露之后可能影响您的
Expand All @@ -65,7 +65,7 @@ AccessKeySecret,在使用Aliyun OSS SDK时需要提供您的这两个信息。
OSS支持自定义域名绑定,允许用户将自己的域名指向阿里云OSS的服务地址
(CNAME),这样用户迁移到OSS上时应用内资源的路径可以不用修改。绑定的域
名指向OSS的一个bucket。绑定域名的操作只能在OSS控制台进行。更多关于自定
义域名绑定的内容请到官网了解:[OSS自定义域名绑定][2]
义域名绑定的内容请到官网了解:[OSS自定义域名绑定][custom-domain]

用户绑定了域名后,使用SDK时指定的endpoint可以使用标准的OSS服务地址,也
可以使用用户绑定的域名:
Expand All @@ -84,6 +84,28 @@ OSS支持自定义域名绑定,允许用户将自己的域名指向阿里云OS
3. 在{Aliyun::OSS::Client#get_bucket}时仍需要指定bucket名字,并且要与
域名所绑定的bucket名字相同

#### 使用STS创建Client

OSS支持用户使用STS进行访问,更多有关STS的内容,请参考 [阿里云STS][aliyun-sts]
在使用STS之前需要先向STS申请一个临时token,
aliyun-sdk中包含了STS的SDK,使用时只需要`require 'aliyun/sts'`即可:

require 'aliyun/sts'
sts = Aliyun::STS::Client.new(
access_key_id: 'access_key_id',
access_key_secret: 'access_key_secret')

token = sts.assume_role('role-arn', 'my-app')

client = Aliyun::OSS::Client.new(
:endpoint => 'http://img.my-domain.com',
:access_key_id => token.access_key_id,
:access_key_secret => token.access_key_secret,
:sts_token => token.sts_token)

注意使用STS时必须指定`:sts_token`参数。用户还可以通过`STS::Client`申请
带Policy的token,细节请参考[API文档][sdk-api]

### 列出当前所有的Bucket

buckets = client.list_buckets
Expand Down Expand Up @@ -360,5 +382,7 @@ SDK采用rspec进行测试,如果要对SDK进行修改,请确保没有break
- 阿里云官网文档:http://help.aliyun.com/product/8314910_oss.html


[1]: http://help.aliyun.com/document_detail/oss/user_guide/endpoint_region.html
[2]: http://help.aliyun.com/document_detail/oss/user_guide/oss_concept/oss_cname.html
[region-list]: https://help.aliyun.com/document_detail/oss/user_guide/endpoint_region.html
[custom-domain]: https://help.aliyun.com/document_detail/oss/user_guide/oss_concept/oss_cname.html
[aliyun-sts]: https://help.aliyun.com/document_detail/ram/intro/concepts.html
[sdk-api]: http://www.rubydoc.info/gems/aliyun-sdk/
4 changes: 2 additions & 2 deletions aliyun-sdk.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'aliyun/oss/version'
require 'aliyun/version'

Gem::Specification.new do |spec|
spec.name = 'aliyun-sdk'
spec.version = Aliyun::OSS::VERSION
spec.version = Aliyun::VERSION
spec.authors = ['Tianlong Wu']
spec.email = ['[email protected]']

Expand Down
2 changes: 1 addition & 1 deletion examples/aliyun/oss/bucket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
require 'aliyun/oss'

# 初始化OSS client
Aliyun::OSS::Logging.set_log_level(Logger::DEBUG)
Aliyun::Common::Logging.set_log_level(Logger::DEBUG)
conf_file = '~/.oss.yml'
conf = YAML.load(File.read(File.expand_path(conf_file)))
client = Aliyun::OSS::Client.new(
Expand Down
2 changes: 1 addition & 1 deletion examples/aliyun/oss/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
require 'aliyun/oss'

# 初始化OSS client
Aliyun::OSS::Logging.set_log_level(Logger::DEBUG)
Aliyun::Common::Logging.set_log_level(Logger::DEBUG)
conf_file = '~/.oss.yml'
conf = YAML.load(File.read(File.expand_path(conf_file)))
bucket = Aliyun::OSS::Client.new(
Expand Down
2 changes: 1 addition & 1 deletion examples/aliyun/oss/resumable_download.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
require 'aliyun/oss'

# 初始化OSS Bucket
Aliyun::OSS::Logging.set_log_level(Logger::DEBUG)
Aliyun::Common::Logging.set_log_level(Logger::DEBUG)
conf_file = '~/.oss.yml'
conf = YAML.load(File.read(File.expand_path(conf_file)))
bucket = Aliyun::OSS::Client.new(
Expand Down
2 changes: 1 addition & 1 deletion examples/aliyun/oss/resumable_upload.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
require 'aliyun/oss'

# 初始化OSS Bucket
Aliyun::OSS::Logging.set_log_level(Logger::DEBUG)
Aliyun::Common::Logging.set_log_level(Logger::DEBUG)
conf_file = '~/.oss.yml'
conf = YAML.load(File.read(File.expand_path(conf_file)))
bucket = Aliyun::OSS::Client.new(
Expand Down
2 changes: 1 addition & 1 deletion examples/aliyun/oss/streaming.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
# 和下载。

# 初始化OSS client
Aliyun::OSS::Logging.set_log_level(Logger::DEBUG)
Aliyun::Common::Logging.set_log_level(Logger::DEBUG)
conf_file = '~/.oss.yml'
conf = YAML.load(File.read(File.expand_path(conf_file)))
bucket = Aliyun::OSS::Client.new(
Expand Down
48 changes: 48 additions & 0 deletions examples/aliyun/oss/using_sts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# -*- encoding: utf-8 -*-

$LOAD_PATH.unshift(File.expand_path("../../../../lib", __FILE__))
require 'yaml'
require 'aliyun/sts'
require 'aliyun/oss'

# 初始化OSS client
Aliyun::Common::Logging.set_log_level(Logger::DEBUG)
conf_file = '~/.sts.yml'
conf = YAML.load(File.read(File.expand_path(conf_file)))

# 辅助打印函数
def demo(msg)
puts "######### #{msg} ########"
puts
yield
puts "-------------------------"
puts
end

demo "Using STS" do
sts = Aliyun::STS::Client.new(
:access_key_id => conf['access_key_id'],
:access_key_secret => conf['access_key_secret'])

token = sts.assume_role(
'acs:ram::52352:role/aliyunosstokengeneratorrole', 'app-1')

client = Aliyun::OSS::Client.new(
:endpoint => 'http://oss-cn-hangzhou.aliyuncs.com',
:sts_token => token.security_token,
:access_key_id => token.access_key_id,
:access_key_secret => token.access_key_secret)

unless client.bucket_exists?('bucket-for-sts-test')
client.create_bucket('bucket-for-sts-test')
end

bucket = client.get_bucket('bucket-for-sts-test')

bucket.put_object('hello') { |s| s << 'hello' }
bucket.put_object('world') { |s| s << 'world' }

bucket.list_objects.take(10).each do |obj|
puts "Object: #{obj.key}, size: #{obj.size}"
end
end
59 changes: 59 additions & 0 deletions examples/aliyun/sts/assume_role.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# -*- encoding: utf-8 -*-

$LOAD_PATH.unshift(File.expand_path("../../../../lib", __FILE__))
require 'yaml'
require 'aliyun/sts'

Aliyun::Common::Logging.set_log_level(Logger::DEBUG)
conf_file = '~/.sts.yml'
conf = YAML.load(File.read(File.expand_path(conf_file)))
client = Aliyun::STS::Client.new(
:access_key_id => conf['access_key_id'],
:access_key_secret => conf['access_key_secret'])

# 辅助打印函数
def demo(msg)
puts "######### #{msg} ########"
puts
yield
puts "-------------------------"
puts
end

token = client.assume_role(
'acs:ram::52352:role/aliyunosstokengeneratorrole', 'app-1')

demo "Assume role" do
begin
token = client.assume_role(
'acs:ram::52352:role/aliyunosstokengeneratorrole', 'app-1')

puts "Credentials for session: #{token.session_name}"
puts "access key id: #{token.access_key_id}"
puts "access key secret: #{token.access_key_secret}"
puts "security token: #{token.security_token}"
puts "expiration at: #{token.expiration}"
rescue => e
puts "AssumeRole failed: #{e.message}"
end
end

demo "Assume role with policy" do
begin
policy = Aliyun::STS::Policy.new
policy.allow(
['oss:Get*', 'oss:PutObject'],
['acs:oss:*:*:my-bucket', 'acs:oss:*:*:my-bucket/*'])

token = client.assume_role(
'acs:ram::52352:role/aliyunosstokengeneratorrole', 'app-2', policy, 900)

puts "Credentials for session: #{token.session_name}"
puts "access key id: #{token.access_key_id}"
puts "access key secret: #{token.access_key_secret}"
puts "security token: #{token.security_token}"
puts "expiration at: #{token.expiration}"
rescue => e
puts "AssumeRole failed: #{e.message}"
end
end
6 changes: 6 additions & 0 deletions lib/aliyun/common.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# -*- encoding: utf-8 -*-

require_relative 'version'
require_relative 'common/struct'
require_relative 'common/logging'
require_relative 'common/exception'
18 changes: 18 additions & 0 deletions lib/aliyun/common/exception.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- encoding: utf-8 -*-

module Aliyun
module Common

##
# Base exception class
#
class Exception < RuntimeError
attr_reader :message

def initialize(message)
@message = message
end
end

end # Common
end # Aliyun
6 changes: 3 additions & 3 deletions lib/aliyun/oss/logging.rb → lib/aliyun/common/logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
require 'logger'

module Aliyun
module OSS
module Common
##
# Logging support
# @example
# include Logging
# logger.info(xxx)
module Logging

DEFAULT_LOG_FILE = "./oss_sdk.log"
DEFAULT_LOG_FILE = "./aliyun_sdk.log"
MAX_NUM_LOG = 100
ROTATE_SIZE = 10 * 1024 * 1024

Expand Down Expand Up @@ -42,5 +42,5 @@ def self.logger
end

end # logging
end # OSS
end # Common
end # Aliyun
56 changes: 56 additions & 0 deletions lib/aliyun/common/struct.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# -*- encoding: utf-8 -*-

module Aliyun
module Common

# Common structs used. It provides a 'attrs' helper method for
# subclass to define its attributes. 'attrs' is based on
# attr_reader and provide additional functionalities for classes
# that inherits Struct::Base :
# * the constuctor is provided to accept options and set the
# corresponding attibute automatically
# * the #to_s method is rewrite to concatenate the defined
# attributes keys and values
# @example
# class X < Struct::Base
# attrs :foo, :bar
# end
#
# x.new(:foo => 'hello', :bar => 'world')
# x.foo # == "hello"
# x.bar # == "world"
# x.to_s # == "foo: hello, bar: world"
module Struct
class Base
module AttrHelper
def attrs(*s)
define_method(:attrs) {s}
attr_reader(*s)
end
end

extend AttrHelper

def initialize(opts = {})
extra_keys = opts.keys - attrs
unless extra_keys.empty?
fail Common::Exception,
"Unexpected extra keys: #{extra_keys.join(', ')}"
end

attrs.each do |attr|
instance_variable_set("@#{attr}", opts[attr])
end
end

def to_s
attrs.map do |attr|
v = instance_variable_get("@#{attr}")
"#{attr.to_s}: #{v}"
end.join(", ")
end
end # Base
end # Struct

end # Common
end # Aliyun
3 changes: 1 addition & 2 deletions lib/aliyun/oss.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# -*- encoding: utf-8 -*-

require_relative 'oss/version'
require_relative 'oss/logging'
require_relative 'common'
require_relative 'oss/util'
require_relative 'oss/exception'
require_relative 'oss/struct'
Expand Down
2 changes: 1 addition & 1 deletion lib/aliyun/oss/bucket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module OSS
# website, lifecycle, cors)
# 2. object相关:上传、下载、追加、拷贝object等
# 3. multipart相关:断点续传、断点续载
class Bucket < Struct::Base
class Bucket < Common::Struct::Base

attrs :name, :location, :creation_time

Expand Down
4 changes: 2 additions & 2 deletions lib/aliyun/oss/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ module OSS
# bucket = client.get_bucket('my-bucket')
class Client

include Logging

# 构造OSS client,用于操作buckets。
# @param opts [Hash] 构造Client时的参数选项
# @option opts [String] :endpoint [必填]OSS服务的地址,可以是以
Expand All @@ -30,6 +28,8 @@ class Client
# KEY SECRET,如果不填则会尝试匿名访问
# @option opts [Boolean] :cname [可选] 指定endpoint是否是用户绑
# 定的域名
# @option opts [Boolean] :sts_token [可选] 指定STS的
# SecurityToken,如果指定,则使用STS授权访问
# @option opts [Fixnum] :open_timeout [可选] 指定建立连接的超时
# 时间,默认为10秒
# @option opts [Fixnum] :read_timeout [可选] 指定等待响应的超时
Expand Down
5 changes: 3 additions & 2 deletions lib/aliyun/oss/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ module OSS
# A place to store various configurations: credentials, api
# timeout, retry mechanism, etc
#
class Config < Struct::Base
class Config < Common::Struct::Base

attrs :endpoint, :cname, :access_key_id, :access_key_secret,
attrs :endpoint, :cname, :sts_token,
:access_key_id, :access_key_secret,
:open_timeout, :read_timeout

def initialize(opts = {})
Expand Down
Loading

0 comments on commit ed69306

Please sign in to comment.