hcloud 0.1.0.pre.alpha4 → 0.1.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/.gitignore +1 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +1 -0
- data/README.md +21 -0
- data/hcloud.gemspec +4 -0
- data/lib/hcloud.rb +2 -0
- data/lib/hcloud/abstract_resource.rb +90 -0
- data/lib/hcloud/action_resource.rb +7 -12
- data/lib/hcloud/client.rb +12 -3
- data/lib/hcloud/image.rb +1 -1
- data/lib/hcloud/image_resource.rb +4 -8
- data/lib/hcloud/iso_resource.rb +2 -4
- data/lib/hcloud/location_resource.rb +3 -4
- data/lib/hcloud/multi_reply.rb +22 -0
- data/lib/hcloud/pagination.rb +14 -0
- data/lib/hcloud/server_resource.rb +2 -4
- data/lib/hcloud/ssh_key_resource.rb +4 -5
- data/lib/hcloud/version.rb +1 -1
- metadata +64 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42e5e0786794e6040e88021aeec5ea8d0c3da4d8
|
4
|
+
data.tar.gz: b2368e1557cecb9e16089cc9a850979b85faae7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e885d2e44be9a4bc6750b55c859de56d02059de3611c63c684f7bff51931f8d8ba677f430e7b74fa48b7f1adea837cefd0fb2607d209682b3ba81035b426b41
|
7
|
+
data.tar.gz: b582dc6e91e9dccb04cc5469d83a28795f55d3f7ce7d5da0826fe6c8035a58bbc89ef17cf2163b164a1577c6aba4fde4b0d03b6eb325b2a0cca87efd0a4b0f03
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Hcloud
|
2
2
|
|
3
|
+
[](https://travis-ci.org/tonobo/hcloud-ruby)
|
4
|
+
[](https://codecov.io/gh/tonobo/hcloud-ruby)
|
5
|
+
|
3
6
|
This is an unoffical ruby client for HetznerCloud Api service.
|
4
7
|
|
5
8
|
**Its currently in development and lacking a lot of feature.
|
@@ -43,11 +46,29 @@ end
|
|
43
46
|
|
44
47
|
* Create a server
|
45
48
|
|
49
|
+
Nonblocking:
|
50
|
+
|
46
51
|
```ruby
|
47
52
|
c.servers.create(name: "moo5", server_type: "cx11", image: "ubuntu-16.04")
|
48
53
|
#=> [#<Hcloud::Action>, <#Hcloud::Server>, "root_password"]
|
49
54
|
```
|
50
55
|
|
56
|
+
Wating for finish:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
action,server = c.servers.create(name: "moo5", server_type: "cx11", image: "ubuntu-16.04")
|
60
|
+
|
61
|
+
while action.status == "running"
|
62
|
+
puts "Waiting for Action #{action.id} to complete ..."
|
63
|
+
action = c.actions.find(action.id)
|
64
|
+
server = c.servers.find(server.id)
|
65
|
+
puts "Action Status: #{action.status}"
|
66
|
+
puts "Server Status: #{server.status}"
|
67
|
+
puts "Server IP Config: #{server.public_net["ipv4"]}"
|
68
|
+
sleep 5
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
51
72
|
* Update servers' name
|
52
73
|
|
53
74
|
```ruby
|
data/hcloud.gemspec
CHANGED
@@ -21,6 +21,10 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_development_dependency "bundler", "~> 1.15"
|
23
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "grape"
|
25
|
+
spec.add_development_dependency "activesupport"
|
26
|
+
spec.add_development_dependency "rspec"
|
27
|
+
spec.add_development_dependency "webmock"
|
24
28
|
spec.add_runtime_dependency "typhoeus"
|
25
29
|
spec.add_runtime_dependency "oj"
|
26
30
|
spec.add_runtime_dependency "activesupport"
|
data/lib/hcloud.rb
CHANGED
@@ -5,6 +5,7 @@ module Hcloud
|
|
5
5
|
autoload :Error, 'hcloud/errors'
|
6
6
|
autoload :Client, 'hcloud/client'
|
7
7
|
autoload :AbstractResource, 'hcloud/abstract_resource'
|
8
|
+
autoload :MultiReply, 'hcloud/multi_reply'
|
8
9
|
autoload :ServerResource, 'hcloud/server_resource'
|
9
10
|
autoload :EntryLoader, 'hcloud/entry_loader'
|
10
11
|
autoload :FloatingIP, 'hcloud/floating_ip'
|
@@ -24,4 +25,5 @@ module Hcloud
|
|
24
25
|
autoload :ActionResource, 'hcloud/action_resource'
|
25
26
|
autoload :Iso, 'hcloud/iso'
|
26
27
|
autoload :IsoResource, 'hcloud/iso_resource'
|
28
|
+
autoload :Pagination, 'hcloud/pagination'
|
27
29
|
end
|
@@ -1,12 +1,66 @@
|
|
1
1
|
module Hcloud
|
2
2
|
class AbstractResource
|
3
|
+
include Enumerable
|
4
|
+
|
3
5
|
attr_reader :client, :parent, :base_path
|
4
6
|
|
5
7
|
def initialize(client:, parent: nil, base_path: "")
|
6
8
|
@client = client
|
7
9
|
@parent = parent
|
10
|
+
@page = 1
|
11
|
+
@per_page = 25
|
12
|
+
@order = []
|
8
13
|
@base_path = base_path
|
9
14
|
end
|
15
|
+
|
16
|
+
def page(page)
|
17
|
+
@page = page
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def per_page(per_page)
|
22
|
+
@per_page = per_page
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def limit(limit)
|
27
|
+
@limit = limit
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def order(*sort)
|
32
|
+
@order = sort.flat_map do |s|
|
33
|
+
case s
|
34
|
+
when Symbol, String then s.to_s
|
35
|
+
when Hash then s.map { |k, v| "#{k}:#{v}" }
|
36
|
+
else
|
37
|
+
raise ArgumentError,
|
38
|
+
"Unable to resolve type for given #{s.inspect} from #{sort}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def mj(path, **o, &block)
|
45
|
+
if !client.nil? and client.auto_pagination
|
46
|
+
requests = __entries__(path, **o)
|
47
|
+
if requests.all?{|x| x.is_a? Hash }
|
48
|
+
m = MultiReply.new(j: requests, pagination: :auto)
|
49
|
+
m.cb = block
|
50
|
+
return m
|
51
|
+
end
|
52
|
+
client.hydra.run
|
53
|
+
j = requests.map do |x|
|
54
|
+
Oj.load(x.response.body)
|
55
|
+
end
|
56
|
+
m = MultiReply.new(j: j, pagination: :auto)
|
57
|
+
m.cb = block
|
58
|
+
return m
|
59
|
+
end
|
60
|
+
m = MultiReply.new(j: [Oj.load(request(path, o.merge(ep: ep)).run.body)])
|
61
|
+
m.cb = block
|
62
|
+
m
|
63
|
+
end
|
10
64
|
|
11
65
|
def each(&block)
|
12
66
|
all.each do |member|
|
@@ -16,8 +70,44 @@ module Hcloud
|
|
16
70
|
|
17
71
|
protected
|
18
72
|
|
73
|
+
def page_params(per_page: nil, page: nil)
|
74
|
+
{ per_page: per_page || @per_page, page: page || @page }.to_param
|
75
|
+
end
|
76
|
+
|
77
|
+
def sort_params
|
78
|
+
@order.to_a.map{|x| "sort=#{x}" }.join("&")
|
79
|
+
end
|
80
|
+
|
81
|
+
def ep(per_page: nil, page: nil)
|
82
|
+
r = []
|
83
|
+
(x = page_params(per_page: per_page, page: page)).empty? ? nil : r << x
|
84
|
+
(x = sort_params).empty? ? nil : r << x
|
85
|
+
r.compact.join("&")
|
86
|
+
end
|
87
|
+
|
19
88
|
def request(*args)
|
20
89
|
client.request(*args)
|
21
90
|
end
|
91
|
+
|
92
|
+
def __entries__(path, **o)
|
93
|
+
ret = Oj.load(request(path, o.merge(ep: ep(per_page: 1, page: 1))).run.body)
|
94
|
+
a = ret.dig("meta", "pagination", "total_entries").to_i
|
95
|
+
if a <= 1
|
96
|
+
return [ret]
|
97
|
+
end
|
98
|
+
unless @limit.nil?
|
99
|
+
a = @limit if a > @limit
|
100
|
+
end
|
101
|
+
r = a / Client::MAX_ENTRIES_PER_PAGE + (a % Client::MAX_ENTRIES_PER_PAGE)
|
102
|
+
requests = r.times.map do |i|
|
103
|
+
per_page = Client::MAX_ENTRIES_PER_PAGE
|
104
|
+
if !@limit.nil? and r == (i+1) and a % per_page != 0
|
105
|
+
per_page = a % per_page
|
106
|
+
end
|
107
|
+
req = request(path, o.merge(ep: ep(per_page: per_page, page: i+1)))
|
108
|
+
client.hydra.queue req
|
109
|
+
req
|
110
|
+
end
|
111
|
+
end
|
22
112
|
end
|
23
113
|
end
|
@@ -1,14 +1,12 @@
|
|
1
1
|
|
2
2
|
module Hcloud
|
3
3
|
class ActionResource < AbstractResource
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
Oj.load(request(base_path("actions"), q: {sort: sort}).run.body)["actions"].map do |x|
|
8
|
-
Action.new(x, self, client)
|
4
|
+
def all
|
5
|
+
mj(base_path("actions")) do |j|
|
6
|
+
j.flat_map{|x| x["actions"].map{ |x| Action.new(x, self, client) } }
|
9
7
|
end
|
10
8
|
end
|
11
|
-
|
9
|
+
|
12
10
|
def find(id)
|
13
11
|
Action.new(
|
14
12
|
Oj.load(request(base_path("actions/#{id.to_i}")).run.body)["action"],
|
@@ -22,12 +20,9 @@ module Hcloud
|
|
22
20
|
rescue Error::NotFound
|
23
21
|
end
|
24
22
|
|
25
|
-
def where(status: nil
|
26
|
-
|
27
|
-
|
28
|
-
q: {status: status, sort: sort}).run.body
|
29
|
-
)["actions"].map do |x|
|
30
|
-
Action.new(x, self, client)
|
23
|
+
def where(status: nil)
|
24
|
+
mj(base_path("actions"), q: {status: status}) do |j|
|
25
|
+
j.flat_map{|x| x["actions"].map{ |x| Action.new(x, self, client) }}
|
31
26
|
end
|
32
27
|
end
|
33
28
|
|
data/lib/hcloud/client.rb
CHANGED
@@ -3,9 +3,14 @@ autoload :Oj, "oj"
|
|
3
3
|
|
4
4
|
module Hcloud
|
5
5
|
class Client
|
6
|
-
|
7
|
-
|
6
|
+
MAX_ENTRIES_PER_PAGE = 50
|
7
|
+
|
8
|
+
attr_reader :token, :auto_pagination, :hydra
|
9
|
+
def initialize(token:, auto_pagination: false, concurrency: 20)
|
8
10
|
@token = token
|
11
|
+
@auto_pagination = auto_pagination
|
12
|
+
@concurrency = concurrency
|
13
|
+
@hydra = Typhoeus::Hydra.new(max_concurrency: concurrency)
|
9
14
|
end
|
10
15
|
|
11
16
|
def authorized?
|
@@ -57,9 +62,13 @@ module Hcloud
|
|
57
62
|
options[:body] = Oj.dump(x, mode: :compat)
|
58
63
|
options[:method] ||= :post
|
59
64
|
end
|
65
|
+
q = []
|
66
|
+
q << options.delete(:ep).to_s
|
60
67
|
if x = options.delete(:q)
|
61
|
-
|
68
|
+
q << x.to_param
|
62
69
|
end
|
70
|
+
path = path.dup
|
71
|
+
path << "?"+q.join("&")
|
63
72
|
r = Typhoeus::Request.new(
|
64
73
|
"https://api.hetzner.cloud/v1/#{path}",
|
65
74
|
{
|
data/lib/hcloud/image.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Hcloud
|
2
2
|
class ImageResource < AbstractResource
|
3
|
-
include Enumerable
|
4
|
-
|
5
3
|
def all
|
6
|
-
|
7
|
-
Image.new(x, self, client)
|
4
|
+
mj("images") do |j|
|
5
|
+
j.flat_map{|x| x["images"].map{ |x| Image.new(x, self, client) } }
|
8
6
|
end
|
9
7
|
end
|
10
8
|
|
@@ -33,10 +31,8 @@ module Hcloud
|
|
33
31
|
method(:where).parameters.inject(query) do |r,x|
|
34
32
|
(var = eval(x.last.to_s)).nil? ? r : r.merge!(x.last => var)
|
35
33
|
end
|
36
|
-
|
37
|
-
|
38
|
-
)["images"].map do |x|
|
39
|
-
Image.new(x, self, client)
|
34
|
+
mj("images", q: query) do |j|
|
35
|
+
j.flat_map{|x| x["images"].map{ |x| Image.new(x, self, client) } }
|
40
36
|
end
|
41
37
|
end
|
42
38
|
|
data/lib/hcloud/iso_resource.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Hcloud
|
2
2
|
class IsoResource < AbstractResource
|
3
|
-
include Enumerable
|
4
|
-
|
5
3
|
def all
|
6
|
-
|
7
|
-
Iso.new(x, self, client)
|
4
|
+
mj("isos") do |j|
|
5
|
+
j.flat_map{|x| x["isos"].map{ |x| Iso.new(x, self, client) } }
|
8
6
|
end
|
9
7
|
end
|
10
8
|
|
@@ -1,10 +1,9 @@
|
|
1
1
|
module Hcloud
|
2
2
|
class LocationResource < AbstractResource
|
3
|
-
include Enumerable
|
4
|
-
|
5
3
|
def all
|
6
|
-
|
7
|
-
|
4
|
+
mj("locations") do |j|
|
5
|
+
j.flat_map{|x| x["locations"].map{ |x| Location.new(x, self, client) } }
|
6
|
+
end
|
8
7
|
end
|
9
8
|
|
10
9
|
def find(id)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Hcloud
|
2
|
+
class MultiReply
|
3
|
+
include Enumerable
|
4
|
+
attr_accessor :cb
|
5
|
+
|
6
|
+
def initialize(j:, pagination: nil)
|
7
|
+
@j = j
|
8
|
+
@pagination = pagination
|
9
|
+
end
|
10
|
+
|
11
|
+
def pagination
|
12
|
+
@pagination || Pagination.new(@j.first.to_h["meta"].to_h["pagination"], nil, nil)
|
13
|
+
end
|
14
|
+
|
15
|
+
def each(&block)
|
16
|
+
@cb.call(@j).each do |member|
|
17
|
+
block.call(member)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module Hcloud
|
2
2
|
class ServerResource < AbstractResource
|
3
|
-
include Enumerable
|
4
|
-
|
5
3
|
def create(name:,
|
6
4
|
server_type:,
|
7
5
|
datacenter: nil,
|
@@ -23,8 +21,8 @@ module Hcloud
|
|
23
21
|
end
|
24
22
|
|
25
23
|
def all
|
26
|
-
|
27
|
-
Server.new(x, self, client)
|
24
|
+
mj("servers") do |j|
|
25
|
+
j.flat_map{|x| x["servers"].map{ |x| Server.new(x, self, client) } }
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
@@ -1,15 +1,14 @@
|
|
1
1
|
module Hcloud
|
2
2
|
class SSHKeyResource < AbstractResource
|
3
|
-
include Enumerable
|
4
|
-
|
5
3
|
def all
|
6
|
-
|
7
|
-
|
4
|
+
mj("ssh_keys") do |j|
|
5
|
+
j.flat_map{|x| x["ssh_keys"].map{ |x| SSHKey.new(x, self, client) } }
|
6
|
+
end
|
8
7
|
end
|
9
8
|
|
10
9
|
def create(name:, public_key:)
|
11
10
|
j = Oj.load(request("ssh_keys", j: {name: name, public_key: public_key}).run.body)
|
12
|
-
SSHKey.new(j, self, client)
|
11
|
+
SSHKey.new(j["ssh_key"], self, client)
|
13
12
|
end
|
14
13
|
|
15
14
|
def find(id)
|
data/lib/hcloud/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hcloud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Foerster
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,62 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: grape
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
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: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
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: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
41
97
|
- !ruby/object:Gem::Dependency
|
42
98
|
name: typhoeus
|
43
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -88,6 +144,8 @@ extensions: []
|
|
88
144
|
extra_rdoc_files: []
|
89
145
|
files:
|
90
146
|
- ".gitignore"
|
147
|
+
- ".rspec"
|
148
|
+
- ".travis.yml"
|
91
149
|
- Gemfile
|
92
150
|
- README.md
|
93
151
|
- Rakefile
|
@@ -111,6 +169,8 @@ files:
|
|
111
169
|
- lib/hcloud/iso_resource.rb
|
112
170
|
- lib/hcloud/location.rb
|
113
171
|
- lib/hcloud/location_resource.rb
|
172
|
+
- lib/hcloud/multi_reply.rb
|
173
|
+
- lib/hcloud/pagination.rb
|
114
174
|
- lib/hcloud/server.rb
|
115
175
|
- lib/hcloud/server_resource.rb
|
116
176
|
- lib/hcloud/server_type.rb
|
@@ -132,9 +192,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
192
|
version: '0'
|
133
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
194
|
requirements:
|
135
|
-
- - "
|
195
|
+
- - ">="
|
136
196
|
- !ruby/object:Gem::Version
|
137
|
-
version:
|
197
|
+
version: '0'
|
138
198
|
requirements: []
|
139
199
|
rubyforge_project:
|
140
200
|
rubygems_version: 2.5.2.2
|