onlyoffice_digitalocean_wrapper 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/lib/onlyoffice_digitalocean_wrapper.rb +2 -0
- data/lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper.rb +22 -105
- data/lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper/digitalocean_exceptions.rb +10 -0
- data/lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper/exceptions_retryer.rb +25 -0
- data/lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper/getters.rb +64 -0
- data/lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper/power_actions.rb +24 -0
- data/lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper/token_methods.rb +28 -0
- data/lib/onlyoffice_digitalocean_wrapper/version.rb +3 -1
- metadata +14 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '08215ee49f6936d3f70ed161523fcc48b592c8751d34d7ffbef3307bb40eb749'
|
4
|
+
data.tar.gz: 0dff61f8a1d793aa122ac9da2dc5fb6211c3abd857b648064913a145647e9760
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd8d6319ac155f23e09a7d5529e0c8ce413a21550f5a017c9b6fd0facf09b80ec9bd9ab65b6eb01ee14defb09f0a125ad3e589f7f9e94e511ac55da7c7b35a9f
|
7
|
+
data.tar.gz: 908593c16b2993bf04ea512a9010e3ee98c7f28eec7cc37819d861a5acc5b8b6b19e3ad7e416ecccf5fe0d3be98ab43e29ffb366545b518933309b24fd87adc8
|
@@ -1,78 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'droplet_kit'
|
2
4
|
require 'onlyoffice_logger_helper'
|
3
5
|
require_relative 'digitalocean_wrapper/digitalocean_exceptions'
|
6
|
+
require_relative 'digitalocean_wrapper/exceptions_retryer'
|
7
|
+
require_relative 'digitalocean_wrapper/getters'
|
8
|
+
require_relative 'digitalocean_wrapper/power_actions'
|
9
|
+
require_relative 'digitalocean_wrapper/token_methods'
|
4
10
|
|
5
11
|
module OnlyofficeDigitaloceanWrapper
|
6
12
|
# Class for wrapping DigitalOcean API gem
|
7
13
|
class DigitalOceanWrapper
|
14
|
+
include Getters
|
15
|
+
include ExceptionsRetryer
|
16
|
+
include PowerActions
|
17
|
+
include TokenMethods
|
18
|
+
|
19
|
+
DROPLET_SIZES = %w[512mb 1gb 2gb 4gb 8gb 16gb 32gb 48gb 64gb].freeze
|
8
20
|
attr_accessor :client
|
9
21
|
|
10
22
|
def initialize(access_token = nil)
|
11
|
-
access_token ||=
|
23
|
+
access_token ||= read_token
|
12
24
|
@client = DropletKit::Client.new(access_token: access_token)
|
13
25
|
raise ArgumentError, 'DigitalOceanWrapper: Your Access Token is Incorrect' unless correct_access_token?
|
14
26
|
end
|
15
27
|
|
16
|
-
# Check if access token is correct
|
17
|
-
# @return [true, false] result of check
|
18
|
-
def correct_access_token?
|
19
|
-
begin
|
20
|
-
@client.droplets.all.first
|
21
|
-
rescue DropletKit::Error
|
22
|
-
return false
|
23
|
-
end
|
24
|
-
true
|
25
|
-
end
|
26
|
-
|
27
|
-
# Check if token is correct. If not trying to read new token
|
28
|
-
# If reading failed - fail
|
29
|
-
def assure_correct_token
|
30
|
-
return if correct_access_token?
|
31
|
-
@client = DropletKit::Client.new(access_token: DigitalOceanWrapper.read_token)
|
32
|
-
return if correct_access_token?
|
33
|
-
raise ArgumentError, 'Access token for DigitalOcean API is incorrect'
|
34
|
-
end
|
35
|
-
|
36
|
-
def get_image_id_by_name(image_name)
|
37
|
-
assure_correct_token
|
38
|
-
all_droplets = @client.images.all
|
39
|
-
image = all_droplets.find { |x| x.name == image_name }
|
40
|
-
raise DigitalOceanImageNotFound, image_name if image.nil?
|
41
|
-
OnlyofficeLoggerHelper.log("get_image_id_by_name(#{image_name}): #{image.id}")
|
42
|
-
image.id
|
43
|
-
end
|
44
|
-
|
45
|
-
# Get droplet by its name
|
46
|
-
# @param [String] droplet_name
|
47
|
-
# @return [DropletKit::Droplet] droplet
|
48
|
-
def droplet_by_name(droplet_name)
|
49
|
-
assure_correct_token
|
50
|
-
droplets = @client.droplets.all
|
51
|
-
droplets.find { |x| x.name == droplet_name }
|
52
|
-
end
|
53
|
-
|
54
|
-
def get_droplet_id_by_name(droplet_name)
|
55
|
-
droplet = droplet_by_name(droplet_name)
|
56
|
-
if droplet.nil?
|
57
|
-
OnlyofficeLoggerHelper.log("get_droplet_id_by_name(#{droplet_name}): not found any droplets")
|
58
|
-
nil
|
59
|
-
else
|
60
|
-
OnlyofficeLoggerHelper.log("get_droplet_id_by_name(#{droplet_name}): #{droplet.id}")
|
61
|
-
droplet.id
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def get_droplet_ip_by_name(droplet_name)
|
66
|
-
droplet = droplet_by_name(droplet_name)
|
67
|
-
if droplet.nil?
|
68
|
-
OnlyofficeLoggerHelper.log("There is no created droplet with name: #{droplet_name}")
|
69
|
-
return
|
70
|
-
end
|
71
|
-
ip = droplet.networks.first.first.ip_address
|
72
|
-
OnlyofficeLoggerHelper.log("get_droplet_ip_by_name(#{droplet_name}): #{ip}")
|
73
|
-
ip
|
74
|
-
end
|
75
|
-
|
76
28
|
def current_kernel(droplet_name)
|
77
29
|
droplet = droplet_by_name(droplet_name)
|
78
30
|
kernel_name = droplet.kernel.name
|
@@ -80,21 +32,8 @@ module OnlyofficeDigitaloceanWrapper
|
|
80
32
|
kernel_name
|
81
33
|
end
|
82
34
|
|
83
|
-
def
|
84
|
-
|
85
|
-
if droplet.nil?
|
86
|
-
OnlyofficeLoggerHelper.log("get_droplet_status_by_name(#{droplet_name}): not found any droplets")
|
87
|
-
nil
|
88
|
-
else
|
89
|
-
status = droplet.status
|
90
|
-
status = :locked if droplet.locked
|
91
|
-
OnlyofficeLoggerHelper.log("get_droplet_status_by_name(#{droplet_name}): #{status}")
|
92
|
-
status
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def wait_until_droplet_have_status(droplet_name, status = 'active')
|
97
|
-
timeout = 300
|
35
|
+
def wait_until_droplet_have_status(droplet_name, status = 'active', params = {})
|
36
|
+
timeout = params.fetch(:timeout, 300)
|
98
37
|
counter = 0
|
99
38
|
while get_droplet_status_by_name(droplet_name) != status && counter < timeout
|
100
39
|
counter += 10
|
@@ -102,6 +41,8 @@ module OnlyofficeDigitaloceanWrapper
|
|
102
41
|
OnlyofficeLoggerHelper.log("waiting for droplet (#{droplet_name}) to have "\
|
103
42
|
"status: #{status} for #{counter} seconds of #{timeout}")
|
104
43
|
end
|
44
|
+
raise DropletOperationTimeout, "#{droplet_name} was not #{status} for #{timeout}s" if counter >= timeout
|
45
|
+
|
105
46
|
get_droplet_status_by_name(droplet_name)
|
106
47
|
end
|
107
48
|
|
@@ -114,9 +55,13 @@ module OnlyofficeDigitaloceanWrapper
|
|
114
55
|
|
115
56
|
def restore_image_by_name(image_name = 'nct-at-stable',
|
116
57
|
droplet_name = image_name,
|
117
|
-
region = '
|
58
|
+
region = 'nyc3',
|
118
59
|
size = '2gb',
|
119
60
|
tags: nil)
|
61
|
+
unless DROPLET_SIZES.include?(size)
|
62
|
+
raise DigitalOceanSizeNotSupported,
|
63
|
+
"There is no support of droplets with size: #{size}"
|
64
|
+
end
|
120
65
|
image_id = get_image_id_by_name(image_name)
|
121
66
|
droplet = DropletKit::Droplet.new(name: droplet_name,
|
122
67
|
region: region,
|
@@ -132,39 +77,11 @@ module OnlyofficeDigitaloceanWrapper
|
|
132
77
|
created
|
133
78
|
end
|
134
79
|
|
135
|
-
def power_off_droplet(droplet_name)
|
136
|
-
droplet_id = get_droplet_id_by_name(droplet_name)
|
137
|
-
client.droplet_actions.power_off(droplet_id: droplet_id)
|
138
|
-
wait_until_droplet_have_status(droplet_name, 'off')
|
139
|
-
end
|
140
|
-
|
141
|
-
def power_on_droplet(droplet_name)
|
142
|
-
droplet_id = get_droplet_id_by_name(droplet_name)
|
143
|
-
client.droplet_actions.power_on(droplet_id: droplet_id)
|
144
|
-
wait_until_droplet_have_status(droplet_name)
|
145
|
-
end
|
146
|
-
|
147
|
-
def reboot_droplet(droplet_name)
|
148
|
-
droplet_id = get_droplet_id_by_name(droplet_name)
|
149
|
-
client.droplet_actions.reboot(droplet_id: droplet_id)
|
150
|
-
wait_until_droplet_have_status(droplet_name)
|
151
|
-
end
|
152
|
-
|
153
80
|
def destroy_droplet_by_name(droplet_name = 'nct-at1')
|
154
81
|
droplet_id = get_droplet_id_by_name(droplet_name)
|
155
82
|
client.droplets.delete(id: droplet_id)
|
156
83
|
OnlyofficeLoggerHelper.log("destroy_droplet_by_name(#{droplet_name})")
|
157
84
|
wait_until_droplet_have_status(droplet_name, nil)
|
158
85
|
end
|
159
|
-
|
160
|
-
# Read access token from file system
|
161
|
-
# @return [String] token
|
162
|
-
def self.read_token
|
163
|
-
return ENV['DO_ACCESS_TOKEN'] if ENV['DO_ACCESS_TOKEN']
|
164
|
-
File.read(Dir.home + '/.do/access_token').delete("\n")
|
165
|
-
rescue Errno::ENOENT
|
166
|
-
raise Errno::ENOENT, "No access token found in #{Dir.home}/.do/ directory." \
|
167
|
-
"Please create files #{Dir.home}/.do/access_token"
|
168
|
-
end
|
169
86
|
end
|
170
87
|
end
|
@@ -1,5 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module OnlyofficeDigitaloceanWrapper
|
2
4
|
# Class raised if image with name is not found
|
3
5
|
class DigitalOceanImageNotFound < StandardError
|
4
6
|
end
|
7
|
+
|
8
|
+
# Class raised if droplet size is not supported
|
9
|
+
class DigitalOceanSizeNotSupported < StandardError
|
10
|
+
end
|
11
|
+
|
12
|
+
# Class raised if droplet opertaion is timeout
|
13
|
+
class DropletOperationTimeout < StandardError
|
14
|
+
end
|
5
15
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnlyofficeDigitaloceanWrapper
|
4
|
+
# Module to ignore DigitalOcean exception if they happen irregularly
|
5
|
+
module ExceptionsRetryer
|
6
|
+
# Retry if exception happened
|
7
|
+
# @param exception [Exception] exception to retry
|
8
|
+
# @param retries [Integer] how much to retry
|
9
|
+
# @param timeout [Integer] wait until next retry
|
10
|
+
def retry_exception(exception = DropletKit::Error,
|
11
|
+
retries: 5,
|
12
|
+
timeout: 10)
|
13
|
+
try = 0
|
14
|
+
begin
|
15
|
+
yield
|
16
|
+
rescue exception => e
|
17
|
+
try += 1
|
18
|
+
OnlyofficeLoggerHelper.log("Error '#{exception}, #{e}' happened during "\
|
19
|
+
"operation. Retrying #{try} of #{retries}")
|
20
|
+
sleep timeout # Time to cooldown error
|
21
|
+
try <= retries ? retry : raise
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnlyofficeDigitaloceanWrapper
|
4
|
+
# Get image, droplet by metadata
|
5
|
+
module Getters
|
6
|
+
def get_image_id_by_name(image_name)
|
7
|
+
all_droplets = @client.images.all
|
8
|
+
image = all_droplets.find { |x| x.name == image_name }
|
9
|
+
raise DigitalOceanImageNotFound, image_name if image.nil?
|
10
|
+
|
11
|
+
OnlyofficeLoggerHelper.log("get_image_id_by_name(#{image_name}): #{image.id}")
|
12
|
+
image.id
|
13
|
+
end
|
14
|
+
|
15
|
+
# Get droplet by its name
|
16
|
+
# @param [String] droplet_name
|
17
|
+
# @return [DropletKit::Droplet] droplet
|
18
|
+
def droplet_by_name(droplet_name)
|
19
|
+
retry_exception do
|
20
|
+
droplets = @client.droplets.all
|
21
|
+
droplets.find { |x| x.name == droplet_name }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_droplet_id_by_name(droplet_name)
|
26
|
+
droplet = droplet_by_name(droplet_name)
|
27
|
+
if droplet.nil?
|
28
|
+
OnlyofficeLoggerHelper.log("get_droplet_id_by_name(#{droplet_name}): not found any droplets")
|
29
|
+
nil
|
30
|
+
else
|
31
|
+
OnlyofficeLoggerHelper.log("get_droplet_id_by_name(#{droplet_name}): #{droplet.id}")
|
32
|
+
droplet.id
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_droplet_ip_by_name(droplet_name)
|
37
|
+
droplet = droplet_by_name(droplet_name)
|
38
|
+
if droplet.nil?
|
39
|
+
OnlyofficeLoggerHelper.log("There is no created droplet with name: #{droplet_name}")
|
40
|
+
return
|
41
|
+
end
|
42
|
+
retry_exception do
|
43
|
+
ip = droplet.networks.first.first.ip_address
|
44
|
+
OnlyofficeLoggerHelper.log("get_droplet_ip_by_name(#{droplet_name}): #{ip}")
|
45
|
+
ip
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_droplet_status_by_name(droplet_name)
|
50
|
+
droplet = droplet_by_name(droplet_name)
|
51
|
+
if droplet.nil?
|
52
|
+
OnlyofficeLoggerHelper.log("get_droplet_status_by_name(#{droplet_name}): not found any droplets")
|
53
|
+
nil
|
54
|
+
else
|
55
|
+
retry_exception do
|
56
|
+
status = droplet.status
|
57
|
+
status = :locked if droplet.locked
|
58
|
+
OnlyofficeLoggerHelper.log("get_droplet_status_by_name(#{droplet_name}): #{status}")
|
59
|
+
status
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnlyofficeDigitaloceanWrapper
|
4
|
+
# Actions with power (turn on/off, reboot)
|
5
|
+
module PowerActions
|
6
|
+
def power_off_droplet(droplet_name)
|
7
|
+
droplet_id = get_droplet_id_by_name(droplet_name)
|
8
|
+
client.droplet_actions.power_off(droplet_id: droplet_id)
|
9
|
+
wait_until_droplet_have_status(droplet_name, 'off')
|
10
|
+
end
|
11
|
+
|
12
|
+
def power_on_droplet(droplet_name)
|
13
|
+
droplet_id = get_droplet_id_by_name(droplet_name)
|
14
|
+
client.droplet_actions.power_on(droplet_id: droplet_id)
|
15
|
+
wait_until_droplet_have_status(droplet_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def reboot_droplet(droplet_name)
|
19
|
+
droplet_id = get_droplet_id_by_name(droplet_name)
|
20
|
+
client.droplet_actions.reboot(droplet_id: droplet_id)
|
21
|
+
wait_until_droplet_have_status(droplet_name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnlyofficeDigitaloceanWrapper
|
4
|
+
# Methods to login in account
|
5
|
+
module TokenMethods
|
6
|
+
# Check if access token is correct
|
7
|
+
# @return [true, false] result of check
|
8
|
+
def correct_access_token?
|
9
|
+
begin
|
10
|
+
@client.droplets.all.first
|
11
|
+
rescue DropletKit::Error
|
12
|
+
return false
|
13
|
+
end
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
# Read access token from file system
|
18
|
+
# @return [String] token
|
19
|
+
def read_token
|
20
|
+
return ENV['DO_ACCESS_TOKEN'] if ENV['DO_ACCESS_TOKEN']
|
21
|
+
|
22
|
+
File.read(Dir.home + '/.do/access_token').delete("\n")
|
23
|
+
rescue Errno::ENOENT
|
24
|
+
raise Errno::ENOENT, "No access token found in #{Dir.home}/.do/ directory." \
|
25
|
+
"Please create files #{Dir.home}/.do/access_token"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: onlyoffice_digitalocean_wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pavel Lobashov
|
@@ -9,50 +9,36 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-02-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: activesupport
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - "~>"
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '4'
|
21
|
-
type: :runtime
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - "~>"
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: '4'
|
28
14
|
- !ruby/object:Gem::Dependency
|
29
15
|
name: droplet_kit
|
30
16
|
requirement: !ruby/object:Gem::Requirement
|
31
17
|
requirements:
|
32
18
|
- - "~>"
|
33
19
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
20
|
+
version: '3'
|
35
21
|
type: :runtime
|
36
22
|
prerelease: false
|
37
23
|
version_requirements: !ruby/object:Gem::Requirement
|
38
24
|
requirements:
|
39
25
|
- - "~>"
|
40
26
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
27
|
+
version: '3'
|
42
28
|
- !ruby/object:Gem::Dependency
|
43
29
|
name: onlyoffice_logger_helper
|
44
30
|
requirement: !ruby/object:Gem::Requirement
|
45
31
|
requirements:
|
46
|
-
- -
|
32
|
+
- - "~>"
|
47
33
|
- !ruby/object:Gem::Version
|
48
|
-
version: 1
|
34
|
+
version: '1'
|
49
35
|
type: :runtime
|
50
36
|
prerelease: false
|
51
37
|
version_requirements: !ruby/object:Gem::Requirement
|
52
38
|
requirements:
|
53
|
-
- -
|
39
|
+
- - "~>"
|
54
40
|
- !ruby/object:Gem::Version
|
55
|
-
version: 1
|
41
|
+
version: '1'
|
56
42
|
description: Wrapper gem for DigitalOcean. Use in testing projects
|
57
43
|
email:
|
58
44
|
- shockwavenn@gmail.com
|
@@ -65,6 +51,10 @@ files:
|
|
65
51
|
- lib/onlyoffice_digitalocean_wrapper.rb
|
66
52
|
- lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper.rb
|
67
53
|
- lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper/digitalocean_exceptions.rb
|
54
|
+
- lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper/exceptions_retryer.rb
|
55
|
+
- lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper/getters.rb
|
56
|
+
- lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper/power_actions.rb
|
57
|
+
- lib/onlyoffice_digitalocean_wrapper/digitalocean_wrapper/token_methods.rb
|
68
58
|
- lib/onlyoffice_digitalocean_wrapper/version.rb
|
69
59
|
homepage: https://github.com/onlyoffice-testing-robot/onlyoffice_digitalocean_wrapper
|
70
60
|
licenses:
|
@@ -78,15 +68,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
68
|
requirements:
|
79
69
|
- - ">="
|
80
70
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
71
|
+
version: '2.2'
|
82
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
73
|
requirements:
|
84
74
|
- - ">="
|
85
75
|
- !ruby/object:Gem::Version
|
86
76
|
version: '0'
|
87
77
|
requirements: []
|
88
|
-
|
89
|
-
rubygems_version: 2.5.1
|
78
|
+
rubygems_version: 3.0.6
|
90
79
|
signing_key:
|
91
80
|
specification_version: 4
|
92
81
|
summary: Wrapper gem for DigitalOcean
|