hcloud 0.1.0.pre.alpha0
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 +7 -0
- data/.gitignore +11 -0
- data/Gemfile +8 -0
- data/README.md +67 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/hcloud.gemspec +27 -0
- data/lib/hcloud.rb +16 -0
- data/lib/hcloud/abstract_resource.rb +14 -0
- data/lib/hcloud/action.rb +16 -0
- data/lib/hcloud/client.rb +66 -0
- data/lib/hcloud/datacenter.rb +13 -0
- data/lib/hcloud/entry_loader.rb +36 -0
- data/lib/hcloud/errors.rb +17 -0
- data/lib/hcloud/image.rb +22 -0
- data/lib/hcloud/location.rb +16 -0
- data/lib/hcloud/server.rb +47 -0
- data/lib/hcloud/server_resource.rb +37 -0
- data/lib/hcloud/server_type.rb +17 -0
- data/lib/hcloud/version.rb +3 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9cdf9035c8dc3386625887bdb9e02a25f8fe2c0b
|
4
|
+
data.tar.gz: c3b771e29328e7708f3f7251eb135a14335b0294
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fb30c007428c885f476da3f59bd7c9bf918b0362a775822d31cc0ebb8a623d68fcbee05daea20d112d93acf4af21791a5ba36b24ddb6bf78bde184259ef71324
|
7
|
+
data.tar.gz: f6a1ae0b6cbc07df8786655579c27893c5e213b709d020064e335f0a7f0a031b099c4368c318f58e3e8c5fa415460350e6b3c643d06cc77d8080567f871bc96e
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Hcloud
|
2
|
+
|
3
|
+
This is an unoffical ruby client for HetznerCloud Api service.
|
4
|
+
|
5
|
+
**Its currently in development and lacking a lot of feature.
|
6
|
+
The bindings are also not considered stable.**
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'hcloud'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install hcloud
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
### Client
|
27
|
+
|
28
|
+
* Create a client instance.
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
c = Hcloud::Client.new(token: "<your project token>")
|
32
|
+
```
|
33
|
+
|
34
|
+
### Server Resource
|
35
|
+
|
36
|
+
* List servers
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
c.servers.each do |server|
|
40
|
+
server.datacenter.location.id #=> 1
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
* Create a server
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
c.servers.create(name: "moo5", server_type: "cx11", image: "ubuntu-16.04")
|
48
|
+
#=> #<Hcloud::Server>
|
49
|
+
```
|
50
|
+
|
51
|
+
* Update servers' name
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
c.servers.count
|
55
|
+
#=> 2
|
56
|
+
c.servers.first.update(name: "moo")
|
57
|
+
#=> #<Hcloud::Server>
|
58
|
+
c.servers.each{|x| x.update(name: "moo") }
|
59
|
+
Hcloud::Error::UniquenessError: server name is already used
|
60
|
+
```
|
61
|
+
|
62
|
+
* Delete a server
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
c.servers.first.delete
|
66
|
+
#=> #<Hcloud::Action>
|
67
|
+
```
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "hcloud"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/hcloud.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "hcloud/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "hcloud"
|
8
|
+
spec.version = Hcloud::VERSION
|
9
|
+
spec.authors = ["Tim Foerster"]
|
10
|
+
spec.email = ["github@moo.gl"]
|
11
|
+
|
12
|
+
spec.summary = %q{HetznerCloud native Ruby client}
|
13
|
+
spec.homepage = "https://github.com/tonobo/hcloud"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "typhoeus"
|
25
|
+
spec.add_development_dependency "oj"
|
26
|
+
spec.add_development_dependency "activesupport"
|
27
|
+
end
|
data/lib/hcloud.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "hcloud/version"
|
2
|
+
require 'active_support/core_ext/object/to_query'
|
3
|
+
|
4
|
+
module Hcloud
|
5
|
+
autoload :Error, 'hcloud/errors'
|
6
|
+
autoload :Client, 'hcloud/client'
|
7
|
+
autoload :AbstractResource, 'hcloud/abstract_resource'
|
8
|
+
autoload :ServerResource, 'hcloud/server_resource'
|
9
|
+
autoload :EntryLoader, 'hcloud/entry_loader'
|
10
|
+
autoload :Server, 'hcloud/server'
|
11
|
+
autoload :ServerType, 'hcloud/server_type'
|
12
|
+
autoload :Datacenter, 'hcloud/datacenter'
|
13
|
+
autoload :Location, 'hcloud/location'
|
14
|
+
autoload :Image, 'hcloud/image'
|
15
|
+
autoload :Action, 'hcloud/action'
|
16
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
autoload :Typhoeus, "typhoeus"
|
2
|
+
autoload :Oj, "oj"
|
3
|
+
|
4
|
+
module Hcloud
|
5
|
+
class Client
|
6
|
+
attr_reader :token
|
7
|
+
def initialize(token:)
|
8
|
+
@token = token
|
9
|
+
end
|
10
|
+
|
11
|
+
def authorized?
|
12
|
+
request("server_types").run
|
13
|
+
true
|
14
|
+
rescue Error::Unauthorized
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
def servers
|
19
|
+
ServerResource.new(client: self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def request(path, **options)
|
23
|
+
code = options.delete(:code)
|
24
|
+
if x = options.delete(:j)
|
25
|
+
options[:body] = Oj.dump(x, mode: :compat)
|
26
|
+
options[:method] ||= :post
|
27
|
+
end
|
28
|
+
r = Typhoeus::Request.new(
|
29
|
+
"https://api.hetzner.cloud/v1/#{path}",
|
30
|
+
{
|
31
|
+
headers: {
|
32
|
+
"Authorization" => "Bearer #{token}",
|
33
|
+
"Content-Type" => "application/json",
|
34
|
+
},
|
35
|
+
}.merge(options)
|
36
|
+
)
|
37
|
+
r.on_complete do |response|
|
38
|
+
case response.code
|
39
|
+
when code
|
40
|
+
raise Error::UnexpectedError, response.body
|
41
|
+
when 401
|
42
|
+
raise Error::Unauthorized
|
43
|
+
when 0
|
44
|
+
raise Error::ServerError, "Connection error: #{response.return_code}"
|
45
|
+
when 400...600
|
46
|
+
j = Oj.load(response.body)
|
47
|
+
code = j.dig("error", "code")
|
48
|
+
error_class = case code
|
49
|
+
when "invalid_input" then Error::InvalidInput
|
50
|
+
when "forbidden" then Error::Forbidden
|
51
|
+
when "locked" then Error::Locked
|
52
|
+
when "not_found" then Error::NotFound
|
53
|
+
when "rate_limit_exceeded" then Error::RateLimitExceeded
|
54
|
+
when "resource_unavailable" then Error::ResourceUnavilable
|
55
|
+
when "service_error" then Error::ServiceError
|
56
|
+
when "uniqueness_error" then Error::UniquenessError
|
57
|
+
else
|
58
|
+
Error::ServerError
|
59
|
+
end
|
60
|
+
raise error_class, j.dig("error", "message")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
r
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
module Hcloud
|
3
|
+
module EntryLoader
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do |klass|
|
7
|
+
klass.send(:attr_reader, :parent, :client)
|
8
|
+
klass.const_get(:Attributes).each do |attribute, value|
|
9
|
+
klass.send(:attr_accessor, attribute)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(resource, parent, client)
|
14
|
+
@parent = parent
|
15
|
+
@client = client
|
16
|
+
self.class.const_get(:Attributes).each do |attribute, value|
|
17
|
+
case value
|
18
|
+
when nil
|
19
|
+
self.send("#{attribute}=", resource[attribute.to_s])
|
20
|
+
when :time
|
21
|
+
unless resource[attribute.to_s].nil?
|
22
|
+
self.send("#{attribute}=", Time.parse(resource[attribute.to_s]))
|
23
|
+
end
|
24
|
+
else
|
25
|
+
if value.is_a?(Class) and value.include?(EntryLoader)
|
26
|
+
self.send("#{attribute}=", value.new(resource[attribute.to_s], self, client))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def request(*args)
|
33
|
+
client.request(*args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Hcloud
|
2
|
+
class Error < StandardError
|
3
|
+
class Unauthorized < Error; end
|
4
|
+
class ServerError < Error; end
|
5
|
+
class Forbidden < Error; end
|
6
|
+
class InvalidInput < Error; end
|
7
|
+
class Locked < Error; end
|
8
|
+
class NotFound < Error; end
|
9
|
+
class RateLimitExceeded < Error; end
|
10
|
+
class ResourceUnavilable < Error; end
|
11
|
+
class ServiceError < Error; end
|
12
|
+
class UniquenessError < Error; end
|
13
|
+
class UnknownError < Error; end
|
14
|
+
class UnexpectedError < Error; end
|
15
|
+
class ResourcePathError < Error; end
|
16
|
+
end
|
17
|
+
end
|
data/lib/hcloud/image.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Hcloud
|
2
|
+
class Image
|
3
|
+
Attributes = {
|
4
|
+
id: nil,
|
5
|
+
type: nil,
|
6
|
+
status: nil,
|
7
|
+
name: nil,
|
8
|
+
description: nil,
|
9
|
+
image_size: nil,
|
10
|
+
disk_size: nil,
|
11
|
+
created: :time,
|
12
|
+
created_from: nil,
|
13
|
+
bound_to: nil,
|
14
|
+
os_flavor: nil,
|
15
|
+
os_version: nil,
|
16
|
+
rapid_deploy: nil,
|
17
|
+
}
|
18
|
+
|
19
|
+
include EntryLoader
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Hcloud
|
2
|
+
class Server
|
3
|
+
Attributes = {
|
4
|
+
id: nil,
|
5
|
+
name: nil,
|
6
|
+
status: nil,
|
7
|
+
created: :time,
|
8
|
+
public_net: nil,
|
9
|
+
server_type: ServerType,
|
10
|
+
datacenter: Datacenter,
|
11
|
+
image: Image,
|
12
|
+
iso: nil,
|
13
|
+
rescue_enabled: nil,
|
14
|
+
locked: nil,
|
15
|
+
backup_window: nil,
|
16
|
+
outgoing_traffic: nil,
|
17
|
+
ingoing_traffic: nil,
|
18
|
+
included_traffic: nil
|
19
|
+
}
|
20
|
+
|
21
|
+
include EntryLoader
|
22
|
+
|
23
|
+
def update(name:)
|
24
|
+
Server.new(
|
25
|
+
Oj.load(request(base_path, j: {name: name}, method: :put).run.body)["server"],
|
26
|
+
parent,
|
27
|
+
client
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def destroy
|
32
|
+
Action.new(
|
33
|
+
Oj.load(request(base_path, method: :delete).run.body)["action"],
|
34
|
+
parent,
|
35
|
+
client
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def base_path
|
42
|
+
return "servers/#{id}" unless id.nil?
|
43
|
+
raise ResourcePathError, "Unable to build resource path. Id is nil."
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Hcloud
|
2
|
+
class ServerResource < AbstractResource
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def create(name:,
|
6
|
+
server_type:,
|
7
|
+
datacenter: nil,
|
8
|
+
location: nil,
|
9
|
+
start_after_create: nil,
|
10
|
+
image:,
|
11
|
+
ssh_keys: [],
|
12
|
+
user_data: nil)
|
13
|
+
query = {}
|
14
|
+
method(:create).parameters.inject(query) do |r,x|
|
15
|
+
(var = eval(x.last.to_s)).nil? ? r : r.merge!(x.last => var)
|
16
|
+
end
|
17
|
+
Server.new(
|
18
|
+
Oj.load(request("servers", j: query, code: 200).run.body)["server"],
|
19
|
+
self,
|
20
|
+
client
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def all
|
25
|
+
Oj.load(request("servers").run.body)["servers"].map do |x|
|
26
|
+
Server.new(x, self, client)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def each(&block)
|
31
|
+
all.each do |member|
|
32
|
+
block.call(member)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hcloud
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.pre.alpha0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tim Foerster
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.15'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.15'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: typhoeus
|
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: oj
|
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: activesupport
|
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
|
+
description:
|
84
|
+
email:
|
85
|
+
- github@moo.gl
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- Gemfile
|
92
|
+
- README.md
|
93
|
+
- Rakefile
|
94
|
+
- bin/console
|
95
|
+
- bin/setup
|
96
|
+
- hcloud.gemspec
|
97
|
+
- lib/hcloud.rb
|
98
|
+
- lib/hcloud/abstract_resource.rb
|
99
|
+
- lib/hcloud/action.rb
|
100
|
+
- lib/hcloud/client.rb
|
101
|
+
- lib/hcloud/datacenter.rb
|
102
|
+
- lib/hcloud/entry_loader.rb
|
103
|
+
- lib/hcloud/errors.rb
|
104
|
+
- lib/hcloud/image.rb
|
105
|
+
- lib/hcloud/location.rb
|
106
|
+
- lib/hcloud/server.rb
|
107
|
+
- lib/hcloud/server_resource.rb
|
108
|
+
- lib/hcloud/server_type.rb
|
109
|
+
- lib/hcloud/version.rb
|
110
|
+
homepage: https://github.com/tonobo/hcloud
|
111
|
+
licenses: []
|
112
|
+
metadata: {}
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">"
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: 1.3.1
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 2.5.2.2
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: HetznerCloud native Ruby client
|
133
|
+
test_files: []
|