bucket_client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.gitlab-ci.yml +70 -0
  4. data/.idea/bucket_client.iml +105 -0
  5. data/.idea/encodings.xml +4 -0
  6. data/.idea/misc.xml +7 -0
  7. data/.idea/modules.xml +8 -0
  8. data/.idea/runConfigurations/Integration_Test.xml +37 -0
  9. data/.idea/runConfigurations/Unit_Test.xml +37 -0
  10. data/.rspec +3 -0
  11. data/CODE_OF_CONDUCT.md +74 -0
  12. data/Gemfile +6 -0
  13. data/Gemfile.lock +114 -0
  14. data/LICENSE.txt +21 -0
  15. data/README.md +870 -0
  16. data/Rakefile +6 -0
  17. data/bin/console +14 -0
  18. data/bin/setup +8 -0
  19. data/bucket_client.gemspec +46 -0
  20. data/integration/aws_blob_spec.rb +134 -0
  21. data/integration/aws_bucket_spec.rb +145 -0
  22. data/integration/azure_blob_spec.rb +132 -0
  23. data/integration/azure_bucket_spec.rb +132 -0
  24. data/integration/dev_blob_spec.rb +131 -0
  25. data/integration/dev_bucket_spec.rb +140 -0
  26. data/integration/do_blob_spec.rb +134 -0
  27. data/integration/do_bucket_spec.rb +144 -0
  28. data/integration/gcp_blob_spec.rb +132 -0
  29. data/integration/gcp_bucket_spec.rb +132 -0
  30. data/integration/img.jpg +0 -0
  31. data/lib/bucket_client.rb +66 -0
  32. data/lib/bucket_client/aws/aws_bucket.rb +85 -0
  33. data/lib/bucket_client/aws/aws_client.rb +195 -0
  34. data/lib/bucket_client/aws/aws_http_client.rb +32 -0
  35. data/lib/bucket_client/aws/aws_policy_factory.rb +26 -0
  36. data/lib/bucket_client/aws4_request_signer.rb +133 -0
  37. data/lib/bucket_client/azure/azure_bucket.rb +83 -0
  38. data/lib/bucket_client/azure/azure_client.rb +197 -0
  39. data/lib/bucket_client/bucket.rb +388 -0
  40. data/lib/bucket_client/bucket_operation_exception.rb +8 -0
  41. data/lib/bucket_client/client.rb +408 -0
  42. data/lib/bucket_client/dev/local_bucket.rb +84 -0
  43. data/lib/bucket_client/dev/local_client.rb +148 -0
  44. data/lib/bucket_client/digital_ocean/digital_ocean_acl_factory.rb +39 -0
  45. data/lib/bucket_client/digital_ocean/digital_ocean_bucket.rb +81 -0
  46. data/lib/bucket_client/digital_ocean/digital_ocean_client.rb +275 -0
  47. data/lib/bucket_client/digital_ocean/digital_ocean_http_client.rb +31 -0
  48. data/lib/bucket_client/gcp/gcp_bucket.rb +79 -0
  49. data/lib/bucket_client/gcp/gcp_client.rb +171 -0
  50. data/lib/bucket_client/operation_result.rb +33 -0
  51. data/lib/bucket_client/version.rb +3 -0
  52. metadata +246 -0
@@ -0,0 +1,31 @@
1
+ module BucketClient
2
+ class DigitalOceanHttpClient
3
+ # @param [Client::AWS4RequestSigner] signer aws4 signer
4
+ # @param [String] region region of the service
5
+ # @param [KirinHttp::Client] http Http client to send http Message
6
+ def initialize(signer, region, http)
7
+ @signer = signer
8
+ @region = region
9
+ @http = http
10
+ end
11
+
12
+ # @param [Symbol] method
13
+ # @param [String] endpoint
14
+ # @param [Object] content
15
+ # @param [String] type
16
+ # @param [String] accept
17
+ # @param [Hash] headers
18
+ # @return [KirinHttp::Response]
19
+ def query(method, endpoint, content = nil, type = "application/xml", accept = nil, headers = {})
20
+ accept = type if accept.nil?
21
+ header = {
22
+ "Content-Type": type,
23
+ "Accept": accept
24
+ }.merge(headers)
25
+ message = KirinHttp::Message.new(endpoint, method, content, header)
26
+ message = @signer.sign message, "s3", @region
27
+ @http.send message
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,79 @@
1
+ module BucketClient
2
+ class GCPBucket < Bucket
3
+ attr_reader :key
4
+
5
+ # @param [GCPClient] parent
6
+ # @param [String] key
7
+ def initialize(parent, key)
8
+ @bucket_client = parent
9
+ @key = key
10
+ end
11
+
12
+ def get_uri(key)
13
+ "https://storage.googleapis.com/#{@key}/#{key}"
14
+ end
15
+
16
+ def get_blob_with_uri(uri)
17
+ @bucket_client.get_blob uri
18
+ end
19
+
20
+ def exist_blob_with_uri(uri)
21
+ @bucket_client.exist_blob(uri)
22
+ end
23
+
24
+ def put_blob_with_uri(payload, uri)
25
+ @bucket_client.put_blob payload, uri
26
+ end
27
+
28
+ def update_blob_with_uri(payload, uri)
29
+ exist = exist_blob_with_uri uri
30
+ if exist
31
+ put_blob_with_uri payload, uri
32
+ else
33
+ OperationResult.new false, "Blob does not exist", nil, 400
34
+ end
35
+ end
36
+
37
+ def delete_blob_with_uri(uri)
38
+ @bucket_client.delete_blob(uri)
39
+ end
40
+
41
+ def delete_blob_if_exist_with_uri(uri)
42
+ @bucket_client.delete_blob_if_exist(uri)
43
+ end
44
+
45
+ def get_blob(key)
46
+ get_blob_with_uri(get_uri key)
47
+ end
48
+
49
+ def exist_blob(key)
50
+ exist_blob_with_uri(get_uri key)
51
+ end
52
+
53
+ def put_blob(payload, key)
54
+ put_blob_with_uri(payload, get_uri(key))
55
+ end
56
+
57
+ def create_blob(payload, key)
58
+ exist = exist_blob key
59
+ if exist
60
+ OperationResult.new false, "Blob already exist", nil, 400
61
+ else
62
+ put_blob payload, key
63
+ end
64
+ end
65
+
66
+ def update_blob(payload, key)
67
+ update_blob_with_uri(payload, get_uri(key))
68
+ end
69
+
70
+ def delete_blob(key)
71
+ delete_blob_with_uri(get_uri key)
72
+ end
73
+
74
+ def delete_blob_if_exist(key)
75
+ delete_blob_if_exist_with_uri(get_uri key)
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,171 @@
1
+ require "google/cloud/storage"
2
+ require "mimemagic"
3
+ require "bucket_client/operation_result"
4
+ require "bucket_client/gcp/gcp_bucket"
5
+
6
+ module BucketClient
7
+ class GCPClient < Client
8
+ def initialize(project_id, secret)
9
+ @client = Google::Cloud::Storage.new(project_id: project_id, keyfile: secret)
10
+ end
11
+
12
+ def exist_bucket(key)
13
+ !@client.bucket(key).nil?
14
+ end
15
+
16
+ def get_bucket!(key)
17
+ GCPBucket.new(self, key)
18
+ end
19
+
20
+ def put_bucket(key)
21
+ exist = exist_bucket key
22
+ if exist
23
+ bucket = get_bucket! key
24
+ OperationResult.new(true, "OK", bucket, 200)
25
+ else
26
+ create_bucket key
27
+ end
28
+ end
29
+
30
+ def create_bucket(key)
31
+ begin
32
+ @client.create_bucket key
33
+ bucket = get_bucket! key
34
+ OperationResult.new(true, "OK", bucket, 200)
35
+ rescue StandardError => e
36
+ OperationResult.new(false, e.message, nil, 400)
37
+ end
38
+ end
39
+
40
+ def delete_bucket(key)
41
+ exist = exist_bucket key
42
+ if exist
43
+ bucket = @client.bucket(key)
44
+ success = bucket.delete
45
+ message = success ? "Deleted" : "Failed to delete"
46
+ code = success ? 204 : 400
47
+ OperationResult.new(success, message, nil, code)
48
+ else
49
+ OperationResult.new(false, "Bucket does not exist", nil, 404)
50
+ end
51
+ end
52
+
53
+ def delete_bucket_if_exist(key)
54
+ exist = exist_bucket key
55
+ if exist
56
+ delete_bucket key
57
+ else
58
+ OperationResult.new(true, "Bucket already deleted", nil, 200)
59
+ end
60
+ end
61
+
62
+ def set_read_policy(key, access)
63
+ raise ArgumentError.new("Read Policy not accepted") if access != :public && access != :private
64
+ begin
65
+ bucket = @client.bucket key
66
+ modify_acl bucket, access
67
+ bucket.files.each do |file|
68
+ modify_acl file, access
69
+ end
70
+ OperationResult.new(true, "OK", nil, 200)
71
+ rescue StandardError => e
72
+ OperationResult.new(false, e.message, nil, 400)
73
+ end
74
+ end
75
+
76
+ def set_get_cors(key, cors)
77
+ begin
78
+
79
+ bucket = @client.bucket key
80
+ bucket.cors(&:clear)
81
+ bucket.cors {|rules| rules.add_rule cors, "GET"}
82
+ OperationResult.new(true, "OK", nil, 200)
83
+ rescue StandardError => e
84
+ OperationResult.new(false, e.message, nil, 400)
85
+ end
86
+ end
87
+
88
+ def get_blob(uri)
89
+ data = break_uri uri
90
+ begin
91
+ bucket = @client.bucket data[:bucket]
92
+ blob = bucket.file data[:blob]
93
+ bin = blob.download.read
94
+ OperationResult.new(true, "OK", bin, 200)
95
+ rescue StandardError => e
96
+ OperationResult.new(false, e.message, nil, 400)
97
+ end
98
+ end
99
+
100
+ def exist_blob(uri)
101
+ data = break_uri uri
102
+ bucket = @client.bucket data[:bucket]
103
+ bucket.file(data[:blob], skip_lookup: true).exists?
104
+ end
105
+
106
+ def put_blob(payload, uri)
107
+ mime = MimeMagic.by_magic payload
108
+ data = break_uri uri
109
+ begin
110
+ # @type [Google::Cloud::Storage::Bucket]
111
+ bucket = @client.bucket data[:bucket]
112
+ f = StringIO.new
113
+ f << payload
114
+ file = bucket.create_file f, data[:blob], cache_control: "no-cache", content_type: mime.type
115
+ OperationResult.new(true, "OK", file.public_url, 200)
116
+ rescue StandardError => e
117
+ OperationResult.new(false, e.message, nil, 400)
118
+ end
119
+ end
120
+
121
+ def update_blob(payload, uri)
122
+ exist = exist_blob uri
123
+ if exist
124
+ put_blob payload, uri
125
+ else
126
+ OperationResult.new(false, "Blob does not exist", nil, 404)
127
+ end
128
+ end
129
+
130
+ def delete_blob_if_exist(uri)
131
+ exist = exist_blob uri
132
+ if exist
133
+ delete_blob uri
134
+ else
135
+ OperationResult.new(true, "Blob already deleted", nil, 204)
136
+ end
137
+ end
138
+
139
+ def delete_blob(uri)
140
+ data = break_uri uri
141
+ begin
142
+ bucket = @client.bucket data[:bucket]
143
+ bucket.file(data[:blob], skip_lookup: true).delete
144
+ OperationResult.new(true, "Deleted Blob", nil, 204)
145
+ rescue StandardError => e
146
+ OperationResult.new(false, e.message, nil, 400)
147
+ end
148
+ end
149
+
150
+ private
151
+
152
+ def break_uri(uri)
153
+ url = Addressable::URI.parse uri
154
+ fragments = url.path.split("/").select {|x| !x.nil? && !x.empty?}
155
+ bucket = fragments[0]
156
+ blob = fragments.drop(1).join "/"
157
+ {bucket: bucket, blob: blob}
158
+ end
159
+
160
+ def modify_acl(principal, access)
161
+ if access == :private
162
+ principal.acl.private!
163
+ principal.default_acl.private!
164
+ else
165
+ principal.acl.public!
166
+ principal.default_acl.public!
167
+ end
168
+ end
169
+
170
+ end
171
+ end
@@ -0,0 +1,33 @@
1
+ class OperationResult
2
+
3
+ def initialize(success, message, value, code)
4
+ @success = success
5
+ @message = message
6
+ @value = value
7
+ @code = code
8
+ end
9
+
10
+ # Message from the server of the operation. Failure message will be here too
11
+ # @return [String]
12
+ def message
13
+ @message
14
+ end
15
+
16
+ # HTTP Status code of the operation.
17
+ # @return [Integer]
18
+ def code
19
+ @code
20
+ end
21
+
22
+ # Whether the operation was successful
23
+ # @return [Boolean]
24
+ def success
25
+ @success
26
+ end
27
+
28
+ # Value of the operation result if it has a value.
29
+ # Can be uri or byte array
30
+ def value
31
+ @value
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module BucketClient
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,246 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bucket_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - kirinnee
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-03-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kirin_http
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mimemagic
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ox
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: azure-storage-blob
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: addressable
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.5'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: google-cloud-storage
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.17'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.17'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.17'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.17'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '10.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: dotenv
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: |-
154
+ Bucket Client is a ruby gem that allows programmers to interact with popular Blob Storage cloud
155
+ services. This intends to act as a layer of abstraction, much like ORM is to databases.
156
+
157
+ With this, you may easily change the blob storage provider or even defer them.
158
+
159
+ The supported cloud storage include:
160
+ - Google Cloud Platform Cloud Storage
161
+ - Amazon Web Service S3 Bucket
162
+ - Digital Ocean Spaces
163
+ - Azure Blob Storage (Microsoft).
164
+ email:
165
+ - kirinnee97@gmail.com
166
+ executables: []
167
+ extensions: []
168
+ extra_rdoc_files: []
169
+ files:
170
+ - ".env"
171
+ - ".gitignore"
172
+ - ".gitlab-ci.yml"
173
+ - ".idea/bucket_client.iml"
174
+ - ".idea/encodings.xml"
175
+ - ".idea/misc.xml"
176
+ - ".idea/modules.xml"
177
+ - ".idea/runConfigurations/Integration_Test.xml"
178
+ - ".idea/runConfigurations/Unit_Test.xml"
179
+ - ".idea/vcs.xml"
180
+ - ".rspec"
181
+ - CODE_OF_CONDUCT.md
182
+ - Gemfile
183
+ - Gemfile.lock
184
+ - LICENSE.txt
185
+ - README.md
186
+ - Rakefile
187
+ - bin/console
188
+ - bin/setup
189
+ - bucket_client.gemspec
190
+ - integration/aws_blob_spec.rb
191
+ - integration/aws_bucket_spec.rb
192
+ - integration/azure_blob_spec.rb
193
+ - integration/azure_bucket_spec.rb
194
+ - integration/dev_blob_spec.rb
195
+ - integration/dev_bucket_spec.rb
196
+ - integration/do_blob_spec.rb
197
+ - integration/do_bucket_spec.rb
198
+ - integration/gcp_blob_spec.rb
199
+ - integration/gcp_bucket_spec.rb
200
+ - integration/img.jpg
201
+ - lib/bucket_client.rb
202
+ - lib/bucket_client/aws/aws_bucket.rb
203
+ - lib/bucket_client/aws/aws_client.rb
204
+ - lib/bucket_client/aws/aws_http_client.rb
205
+ - lib/bucket_client/aws/aws_policy_factory.rb
206
+ - lib/bucket_client/aws4_request_signer.rb
207
+ - lib/bucket_client/azure/azure_bucket.rb
208
+ - lib/bucket_client/azure/azure_client.rb
209
+ - lib/bucket_client/bucket.rb
210
+ - lib/bucket_client/bucket_operation_exception.rb
211
+ - lib/bucket_client/client.rb
212
+ - lib/bucket_client/dev/local_bucket.rb
213
+ - lib/bucket_client/dev/local_client.rb
214
+ - lib/bucket_client/digital_ocean/digital_ocean_acl_factory.rb
215
+ - lib/bucket_client/digital_ocean/digital_ocean_bucket.rb
216
+ - lib/bucket_client/digital_ocean/digital_ocean_client.rb
217
+ - lib/bucket_client/digital_ocean/digital_ocean_http_client.rb
218
+ - lib/bucket_client/gcp/gcp_bucket.rb
219
+ - lib/bucket_client/gcp/gcp_client.rb
220
+ - lib/bucket_client/operation_result.rb
221
+ - lib/bucket_client/version.rb
222
+ homepage: https://gitlab.com/ruby-gem/bucket_client
223
+ licenses:
224
+ - MIT
225
+ metadata: {}
226
+ post_install_message:
227
+ rdoc_options: []
228
+ require_paths:
229
+ - lib
230
+ required_ruby_version: !ruby/object:Gem::Requirement
231
+ requirements:
232
+ - - ">="
233
+ - !ruby/object:Gem::Version
234
+ version: '0'
235
+ required_rubygems_version: !ruby/object:Gem::Requirement
236
+ requirements:
237
+ - - ">="
238
+ - !ruby/object:Gem::Version
239
+ version: '0'
240
+ requirements: []
241
+ rubygems_version: 3.0.1
242
+ signing_key:
243
+ specification_version: 4
244
+ summary: A gem that allows for ruby code to interact with cloud blob storage such
245
+ as AWS S3, GCP Cloud Storage and Azure Blob Storage
246
+ test_files: []