triton-internal 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 +7 -0
- data/Users/thomas/tdh/triton/Gemfile +4 -0
- data/Users/thomas/tdh/triton/Gemfile.lock +51 -0
- data/Users/thomas/tdh/triton/LICENSE +21 -0
- data/Users/thomas/tdh/triton/README.md +87 -0
- data/Users/thomas/tdh/triton/Rakefile +6 -0
- data/Users/thomas/tdh/triton/bin/console +17 -0
- data/Users/thomas/tdh/triton/bin/setup +8 -0
- data/Users/thomas/tdh/triton/lib/triton/api_base.rb +120 -0
- data/Users/thomas/tdh/triton/lib/triton/cnapi.rb +78 -0
- data/Users/thomas/tdh/triton/lib/triton/imgapi.rb +38 -0
- data/Users/thomas/tdh/triton/lib/triton/indifferent_hash.rb +120 -0
- data/Users/thomas/tdh/triton/lib/triton/internal.rb +7 -0
- data/Users/thomas/tdh/triton/lib/triton/napi.rb +51 -0
- data/Users/thomas/tdh/triton/lib/triton/papi.rb +15 -0
- data/Users/thomas/tdh/triton/lib/triton/remote_exception.rb +53 -0
- data/Users/thomas/tdh/triton/lib/triton/version.rb +3 -0
- data/Users/thomas/tdh/triton/lib/triton/vmapi.rb +50 -0
- data/Users/thomas/tdh/triton/lib/triton.rb +57 -0
- data/Users/thomas/tdh/triton/pkg/triton-internal-0.1.0.gem +0 -0
- data/Users/thomas/tdh/triton/spec/api_base_spec.rb +288 -0
- data/Users/thomas/tdh/triton/spec/spec_helper.rb +16 -0
- data/Users/thomas/tdh/triton/spec/triton_spec.rb +32 -0
- data/Users/thomas/tdh/triton/triton-internal.gemspec +30 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4b93f09a9ba8fe9f2356cd506c08dcc37195781c
|
4
|
+
data.tar.gz: 6a0a7664fbbfcbfce694722ca47f09603444f49e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 19539963e4447514c4c8777634dfcfbbe2276be0ce999176b14107dd9fbc48167547b7fbcb66330847f99d5b269f0decf6c8b9d7fdbc5808944f3db55534a478
|
7
|
+
data.tar.gz: 0ad33a967873f7e48b302870721ddeacf9038b5e8fcd9e6cb6184c19465aa17de41bd362008f9337b4bc566b2fc38918c887fed6451ed158c2ec021350834582
|
@@ -0,0 +1,51 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
triton-internal (0.1.0)
|
5
|
+
rest-client (~> 1.8)
|
6
|
+
socksify (~> 1.7)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
diff-lcs (1.3)
|
12
|
+
domain_name (0.5.20170404)
|
13
|
+
unf (>= 0.0.5, < 1.0.0)
|
14
|
+
http-cookie (1.0.3)
|
15
|
+
domain_name (~> 0.5)
|
16
|
+
mime-types (2.99.3)
|
17
|
+
netrc (0.11.0)
|
18
|
+
rake (10.5.0)
|
19
|
+
rest-client (1.8.0)
|
20
|
+
http-cookie (>= 1.0.2, < 2.0)
|
21
|
+
mime-types (>= 1.16, < 3.0)
|
22
|
+
netrc (~> 0.7)
|
23
|
+
rspec (3.6.0)
|
24
|
+
rspec-core (~> 3.6.0)
|
25
|
+
rspec-expectations (~> 3.6.0)
|
26
|
+
rspec-mocks (~> 3.6.0)
|
27
|
+
rspec-core (3.6.0)
|
28
|
+
rspec-support (~> 3.6.0)
|
29
|
+
rspec-expectations (3.6.0)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.6.0)
|
32
|
+
rspec-mocks (3.6.0)
|
33
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
+
rspec-support (~> 3.6.0)
|
35
|
+
rspec-support (3.6.0)
|
36
|
+
socksify (1.7.0)
|
37
|
+
unf (0.1.4)
|
38
|
+
unf_ext
|
39
|
+
unf_ext (0.0.7.4)
|
40
|
+
|
41
|
+
PLATFORMS
|
42
|
+
ruby
|
43
|
+
|
44
|
+
DEPENDENCIES
|
45
|
+
bundler (~> 1.14)
|
46
|
+
rake (~> 10.0)
|
47
|
+
rspec (~> 3.0)
|
48
|
+
triton-internal!
|
49
|
+
|
50
|
+
BUNDLED WITH
|
51
|
+
1.14.6
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2017 Thomas Haggett
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Triton
|
2
|
+
|
3
|
+
[](https://travis-ci.org/joshado/triton-internal-gem)
|
4
|
+
|
5
|
+
Gem to wrap and mock the Triton internal APIs.
|
6
|
+
|
7
|
+
Currently supports:
|
8
|
+
|
9
|
+
* [Vmapi](https://github.com/joyent/sdc-vmapi/blob/master/docs/index.md)
|
10
|
+
* [Cnapi](https://github.com/joyent/sdc-cnapi/blob/master/docs/index.md)
|
11
|
+
* [Napi](https://github.com/joyent/sdc-napi/blob/master/docs/index.md)
|
12
|
+
* [Papi](https://github.com/joyent/sdc-papi/blob/master/docs/index.md)
|
13
|
+
* [Imgapi](https://github.com/joyent/sdc-imgapi/blob/master/docs/index.md)
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
This library simply exposes the internal Triton API layer as cleaner Ruby function calls with a consistent interface. Rather than re-implement and re-document all the calls, a relatively small set of conventions map the function calls to the HTTP requests allowing the fantastic Joyent documentation, linked above, to be used directly.
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
### Configuration
|
22
|
+
|
23
|
+
When making requests, it calls APIs via their hostnames the suffix needs to be specified. This is dependent on the configuration of the triton cluster. You'll also need access to the Triton `admin` network to make the calls - you can either use this library on a host directly connected to the `admin` network or, alternatively, make calls via a SOCKS proxy.
|
24
|
+
|
25
|
+
It's possible to use the SOCKS proxy built into the `ssh` client:
|
26
|
+
|
27
|
+
ssh -D 1234 root@<headnode ip>
|
28
|
+
|
29
|
+
...
|
30
|
+
|
31
|
+
Triton.socks = '127.0.0.1:1234'
|
32
|
+
|
33
|
+
### Calling methods
|
34
|
+
|
35
|
+
Each (supported) API has a module under the `Triton` namespace - CNAPI, for example, becomes `Triton::Cnapi`. Each API function can be accessed either via the execute method using CamelCase method name from the Joyent documentation:
|
36
|
+
|
37
|
+
> Triton::Vmapi.execute("ListVms", :fields => 'uuid')
|
38
|
+
=> [{"uuid"=>"ff64a98e-3a8a-4d90-a726-0c2fd33e378c"}, ...
|
39
|
+
|
40
|
+
or it can be be called via a direct class method, using a dynamically mapped `snake_case` method name:
|
41
|
+
|
42
|
+
> Triton::Vmapi.list_vms(:fields => 'uuid')
|
43
|
+
=> [{"uuid"=>"ff64a98e-3a8a-4d90-a726-0c2fd33e378c"}, ...
|
44
|
+
|
45
|
+
Note that symbols are mapped out to strings automatically, and the returned object is indifferent to string or symbol access.
|
46
|
+
|
47
|
+
### Handling Responses
|
48
|
+
|
49
|
+
A response hash is returned in the event of a successful response code from the server. If a unsuccessful code is returned, then a `Triton::RemoteException` subclass is raised with the code passed from the server.
|
50
|
+
|
51
|
+
The CreateVm could, for example, return a `ValidationFailed` error code, this is raised as `Triton::RemoteExceptions::ValidationFailed` which inherits from `Triton::RemoteException`. So, code such this should "just work":
|
52
|
+
|
53
|
+
begin
|
54
|
+
Triton::Vmapi.execute("CreateVm", { })
|
55
|
+
rescue Triton::RemoteExceptions::ValidationFailed => e
|
56
|
+
# valiation failed response
|
57
|
+
rescue Triton::RemoteException => e
|
58
|
+
# another server error
|
59
|
+
end
|
60
|
+
|
61
|
+
All `RemoteExceptions` expose a `body` accessor returning the full deserialised JSON error and also the specific `code`, `message` and `errors` accessors.
|
62
|
+
|
63
|
+
## Testing
|
64
|
+
|
65
|
+
There is a set of rspec tests that exercise the various mapping behaviours outlined above, these are purely offline only tests. None of the testing exercises the Triton functionality - this library makes no claims about the behaviour of the various function calls, but does make it easier for consumer applications to mock the calls in it's own testing. The following rspec code should work as expected:
|
66
|
+
|
67
|
+
allow(Triton::Vmapi).to receive(:list_vms)
|
68
|
+
|
69
|
+
...
|
70
|
+
|
71
|
+
expect(Triton::Vmapi).to have_received(:list_vms) do |args|
|
72
|
+
expect(args[:uuid]).to eq('12345....')
|
73
|
+
end
|
74
|
+
|
75
|
+
In addition, you can enable a "test-mode" which will refuse to make live calls and, instead, raise exceptions about leaking calls. This is enabled by specifying
|
76
|
+
|
77
|
+
Triton.test_mode = true
|
78
|
+
|
79
|
+
in your rspec configuration.
|
80
|
+
|
81
|
+
Finally, you can use the console to interact with a live Triton cluster - be careful. You can specify the suffix and SOCKS configuration on the command line:
|
82
|
+
|
83
|
+
$ bundle exec bin/console --suffix ovh-1 --socks 1234
|
84
|
+
irb(main):001:0> Triton::Vmapi.list_vms(:limit => 3, :fields => 'uuid')
|
85
|
+
=> [{"uuid"=>"fffeb0d0-ed59-46e7-b212-5d64d02db417"}, {"uuid"=>"ffe29552-8186-c22f-9a8d-f06ee619c444"}, {"uuid"=>"ff8a2abb-d270-e323-81c2-f0f7f7dff8a1"}]
|
86
|
+
irb(main):002:0>
|
87
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "triton/internal"
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
OptionParser.new do |o|
|
8
|
+
o.on("--socks [host:]port", String, "Configures the library to use a SOCKS proxy at host:port (defaults host to localhost)") do |v|
|
9
|
+
Triton.socks = v
|
10
|
+
end
|
11
|
+
o.on("--suffix suffix", String, "Specifies the triton hostname suffix to use") do |v|
|
12
|
+
Triton.suffix = v
|
13
|
+
end
|
14
|
+
end.parse!(ARGV)
|
15
|
+
|
16
|
+
require "irb"
|
17
|
+
IRB.start(__FILE__)
|
@@ -0,0 +1,120 @@
|
|
1
|
+
class String
|
2
|
+
def camelise
|
3
|
+
return nil unless self =~ /^[a-z\d_]+$/
|
4
|
+
self.gsub(/_?([a-z\d]*)/) { |_| $1.capitalize }
|
5
|
+
end
|
6
|
+
end
|
7
|
+
module Triton
|
8
|
+
|
9
|
+
class ApiBase
|
10
|
+
|
11
|
+
UnknownCall = Class.new(NoMethodError)
|
12
|
+
DefinedMethods = Hash.new { |hash, key| hash[key] = {} }
|
13
|
+
ApiNames = Hash.new
|
14
|
+
|
15
|
+
def self.call(name, opts={})
|
16
|
+
DefinedMethods[self][name] = opts
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.name=(name)
|
20
|
+
ApiNames[self] = name
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.execute(name, params={})
|
24
|
+
new(name, params).execute
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.hostname
|
28
|
+
"#{ApiNames[self]}.#{Triton.suffix}"
|
29
|
+
end
|
30
|
+
|
31
|
+
# We dynamically map from snake_case to CamelCase here
|
32
|
+
def self.method_missing(snake_case, *args)
|
33
|
+
camel_case = snake_case.to_s.camelise
|
34
|
+
if DefinedMethods[self][camel_case]
|
35
|
+
execute(camel_case, *args)
|
36
|
+
else
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.respond_to_missing?(snake_case, include_all=false)
|
42
|
+
camel_case = snake_case.to_s.camelise
|
43
|
+
if DefinedMethods[self][camel_case]
|
44
|
+
true
|
45
|
+
else
|
46
|
+
super(snake_case, include_all)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def initialize(name, params={})
|
51
|
+
@name = name
|
52
|
+
@call = DefinedMethods[self.class][name]
|
53
|
+
@params = params
|
54
|
+
|
55
|
+
raise UnknownCall, "#{@name} isn't a known API method." unless @call
|
56
|
+
end
|
57
|
+
|
58
|
+
def execute
|
59
|
+
if Triton.test_mode
|
60
|
+
raise Triton::TestModeLeak, "Request '#{@name}' leaked when in test mode\n#{request.method.upcase} #{URI.parse(request.url).path}\n#{JSON.pretty_generate(@params)}"
|
61
|
+
end
|
62
|
+
Triton.logger.debug("#{self.class.name}/#{@name}: #{request.method.upcase} #{URI.parse(request.url).path}\n#{JSON.pretty_generate(@params)}")
|
63
|
+
object = JSON.parse(request.execute)
|
64
|
+
if object.is_a?(Hash)
|
65
|
+
IndifferentHash.new.merge!(object)
|
66
|
+
else
|
67
|
+
object
|
68
|
+
end
|
69
|
+
rescue RestClient::Exception => e
|
70
|
+
begin
|
71
|
+
payload = JSON.parse(e.response.body)
|
72
|
+
raise Triton::RemoteException, payload
|
73
|
+
rescue JSON::JSONError
|
74
|
+
raise e
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def request
|
79
|
+
@request ||= begin
|
80
|
+
request_method = @call.fetch(:method, :get).intern
|
81
|
+
path = @call[:path]
|
82
|
+
|
83
|
+
@params.each do |k,v|
|
84
|
+
path = path.gsub(":#{k.to_s}") do |_|
|
85
|
+
@params.delete(k)
|
86
|
+
CGI.escape(v.to_s)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
body_param = @call[:body_param] && @params.delete(@call[:body_param])
|
91
|
+
|
92
|
+
if request_method == :get || !!body_param
|
93
|
+
payload = !!body_param && JSON.generate(body_param)
|
94
|
+
query = @params.map { |k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" }.join("&")
|
95
|
+
else
|
96
|
+
query = nil
|
97
|
+
payload = JSON.dump(@params)
|
98
|
+
end
|
99
|
+
|
100
|
+
url = URI.parse("http://#{self.class.hostname}#{path}")
|
101
|
+
url.query = if url.query
|
102
|
+
"#{url.query}&#{query}"
|
103
|
+
else
|
104
|
+
query
|
105
|
+
end
|
106
|
+
|
107
|
+
RestClient::Request.new({
|
108
|
+
:method => request_method,
|
109
|
+
:url => url.to_s,
|
110
|
+
:headers => {
|
111
|
+
'Accept' => 'application/json',
|
112
|
+
'Content-Type' => !!payload ? 'application/json' : nil
|
113
|
+
},
|
114
|
+
:payload => payload
|
115
|
+
})
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Triton
|
2
|
+
class Cnapi < ApiBase
|
3
|
+
|
4
|
+
# The commit used to compile this itnerface:
|
5
|
+
# https://github.com/joyent/sdc-cnapi/blob/ba575c6136179f74ca16f086d1d71b9032e44e8d/docs/index.md
|
6
|
+
#
|
7
|
+
|
8
|
+
self.name = "cnapi"
|
9
|
+
|
10
|
+
call('SelectServer', :method => :post, :path => '/allocate')
|
11
|
+
call('ServerCapacity', :method => :post, :path => '/capacity')
|
12
|
+
call('BootParamsGetDefault', :method => :get, :path => '/boot/default')
|
13
|
+
call('BootParamsSetDefault', :method => :put, :path => '/boot/default')
|
14
|
+
call('BootParamsUpdateDefault', :method => :post, :path => '/boot/default')
|
15
|
+
call('BootParamsGet', :method => :get, :path => '/boot/:server_uuid')
|
16
|
+
call('BootParamsSet', :method => :put, :path => '/boot/:server_uuid')
|
17
|
+
call('BootParamsUpdate', :method => :post, :path => '/boot/:server_uuid')
|
18
|
+
call('TaskGet', :method => :get, :path => '/tasks/:task_id')
|
19
|
+
call('TaskWait', :method => :get, :path => '/tasks/:task_id/wait')
|
20
|
+
call('ImageGet', :method => :get, :path => '/servers/:server_uuid/images/:uuid')
|
21
|
+
call('Ping', :method => :get, :path => '/ping')
|
22
|
+
call('NicUpdate', :method => :put, :path => '/servers/:server_uuid/nics')
|
23
|
+
call('PlatformList', :method => :get, :path => '/platforms')
|
24
|
+
call('CommandExecute', :method => :post, :path => '/servers/:server_uuid/execute')
|
25
|
+
call('ServerList', :method => :get, :path => '/servers')
|
26
|
+
call('ServerGet', :method => :get, :path => '/servers/:server_uuid')
|
27
|
+
call('ServerUpdate', :method => :post, :path => '/servers/:server_uuid')
|
28
|
+
call('ServerReboot', :method => :post, :path => '/servers/:server_uuid/reboot')
|
29
|
+
call('ServerFactoryReset', :method => :put, :path => '/servers/:server_uuid/factory-reset')
|
30
|
+
call('ServerSetup', :method => :put, :path => '/servers/:server_uuid/setup')
|
31
|
+
call('ServerSysinfoRefresh', :method => :post, :path => '/servers/:server_uuid/sysinfo-refresh')
|
32
|
+
call('ServerDelete', :method => :delete, :path => '/servers/:server_uuid')
|
33
|
+
call('ServerTaskHistory', :method => :get, :path => '/servers/:server_uuid/task-history')
|
34
|
+
call('ServerEnsureImage', :method => :get, :path => '/servers/:server_uuid/ensure-image')
|
35
|
+
call('ServerInstallAgent', :method => :post, :path => '/servers/:server_uuid/install-agent')
|
36
|
+
call('ServerCnAgentPause', :method => :get, :path => '/servers/:server_uuid/cn-agent/pause')
|
37
|
+
call('ServerCnAgentResume', :method => :get, :path => '/servers/:server_uuid/cn-agent/resume')
|
38
|
+
call('VmList', :method => :get, :path => '/servers/:server_uuid/vms')
|
39
|
+
call('VmLoad', :method => :get, :path => '/servers/:server_uuid/vms/:uuid')
|
40
|
+
call('VmInfo', :method => :get, :path => '/servers/:server_uuid/vms/:uuid/info')
|
41
|
+
call('VmVncInfo', :method => :get, :path => '/servers/:server_uuid/vms/:uuid/vnc')
|
42
|
+
call('VmUpdate', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/update')
|
43
|
+
call('VmNicsUpdate', :method => :post, :path => '/servers/:server_uuid/vms/nics/update')
|
44
|
+
call('VmStart', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/start')
|
45
|
+
call('VmStop', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/stop')
|
46
|
+
call('VmKill', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/kill')
|
47
|
+
call('VmReboot', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/reboot')
|
48
|
+
call('VmCreate', :method => :post, :path => '/servers/:server_uuid/vms')
|
49
|
+
call('VmReprovision', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/reprovision')
|
50
|
+
call('VmDestroy', :method => :delete, :path => '/servers/:server_uuid/vms/:uuid')
|
51
|
+
call('VmDockerExec', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/docker-exec')
|
52
|
+
call('VmDockerCopy', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/docker-copy')
|
53
|
+
call('VmDockerStats', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/docker-stats')
|
54
|
+
call('VmDockerBuild', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/docker-build')
|
55
|
+
call('VmImagesCreate', :method => :post, :path => '/servers/:server_uuid/vms/:uuid/images')
|
56
|
+
call('VmSnapshotCreate', :method => :put, :path => '/servers/:server_uuid/vms/:uuid/snapshots')
|
57
|
+
call('VmSnapshotRollback', :method => :put, :path => '/servers/:server_uuid/vms/:uuid/snapshots/:snapshot_name/rollback')
|
58
|
+
call('VmSnapshotDestroy', :method => :delete, :path => '/servers/:server_uuid/vms/:uuid/snapshots/:snapshot_name')
|
59
|
+
call('ServerWaitlistList', :method => :get, :path => '/servers/:server_uuid/tickets')
|
60
|
+
call('ServerWaitlistTicketCreate', :method => :post, :path => '/servers/:server_uuid/tickets')
|
61
|
+
call('ServerWaitlistGetTicket', :method => :post, :path => '/tickets/:ticket_uuid')
|
62
|
+
call('ServerWaitlistDeleteTicket', :method => :delete, :path => '/tickets/:ticket_uuid')
|
63
|
+
call('ServerWaitlistTicketsDeleteAll', :method => :delete, :path => '/servers/:server_uuid/tickets')
|
64
|
+
call('ServerWaitlistTicketsWait', :method => :get, :path => '/tickets/:ticket_uuid/wait')
|
65
|
+
call('ServerWaitlistTicketsRelease', :method => :get, :path => '/tickets/:ticket_uuid/release')
|
66
|
+
call('DatasetsList', :method => :get, :path => '/servers/:server_uuid/datasets')
|
67
|
+
call('DatasetCreate', :method => :post, :path => '/servers/:server_uuid/datasets')
|
68
|
+
call('SnapshotCreate', :method => :post, :path => '/servers/:server_uuid/datasets/:dataset/snapshot')
|
69
|
+
call('SnapshotRollback', :method => :post, :path => '/servers/:server_uuid/datasets/:dataset/rollback')
|
70
|
+
call('SnapshotList', :method => :get, :path => '/servers/:server_uuid/datasets/:dataset/snapshots')
|
71
|
+
call('DatasetPropertiesGetAll', :method => :get, :path => '/servers/:server_uuid/dataset-properties')
|
72
|
+
call('DatasetPropertiesGet', :method => :get, :path => '/servers/:server_uuid/datasets/:dataset/properties')
|
73
|
+
call('DatasetPropertiesSet', :method => :post, :path => '/servers/:server_uuid/datasets/:dataset/properties')
|
74
|
+
call('DatasetDestroy', :method => :delete, :path => '/servers/:server_uuid/datasets/:dataset')
|
75
|
+
call('ZpoolList', :method => :get, :path => '/servers/:server_uuid/zpools')
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Triton
|
2
|
+
class Imgapi < ApiBase
|
3
|
+
|
4
|
+
# The commit used to compile this itnerface:
|
5
|
+
# https://github.com/joyent/sdc-imgapi/blob/f71f1e97b49e69830aa64d45e3ab5ef141ae3357/docs/index.md
|
6
|
+
#
|
7
|
+
|
8
|
+
self.name = "imgapi"
|
9
|
+
|
10
|
+
call('ListImages', :method => :get, :path => '/images')
|
11
|
+
call('GetImage', :method => :get, :path => '/images/:uuid')
|
12
|
+
call('GetImageFile', :method => :get, :path => '/images/:uuid/file')
|
13
|
+
call('GetImageIcon', :method => :get, :path => '/images/:uuid/icon')
|
14
|
+
call('DeleteImageIcon', :method => :delete, :path => '/images/:uuid/icon')
|
15
|
+
call('DeleteImage', :method => :delete, :path => '/images/:uuid')
|
16
|
+
call('CreateImage', :method => :post, :path => '/images')
|
17
|
+
call('CreateImageFromVm', :method => :post, :path => '/images?action=create-from-vm')
|
18
|
+
call('ExportImage', :method => :post, :path => '/images/:uuid?action=export')
|
19
|
+
call('AddImageFile', :method => :put, :path => '/images/:uuid/file')
|
20
|
+
call('AddImageIcon', :method => :put, :path => '/images/:uuid/icon')
|
21
|
+
call('ActivateImage', :method => :post, :path => '/images/:uuid?action=activate')
|
22
|
+
call('DisableImage', :method => :post, :path => '/images/:uuid?action=disable')
|
23
|
+
call('EnableImage', :method => :post, :path => '/images/:uuid?action=enable')
|
24
|
+
call('AddImageAcl', :method => :post, :path => '/images/:uuid/acl?action=add')
|
25
|
+
call('RemoveImageAcl', :method => :post, :path => '/images/:uuid/acl?action=remove')
|
26
|
+
call('UpdateImage', :method => :post, :path => '/images/:uuid?action=update')
|
27
|
+
call('AdminImportImage', :method => :post, :path => '/images/:uuid?action=import')
|
28
|
+
call('AdminImportRemoteImage', :method => :post, :path => '/images/:uuid?action=import-remote')
|
29
|
+
call('AdminImportDockerImage', :method => :post, :path => '/images?action=import-docker-image')
|
30
|
+
call('AdminChangeImageStor', :method => :post, :path => '/images/:uuid?action=change-stor&stor=:newstor')
|
31
|
+
call('ListImageJobs', :method => :get, :path => '/images/:uuid/jobs')
|
32
|
+
call('ListChannels', :method => :get, :path => '/channels')
|
33
|
+
call('ChannelAddImage', :method => :post, :path => '/images/:uuid?action=channel-add')
|
34
|
+
call('Ping', :method => :get, :path => '/ping')
|
35
|
+
call('AdminGetState', :method => :get, :path => '/state')
|
36
|
+
call('AdminReloadAuthKeys', :method => :post, :path => '/authkeys/reload')
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# This class has been permamently borrowed from Sinatra, that repo is MIT licensed
|
2
|
+
# and has these copyright notices:
|
3
|
+
#
|
4
|
+
# Copyright (c) 2007, 2008, 2009 Blake Mizerany
|
5
|
+
# Copyright (c) 2010-2017 Konstantin Haase
|
6
|
+
# Copyright (c) 2015-2017 Zachary Scott
|
7
|
+
#
|
8
|
+
|
9
|
+
class IndifferentHash < Hash
|
10
|
+
def self.[](*args)
|
11
|
+
new.merge!(Hash[*args])
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(*args)
|
15
|
+
super(*args.map(&method(:convert_value)))
|
16
|
+
end
|
17
|
+
|
18
|
+
def default(*args)
|
19
|
+
super(*args.map(&method(:convert_key)))
|
20
|
+
end
|
21
|
+
|
22
|
+
def default=(value)
|
23
|
+
super(convert_value(value))
|
24
|
+
end
|
25
|
+
|
26
|
+
def assoc(key)
|
27
|
+
super(convert_key(key))
|
28
|
+
end
|
29
|
+
|
30
|
+
def rassoc(value)
|
31
|
+
super(convert_value(value))
|
32
|
+
end
|
33
|
+
|
34
|
+
def fetch(key, *args)
|
35
|
+
super(convert_key(key), *args.map(&method(:convert_value)))
|
36
|
+
end
|
37
|
+
|
38
|
+
def [](key)
|
39
|
+
super(convert_key(key))
|
40
|
+
end
|
41
|
+
|
42
|
+
def []=(key, value)
|
43
|
+
super(convert_key(key), convert_value(value))
|
44
|
+
end
|
45
|
+
|
46
|
+
alias_method :store, :[]=
|
47
|
+
|
48
|
+
def key(value)
|
49
|
+
super(convert_value(value))
|
50
|
+
end
|
51
|
+
|
52
|
+
def key?(key)
|
53
|
+
super(convert_key(key))
|
54
|
+
end
|
55
|
+
|
56
|
+
alias_method :has_key?, :key?
|
57
|
+
alias_method :include?, :key?
|
58
|
+
alias_method :member?, :key?
|
59
|
+
|
60
|
+
def value?(value)
|
61
|
+
super(convert_value(value))
|
62
|
+
end
|
63
|
+
|
64
|
+
alias_method :has_value?, :value?
|
65
|
+
|
66
|
+
def delete(key)
|
67
|
+
super(convert_key(key))
|
68
|
+
end
|
69
|
+
|
70
|
+
def dig(key, *other_keys)
|
71
|
+
super(convert_key(key), *other_keys)
|
72
|
+
end if method_defined?(:dig) # Added in Ruby 2.3
|
73
|
+
|
74
|
+
def fetch_values(*keys)
|
75
|
+
super(*keys.map(&method(:convert_key)))
|
76
|
+
end if method_defined?(:fetch_values) # Added in Ruby 2.3
|
77
|
+
|
78
|
+
def values_at(*keys)
|
79
|
+
super(*keys.map(&method(:convert_key)))
|
80
|
+
end
|
81
|
+
|
82
|
+
def merge!(other_hash)
|
83
|
+
return super if other_hash.is_a?(self.class)
|
84
|
+
|
85
|
+
other_hash.each_pair do |key, value|
|
86
|
+
key = convert_key(key)
|
87
|
+
value = yield(key, self[key], value) if block_given? && key?(key)
|
88
|
+
self[key] = convert_value(value)
|
89
|
+
end
|
90
|
+
|
91
|
+
self
|
92
|
+
end
|
93
|
+
|
94
|
+
alias_method :update, :merge!
|
95
|
+
|
96
|
+
def merge(other_hash, &block)
|
97
|
+
dup.merge!(other_hash, &block)
|
98
|
+
end
|
99
|
+
|
100
|
+
def replace(other_hash)
|
101
|
+
super(other_hash.is_a?(self.class) ? other_hash : self.class[other_hash])
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def convert_key(key)
|
107
|
+
key.is_a?(Symbol) ? key.to_s : key
|
108
|
+
end
|
109
|
+
|
110
|
+
def convert_value(value)
|
111
|
+
case value
|
112
|
+
when Hash
|
113
|
+
value.is_a?(self.class) ? value : self.class[value]
|
114
|
+
when Array
|
115
|
+
value.map(&method(:convert_value))
|
116
|
+
else
|
117
|
+
value
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Triton
|
2
|
+
class Napi < ApiBase
|
3
|
+
|
4
|
+
# The commit used to compile this itnerface:
|
5
|
+
# https://github.com/joyent/sdc-napi/blob/6dcd7540d5171e71260f54150ac6b5e43cf75acc/docs/index.md
|
6
|
+
#
|
7
|
+
|
8
|
+
self.name = "napi"
|
9
|
+
|
10
|
+
call('Ping', :method => :get, :path => '/ping')
|
11
|
+
call('ListNicTags', :method => :get, :path => '/nic_tags')
|
12
|
+
call('GetNicTag', :method => :get, :path => '/nic_tags/:name')
|
13
|
+
call('CreateNicTag', :method => :post, :path => '/nic_tags')
|
14
|
+
call('UpdateNicTag', :method => :put, :path => '/nic_tags/:name')
|
15
|
+
call('DeleteNicTag', :method => :delete, :path => '/nic_tags/:name')
|
16
|
+
call('ListNetworks', :method => :get, :path => '/networks')
|
17
|
+
call('CreateNetwork', :method => :post, :path => '/networks')
|
18
|
+
call('UpdateNetwork', :method => :put, :path => '/networks/:network_uuid')
|
19
|
+
call('GetNetwork', :method => :get, :path => '/networks/:network_uuid')
|
20
|
+
call('DeleteNetwork', :method => :delete, :path => '/networks/:network_uuid')
|
21
|
+
call('ProvisionNic', :method => :post, :path => '/networks/:network_uuid/nics')
|
22
|
+
call('ListIPs', :method => :get, :path => '/networks/:network_uuid/ips')
|
23
|
+
call('GetIP', :method => :get, :path => '/networks/:network_uuid/ips/:ip_address')
|
24
|
+
call('UpdateIP', :method => :put, :path => '/networks/:network_uuid/ips/:ip_address')
|
25
|
+
call('ListFabricVLANs', :method => :get, :path => '/fabrics/:owner_uuid/vlans')
|
26
|
+
call('CreateFabricVLAN', :method => :post, :path => '/fabrics/:owner_uuid/vlans')
|
27
|
+
call('GetFabricVLAN', :method => :get, :path => '/fabrics/:owner_uuid/vlans/:vlan_id')
|
28
|
+
call('UpdateFabricVLAN', :method => :put, :path => '/fabrics/:owner_uuid/vlans/:vlan_id')
|
29
|
+
call('DeleteFabricVLAN', :method => :delete, :path => '/fabrics/:owner_uuid/vlans/:vlan_id')
|
30
|
+
call('ListFabricNetworks', :method => :get, :path => '/fabrics/:owner_uuid/vlans/:vlan_id/networks')
|
31
|
+
call('CreateFabricNetwork', :method => :post, :path => '/fabrics/:owner_uuid/vlans/:vlan_id/networks')
|
32
|
+
call('GetFabricNetwork', :method => :get, :path => '/fabrics/:owner_uuid/vlans/:vlan_id/networks/:network_uuid')
|
33
|
+
call('DeleteFabricNetwork', :method => :delete, :path => '/fabrics/:owner_uuid/vlans/:vlan_id/networks/:network_uuid')
|
34
|
+
call('ListNics', :method => :get, :path => '/nics')
|
35
|
+
call('CreateNic', :method => :post, :path => '/nics')
|
36
|
+
call('GetNic', :method => :get, :path => '/nics/:mac_address')
|
37
|
+
call('UpdateNic', :method => :put, :path => '/nics/:mac_address')
|
38
|
+
call('DeleteNic', :method => :delete, :path => '/nics/:mac_address')
|
39
|
+
call('ListNetworkPools', :method => :get, :path => '/network_pools')
|
40
|
+
call('CreateNetworkPool', :method => :post, :path => '/network_pools')
|
41
|
+
call('GetNetworkPool', :method => :get, :path => '/network_pools/:uuid')
|
42
|
+
call('UpdateNetworkPool', :method => :put, :path => '/network_pools/:uuid')
|
43
|
+
call('DeleteNetworkPool', :method => :delete, :path => '/network_pools/:uuid')
|
44
|
+
call('SearchIPs', :method => :get, :path => '/search/ips')
|
45
|
+
call('ListAggregations', :method => :get, :path => '/aggregations')
|
46
|
+
call('GetAggregation', :method => :get, :path => '/aggregations/:id')
|
47
|
+
call('CreateAggregation', :method => :post, :path => '/aggregations')
|
48
|
+
call('UpdateAggregation', :method => :put, :path => '/aggregations/:id')
|
49
|
+
call('DeleteAggregation', :method => :delete, :path => '/aggregations/:id')
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Triton
|
2
|
+
class Papi < ApiBase
|
3
|
+
|
4
|
+
# The commit used to compile this itnerface:
|
5
|
+
# https://github.com/joyent/sdc-papi/blob/30bcc2ce58ba5b2b27ca16fa33dc56704f865803/docs/index.md
|
6
|
+
#
|
7
|
+
self.name = "papi"
|
8
|
+
|
9
|
+
call('ListPackages', :method => :get, :path => '/packages')
|
10
|
+
call('GetPackage', :method => :get, :path =>'/packages/:uuid')
|
11
|
+
call('CreatePackage', :method => :post, :path =>'/packages')
|
12
|
+
call('UpdatePackage', :method => :put, :path =>'/packages/:uuid')
|
13
|
+
call('Ping', :method => :get, :path => '/ping')
|
14
|
+
end
|
15
|
+
end
|