hcloud 0.1.0.pre.alpha4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/tonobo/hcloud-ruby.svg?branch=master)](https://travis-ci.org/tonobo/hcloud-ruby)
|
4
|
+
[![codecov](https://codecov.io/gh/tonobo/hcloud-ruby/branch/master/graph/badge.svg)](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
|