archived_remote_object 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 255eec19ca259dc36cf8fdd0bdeac77e787044de8130631c539f3363c8a5cbf1
4
- data.tar.gz: c33825094d55dce29d7f45e13fca5a2ff18ba21048140fdb12b2bf9a44b41054
3
+ metadata.gz: 6a23d5372acad1ed18a22290fa96896f087af0a44a845aaa3b0bad2286548f6e
4
+ data.tar.gz: 67df0189bc73dc809acf27cbccff73bfd40e67aed2dfb5f0bbd5ed9a08821ead
5
5
  SHA512:
6
- metadata.gz: 878e44a20cccd12a454ca35d040588a38a37745c5f598646b1b4a543fa19df30c280b875feda87dd39878b5aab7701a88ac1970e804b245773961ee348a3d684
7
- data.tar.gz: 3eaaf3e07296ea1e6648dcc03d20657bca9ea6526f72c1c76ba5ff3d1f3675bdc6c7b983b584394065c3eb5af96fc2c940c868a6c6519d5eae108c1e26361397
6
+ metadata.gz: 832ba8691bc45707ee395dd262c4775b1f8c665bf6fd547f5bd0ddff2636e46ebec96ab5bb272e829b7de475c0c318e53dac1a551304731f638ad434cef194a5
7
+ data.tar.gz: a581302350ca3880e276b68db2d158f8be63f61481fd79066e2b3f73e78fdac35eb8362390c5b3614a136507684fd8fc9e6d8e7b00d1a935dd703c717e0ff301
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Aleksey Strizhak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,25 @@
1
+ require "archived_remote_object/version"
2
+ require "archived_remote_object/configuration"
3
+ require "archived_remote_object/archive/archived_object"
4
+ require "archived_remote_object/archive/restored_object"
5
+ require "archived_remote_object/aws_s3/archived_object"
6
+ require "archived_remote_object/aws_s3/remote_object"
7
+ require "archived_remote_object/aws_s3/client"
8
+
9
+ module ArchivedRemoteObject
10
+ def self.get_object(key) # rubocop:disable Metrics/MethodLength
11
+ Archive::RestoredObject.new(
12
+ key: key,
13
+ archived_object: Archive::ArchivedObject.new(
14
+ key: key,
15
+ remote_object: AwsS3::ArchivedObject.new(
16
+ key: key,
17
+ remote_object: AwsS3::RemoteObject.new(
18
+ key: key,
19
+ remote_client: AwsS3::Client.new
20
+ )
21
+ )
22
+ )
23
+ ).call
24
+ end
25
+ end
@@ -0,0 +1,58 @@
1
+ require "archived_remote_object/aws_s3/archived_object"
2
+
3
+ module ArchivedRemoteObject
4
+ module Archive
5
+ class ArchivedObject
6
+ CantBeRestoredError = Class.new(StandardError)
7
+
8
+ def initialize(
9
+ key:,
10
+ remote_object: AwsS3::ArchivedObject.new(key: key)
11
+ )
12
+ self.remote_object = remote_object
13
+ end
14
+
15
+ def archived?
16
+ remote_object.archived?
17
+ end
18
+
19
+ def restore_in_progress?
20
+ return false unless archived?
21
+
22
+ remote_object.restore_in_progress?
23
+ end
24
+
25
+ def restored?
26
+ return false unless archived?
27
+
28
+ remote_object.restored?
29
+ end
30
+
31
+ def restore
32
+ raise CantBeRestoredError if available? || restore_in_progress?
33
+
34
+ remote_object.restore
35
+ end
36
+
37
+ def available?
38
+ !archived? || restored?
39
+ end
40
+
41
+ def sync
42
+ tap { remote_object.sync }
43
+ end
44
+
45
+ def debug_state
46
+ {
47
+ restore_in_progress: restore_in_progress?,
48
+ restored: restored?,
49
+ **remote_object.debug_state
50
+ }
51
+ end
52
+
53
+ private
54
+
55
+ attr_accessor :remote_object
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,46 @@
1
+ require "ostruct"
2
+ require "archived_remote_object/archive/archived_object"
3
+
4
+ module ArchivedRemoteObject
5
+ module Archive
6
+ class RestoredObject
7
+ def initialize(
8
+ key:,
9
+ archived_object: Archive::ArchivedObject.new(key: key)
10
+ )
11
+ self.archived_object = archived_object
12
+ end
13
+
14
+ def call
15
+ assign_attributes
16
+
17
+ if attributes.status == :archived
18
+ archived_object.restore
19
+ attributes.status = :restoration_initiated
20
+ end
21
+
22
+ attributes
23
+ end
24
+
25
+ private
26
+
27
+ def attributes
28
+ @attributes ||= OpenStruct.new
29
+ end
30
+
31
+ def assign_attributes # rubocop:disable Metrics/AbcSize
32
+ if archived_object.available?
33
+ attributes.status = :available
34
+ elsif archived_object.restore_in_progress?
35
+ attributes.status = :in_progress
36
+ attributes.debug_state = archived_object.debug_state
37
+ else
38
+ attributes.status = :archived
39
+ attributes.debug_state = archived_object.debug_state
40
+ end
41
+ end
42
+
43
+ attr_accessor :archived_object
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,66 @@
1
+ require "archived_remote_object/aws_s3/remote_object"
2
+
3
+ module ArchivedRemoteObject
4
+ module AwsS3
5
+ class ArchivedObject
6
+ RestoreResponseChangedError = Class.new(StandardError)
7
+
8
+ def initialize(
9
+ key:,
10
+ remote_object: AwsS3::RemoteObject.new(key: key)
11
+ )
12
+ self.key = key
13
+ self.remote_object = remote_object
14
+ end
15
+
16
+ def archived?
17
+ remote_object.attributes.storage_class == "DEEP_ARCHIVE"
18
+ end
19
+
20
+ def restore_in_progress?
21
+ restore_in_progress = parse_restore_status[0]
22
+ return false unless restore_in_progress
23
+
24
+ restore_in_progress.to_s.downcase == "true"
25
+ end
26
+
27
+ def restored?
28
+ return false unless expiry_date
29
+
30
+ Time.parse(expiry_date) > Time.now
31
+ end
32
+
33
+ def restore
34
+ remote_object.restore(key: key, duration: restore_duration_days)
35
+ end
36
+
37
+ def sync
38
+ tap { remote_object.sync }
39
+ end
40
+
41
+ def debug_state
42
+ remote_object.debug_state
43
+ end
44
+
45
+ private
46
+
47
+ attr_accessor :key, :remote_object
48
+
49
+ def restore_duration_days
50
+ ArchivedRemoteObject.configuration.archive_restore_duration_days
51
+ end
52
+
53
+ def expiry_date
54
+ parse_restore_status[1]
55
+ end
56
+
57
+ def parse_restore_status
58
+ remote_object.attributes.restore =~ /ongoing-request="(.+?)"(, expiry-date="(.+?)")?/
59
+ last_match = Regexp.last_match
60
+ raise RestoreResponseChangedError if !remote_object.attributes.restore.nil? && !last_match
61
+
62
+ last_match&.captures || []
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,47 @@
1
+ require "aws-sdk-s3"
2
+
3
+ module ArchivedRemoteObject
4
+ module AwsS3
5
+ class Client
6
+ attr_accessor :s3_client
7
+
8
+ def initialize
9
+ self.s3_client = Aws::S3::Client.new(
10
+ stub_responses: stubbed?,
11
+ region: ArchivedRemoteObject.configuration.aws_region,
12
+ credentials: Aws::Credentials.new(
13
+ ArchivedRemoteObject.configuration.aws_access_key_id,
14
+ ArchivedRemoteObject.configuration.aws_secret_access_key
15
+ )
16
+ )
17
+ end
18
+
19
+ def fetch_object_data(key:, stubbed_response: {})
20
+ if stubbed?
21
+ response = {
22
+ storage_class: "DEEP_ARCHIVE",
23
+ restore: nil,
24
+ **stubbed_response
25
+ }
26
+ s3_client.stub_responses(:head_object, response)
27
+ end
28
+ s3_client.head_object(bucket: bucket, key: key)
29
+ end
30
+
31
+ def restore(key:, duration:)
32
+ s3_client.stub_responses(:restore_object) if stubbed?
33
+ s3_client.restore_object(bucket: bucket, key: key, restore_request: { days: duration })
34
+ end
35
+
36
+ private
37
+
38
+ def bucket
39
+ ArchivedRemoteObject.configuration.aws_bucket
40
+ end
41
+
42
+ def stubbed?
43
+ ArchivedRemoteObject.configuration.stub_client_requests
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,44 @@
1
+ require "archived_remote_object/aws_s3/client"
2
+
3
+ module ArchivedRemoteObject
4
+ module AwsS3
5
+ class RemoteObject
6
+ attr_accessor :key, :remote_client
7
+
8
+ def initialize(
9
+ key:,
10
+ remote_client: AwsS3::Client.new
11
+ )
12
+ self.key = key
13
+ self.remote_client = remote_client
14
+ end
15
+
16
+ def attributes
17
+ return @attributes if @attributes
18
+
19
+ fetch_attributes
20
+ end
21
+
22
+ def restore(**args)
23
+ remote_client.restore(**args)
24
+ end
25
+
26
+ def sync
27
+ tap { fetch_attributes }
28
+ end
29
+
30
+ def debug_state
31
+ {
32
+ restore: attributes.restore,
33
+ storage_class: attributes.storage_class
34
+ }
35
+ end
36
+
37
+ private
38
+
39
+ def fetch_attributes
40
+ @attributes = remote_client.fetch_object_data(key: key)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,13 @@
1
+ require "ostruct"
2
+
3
+ module ArchivedRemoteObject
4
+ class << self
5
+ def configuration
6
+ @configuration ||= OpenStruct.new
7
+ end
8
+
9
+ def configure
10
+ yield(configuration)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module ArchivedRemoteObject
2
+ VERSION = "0.1.1".freeze
3
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: archived_remote_object
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleksey Strizhak
@@ -73,7 +73,16 @@ email:
73
73
  executables: []
74
74
  extensions: []
75
75
  extra_rdoc_files: []
76
- files: []
76
+ files:
77
+ - LICENSE.txt
78
+ - lib/archived_remote_object.rb
79
+ - lib/archived_remote_object/archive/archived_object.rb
80
+ - lib/archived_remote_object/archive/restored_object.rb
81
+ - lib/archived_remote_object/aws_s3/archived_object.rb
82
+ - lib/archived_remote_object/aws_s3/client.rb
83
+ - lib/archived_remote_object/aws_s3/remote_object.rb
84
+ - lib/archived_remote_object/configuration.rb
85
+ - lib/archived_remote_object/version.rb
77
86
  homepage: https://github.com/Mifrill/archived_remote_object.git
78
87
  licenses:
79
88
  - MIT