lunanode 0.1.5
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/.codeclimate.yml +16 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.rubocop.yml +94 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +11 -0
- data/.yardopts +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +50 -0
- data/Rakefile +19 -0
- data/bin/console +8 -0
- data/bin/setup +8 -0
- data/lib/lunanode.rb +12 -0
- data/lib/lunanode/action_generator.rb +105 -0
- data/lib/lunanode/api.rb +172 -0
- data/lib/lunanode/api_actions.rb +41 -0
- data/lib/lunanode/api_actions/default/dns.rb +55 -0
- data/lib/lunanode/api_actions/default/email.rb +59 -0
- data/lib/lunanode/api_actions/default/floating.rb +19 -0
- data/lib/lunanode/api_actions/default/image.rb +31 -0
- data/lib/lunanode/api_actions/default/lb.rb +35 -0
- data/lib/lunanode/api_actions/default/monitor.rb +47 -0
- data/lib/lunanode/api_actions/default/network.rb +19 -0
- data/lib/lunanode/api_actions/default/plan.rb +11 -0
- data/lib/lunanode/api_actions/default/region.rb +11 -0
- data/lib/lunanode/api_actions/default/script.rb +11 -0
- data/lib/lunanode/api_actions/default/securitygroup.rb +35 -0
- data/lib/lunanode/api_actions/default/vm.rb +99 -0
- data/lib/lunanode/api_actions/default/volume.rb +47 -0
- data/lib/lunanode/api_actions/dns.rb +10 -0
- data/lib/lunanode/api_actions/email.rb +10 -0
- data/lib/lunanode/api_actions/floating.rb +10 -0
- data/lib/lunanode/api_actions/image.rb +17 -0
- data/lib/lunanode/api_actions/lb.rb +10 -0
- data/lib/lunanode/api_actions/monitor.rb +10 -0
- data/lib/lunanode/api_actions/network.rb +10 -0
- data/lib/lunanode/api_actions/plan.rb +10 -0
- data/lib/lunanode/api_actions/region.rb +10 -0
- data/lib/lunanode/api_actions/script.rb +10 -0
- data/lib/lunanode/api_actions/securitygroup.rb +10 -0
- data/lib/lunanode/api_actions/vm.rb +10 -0
- data/lib/lunanode/api_actions/volume.rb +10 -0
- data/lib/lunanode/api_error.rb +5 -0
- data/lib/lunanode/version.rb +4 -0
- data/lunanode.gemspec +33 -0
- data/lunanode_api_def.yaml +391 -0
- metadata +191 -0
data/lib/lunanode/api.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
require "rest-client"
|
5
|
+
|
6
|
+
module Lunanode
|
7
|
+
# Class for accessing the Lunanode API.
|
8
|
+
#
|
9
|
+
# The class is instantiated by either passing it a JSON file containing
|
10
|
+
# the keys `api_id` and `api_key`, or specifying the ID and key directly:
|
11
|
+
# api = Lunanode::API.new("credentials_file.json")
|
12
|
+
# api = Lunanode::API.new(api_id: "ABCDEFG", api_key: "HIJKLMNOP")
|
13
|
+
#
|
14
|
+
# Once instantiated, action methods follow the example:
|
15
|
+
# api.vm_list # no parameters
|
16
|
+
# api.vm_info(vm_id: "My-VM-ID") # required parameters
|
17
|
+
# api.image_list(region: "Toronto") # optional parameters
|
18
|
+
#
|
19
|
+
# Required and optional arguments are specified in the method definitions,
|
20
|
+
# but can can be queried via {API.params_for}. They follow the API
|
21
|
+
# specification athttps://wiki.lunanode.com/index.php/API
|
22
|
+
#
|
23
|
+
class API
|
24
|
+
#
|
25
|
+
# Class-level definitions
|
26
|
+
#
|
27
|
+
|
28
|
+
API_ENDPOINT = "https://dynamic.lunanode.com/api/".freeze
|
29
|
+
@params_for = {}
|
30
|
+
|
31
|
+
# Show parameter info for any API method.
|
32
|
+
#
|
33
|
+
# @param method_name[#to_sym] The name of the API method
|
34
|
+
# @return [Hash] information about the method parameters
|
35
|
+
#
|
36
|
+
def self.params_for(method_name)
|
37
|
+
@params_for[method_name] ||= begin
|
38
|
+
method_name = method_name.to_sym
|
39
|
+
param_groups = instance_method(method_name).parameters.group_by(&:first)
|
40
|
+
out = {
|
41
|
+
required: param_groups[:keyreq] && param_group[:keyreq].map(&:last),
|
42
|
+
optional: param_groups[:key] && param_groups[:key].map(&:last),
|
43
|
+
additional: param_groups.key?(:keyrest),
|
44
|
+
}
|
45
|
+
out.each do |k, v|
|
46
|
+
if v
|
47
|
+
v.freeze
|
48
|
+
else
|
49
|
+
out.delete(k)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
out.freeze
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Instance-level definitions
|
58
|
+
#
|
59
|
+
|
60
|
+
include APIActions
|
61
|
+
attr_reader :api_id
|
62
|
+
|
63
|
+
# @overload initialize(credentials_file)
|
64
|
+
# Instantiate an API object from a credentials file.
|
65
|
+
# @param credentials_file[IO,String] a JSON credentials file
|
66
|
+
# (which contains the keys `api_id` and `api_key`)
|
67
|
+
#
|
68
|
+
# @overload initialize(api_id: nil, api_key: nil)
|
69
|
+
# Instantiate an API object from an API ID and API Key.
|
70
|
+
# @param api_id[String] A LunaNode API ID
|
71
|
+
# @param api_key[String] A LunaNode API Key
|
72
|
+
#
|
73
|
+
def initialize(credentials_file = nil, api_id: nil, api_key: nil)
|
74
|
+
if !credentials_file.nil? && File.exist?(credentials_file)
|
75
|
+
credentials_data = File.read(credentials_file)
|
76
|
+
credentials = JSON.parse(credentials_data, symbolize_names: true)
|
77
|
+
@api_id = credentials[:api_id]
|
78
|
+
@api_key = credentials[:api_key]
|
79
|
+
else
|
80
|
+
@api_id = api_id
|
81
|
+
@api_key = api_key
|
82
|
+
end
|
83
|
+
@api_id = @api_id.to_s.freeze
|
84
|
+
@api_key = @api_key.to_s.freeze
|
85
|
+
@rest_client = RestClient::Resource.new(
|
86
|
+
API_ENDPOINT,
|
87
|
+
verify_ssl: OpenSSL::SSL::VERIFY_PEER
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Display a string representation of the object without key information.
|
92
|
+
def inspect
|
93
|
+
"#<#{self.class.name}: api_id=#{api_id.inspect}>"
|
94
|
+
end
|
95
|
+
alias to_s inspect
|
96
|
+
|
97
|
+
# Send an arbitrary API action without any parameter checks.
|
98
|
+
#
|
99
|
+
# @param category[#to_sym] The API action category (i.e. dns, image, vm...)
|
100
|
+
# @param action[#to_sym] The API action name (i.e. create, list...)
|
101
|
+
# @param params[Hash] Any parameters required for the action.
|
102
|
+
#
|
103
|
+
# @return [Hash,Array,String] Response data from the API action.
|
104
|
+
# @raise [APIError] If there was a problem with the action.
|
105
|
+
#
|
106
|
+
def action(category, action, **params)
|
107
|
+
resp = call_api("#{category}/#{action}/", params)
|
108
|
+
raise APIError, %("#{resp[:error]}") unless resp[:success] == "yes"
|
109
|
+
resp.delete(:success)
|
110
|
+
|
111
|
+
if resp.size == 1
|
112
|
+
resp.values.first
|
113
|
+
else
|
114
|
+
resp
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
attr_reader :api_key, :rest_client
|
121
|
+
|
122
|
+
# Make an API call and return response.
|
123
|
+
def call_api(handler_path, params)
|
124
|
+
req_formdata = auth_request_formdata(handler_path, clean_params(params))
|
125
|
+
JSON.parse(rest_client[handler_path].post(req_formdata),
|
126
|
+
symbolize_names: true)
|
127
|
+
rescue RestClient::Exception => err
|
128
|
+
err.message += "\n Request Path: #{rest_client.url}#{handler_path}" \
|
129
|
+
"\n Request Data: #{req_data}"
|
130
|
+
raise err
|
131
|
+
end
|
132
|
+
|
133
|
+
# Clean empty request parameters
|
134
|
+
def clean_params(params)
|
135
|
+
params.each_with_object({}) do |(k, v), acc|
|
136
|
+
if k && k.respond_to?(:to_sym) && v && v.respond_to?(:to_s)
|
137
|
+
acc[k.to_sym] = v.to_s
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Create signed request data
|
143
|
+
def auth_request_formdata(handler_path, params)
|
144
|
+
req_msg = raw_request_message(params)
|
145
|
+
nonce = gen_nonce
|
146
|
+
signature = gen_signature(handler_path, req_msg, nonce)
|
147
|
+
{
|
148
|
+
req: req_msg,
|
149
|
+
signature: signature,
|
150
|
+
nonce: nonce,
|
151
|
+
}
|
152
|
+
end
|
153
|
+
|
154
|
+
# Generate raw, unsigned request message.
|
155
|
+
def raw_request_message(params)
|
156
|
+
params[:api_id] = api_id
|
157
|
+
params[:api_partialkey] = api_key.slice(0, 64)
|
158
|
+
params.to_json
|
159
|
+
end
|
160
|
+
|
161
|
+
# Generate nonce for request
|
162
|
+
def gen_nonce
|
163
|
+
Time.now.utc.to_i.to_s
|
164
|
+
end
|
165
|
+
|
166
|
+
# Generate signature for request
|
167
|
+
def gen_signature(handler_path, req_msg, nonce)
|
168
|
+
message = "#{handler_path}|#{req_msg}|#{nonce}"
|
169
|
+
OpenSSL::HMAC.hexdigest("SHA512", api_key, message)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lunanode/api_actions/dns"
|
4
|
+
require "lunanode/api_actions/email"
|
5
|
+
require "lunanode/api_actions/floating"
|
6
|
+
require "lunanode/api_actions/image"
|
7
|
+
require "lunanode/api_actions/lb"
|
8
|
+
require "lunanode/api_actions/monitor"
|
9
|
+
require "lunanode/api_actions/network"
|
10
|
+
require "lunanode/api_actions/plan"
|
11
|
+
require "lunanode/api_actions/region"
|
12
|
+
require "lunanode/api_actions/script"
|
13
|
+
require "lunanode/api_actions/securitygroup"
|
14
|
+
require "lunanode/api_actions/vm"
|
15
|
+
require "lunanode/api_actions/volume"
|
16
|
+
|
17
|
+
module Lunanode
|
18
|
+
# Module containing all API action methods included from various component
|
19
|
+
# modules.
|
20
|
+
#
|
21
|
+
# Standard API action methods were automatically generated from a datafile to
|
22
|
+
# specifying all required and optional parameters as keyword arguments.
|
23
|
+
#
|
24
|
+
# See https://wiki.lunanode.com/index.php/API for more details on the
|
25
|
+
# individual actions and parameters.
|
26
|
+
module APIActions
|
27
|
+
# Modules are included in reverse order so that YARD shows them correctly.
|
28
|
+
include Volume
|
29
|
+
include VM
|
30
|
+
include Securitygroup
|
31
|
+
include Script
|
32
|
+
include Plan
|
33
|
+
include Network
|
34
|
+
include Monitor
|
35
|
+
include LB
|
36
|
+
include Image
|
37
|
+
include Floating
|
38
|
+
include Email
|
39
|
+
include DNS
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lunanode
|
4
|
+
module APIActions
|
5
|
+
module DNS
|
6
|
+
def dns_list
|
7
|
+
action(:dns, :list)
|
8
|
+
end
|
9
|
+
|
10
|
+
def dns_set(ip:, hostname:)
|
11
|
+
action(:dns, :set, ip: ip, hostname: hostname)
|
12
|
+
end
|
13
|
+
|
14
|
+
def dns_zone_list
|
15
|
+
action(:dns, :zone_list)
|
16
|
+
end
|
17
|
+
|
18
|
+
def dns_zone_add(origin:, ttl: nil)
|
19
|
+
action(:dns, :zone_add, origin: origin, ttl: ttl)
|
20
|
+
end
|
21
|
+
|
22
|
+
def dns_zone_remove(zone_id:)
|
23
|
+
action(:dns, :zone_remove, zone_id: zone_id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def dns_record_list(zone_id:)
|
27
|
+
action(:dns, :record_list, zone_id: zone_id)
|
28
|
+
end
|
29
|
+
|
30
|
+
def dns_record_add(zone_id:, name:, data:, ttl:, type:)
|
31
|
+
action(:dns, :record_add, zone_id: zone_id, name: name, data: data, ttl: ttl, type: type)
|
32
|
+
end
|
33
|
+
|
34
|
+
def dns_record_remove(record_id:)
|
35
|
+
action(:dns, :record_remove, record_id: record_id)
|
36
|
+
end
|
37
|
+
|
38
|
+
def dns_dyn_list
|
39
|
+
action(:dns, :dyn_list)
|
40
|
+
end
|
41
|
+
|
42
|
+
def dns_dyn_add(name:, ip:)
|
43
|
+
action(:dns, :dyn_add, name: name, ip: ip)
|
44
|
+
end
|
45
|
+
|
46
|
+
def dns_dyn_update(dyn_id:, name:, ip:)
|
47
|
+
action(:dns, :dyn_update, dyn_id: dyn_id, name: name, ip: ip)
|
48
|
+
end
|
49
|
+
|
50
|
+
def dns_dyn_remove(dyn_id:)
|
51
|
+
action(:dns, :dyn_remove, dyn_id: dyn_id)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lunanode
|
4
|
+
module APIActions
|
5
|
+
module Email
|
6
|
+
def email_usage
|
7
|
+
action(:email, :usage)
|
8
|
+
end
|
9
|
+
|
10
|
+
def email_domain_list
|
11
|
+
action(:email, :domain_list)
|
12
|
+
end
|
13
|
+
|
14
|
+
def email_domain_add(name:)
|
15
|
+
action(:email, :domain_add, name: name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def email_domain_remove(domain_id:)
|
19
|
+
action(:email, :domain_remove, domain_id: domain_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def email_domain_dkim_set(domain_id:, selector:, private_key:)
|
23
|
+
action(:email, :domain_dkim_set, domain_id: domain_id, selector: selector, private_key: private_key)
|
24
|
+
end
|
25
|
+
|
26
|
+
def email_domain_dkim_unset(domain_id:)
|
27
|
+
action(:email, :domain_dkim_unset, domain_id: domain_id)
|
28
|
+
end
|
29
|
+
|
30
|
+
def email_user_list(domain_id:)
|
31
|
+
action(:email, :user_list, domain_id: domain_id)
|
32
|
+
end
|
33
|
+
|
34
|
+
def email_user_add(domain_id:, username:, password:)
|
35
|
+
action(:email, :user_add, domain_id: domain_id, username: username, password: password)
|
36
|
+
end
|
37
|
+
|
38
|
+
def email_user_set_password(domain_id:, user_id:, password:)
|
39
|
+
action(:email, :user_set_password, domain_id: domain_id, user_id: user_id, password: password)
|
40
|
+
end
|
41
|
+
|
42
|
+
def email_user_remove(domain_id:, user_id:)
|
43
|
+
action(:email, :user_remove, domain_id: domain_id, user_id: user_id)
|
44
|
+
end
|
45
|
+
|
46
|
+
def email_alias_list(domain_id:)
|
47
|
+
action(:email, :alias_list, domain_id: domain_id)
|
48
|
+
end
|
49
|
+
|
50
|
+
def email_alias_add(domain_id:, name:, target:)
|
51
|
+
action(:email, :alias_add, domain_id: domain_id, name: name, target: target)
|
52
|
+
end
|
53
|
+
|
54
|
+
def email_alias_remove(domain_id:, alias_id:)
|
55
|
+
action(:email, :alias_remove, domain_id: domain_id, alias_id: alias_id)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lunanode
|
4
|
+
module APIActions
|
5
|
+
module Floating
|
6
|
+
def floating_list
|
7
|
+
action(:floating, :list)
|
8
|
+
end
|
9
|
+
|
10
|
+
def floating_add(region:)
|
11
|
+
action(:floating, :add, region: region)
|
12
|
+
end
|
13
|
+
|
14
|
+
def floating_delete(region:, ip:)
|
15
|
+
action(:floating, :delete, region: region, ip: ip)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lunanode
|
4
|
+
module APIActions
|
5
|
+
module Image
|
6
|
+
def image_list(region: nil)
|
7
|
+
action(:image, :list, region: region)
|
8
|
+
end
|
9
|
+
|
10
|
+
def image_delete(image_id:)
|
11
|
+
action(:image, :delete, image_id: image_id)
|
12
|
+
end
|
13
|
+
|
14
|
+
def image_details(image_id:)
|
15
|
+
action(:image, :details, image_id: image_id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def image_replicate(image_id:, region:)
|
19
|
+
action(:image, :replicate, image_id: image_id, region: region)
|
20
|
+
end
|
21
|
+
|
22
|
+
def image_fetch(region:, name:, location:, format:, virtio: nil)
|
23
|
+
action(:image, :fetch, region: region, name: name, location: location, format: format, virtio: virtio)
|
24
|
+
end
|
25
|
+
|
26
|
+
def image_retrieve(image_id:)
|
27
|
+
action(:image, :retrieve, image_id: image_id)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lunanode
|
4
|
+
module APIActions
|
5
|
+
module LB
|
6
|
+
def lb_list(region:, net_id: nil)
|
7
|
+
action(:lb, :list, region: region, net_id: net_id)
|
8
|
+
end
|
9
|
+
|
10
|
+
def lb_create(region:, net_id:, name:, method:, protocol:, connection_limit:, port:)
|
11
|
+
action(:lb, :create, region: region, net_id: net_id, name: name, method: method, protocol: protocol, connection_limit: connection_limit, port: port)
|
12
|
+
end
|
13
|
+
|
14
|
+
def lb_delete(region:, lb_id:)
|
15
|
+
action(:lb, :delete, region: region, lb_id: lb_id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def lb_info(region:, lb_id:)
|
19
|
+
action(:lb, :info, region: region, lb_id: lb_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def lb_member_add(region:, lb_id:, ip:, port:)
|
23
|
+
action(:lb, :member_add, region: region, lb_id: lb_id, ip: ip, port: port)
|
24
|
+
end
|
25
|
+
|
26
|
+
def lb_member_remove(region:, lb_id:, member_id:)
|
27
|
+
action(:lb, :member_remove, region: region, lb_id: lb_id, member_id: member_id)
|
28
|
+
end
|
29
|
+
|
30
|
+
def lb_associate(region:, lb_id:, ip:)
|
31
|
+
action(:lb, :associate, region: region, lb_id: lb_id, ip: ip)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lunanode
|
4
|
+
module APIActions
|
5
|
+
module Monitor
|
6
|
+
def monitor_check_list
|
7
|
+
action(:monitor, :check_list)
|
8
|
+
end
|
9
|
+
|
10
|
+
def monitor_check_types
|
11
|
+
action(:monitor, :check_types)
|
12
|
+
end
|
13
|
+
|
14
|
+
def monitor_check_add(name:, type:, fail_count:, success_count:, check_interval:, **from_check_type)
|
15
|
+
action(:monitor, :check_add, name: name, type: type, fail_count: fail_count, success_count: success_count, check_interval: check_interval, **from_check_type)
|
16
|
+
end
|
17
|
+
|
18
|
+
def monitor_check_remove(check_id:)
|
19
|
+
action(:monitor, :check_remove, check_id: check_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def monitor_contact_list
|
23
|
+
action(:monitor, :contact_list)
|
24
|
+
end
|
25
|
+
|
26
|
+
def monitor_contact_add
|
27
|
+
action(:monitor, :contact_add)
|
28
|
+
end
|
29
|
+
|
30
|
+
def monitor_contact_remove(type:, rel:)
|
31
|
+
action(:monitor, :contact_remove, type: type, rel: rel)
|
32
|
+
end
|
33
|
+
|
34
|
+
def monitor_alert_list(check_id:)
|
35
|
+
action(:monitor, :alert_list, check_id: check_id)
|
36
|
+
end
|
37
|
+
|
38
|
+
def monitor_alert_add(check_id:, contact_id:)
|
39
|
+
action(:monitor, :alert_add, check_id: check_id, contact_id: contact_id)
|
40
|
+
end
|
41
|
+
|
42
|
+
def monitor_alert_remove(alert_id:)
|
43
|
+
action(:monitor, :alert_remove, alert_id: alert_id)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|