swift-storage 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e3246e84c36a57fc2892b66434fda76d6a0985c5
4
+ data.tar.gz: 76f1ad2fa5f6b47e0d704ca2ec2095d3ac1ee7fc
5
+ SHA512:
6
+ metadata.gz: 9d0bee3254a69d404e1ef30e9ee454cc81d894dcb59a69dd7c2e5d4e8269ce5a38b402a5cfaf54527bbbada5f80190ddd16094eaf2703094fb28ff069c5f6a79
7
+ data.tar.gz: 5035e8d1b0ac40516926bf47aab4e6d3a8597c23bc3acff638cce78018b1da0b18000281b9cb67b4f19878c6fe2ce8fc18bd74d37cc42343061f3eab28d17705
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .envrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in swift-ruby.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ guard :rspec, cmd: 'bundle exec rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^spec/[^/]+\.rb$}) { "spec" }
4
+ watch(%r{^lib/.+rb$}) { "spec" }
5
+ end
6
+
7
+
8
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Nicolas Goy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Swift::Ruby
2
+
3
+ Ruby client for Openstack swift
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'swift-ruby'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install swift-ruby
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/swift-ruby/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
7
+ task :test => :spec
@@ -0,0 +1,15 @@
1
+ require "net/http"
2
+ require "swift_storage/version"
3
+ require "swift_storage/errors"
4
+ require "swift_storage/utils"
5
+ require "swift_storage/headers"
6
+ require "swift_storage/node"
7
+ require "swift_storage/account"
8
+ require "swift_storage/container"
9
+ require "swift_storage/container_collection"
10
+ require "swift_storage/object"
11
+ require "swift_storage/object_collection"
12
+ require "swift_storage/service"
13
+
14
+ module SwiftStorage
15
+ end
@@ -0,0 +1,35 @@
1
+ class SwiftStorage::Account < SwiftStorage::Node
2
+
3
+ parent_node :service
4
+
5
+
6
+ # Write account meta data
7
+ #
8
+ # @param temp_url_key [String]
9
+ # The shared secret used to sign temporary URLs.
10
+ # Changing this key will invalidate all temporary URLs signed with the older
11
+ # key.
12
+ #
13
+ def write(temp_url_key: nil)
14
+ h = {}
15
+ h[H::ACCOUNT_TEMP_URL_KEY] = temp_url_key if temp_url_key
16
+
17
+ request(relative_path, :method => :post, :headers => h)
18
+ end
19
+
20
+ # Returns the temporary URL key
21
+ #
22
+ # @return [String]
23
+ # Key used to sign temporary URLs
24
+ #
25
+ def temp_url_key
26
+ metadata.temp_url_key rescue nil
27
+ end
28
+
29
+ def relative_path
30
+ ''
31
+ end
32
+
33
+
34
+ end
35
+
@@ -0,0 +1,67 @@
1
+ class SwiftStorage::Container < SwiftStorage::Node
2
+
3
+ parent_node :service
4
+
5
+
6
+ def relative_path
7
+ name
8
+ end
9
+
10
+ header_attributes :bytes_used,
11
+ :object_count
12
+
13
+
14
+ # Returns the object collection for this container
15
+ #
16
+ # @return [SwiftStorage::ObjectCollection]
17
+ # The object collection.
18
+ #
19
+ def objects
20
+ @objects ||= SwiftStorage::ObjectCollection.new(self)
21
+ end
22
+
23
+ # Create the container
24
+ #
25
+ def create
26
+ request(relative_path, :method => :put)
27
+ end
28
+
29
+ # Write the container meta data
30
+ #
31
+ # @note This overrides all ACL set on the container.
32
+ #
33
+ # Each ACL is a string in the following format:
34
+ #
35
+ # - `team:jon` give access to user "jon" of account "team"
36
+ #
37
+ # @param read_acl [Array<String>]
38
+ # An array of ACL.
39
+ #
40
+ # @param write_acl [Array<String>]
41
+ # An array of ACL.
42
+ #
43
+ def write(write_acl: nil, read_acl: nil)
44
+ h = {}
45
+ read_acl = read_acl.join(',') if read_acl.respond_to?(:to_ary)
46
+ write_acl = write_acl.join(',') if write_acl.respond_to?(:to_ary)
47
+
48
+ h[H::CONTAINER_READ] = read_acl
49
+ h[H::CONTAINER_WRITE] = write_acl
50
+
51
+ request(relative_path, :method => :post, :headers => h)
52
+ end
53
+
54
+ # Read the container meta data
55
+ #
56
+ # @return [Struct]
57
+ # A struct with `read` and `write` ACL, each entry contains an Array of
58
+ # String.
59
+ def acl
60
+ r = headers.read.split(',') rescue nil
61
+ w = headers.write.split(',') rescue nil
62
+ struct(:read => r, :write => w)
63
+ end
64
+
65
+
66
+ end
67
+
@@ -0,0 +1,34 @@
1
+ class SwiftStorage::ContainerCollection < SwiftStorage::Node
2
+
3
+ parent_node :service
4
+
5
+
6
+ # Return all containers
7
+ #
8
+ # @note This method will return only the first 1000 containers.
9
+ #
10
+ # @return [Array<SwiftStorage::Container>]
11
+ # Containers in this collection.
12
+ #
13
+ def all
14
+ get_lines('').map { |name| SwiftStorage::Container.new(service, name)}
15
+ end
16
+
17
+ # Return a particular container
18
+ #
19
+ # @note This always return a container, regadeless of it's existence
20
+ # on the server. This call do NOT contact the server.
21
+ #
22
+ # @param name [String]
23
+ # The name (sometimes named key) of the container
24
+ #
25
+ # @return [SwiftStorage::Object]
26
+ # Container with given name
27
+ #
28
+ def [](name)
29
+ SwiftStorage::Container.new(service, name)
30
+ end
31
+
32
+ end
33
+
34
+
@@ -0,0 +1,15 @@
1
+ module SwiftStorage::Errors
2
+
3
+ class AuthError < StandardError
4
+ end
5
+
6
+ class NotFoundError < StandardError
7
+ end
8
+
9
+ class ServerError < StandardError
10
+ end
11
+
12
+ class ForbiddenError < StandardError
13
+ end
14
+
15
+ end
@@ -0,0 +1,23 @@
1
+ module SwiftStorage
2
+
3
+ module Headers
4
+ STORAGE_URL = 'X-Storage-Url'.freeze
5
+ AUTH_TOKEN = 'X-Auth-Token'.freeze
6
+ AUTH_USER = 'X-Auth-User'.freeze
7
+ AUTH_KEY = 'X-Auth-Key'.freeze
8
+ STORAGE_TOKEN = 'X-Storage-Token'.freeze
9
+ CONNECTION = 'Connection'.freeze
10
+ PROXY_CONNECTION = 'Proxy-Connection'.freeze
11
+ CONTENT_TYPE = 'Content-Type'.freeze
12
+ CONTENT_DISPOSITION = 'Content-Disposition'.freeze
13
+ DELETE_AT = 'X-Delete-At'.freeze
14
+ DELETE_AFTER = 'X-Delete-After'.freeze
15
+ CACHE_CONTROL = 'Cache-Control'.freeze
16
+ EXPIRES = 'Expires'.freeze
17
+ OBJECT_MANIFEST = 'X-Object-Manifest'.freeze
18
+ CONTAINER_READ = 'X-Container-Read'.freeze
19
+ CONTAINER_WRITE = 'X-Container-Write'.freeze
20
+ ACCOUNT_TEMP_URL_KEY = 'X-Account-Meta-Temp-URL-Key'.freeze
21
+ end
22
+
23
+ end
@@ -0,0 +1,133 @@
1
+ class SwiftStorage::Node
2
+
3
+ include SwiftStorage::Utils
4
+
5
+ attr_accessor :parent,
6
+ :name
7
+
8
+ def initialize(parent, name=nil)
9
+ @parent = parent
10
+ @name = name
11
+ end
12
+
13
+ def request(*args)
14
+ service.request(*args)
15
+ end
16
+
17
+ # Returns the service for this node
18
+ #
19
+ # @return [SwiftStorage::Service]
20
+ # The service this node is bound to
21
+ #
22
+ def service
23
+ unless defined?(@service)
24
+ p = parent
25
+ while p && !(SwiftStorage::Service === p)
26
+ p = p.parent
27
+ end
28
+ @service = p
29
+ end
30
+ @service
31
+ end
32
+
33
+ def get_lines(path)
34
+ headers = {'Accept' => 'text/plain'}
35
+ response = request(path, :headers => headers)
36
+ body = response.body
37
+ if body.nil? || body.empty?
38
+ []
39
+ else
40
+ body.lines.map(&:strip)
41
+ end
42
+ end
43
+
44
+ def to_s
45
+ "#<#{self.class.name} #{name}>"
46
+ end
47
+
48
+ def relative_path
49
+ raise NotImplemented
50
+ end
51
+
52
+ def headers
53
+ return @headers if @headers
54
+
55
+ response ||= request(relative_path, :method => :head)
56
+
57
+ h = {}
58
+ metadata = h[:metadata] = {}
59
+ response.to_hash.each_pair do |k,v|
60
+ if k =~ /^X-#{self.class.header_name}-Meta-?(.+)/i
61
+ k = $1
62
+ t = metadata
63
+ elsif k =~ /^X-#{self.class.header_name}-?(.+)/i
64
+ k = $1
65
+ t = h
66
+ else
67
+ t = h
68
+ end
69
+ k = k.downcase.gsub(/\W/, '_')
70
+ v = v.first if v.respond_to?(:to_ary)
71
+ t[k] = v
72
+ end
73
+ @headers = struct(h)
74
+ end
75
+
76
+ def metadata
77
+ @metadata ||= struct(headers.metadata)
78
+ end
79
+
80
+ def clear_cache
81
+ @headers = nil
82
+ @metadata = nil
83
+ end
84
+
85
+ def exists?
86
+ request(relative_path, :method => :head) && true
87
+ rescue SwiftStorage::Errors::NotFoundError
88
+ false
89
+ end
90
+
91
+ def delete
92
+ request(relative_path, :method => :delete)
93
+ end
94
+
95
+
96
+ private
97
+
98
+ def self.header_name
99
+ self.name.split(':').last
100
+ end
101
+
102
+
103
+ def self.header_attributes(*args)
104
+ args.each do |a|
105
+ define_method(a.to_sym) do
106
+ headers[a]
107
+ end
108
+ end
109
+ end
110
+
111
+ def self.parent_node(name)
112
+ define_method(name.to_sym) do
113
+ parent
114
+ end
115
+ end
116
+
117
+ def merge_metadata(headers, metadata)
118
+ return if metadata.nil?
119
+ metadata.each do |k,v|
120
+ sanitized_key = k.to_s.gsub(/\W/, '-')
121
+ sanitized_key = sanitized_key.split('-').reject{|o| o.nil? || o.empty?}
122
+ full_key = ['X', self.class.header_name, 'Meta'] + sanitized_key
123
+ full_key = full_key.map(&:capitalize).join('-')
124
+ headers[full_key] = v.to_s
125
+ end
126
+ end
127
+
128
+ private
129
+ H = SwiftStorage::Headers
130
+
131
+ end
132
+
133
+