fog-hetznercloud 0.0.1 → 0.0.2
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/README.md +5 -2
- data/Rakefile +1 -0
- data/examples/Gemfile +8 -0
- data/examples/integrationtest.rb +166 -0
- data/examples/keys/.dummy +0 -0
- data/examples/userdata.txt +3 -0
- data/fog-hetznercloud.gemspec +2 -2
- data/lib/fog/hetznercloud/compute.rb +2 -2
- data/lib/fog/hetznercloud/models/compute/action.rb +0 -1
- data/lib/fog/hetznercloud/models/compute/datacenter.rb +13 -0
- data/lib/fog/hetznercloud/models/compute/floating_ip.rb +12 -1
- data/lib/fog/hetznercloud/models/compute/location.rb +0 -1
- data/lib/fog/hetznercloud/models/compute/server.rb +1 -1
- data/lib/fog/hetznercloud/models/compute/servers.rb +29 -4
- data/lib/fog/hetznercloud/requests/compute/update_server.rb +2 -62
- data/lib/fog/hetznercloud/version.rb +1 -1
- metadata +25 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2513d94d86a7673b99f59b766e1a0eda8dc0106
|
4
|
+
data.tar.gz: 818b34b6423ee7a51c25dcfc3b163883cdb52814
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cef2459d83661bc34425320e27cc348224bbacd0257d3db921ba5eb9193856522bfc2742e051660c59e803140edf6b682f23289afdeb01503bf264fd29c61eca
|
7
|
+
data.tar.gz: 10d33c8176c6b505f91d299d1a27c17f8332c6f85098e972b7db22fd382930e37755e03b50ef1dce62c4921b39deb3af4445dcc36fd2f792d37d132a9ce5139f
|
data/README.md
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
|
2
|
+
|
2
3
|
# Rubygem fog-hetznercloud
|
3
4
|
|
4
5
|
Fog provider gem to support [Hetzner Cloud](https://cloud.hetzner.com/).
|
5
6
|
|
6
7
|
## Features and development
|
7
8
|
|
8
|
-
This gem is currently a MVP prototype that is missing some features:
|
9
|
+
This gem is currently a MVP prototype that is **missing** some features like:
|
9
10
|
|
10
11
|
API:
|
11
12
|
* [Pagination Support](https://docs.hetzner.cloud/#header-pagination-1)
|
@@ -53,7 +54,9 @@ default:
|
|
53
54
|
|
54
55
|
## Example
|
55
56
|
|
56
|
-
|
57
|
+
**See [examples/integrationtest.rb](examples/integrationtest.rb) for a reasonable example**
|
58
|
+
|
59
|
+
### Ge mfile
|
57
60
|
|
58
61
|
```ruby
|
59
62
|
source "https://rubygems.org"
|
data/Rakefile
CHANGED
data/examples/Gemfile
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
#!/usr/bin/env ruby2.0
|
2
|
+
#
|
3
|
+
# This is a simple integraiton test performing some usefull server actions.
|
4
|
+
#
|
5
|
+
# This is also intended as some kind of documentation on how to use the library
|
6
|
+
#
|
7
|
+
#
|
8
|
+
require 'fog/hetznercloud'
|
9
|
+
require 'pp'
|
10
|
+
|
11
|
+
# Connecto to Hetznercloud
|
12
|
+
connection = Fog::Compute[:hetznercloud]
|
13
|
+
|
14
|
+
# Some variables
|
15
|
+
ssh_public_keyfile = "./keys/testkey.pub" # needs to be generated first with 'ssh-keygen -t rsa testkey'
|
16
|
+
ssh_private_keyfile = "./keys/testkey" # needs to be generated first with 'ssh-keygen -t rsa testkey'
|
17
|
+
ssh_keyname = "testkey" # Name of the ssh key
|
18
|
+
servername = "testserver" # Name of the server
|
19
|
+
|
20
|
+
# resources created
|
21
|
+
image_snapshot = nil
|
22
|
+
image_backup = nil
|
23
|
+
server = nil
|
24
|
+
floating_ip = nil
|
25
|
+
ssh_key = nil
|
26
|
+
|
27
|
+
raise "Error: Fild #{ssh_private_keyfile} missing (create with 'ssh-keygen -t rsa -N \"\" -f #{ssh_private_keyfile}')" unless File.file?(ssh_private_keyfile)
|
28
|
+
|
29
|
+
begin
|
30
|
+
|
31
|
+
# Lookups, see api doc https://docs.hetzner.cloud for filters
|
32
|
+
connection.datacenters.each { |x| puts "Datacenter #{x.name} located in #{x.location.name}" }
|
33
|
+
connection.locations.each { |x| puts "Location #{x.name} located in #{x.city}" }
|
34
|
+
connection.locations.all(:name => 'fsn1').each { |x| puts "FSN Found" }
|
35
|
+
connection.locations.all(:name => 'nbg1').each { |x| puts "NBG Found" }
|
36
|
+
connection.server_types.each { |x| puts "Server Type #{x.name} (#{x.cores}/#{x.memory}/#{x.disk})" }
|
37
|
+
connection.server_types.all(:name => 'cx11').each { |x| puts "Server cx11 found" }
|
38
|
+
|
39
|
+
## create or select ssh key ...
|
40
|
+
ssh_key = connection.ssh_keys.all(:name => ssh_keyname).first
|
41
|
+
if !ssh_key
|
42
|
+
puts "Creating SSH Key ..."
|
43
|
+
ssh_key = connection.ssh_keys.create(:name => ssh_keyname, :public_key => ssh_public_keyfile)
|
44
|
+
else
|
45
|
+
puts "Using existing SSH Key ..."
|
46
|
+
end
|
47
|
+
|
48
|
+
puts "Creating Floating IP"
|
49
|
+
floating_ip = connection.floating_ips.create(:type => 'ipv4', :home_location => 'fsn1' )
|
50
|
+
puts "Using existing VIP #{floating_ip.ip} #{floating_ip.server.nil? ? 'unbound' : 'assigned to' + floating_ip.server.name}"
|
51
|
+
|
52
|
+
# lookup existing server by name or create new server, works with most resources
|
53
|
+
server = connection.servers.all(:name => servername).first
|
54
|
+
if !server
|
55
|
+
puts "Bootstrapping Server (waiting until ssh is ready)..."
|
56
|
+
server = connection.servers.bootstrap(
|
57
|
+
:name => servername,
|
58
|
+
:image => 'centos-7',
|
59
|
+
:server_type => 'cx11',
|
60
|
+
:location => 'nbg1',
|
61
|
+
:user_data => "./userdata.txt",
|
62
|
+
:private_key_path => ssh_private_keyfile,
|
63
|
+
:ssh_keys => [ ssh_key.identity ],
|
64
|
+
:bootstap_timeout => 120,
|
65
|
+
)
|
66
|
+
else
|
67
|
+
puts "Using existing Server ... "
|
68
|
+
end
|
69
|
+
puts "Server public_ip_address:#{server.public_ip_address} (#{server.public_dns_name}/#{server.reverse_dns_name})"
|
70
|
+
|
71
|
+
puts "Assign VIP #{floating_ip.ip} to #{server.name}"
|
72
|
+
floating_ip.assign(server)
|
73
|
+
|
74
|
+
# now wait for the server to boot
|
75
|
+
puts "Waiting for Server SSH ..."
|
76
|
+
server.wait_for { server.sshable? }
|
77
|
+
|
78
|
+
puts "Adding VIP to server"
|
79
|
+
server.ssh("/sbin/ip addr add dev eth0 #{floating_ip.ip}")
|
80
|
+
|
81
|
+
puts "Changing Root Password"
|
82
|
+
action,password = server.reset_root_password
|
83
|
+
puts "New Root password #{password}"
|
84
|
+
|
85
|
+
puts "Unassigning VIP"
|
86
|
+
floating_ip.unassign()
|
87
|
+
|
88
|
+
puts "SSH in server ..."
|
89
|
+
puts server.ssh('cat /tmp/test').first.stdout # => "test1\r\n"
|
90
|
+
|
91
|
+
puts "Setting API to syncronous mode (wait for action to complete)"
|
92
|
+
server.sync=true
|
93
|
+
|
94
|
+
puts "Create Image (Sync) ..."
|
95
|
+
action, image_snapshot = server.create_image()
|
96
|
+
|
97
|
+
puts "Enable Backup ..."
|
98
|
+
server.enable_backup
|
99
|
+
|
100
|
+
puts "Create Backup (ASync) ..."
|
101
|
+
action, image_backup = server.create_backup()
|
102
|
+
|
103
|
+
puts "Disable Backup ..."
|
104
|
+
server.enable_backup
|
105
|
+
|
106
|
+
# Boot Server in rescue system with SSH Keys
|
107
|
+
puts "Booting into rescue mode"
|
108
|
+
server.enable_rescue(:ssh_keys => [ ssh_keyname ])
|
109
|
+
server.reboot()
|
110
|
+
server.wait_for { server.sshable? }
|
111
|
+
|
112
|
+
puts "SSH in Rescue System ..."
|
113
|
+
puts server.ssh('hostname').first.stdout # => "test1\r\n"
|
114
|
+
|
115
|
+
# Reboot again
|
116
|
+
puts "Booting into normal mode"
|
117
|
+
server.disable_rescue()
|
118
|
+
server.reset()
|
119
|
+
server.wait_for { server.sshable? }
|
120
|
+
|
121
|
+
# Change Server Type
|
122
|
+
puts "Changing Server Type to cx21"
|
123
|
+
server.shutdown()
|
124
|
+
# FIXME: Handle in GEM, sometimes API error ?
|
125
|
+
server.wait_for { server.stopped? }
|
126
|
+
server.change_type(:upgrade_disk => false, :server_type => 'cx21')
|
127
|
+
server.poweron()
|
128
|
+
server.wait_for { server.sshable? }
|
129
|
+
|
130
|
+
puts server.ssh('hostname').first.stdout # => "test1\r\n"
|
131
|
+
|
132
|
+
# Change PTR
|
133
|
+
puts "Changing PTR"
|
134
|
+
server.change_dns_ptr('www.elconas.de')
|
135
|
+
server.reload
|
136
|
+
|
137
|
+
puts "PowerOff Server"
|
138
|
+
server.poweroff
|
139
|
+
|
140
|
+
puts "Setting API to asynchronous mode"
|
141
|
+
server.async=true
|
142
|
+
|
143
|
+
puts "Destroy Server ..."
|
144
|
+
server.destroy
|
145
|
+
rescue Exception => e
|
146
|
+
server.destroy unless server.nil?
|
147
|
+
image_snapshot.destroy unless image_snapshot.nil?
|
148
|
+
image_backup.destroy unless image_backup.nil?
|
149
|
+
floating_ip.destroy unless floating_ip.nil?
|
150
|
+
ssh_key.destroy unless ssh_key.nil?
|
151
|
+
|
152
|
+
## List Accounts
|
153
|
+
connection.servers.each { |x|
|
154
|
+
puts "Server #{x.id}: #{x.name} #{x.public_ip_address}"
|
155
|
+
}
|
156
|
+
connection.floating_ips.each { |x|
|
157
|
+
puts "Floating IP #{x.id}: #{x.ip}"
|
158
|
+
}
|
159
|
+
connection.images.all(:type => 'snapshot').each { |x|
|
160
|
+
puts "Snapshot Image #{x.id}: #{x.description}"
|
161
|
+
}
|
162
|
+
connection.images.all(:type => 'backup').each { |x|
|
163
|
+
puts "Backup Image #{x.id}: #{x.description}"
|
164
|
+
}
|
165
|
+
raise e
|
166
|
+
end
|
File without changes
|
data/fog-hetznercloud.gemspec
CHANGED
@@ -14,7 +14,6 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.license = 'APACHE-2.0'
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f|
|
17
|
-
puts "Checking file #{f}"
|
18
17
|
f.match(%r{^(test|spec|features)/}) || f.match(%r{^\.})
|
19
18
|
}
|
20
19
|
spec.require_paths = ['lib']
|
@@ -22,12 +21,13 @@ Gem::Specification.new do |spec|
|
|
22
21
|
spec.add_development_dependency 'bundler'
|
23
22
|
spec.add_development_dependency 'coveralls'
|
24
23
|
spec.add_development_dependency 'minitest'
|
25
|
-
spec.add_development_dependency 'net-ssh'
|
26
24
|
spec.add_development_dependency 'pry'
|
27
25
|
spec.add_development_dependency 'rake'
|
28
26
|
spec.add_development_dependency 'rubocop'
|
29
27
|
spec.add_development_dependency 'simplecov'
|
28
|
+
spec.add_development_dependency 'bump'
|
30
29
|
|
31
30
|
spec.add_dependency 'fog-core', '>= 1.45.0'
|
32
31
|
spec.add_dependency 'fog-json', '>= 1.0.2'
|
32
|
+
spec.add_dependency 'net-ssh'
|
33
33
|
end
|
@@ -75,7 +75,7 @@ module Fog
|
|
75
75
|
request :list_datacenters
|
76
76
|
request :get_datacenter
|
77
77
|
|
78
|
-
#
|
78
|
+
# Ssh Keys
|
79
79
|
request :list_ssh_keys
|
80
80
|
request :get_ssh_key
|
81
81
|
request :create_ssh_key
|
@@ -128,7 +128,7 @@ module Fog
|
|
128
128
|
end
|
129
129
|
|
130
130
|
def endpoint
|
131
|
-
'https://api.hetzner.cloud/
|
131
|
+
'https://api.hetzner.cloud/'
|
132
132
|
end
|
133
133
|
|
134
134
|
def camelize(str)
|
@@ -9,6 +9,19 @@ module Fog
|
|
9
9
|
attribute :description
|
10
10
|
attribute :location
|
11
11
|
attribute :server_types
|
12
|
+
|
13
|
+
def location=(value)
|
14
|
+
attributes[:location] = case value
|
15
|
+
when Hash
|
16
|
+
service.locations.new(value)
|
17
|
+
when String
|
18
|
+
service.locations.all(name: value).first
|
19
|
+
when Integer
|
20
|
+
service.locations.get(value)
|
21
|
+
else
|
22
|
+
value
|
23
|
+
end
|
24
|
+
end
|
12
25
|
end
|
13
26
|
end
|
14
27
|
end
|
@@ -81,8 +81,19 @@ module Fog
|
|
81
81
|
false
|
82
82
|
end
|
83
83
|
else
|
84
|
+
server_id = case serverid
|
85
|
+
when Fog::Hetznercloud::Compute::Server
|
86
|
+
serverid.identity
|
87
|
+
when String
|
88
|
+
service.servers.all(name: serverid).first.identity
|
89
|
+
when Integer
|
90
|
+
serverid
|
91
|
+
else
|
92
|
+
raise Fog::Hetznercloud::Error::InvalidInputError, 'ERROR: Need Fog::Hetznercloud::Compute::Server|String|Integer'
|
93
|
+
end
|
94
|
+
|
84
95
|
body = {
|
85
|
-
server:
|
96
|
+
server: server_id
|
86
97
|
}
|
87
98
|
|
88
99
|
if (floating_ip = service.floating_ip_assign_to_server(identity, body).body['floating_ip'])
|
@@ -17,22 +17,47 @@ module Fog
|
|
17
17
|
nil
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
# Sets the proc used to determine the IP Address used for ssh/scp interactions.
|
21
|
+
# @example
|
22
|
+
# service.servers.bootstrap :name => "bootstrap-server",
|
23
|
+
# :image => service.flavors.first.id,
|
24
|
+
# :server_type => service.server_types.all(:name => 'cx11').identity,
|
25
|
+
# :private_key_path => "~/.ssh/fog_rsa",
|
26
|
+
# :user_data => "./file",
|
27
|
+
# :location => 'nbg1',
|
28
|
+
# :ssh_keys => [ 'keyname' ],
|
29
|
+
# :bootstap_timeout => 120
|
30
|
+
#
|
31
|
+
# @note
|
32
|
+
# When booting without ssh_keys set, bootstrapping will wait
|
33
|
+
# until the server is read and not until you can ssh into the server
|
34
|
+
# Bootstrapping waits until bootstap_timeout seconds and then destroy
|
35
|
+
# the server. Default timeout is 120 seconds, which should be ok
|
36
|
+
# unless you have a lot of user-data scripts.
|
37
|
+
def bootstrap(new_attributes = {})
|
21
38
|
require 'securerandom'
|
22
39
|
|
23
40
|
defaults = {
|
24
41
|
name: "hc-#{SecureRandom.hex(3)}",
|
25
42
|
image: 'centos-7',
|
26
|
-
server_type: 'cx11'
|
27
|
-
ssh_keys: ssh_keys
|
43
|
+
server_type: 'cx11'
|
28
44
|
}
|
29
45
|
|
46
|
+
bootstap_timeout = new_attributes[:bootstap_timeout].nil? ? 120 : new_attributes[:bootstap_timeout]
|
47
|
+
|
30
48
|
server = create(defaults.merge(new_attributes))
|
31
49
|
|
50
|
+
# if ssh keys are provided wait until we can SSH the server
|
51
|
+
# othwise just wait till the server is ready as we will never
|
52
|
+
# be able to login
|
32
53
|
status = false
|
33
54
|
begin
|
34
55
|
status = Timeout.timeout(bootstap_timeout) do
|
35
|
-
|
56
|
+
if new_attributes[:ssh_keys].nil?
|
57
|
+
server.wait_for { ready? }
|
58
|
+
else
|
59
|
+
server.wait_for { sshable?(auth_methods: %w[publickey]) }
|
60
|
+
end
|
36
61
|
end
|
37
62
|
rescue Timeout::Error => e
|
38
63
|
server.destroy
|
@@ -8,68 +8,8 @@ module Fog
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class Mock
|
11
|
-
def update_server(
|
12
|
-
|
13
|
-
|
14
|
-
server = lookup(:servers, server_id)
|
15
|
-
|
16
|
-
bootscript = if body['bootscript'].is_a?(Hash)
|
17
|
-
lookup(:bootscripts, body['bootscript']['id'])
|
18
|
-
elsif body['bootscript'].is_a?(String)
|
19
|
-
lookup(:bootscripts, body['bootscript'])
|
20
|
-
end
|
21
|
-
|
22
|
-
_, product_server = lookup_product_server(server['commercial_type'])
|
23
|
-
|
24
|
-
if body['enable_ipv6'] && !product_server['network']['ipv6_support']
|
25
|
-
raise_invalid_request_error("Cannot enable ipv6 on #{commercial_type}")
|
26
|
-
end
|
27
|
-
|
28
|
-
volumes = {}
|
29
|
-
body['volumes'].each do |index, volume|
|
30
|
-
volume = lookup(:volumes, volume['id'])
|
31
|
-
|
32
|
-
if volume['server'] && volume['server']['id'] != server['id']
|
33
|
-
message = "volume #{volume['id']} is already attached to a server"
|
34
|
-
raise_invalid_request_error(message)
|
35
|
-
end
|
36
|
-
|
37
|
-
volumes[index] = volume
|
38
|
-
end
|
39
|
-
|
40
|
-
server['bootscript'] = bootscript if bootscript
|
41
|
-
server['dynamic_ip_required'] = body['dynamic_ip_required']
|
42
|
-
server['enable_ipv6'] = body['enable_ipv6']
|
43
|
-
server['hostname'] = body['name']
|
44
|
-
server['modification_date'] = now
|
45
|
-
server['name'] = body['name']
|
46
|
-
server['tags'] = body['tags']
|
47
|
-
server['volumes'] = volumes
|
48
|
-
|
49
|
-
if server['dynamic_ip_required'] && server['state'] == 'running'
|
50
|
-
server['public_ip'] ||= create_dynamic_ip
|
51
|
-
elsif !server['dynamic_ip_required'] && server['public_ip'] && server['public_ip']['dynamic']
|
52
|
-
server['public_ip'] = nil
|
53
|
-
end
|
54
|
-
|
55
|
-
if server['enable_ipv6'] && server['state'] == 'running'
|
56
|
-
server['ipv6'] ||= create_ipv6
|
57
|
-
elsif !server['enable_ipv6']
|
58
|
-
server['ipv6'] = nil
|
59
|
-
end
|
60
|
-
|
61
|
-
data[:volumes].each do |id, volume|
|
62
|
-
if server['volumes'].any? { |_i, v| v['id'] == id }
|
63
|
-
volume['server'] = {
|
64
|
-
'id' => server['id'],
|
65
|
-
'name' => server['name']
|
66
|
-
}
|
67
|
-
elsif volume['server'] && volume['server']['id'] == server['id']
|
68
|
-
volume['server'] = nil
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
response(status: 200, body: { 'server' => server })
|
11
|
+
def update_server(_server_id, _body)
|
12
|
+
Fog::Mock.not_implemented
|
73
13
|
end
|
74
14
|
end
|
75
15
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fog-hetznercloud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Heinzmann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: pry
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rubocop
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: simplecov
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: bump
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: 1.0.2
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: net-ssh
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
153
167
|
description: Fog provider gem to support the Hetzner Cloud.
|
154
168
|
email:
|
155
169
|
- reg@elconas.de
|
@@ -163,6 +177,10 @@ files:
|
|
163
177
|
- Rakefile
|
164
178
|
- bin/console
|
165
179
|
- bin/setup
|
180
|
+
- examples/Gemfile
|
181
|
+
- examples/integrationtest.rb
|
182
|
+
- examples/keys/.dummy
|
183
|
+
- examples/userdata.txt
|
166
184
|
- fog-hetznercloud.gemspec
|
167
185
|
- lib/fog/hetznercloud.rb
|
168
186
|
- lib/fog/hetznercloud/client.rb
|