1and1 1.1 → 1.2.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 +4 -4
- data/.gitattributes +1 -0
- data/.travis.yml +28 -0
- data/1and1.gemspec +2 -2
- data/README.md +87 -14
- data/docs/reference.md +2595 -2446
- data/examples/block_storage_examples.rb +50 -0
- data/examples/ssh_key_examples.rb +38 -0
- data/lib/1and1/block_storage.rb +286 -0
- data/lib/1and1/image.rb +6 -2
- data/lib/1and1/recovery_appliance.rb +73 -0
- data/lib/1and1/server.rb +170 -102
- data/lib/1and1/ssh_keys.rb +227 -0
- data/lib/oneandone.rb +3 -0
- data/sphinx/recovery_appliances.rst +42 -0
- data/test/mock-api/attach-block-storage.json +18 -0
- data/test/mock-api/create-block-storage.json +14 -0
- data/test/mock-api/create-ssh-key.json +10 -0
- data/test/mock-api/delete-block-storage.json +18 -0
- data/test/mock-api/delete-ssh-key.json +13 -0
- data/test/mock-api/detach-block-storage.json +14 -0
- data/test/mock-api/get-block-storage.json +18 -0
- data/test/mock-api/get-recovery-appliance.json +13 -0
- data/test/mock-api/get-ssh-key.json +13 -0
- data/test/mock-api/list-block-storages.json +52 -0
- data/test/mock-api/list-recovery-appliances.json +58 -0
- data/test/mock-api/list-ssh-keys.json +28 -0
- data/test/mock-api/modify-block-storage.json +18 -0
- data/test/mock-api/modify-ssh-key.json +13 -0
- data/test/test_mock_block_storage.rb +167 -0
- data/test/test_mock_recovery_appliance.rb +55 -0
- data/test/test_mock_ssh_key.rb +118 -0
- metadata +36 -12
- data/1and1-1.0.gem +0 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
OneAndOne.start('<API-TOKEN>')
|
2
|
+
|
3
|
+
block_storage = OneAndOne::BlockStorage.new
|
4
|
+
|
5
|
+
# Create a block storage
|
6
|
+
response = block_storage.create(name: 'My block storage',
|
7
|
+
description: 'My block storage description',
|
8
|
+
size: 20,
|
9
|
+
datacenter_id: '908DC2072407C94C8054610AD5A53B8C')
|
10
|
+
|
11
|
+
puts JSON.pretty_generate(response)
|
12
|
+
|
13
|
+
|
14
|
+
# List all block storages on your account
|
15
|
+
response = block_storage.list
|
16
|
+
|
17
|
+
puts JSON.pretty_generate(response)
|
18
|
+
|
19
|
+
|
20
|
+
# Retrieve a single block storage
|
21
|
+
response = block_storage.get(block_storage_id: '<BLOCK-STORAGE-ID>')
|
22
|
+
|
23
|
+
puts JSON.pretty_generate(response)
|
24
|
+
|
25
|
+
|
26
|
+
# Modify a block storage
|
27
|
+
response = block_storage.modify(block_storage_id: '<BLOCK-STORAGE-ID>',
|
28
|
+
name: 'Test Block Storage Rename',
|
29
|
+
description: 'Test Block Storage Description Update')
|
30
|
+
|
31
|
+
puts JSON.pretty_generate(response)
|
32
|
+
|
33
|
+
|
34
|
+
# Attach a block storage to a server
|
35
|
+
response = block_storage.attach_server(block_storage_id: '<BLOCK-STORAGE-ID>',
|
36
|
+
server_id: '<SERVER-ID>')
|
37
|
+
|
38
|
+
puts JSON.pretty_generate(response)
|
39
|
+
|
40
|
+
|
41
|
+
# Detach a block storage from a server
|
42
|
+
response = block_storage.detach_server(block_storage_id: '<BLOCK-STORAGE-ID>')
|
43
|
+
|
44
|
+
puts JSON.pretty_generate(response)
|
45
|
+
|
46
|
+
|
47
|
+
# Delete a block storage
|
48
|
+
response = block_storage.delete(block_storage_id: '<BLOCK-STORAGE-ID>')
|
49
|
+
|
50
|
+
puts JSON.pretty_generate(response)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
OneAndOne.start('<API-TOKEN>') # Init module with API key
|
2
|
+
|
3
|
+
ssh_key = OneAndOne::SshKey.new()
|
4
|
+
|
5
|
+
# Create a new SSH Key
|
6
|
+
response = ssh_key.create(name: 'Test SSH Key',
|
7
|
+
description: 'Test Description',
|
8
|
+
public_key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6U+LbJPFNDkORkrVUSg78IJjNDSBY1NgDzhr0S9rLvRVInHDT+3DsojZDqXglCpaLwNcdIQM1saGlIKlmxJro8Qw2kJRKqhP/DZLmvcz+niUKZ/0ho1a5HAlTJl6ct8DFto/z+hhDIHTRL4i7n+M/n9SNGjQ28EQy6SztsqwV8yheiUIgNO2lOXDi1Pjs7znBLFE305AHpf6pv4jlUE7r280+WAuloZJaNtu2YL4XXKsemBliDet54OJaW/4e+/5TexX0wZwkibdhuCSFJvhCJ6jbJZbdUwCyqlz6tiu75bSUTV7WGlxWtUjZCY0KBO9BPwbTDhxmIAeigDxnSRhekC/5b7cYUVys0JgvxBKiBVg6Bc32c7fjeOrNpUixzVxtm6UQtZDYyOa+1OvPKPpHg1Ugy28aUtqV4yRYQbltkLB8JSKaZvCqzm9d6qXhkCKV2GmMs5glBE0MyZMiwgoc+Ar0HuN3RnYNzIWIZc1CYTfKB+otHEwmb8V4hS6/k50obPa4J81RJekLU/8yY0WDRWVven6hyriBhNJXpI3V84XqSB4cl1HNcFgeat+EbM5e5QuLUn3Uwdt15kugQt5t9LqVK1jyqWQ4CrJ+Yg7/uU7l7fPHH0rvk9LvSv4BXlHETbScUDOnaZnr8m+4HJyucVq1tXdPCCDSyGGNO/IFBw== test@email.com')
|
9
|
+
|
10
|
+
puts JSON.pretty_generate(response)
|
11
|
+
|
12
|
+
|
13
|
+
# List all SSH Key's on your account
|
14
|
+
response = ssh_key.list
|
15
|
+
|
16
|
+
puts JSON.pretty_generate(response)
|
17
|
+
|
18
|
+
|
19
|
+
# Retrieve an SSH Key
|
20
|
+
response = ssh_key.get(ssh_key_id: '<SSH-KEY-ID>')
|
21
|
+
|
22
|
+
puts JSON.pretty_generate(response)
|
23
|
+
|
24
|
+
|
25
|
+
# Modify an SSH Key
|
26
|
+
response = ssh_key.modify(ssh_key_id: '<SSH-KEY-ID>',
|
27
|
+
name: 'New Name',
|
28
|
+
description: 'New Description')
|
29
|
+
|
30
|
+
puts JSON.pretty_generate(response)
|
31
|
+
|
32
|
+
|
33
|
+
# Delete an SSH Key
|
34
|
+
ssh_key = OneAndOne::SshKey.new()
|
35
|
+
|
36
|
+
response = ssh_key.delete(ssh_key_id: '<SSH-KEY-ID>')
|
37
|
+
|
38
|
+
puts JSON.pretty_generate(response)
|
@@ -0,0 +1,286 @@
|
|
1
|
+
module OneAndOne
|
2
|
+
|
3
|
+
|
4
|
+
class BlockStorage
|
5
|
+
|
6
|
+
|
7
|
+
attr_accessor :id
|
8
|
+
attr_accessor :specs
|
9
|
+
|
10
|
+
|
11
|
+
def initialize(test: false)
|
12
|
+
@id = nil
|
13
|
+
@specs = nil
|
14
|
+
|
15
|
+
# Check if hitting mock api or live api
|
16
|
+
if test
|
17
|
+
@connection = Excon.new($base_url, :mock => true)
|
18
|
+
else
|
19
|
+
@connection = Excon.new($base_url)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def list(page: nil, per_page: nil, sort: nil, q: nil, fields: nil)
|
26
|
+
|
27
|
+
# Build hash for query parameters
|
28
|
+
keyword_args = {
|
29
|
+
:page => page,
|
30
|
+
:per_page => per_page,
|
31
|
+
:sort => sort,
|
32
|
+
:q => q,
|
33
|
+
:fields => fields
|
34
|
+
}
|
35
|
+
|
36
|
+
# Clean out null query parameters
|
37
|
+
params = OneAndOne.clean_hash(keyword_args)
|
38
|
+
|
39
|
+
# Build URL
|
40
|
+
path = OneAndOne.build_url('/block_storages')
|
41
|
+
|
42
|
+
# Perform request
|
43
|
+
response = @connection.request(:method => :get,
|
44
|
+
:path => path,
|
45
|
+
:headers => $header,
|
46
|
+
:query => params)
|
47
|
+
|
48
|
+
# Check response status
|
49
|
+
OneAndOne.check_response(response.body, response.status)
|
50
|
+
|
51
|
+
#JSON-ify the response string
|
52
|
+
JSON.parse(response.body)
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def create(name: nil, description: nil, size: nil, datacenter_id: nil, server_id: nil)
|
58
|
+
|
59
|
+
# Build POST body
|
60
|
+
new_block_storage = {
|
61
|
+
'name' => name,
|
62
|
+
'description' => description,
|
63
|
+
'size' => size,
|
64
|
+
'datacenter_id' => datacenter_id,
|
65
|
+
'server' => server_id
|
66
|
+
}
|
67
|
+
|
68
|
+
# Clean out null keys in POST body
|
69
|
+
body = OneAndOne.clean_hash(new_block_storage)
|
70
|
+
|
71
|
+
# Stringify the POST body
|
72
|
+
string_body = body.to_json
|
73
|
+
|
74
|
+
# Build URL
|
75
|
+
path = OneAndOne.build_url('/block_storages')
|
76
|
+
|
77
|
+
# Perform request
|
78
|
+
response = @connection.request(:method => :post,
|
79
|
+
:path => path,
|
80
|
+
:headers => $header,
|
81
|
+
:body => string_body)
|
82
|
+
|
83
|
+
# Check response status
|
84
|
+
OneAndOne.check_response(response.body, response.status)
|
85
|
+
|
86
|
+
#JSON-ify the response string
|
87
|
+
json = JSON.parse(response.body)
|
88
|
+
|
89
|
+
# Save new block storage ID to BlockStorage instance
|
90
|
+
@id = json['id']
|
91
|
+
@specs = json
|
92
|
+
|
93
|
+
# If all good, return JSON
|
94
|
+
json
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
def get(block_storage_id: @id)
|
100
|
+
|
101
|
+
# If user passed in block_storage ID, reassign
|
102
|
+
@id = block_storage_id
|
103
|
+
|
104
|
+
# Build URL
|
105
|
+
path = OneAndOne.build_url("/block_storages/#{@id}")
|
106
|
+
|
107
|
+
# Perform request
|
108
|
+
response = @connection.request(:method => :get,
|
109
|
+
:path => path,
|
110
|
+
:headers => $header)
|
111
|
+
|
112
|
+
# Check response status
|
113
|
+
OneAndOne.check_response(response.body, response.status)
|
114
|
+
|
115
|
+
#JSON-ify the response string
|
116
|
+
json = JSON.parse(response.body)
|
117
|
+
|
118
|
+
# Reload specs attribute
|
119
|
+
@specs = json
|
120
|
+
|
121
|
+
# If all good, return JSON
|
122
|
+
json
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
def modify(block_storage_id: @id, name: nil, description: nil, size: nil)
|
128
|
+
|
129
|
+
# If user passed in block_storage ID, reassign
|
130
|
+
@id = block_storage_id
|
131
|
+
|
132
|
+
# Build PUT body
|
133
|
+
new_storage = {
|
134
|
+
'name' => name,
|
135
|
+
'description' => description,
|
136
|
+
'size' => size,
|
137
|
+
}
|
138
|
+
|
139
|
+
# Clean out null keys in POST body
|
140
|
+
body = OneAndOne.clean_hash(new_storage)
|
141
|
+
|
142
|
+
# Stringify the POST body
|
143
|
+
string_body = body.to_json
|
144
|
+
|
145
|
+
# Build URL
|
146
|
+
path = OneAndOne.build_url("/block_storages/#{@id}")
|
147
|
+
|
148
|
+
# Perform request
|
149
|
+
response = @connection.request(:method => :put,
|
150
|
+
:path => path,
|
151
|
+
:headers => $header,
|
152
|
+
:body => string_body)
|
153
|
+
|
154
|
+
# Check response status
|
155
|
+
OneAndOne.check_response(response.body, response.status)
|
156
|
+
|
157
|
+
#JSON-ify the response string
|
158
|
+
JSON.parse(response.body)
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
def delete(block_storage_id: @id)
|
164
|
+
|
165
|
+
# If user passed in block_storage ID, reassign
|
166
|
+
@id = block_storage_id
|
167
|
+
|
168
|
+
# Build URL
|
169
|
+
path = OneAndOne.build_url("/block_storages/#{@id}")
|
170
|
+
|
171
|
+
# Perform request
|
172
|
+
response = @connection.request(:method => :delete,
|
173
|
+
:path => path,
|
174
|
+
:headers => $header)
|
175
|
+
|
176
|
+
# Check response status
|
177
|
+
OneAndOne.check_response(response.body, response.status)
|
178
|
+
|
179
|
+
#JSON-ify the response string
|
180
|
+
JSON.parse(response.body)
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
def attach_server(block_storage_id: @id, server_id: nil)
|
186
|
+
|
187
|
+
# If user passed in block_storage ID, reassign
|
188
|
+
@id = block_storage_id
|
189
|
+
|
190
|
+
# Build POST body
|
191
|
+
new_server = {
|
192
|
+
'server' => server_id
|
193
|
+
}
|
194
|
+
|
195
|
+
# Clean out null keys in POST body
|
196
|
+
body = OneAndOne.clean_hash(new_server)
|
197
|
+
|
198
|
+
# Stringify the POST body
|
199
|
+
string_body = body.to_json
|
200
|
+
|
201
|
+
# Build URL
|
202
|
+
path = OneAndOne.build_url("/block_storages/#{@id}/server")
|
203
|
+
|
204
|
+
# Perform request
|
205
|
+
response = @connection.request(:method => :post,
|
206
|
+
:path => path,
|
207
|
+
:headers => $header,
|
208
|
+
:body => string_body)
|
209
|
+
|
210
|
+
# Check response status
|
211
|
+
OneAndOne.check_response(response.body, response.status)
|
212
|
+
|
213
|
+
#JSON-ify the response string
|
214
|
+
JSON.parse(response.body)
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
def detach_server(block_storage_id: @id)
|
220
|
+
|
221
|
+
# If user passed in block_storage ID, reassign
|
222
|
+
@id = block_storage_id
|
223
|
+
|
224
|
+
# Build URL
|
225
|
+
path = OneAndOne.build_url("/block_storages/#{@id}/server")
|
226
|
+
|
227
|
+
# Perform request
|
228
|
+
response = @connection.request(:method => :delete,
|
229
|
+
:path => path,
|
230
|
+
:headers => $header)
|
231
|
+
|
232
|
+
# Check response status
|
233
|
+
OneAndOne.check_response(response.body, response.status)
|
234
|
+
|
235
|
+
#JSON-ify the response string
|
236
|
+
JSON.parse(response.body)
|
237
|
+
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
def reload
|
242
|
+
|
243
|
+
# This reload fx is just a wrapper for the get fx
|
244
|
+
get
|
245
|
+
|
246
|
+
end
|
247
|
+
|
248
|
+
|
249
|
+
def wait_for(timeout: 25, interval: 5)
|
250
|
+
|
251
|
+
# Capture start time
|
252
|
+
start = Time.now
|
253
|
+
|
254
|
+
# Poll block storage and check initial state
|
255
|
+
initial_response = get
|
256
|
+
block_storage_state = initial_response['state']
|
257
|
+
|
258
|
+
# Keep polling the block storage's state until good
|
259
|
+
until $good_states.include? block_storage_state
|
260
|
+
|
261
|
+
# Wait 5 seconds before polling again
|
262
|
+
sleep interval
|
263
|
+
|
264
|
+
# Check block storage state again
|
265
|
+
current_response = get
|
266
|
+
block_storage_state = current_response['state']
|
267
|
+
|
268
|
+
# Calculate current duration and check for timeout
|
269
|
+
duration = (Time.now - start) / 60
|
270
|
+
if duration > timeout
|
271
|
+
puts "The operation timed out after #{timeout} minutes.\n"
|
272
|
+
return
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
# Return Duration
|
278
|
+
{:duration => duration}
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
|
283
|
+
end
|
284
|
+
|
285
|
+
|
286
|
+
end
|
data/lib/1and1/image.rb
CHANGED
@@ -83,7 +83,7 @@ module OneAndOne
|
|
83
83
|
|
84
84
|
|
85
85
|
def create(server_id: nil, name: nil, description: nil, frequency: nil,
|
86
|
-
num_images: nil)
|
86
|
+
num_images: nil, source: nil, url: nil, os_id: nil, type: nil)
|
87
87
|
|
88
88
|
# Build POST body
|
89
89
|
new_image = {
|
@@ -91,7 +91,11 @@ module OneAndOne
|
|
91
91
|
'name' => name,
|
92
92
|
'description' => description,
|
93
93
|
'frequency' => frequency,
|
94
|
-
'num_images' => num_images
|
94
|
+
'num_images' => num_images,
|
95
|
+
'source' => source,
|
96
|
+
'url' => url,
|
97
|
+
'os_id' => os_id,
|
98
|
+
'type' => type
|
95
99
|
}
|
96
100
|
|
97
101
|
# Clean out null keys in POST body
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module OneAndOne
|
2
|
+
|
3
|
+
|
4
|
+
class RecoveryAppliance
|
5
|
+
|
6
|
+
|
7
|
+
def initialize(test: false)
|
8
|
+
|
9
|
+
# Check if hitting mock api or live api
|
10
|
+
if test
|
11
|
+
@connection = Excon.new($base_url, :mock => true)
|
12
|
+
else
|
13
|
+
@connection = Excon.new($base_url)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def list(page: nil, per_page: nil, sort: nil, q: nil, fields: nil)
|
20
|
+
|
21
|
+
# Build hash for query parameters
|
22
|
+
keyword_args = {
|
23
|
+
:page => page,
|
24
|
+
:per_page => per_page,
|
25
|
+
:sort => sort,
|
26
|
+
:q => q,
|
27
|
+
:fields => fields
|
28
|
+
}
|
29
|
+
|
30
|
+
# Clean out null query parameters
|
31
|
+
params = OneAndOne.clean_hash(keyword_args)
|
32
|
+
|
33
|
+
# Build URL
|
34
|
+
path = OneAndOne.build_url('/recovery_appliances')
|
35
|
+
|
36
|
+
# Perform request
|
37
|
+
response = @connection.request(:method => :get,
|
38
|
+
:path => path,
|
39
|
+
:headers => $header,
|
40
|
+
:query => params)
|
41
|
+
|
42
|
+
# Check response status
|
43
|
+
OneAndOne.check_response(response.body, response.status)
|
44
|
+
|
45
|
+
#JSON-ify the response string
|
46
|
+
JSON.parse(response.body)
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def get(appliance_id: nil)
|
52
|
+
|
53
|
+
# Build URL
|
54
|
+
path = OneAndOne.build_url("/recovery_appliances/#{appliance_id}")
|
55
|
+
|
56
|
+
# Perform request
|
57
|
+
response = @connection.request(:method => :get,
|
58
|
+
:path => path,
|
59
|
+
:headers => $header)
|
60
|
+
|
61
|
+
# Check response status
|
62
|
+
OneAndOne.check_response(response.body, response.status)
|
63
|
+
|
64
|
+
#JSON-ify the response string
|
65
|
+
JSON.parse(response.body)
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|