terminal.com 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d256dec7f902f6e53bebf75cedb4231ba0123e1b
4
- data.tar.gz: 51cc71d632d28a9b840eaf67a7a353363e8f76fa
3
+ metadata.gz: 521390d3deda294db938d225e60be0f78a8d2be8
4
+ data.tar.gz: c63f9ecdb2493e5d48c62d9d357bdd5f7bf186c7
5
5
  SHA512:
6
- metadata.gz: fb2b0d8e464a88d836015e20984aa000b8304f5dab8ae783a087324b90f19c49ff9a0b4d7a3a99cc50481e986b5b11a771763f73560ab0820915efa189e9f516
7
- data.tar.gz: d06615df3b69e26cf1645ed40bc4081fb18a566c163b520b9142893b44459da3724096ce9daffdec6fef60c738f4e928a76b7780baa57f53265b8d62407aebf5
6
+ metadata.gz: 92ce68a65b841d4f2e1b5cd05550750bd041b4d751a9b96063af1ba991568b7b7fdc81ab359f0177ef25ca34774081173dca6eee58df2bdbb236dd04113b8375
7
+ data.tar.gz: 3b4bfffaef11a6628a86436085e923cac5937b5e2a71c29369edfc681fabfeb7baf87fcdf91902e5c968f7168b8bf9d761c356e59fe021891e81902fcdd1ffed
data/README.md CHANGED
@@ -1,10 +1,19 @@
1
1
  # About
2
2
 
3
- This is a Ruby wrapper for [Terminal.com](https://www.terminal.com) API.
3
+ [![Travis CI Status](https://img.shields.io/travis/botanicus/terminal.com.svg)](https://travis-ci.org/botanicus/terminal.com)
4
+ ![Gem Version](https://badge.fury.io/rb/terminal.com.svg)
5
+ [![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://rubydoc.org/gems/terminal.com/frames)
6
+ ![License](http://img.shields.io/badge/license-MIT-yellowgreen.svg)
4
7
 
5
- At the moment all it does is to dump all the [Terminal.com API endpoints](https://www.terminal.com/api/docs) to `Terminal::API` module, from which you can call them pretty much the same way you'd do with curl, just from Ruby.
8
+ This is a Ruby wrapper for [Terminal.com](https://www.terminal.com) API. It works on **Ruby 2 compatible implementations** (_including Rubinius and JRuby_). Ruby 1.8 or 1.9 are not supported. It contains:
6
9
 
7
- In the future there will be more object-oriented abstraction.
10
+ - [Low-level API](#low-level-api) which is 1:1 mapping to Terminal.com endpoints.
11
+ - [High-level object-oriented API](#high-level-terminalapi).
12
+ - [Command-line client](#command-line-client).
13
+
14
+ This library has **no external dependencies**. You can optionally use it with CodeRay to get syntax-highlighted responses in the command-line client, but the core doesn't depend on any 3rd party library.
15
+
16
+ The library uses `net/http` for network communication. Writing an adapter for a different HTTP library is as simple as overriding `Terminal.call` method. In the future more HTTP libraries _might_ be supported.
8
17
 
9
18
  # Usage
10
19
 
@@ -12,16 +21,82 @@ In the future there will be more object-oriented abstraction.
12
21
 
13
22
  2. Get your `user_token` and `access_token` from [your settings](https://www.terminal.com/settings/api).
14
23
 
15
- ![](docs/terminal-com-api-keys.png)
24
+ ![](https://raw.githubusercontent.com/botanicus/terminal.com/master/docs/terminal-com-api-keys.png)
25
+
26
+ # API
27
+
28
+ **API docs:** [Latest release](http://www.rubydoc.info/gems/terminal.com/frames) | [Git HEAD](http://www.rubydoc.info/github/botanicus/terminal.com/master)
29
+
30
+ ## Low-Level API
31
+
32
+ Module methods exposed on the `Terminal` module are 1:1 mapping of the Terminal.com API. The mapping rules are simple:
33
+
34
+ - All the required arguments are translated to positional arguments and comes in the same order as they are listed on the [Terminal.com API docs](https://www.terminal.com/api/docs) page.
35
+ - All the optional arguments are specified as keyword arguments (options).
36
+
37
+ ### Example
38
+
39
+ ```ruby
40
+ require 'terminal.com'
41
+
42
+ # Let's search featured ruby-related snapshots.
43
+ Terminal.list_public_snapshots(tag: 'ruby', featured: true)
44
+ # {"snapshots" => [{"title" => "JRuby Stack (example included)", "body" => "JRuby is a 100% Java implementation of the Ruby programming language. This snapshot also includes a working example, its source code and the tools needed to develop JRuby applications.", ...
45
+
46
+ # List your Terminals.
47
+ Terminal.list_terminals(my_user_token, my_access_token)
48
+ # {"terminals" => [{"cpu" => "2 (max)", "ram" => "256", "diskspace" => "10", "name" => "Coding Interview: John Doe Jr", ...
49
+
50
+ # Let's start a small instance of the official Ubuntu 14.04 snapshot.
51
+ snapshot_id = '987f8d702dc0a6e8158b48ccd3dec24f819a7ccb2756c396ef1fd7f5b34b7980'
52
+ Terminal.start_snapshot(my_user_token, my_access_token, snapshot_id, cpu: 100, ram: 1600)
53
+ # {"request_id":"1417456495137::james@101ideas.cz:create:207693::4e765da6-2cc0-4054-a0dc-00b47a004d79"}
54
+ ```
55
+
56
+ ## High-Level `Terminal::API`
57
+
58
+ Class `Terminal::API` provides *abstraction for calls to the endpoints that requires authentication*. So instead of calling methods on `Terminal` every time with passing `user_token` and `access_token` as arguments, you can just instantiate `Terminal::API` and reuse your credentials.
59
+
60
+ ### Example
61
+
62
+ ```ruby
63
+ require 'terminal.com/api'
64
+
65
+ terminal_com = Terminal::API.new(my_user_token, my_access_token)
66
+
67
+ # List your Terminals.
68
+ terminal_com.list_terminals
69
+
70
+ # Let's start a small instance of the official Ubuntu 14.04 snapshot.
71
+ snapshot_id = '987f8d702dc0a6e8158b48ccd3dec24f819a7ccb2756c396ef1fd7f5b34b7980'
72
+ terminal_com.start_snapshot(snapshot_id, instance: 'small')
73
+
74
+ # Note that for calls that don't require authentication,
75
+ # you still have to use methods on the Terminal module.
76
+ Terminal.list_public_snapshots
77
+ ```
16
78
 
17
79
  # Command-Line Client
18
80
 
19
- Anything you can do from the library can be done through the CLI client. There are two ways how you can use it.
81
+ Anything the library do can be done through the command-line client. There are two ways how you can use it: [with your credentials saved](#with-configuration) in `~/.terminal.com.json` or [without it](#without-configuration).
20
82
 
21
- ![](docs/terminal-cli-client.png)
83
+ Arguments are mapped exactly the same way as in the Ruby API:
84
+
85
+ - All the required arguments are translated to positional arguments and comes in the same order as they are listed on the [Terminal.com API docs](https://www.terminal.com/api/docs) page.
86
+ - All the optional arguments are specified as keyword arguments.
87
+
88
+ ## Keyword Arguments
89
+
90
+ - Booleans: `--featured` or `--no-featured`.
91
+ - Strings: `--tag=ruby`.
92
+ - Integers `--ram=256`.
93
+
94
+ ![](https://raw.githubusercontent.com/botanicus/terminal.com/master/docs/terminal-cli-client.png)
22
95
 
23
96
  ## Without Configuration
24
97
 
98
+ This is a command-line equivalent of the low-level API: you have to specify `user_token` and `access_token` every single time.
99
+
25
100
  ```bash
26
101
  terminal.com [user_token] [access_token] list_terminals
27
102
  ```
@@ -30,37 +105,51 @@ terminal.com [user_token] [access_token] list_terminals
30
105
 
31
106
  ## With Configuration
32
107
 
33
- Specifying the credentials every single time can be quite tedious. That's where `terminal.com configure` comes in handy:
34
-
35
- ![](docs/terminal-com-configure.png)
108
+ This is a command-line equivalent of the high-level API: your `user_token` and `access_token` are saved in `~/.terminal.com.json`, so you don't have to pass them in every single time.
36
109
 
37
110
  ```bash
38
- # One time only.
39
- terminal.com configure
40
-
41
- # Now you can simply do:
42
111
  terminal.com list_terminals
43
112
  ```
44
113
 
45
- ## Options
114
+ ### How to Save Your Credentials
46
115
 
47
- ```bash
48
- terminal.com list_public_snapshots --tag=ruby --featured
49
- ```
116
+ Run `terminal.com configure` and follow the instructions.
50
117
 
51
- # Example
118
+ ![](https://raw.githubusercontent.com/botanicus/terminal.com/master/docs/terminal-com-configure.png)
52
119
 
53
- ```ruby
54
- require 'terminal.com'
120
+ # Development
55
121
 
56
- # Let's search featured ruby-related snapshots.
57
- Terminal::API.list_public_snapshots(tag: 'ruby', featured: true)
58
- # {"snapshots" => [{"title" => "JRuby Stack (example included)", "body" => "JRuby is a 100% Java implementation of the Ruby programming language. This snapshot also includes a working example, its source code and the tools needed to develop JRuby applications.", ...
122
+ ## Architecture of the Test Suite
59
123
 
60
- # List your Terminals.
61
- my_user_token = '...'
62
- my_access_token = '...'
124
+ The tests don't run against Terminal.com every single time. This is because:
63
125
 
64
- Terminal::API.list_terminals(my_user_token, my_access_token)
65
- # {"terminals" => [{"cpu" => "2 (max)", "ram" => "256", "diskspace" => "10", "name" => "Coding Interview: John Doe Jr", ...
66
- ```
126
+ - It would take a long time, starting all those Terminals, snapshotting them etc.
127
+ - The setup would just take too long. For instance for testing `list_terminals`, we'd ideally have to delete all the Terminals, then create a few and then test the result.
128
+
129
+ So this test suite doesn't test the live API. It test only the library itself through testing VCR-cached responses. Many tests will "break" if you delete the VCR files.
130
+
131
+ Using VCR provides additional benefits:
132
+
133
+ - You can see _exactly_ which request was fired and what was the exact response. No magic.
134
+
135
+ ## Running Tests
136
+
137
+ Running `bundle exec rspec` will run either all the examples, or, if there is one or more example tagged with `:focus`, then it will run only those.
138
+
139
+ _**Hint:** use `fit` or `fdescribe` to easily add focus to a given example or example group._
140
+
141
+ ## Documentation Server
142
+
143
+ We are using [YARD](http://yardoc.org) for generating API documentation.
144
+
145
+ If you want to preview the documentation, run `yard server --reload`.
146
+
147
+ ## Releasing New Version
148
+
149
+ _**TODO:** There should be some task for this._
150
+
151
+ # Links
152
+
153
+ - [Terminal.com API docs](https://www.terminal.com/api/docs)
154
+ - [Latest release API docs](http://www.rubydoc.info/gems/terminal.com/frames)
155
+ - [Git HEAD API docs](http://www.rubydoc.info/github/botanicus/terminal.com/master)
data/bin/terminal.com CHANGED
@@ -12,9 +12,10 @@ def log(message)
12
12
  end
13
13
 
14
14
  def dbg(command, arguments, **options)
15
- log "Terminal::API.#{command}(" +
15
+ log "Terminal.#{command}(" +
16
16
  ("#{arguments.inspect[1..-2]}" unless arguments.empty?).to_s +
17
- (", #{options.inspect[1..-2]}" unless options.empty?).to_s +
17
+ (", " if ! arguments.empty? && ! options.empty?).to_s +
18
+ ("#{options.inspect[1..-2]}" unless options.empty?).to_s +
18
19
  ")\n"
19
20
  end
20
21
 
@@ -36,10 +37,10 @@ def api_call(command, arguments, options)
36
37
  # => [{}]
37
38
  if options
38
39
  dbg command, arguments, options
39
- print_as_json Terminal::API.send(command, *arguments, **options)
40
+ print_as_json Terminal.send(command, *arguments, **options)
40
41
  else
41
42
  dbg command, arguments
42
- print_as_json Terminal::API.send(command, *arguments)
43
+ print_as_json Terminal.send(command, *arguments)
43
44
  end
44
45
  end
45
46
 
@@ -127,13 +128,13 @@ if ARGV.empty?
127
128
  else
128
129
  command = ARGV.shift
129
130
 
130
- unless Terminal::API.respond_to?(command)
131
+ unless Terminal.respond_to?(command)
131
132
  STDERR.puts("Invalid command '#{command}'.\n\n")
132
133
  abort usage
133
134
  end
134
135
 
135
136
  # Not every method requires authentication.
136
- method_args = Terminal::API.method(command).parameters.map(&:last)
137
+ method_args = Terminal.method(command).parameters.map(&:last)
137
138
 
138
139
  if method_args.include?(:options)
139
140
  options = ARGV.reduce(Hash.new) do |buffer, argument|
@@ -156,5 +157,9 @@ else
156
157
  arguments << access_token if method_args.include?(:access_token)
157
158
  arguments.push(*ARGV)
158
159
 
159
- api_call(command, arguments, options)
160
+ begin
161
+ api_call(command, arguments, options)
162
+ rescue Terminal::NetworkError
163
+ abort "It seems that you're offline."
164
+ end
160
165
  end
data/lib/terminal.com.rb CHANGED
@@ -1,385 +1,1066 @@
1
+ # This is the low-level version of Terminal.com API.
2
+ # All it does is 1:1 mapping of Ruby methods to the API.
3
+ #
4
+ # Methods that require authentication have a more
5
+ # user-friendly, object-oriented API in Terminal::API class.
6
+
1
7
  require 'net/http'
2
8
  require 'json'
9
+ require 'time'
3
10
 
4
11
  module Terminal
5
- VERSION = '0.0.1'
6
-
7
- module API
8
- extend self
9
-
10
- API_VERSION = 'v0.1'
11
- HEADERS = {'Content-Type' => 'application/json'}
12
-
13
- ############################
14
- # BROWSE SNAPSHOTS & USERS #
15
- ############################
16
-
17
- # https://www.terminal.com/api/docs#get-snapshot
18
- def get_snapshot(snapshot_id)
19
- call('/get_snapshot', snapshot_id: snapshot_id)
20
- end
21
-
22
- # https://www.terminal.com/api/docs#get-profile
23
- def get_profile(username)
24
- call('/get_profile', username: username)
25
- end
26
-
27
- # https://www.terminal.com/api/docs#list-public-snapshots
28
- def list_public_snapshots(**options)
29
- ensure_options_validity(options,
30
- :username, :tag, :featured, :title, :page, :perPage, :sortby)
31
-
32
- call('/list_public_snapshots', options)
33
- end
34
-
35
- # https://www.terminal.com/api/docs#count-public-snapshots
36
- def count_public_snapshots(**options)
37
- ensure_options_validity(options,
38
- :username, :tag, :featured, :title)
39
-
40
- call('/count_public_snapshots', options)
41
- end
42
-
43
- ###############################
44
- # CREATE AND MANAGE TERMINALS #
45
- ###############################
46
12
 
47
- # https://www.terminal.com/api/docs#list-terminals
48
- def list_terminals(user_token, access_token)
49
- call('/list_terminals',
50
- user_token: user_token, access_token: access_token)
51
- end
52
-
53
- # https://www.terminal.com/api/docs#get-terminal
54
- def get_terminal(user_token, access_token, **options)
55
- ensure_options_validity(options, :container_key, :subdomain)
56
-
57
- options.merge!(user_token: user_token, access_token: access_token)
58
-
59
- call('/get_terminal', options)
60
- end
61
-
62
- # https://www.terminal.com/api/docs#start-snapshot
63
- def start_snapshot(user_token, access_token, snapshot_id, **options)
64
- ensure_options_validity(options,
65
- :cpu, :ram, :temporary, :name, :autopause, :startup_script, :custom_data)
66
-
67
- options.merge!(user_token: user_token, access_token: access_token, snapshot_id: snapshot_id)
68
-
69
- call('/start_snapshot', options)
13
+ # The gem version.
14
+ VERSION = '0.0.2'
15
+
16
+ # The Terminal.com API version.
17
+ API_VERSION = 'v0.1'
18
+
19
+ # The default headers for the requests.
20
+ HEADERS = {'Content-Type' => 'application/json'}
21
+
22
+ # Any network error that can potentially occur in Terminal.call
23
+ # should be encapsulated in this. See {Terminal.call} for implementation
24
+ # details.
25
+ #
26
+ # @api plugin
27
+ class NetworkError < StandardError
28
+ attr_reader :original_error
29
+
30
+ # @param original_error [Exception] The exception raised by an HTTP library.
31
+ # @see Terminal.call
32
+ def initialize(original_error)
33
+ @original_error = original_error
34
+ super <<-EOF
35
+ Network error (#{original_error.class}): #{original_error.message}
36
+ EOF
70
37
  end
38
+ end
71
39
 
72
- # https://www.terminal.com/api/docs#delete-terminal
73
- def delete_terminal(user_token, access_token, container_key)
74
- call('/delete_terminal',
75
- user_token: user_token, access_token: access_token, container_key: container_key)
76
- end
40
+ # @!group BROWSE SNAPSHOTS & USERS
41
+
42
+ # Get information on a snapshot.
43
+ #
44
+ # @param snapshot_id [String] Snapshot ID (the last part of the snapshot URL).
45
+ # @return [Hash] The response data parsed from JSON.
46
+ # @raise [Terminal::NetworkError] Any network-layer error.
47
+ #
48
+ # @example
49
+ # Terminal.get_snapshot('987f8d702dc0a6e8158b48ccd3dec24f819a7ccb2756c396ef1fd7f5b34b7980')
50
+ # # {"snapshot" => {"title" => "Official Ubuntu 14.04", "tags" => "ubuntu", "createdAt" => "2014-07-23T20:27:41.743Z", ...}}
51
+ #
52
+ # @since 0.0.1
53
+ # @see https://www.terminal.com/api/docs#get-snapshot Terminal.com API docs
54
+ def self.get_snapshot(snapshot_id)
55
+ call('/get_snapshot', snapshot_id: snapshot_id)
56
+ end
77
57
 
78
- # https://www.terminal.com/api/docs#restart-terminal
79
- def restart_terminal(user_token, access_token, container_key)
80
- call('/restart_terminal',
81
- user_token: user_token, access_token: access_token, container_key: container_key)
82
- end
58
+ # Get information on a user.
59
+ #
60
+ # @param username [String] Any valid username (i. e. `botanicus`).
61
+ # @return (see .get_snapshot)
62
+ # @raise (see .get_snapshot)
63
+ #
64
+ # @example
65
+ # Terminal.get_profile('botanicus')
66
+ # # {"user" => {"name" => "James C Russell", "url" => "https://twitter.com/botanicus", "location" => "London, UK", ...}}
67
+ #
68
+ # @since 0.0.1
69
+ # @see https://www.terminal.com/api/docs#get-profile Terminal.com API docs
70
+ def self.get_profile(username)
71
+ call('/get_profile', username: username)
72
+ end
83
73
 
84
- # https://www.terminal.com/api/docs#pause-terminal
85
- def pause_terminal(user_token, access_token, container_key)
86
- call('/pause_terminal',
87
- user_token: user_token, access_token: access_token, container_key: container_key)
88
- end
74
+ # Get a count of public snapshots, optionally filtered.
75
+ #
76
+ # @param options [Hash] Filtering options.
77
+ # @option options :username [String] Any valid username (i. e. `botanicus`).
78
+ # @option options :tag [String] Any tag (i. e. `ubuntu`).
79
+ # @option options :featured [true, false] Search only for featured (or non-featured).
80
+ # @option options :title [String] Title to be *matched* against the existing snapshots.
81
+ # @return (see .get_snapshot)
82
+ # @raise (see .get_snapshot)
83
+ #
84
+ # @example Count of all the public snapshots.
85
+ # Terminal.count_public_snapshots
86
+ # # {"snapshot_count" => 474}
87
+ #
88
+ # @example Count of all the featured snapshots.
89
+ # Terminal.count_public_snapshots(featured: true)
90
+ # # {"snapshot_count" => 135}
91
+ #
92
+ # @since 0.0.1
93
+ # @see https://www.terminal.com/api/docs#count-public-snapshots Terminal.com API docs
94
+ def self.count_public_snapshots(**options)
95
+ ensure_options_validity(options,
96
+ :username, :tag, :featured, :title)
97
+
98
+ call('/count_public_snapshots', options)
99
+ end
89
100
 
90
- # https://www.terminal.com/api/docs#resume-terminal
91
- def resume_terminal(user_token, access_token, container_key)
92
- call('/resume_terminal',
93
- user_token: user_token, access_token: access_token, container_key: container_key)
94
- end
101
+ # Get a list of public snapshots, optionally filtered
102
+ # and/or paginated.
103
+ #
104
+ # @param options [Hash] Filtering and pagination options.
105
+ # @option options (see .count_public_snapshots)
106
+ # @option options :page [String] Use with `perPage` for pagination.
107
+ # @option options :perPage [String] Use with `page` for pagination.
108
+ # @option options :sortby [String] Either `popularity` or `date`.
109
+ # @return (see .get_snapshot)
110
+ # @raise (see .get_snapshot)
111
+ #
112
+ # @example Return all the public snapshots.
113
+ # Terminal.list_public_snapshots
114
+ # # {"snapshots" => [{"title" => "Decision Tree", "tags" => "python,ipython", ...}, {...}]}
115
+ #
116
+ # @example Return all the featured snapshots from user botanicus.
117
+ # Terminal.list_public_snapshots(username: 'botanicus', featured: true)
118
+ #
119
+ # @example Return the first page of the search results with 10 items per page, sorted by date.
120
+ # Terminal.list_public_snapshots(tag: 'ubuntu', page: 1, perPage: 10, sortby: 'date')
121
+ #
122
+ # @since 0.0.1
123
+ # @see https://www.terminal.com/api/docs#list-public-snapshots Terminal.com API docs
124
+ def self.list_public_snapshots(**options)
125
+ ensure_options_validity(options,
126
+ :username, :tag, :featured, :title, :page, :perPage, :sortby)
127
+
128
+ call('/list_public_snapshots', options)
129
+ end
95
130
 
96
- # https://www.terminal.com/api/docs#edit-terminal
97
- def edit_terminal(user_token, access_token, container_key, **options)
98
- ensure_options_validity(options,
99
- :cpu, :ram, :diskspace, :name)
131
+ # @!endgroup
132
+ # @!group CREATE AND MANAGE TERMINALS
133
+
134
+ # Get a list of all Terminal instances owned by your account.
135
+ #
136
+ # @param user_token [String] Your user token.
137
+ # @param access_token [String] Your access token.
138
+ # @return (see .get_snapshot)
139
+ # @raise (see .get_snapshot)
140
+ #
141
+ # @example
142
+ # Terminal.list_terminals(user_token, access_token)
143
+ # # {"terminals" => [{"name" => "Coding Interview: John Doe Jr", "ram" => "256", ...}, {...}]}
144
+ #
145
+ # @since 0.0.1
146
+ # @see https://www.terminal.com/api/docs#list-terminals Terminal.com API docs
147
+ def self.list_terminals(user_token, access_token)
148
+ call('/list_terminals',
149
+ user_token: user_token, access_token: access_token)
150
+ end
100
151
 
101
- options.merge!(user_token: user_token, access_token: access_token, container_key: container_key)
152
+ # Get info about a Terminal instance of yours. You can
153
+ # specify either `container_key` or `subdomain`.
154
+ #
155
+ # @param (see .list_terminals)
156
+ # @param options [Hash] Provide either `container_key` or `subdomain`.
157
+ # @option options :container_key [String] A valid container key.
158
+ # You can get it through {.list_terminals}.
159
+ # @option options :subdomain [String] Subdomain of your Terminal (i. e. `johndoe117`).
160
+ # You can see it in the address bar when you're in the Terminal IDE or through {.list_terminals}.
161
+ # @return (see .get_snapshot)
162
+ # @raise (see .get_snapshot)
163
+ #
164
+ # @example Get Terminal info with a container_key.
165
+ # # Using get_terminal directly with list_terminals doesn't really
166
+ # # make sense, since you get all the data in list_terminals, so there
167
+ # # is no need to call get_terminal. This is just to show how you
168
+ # # can get your container key. It works the same with a subdomain.
169
+ # terminals = Terminal.list_terminals(user_token, access_token)
170
+ # container_key = terminals['terminals'].first['container_key']
171
+ #
172
+ # Terminal.get_terminal(user_token, access_token, container_key: container_key)
173
+ # # {"terminal" => {"name" => "Coding Interview: John Doe Jr", "ram" => "256", ...}}
174
+ #
175
+ # @since 0.0.1
176
+ # @see https://www.terminal.com/api/docs#get-terminal Terminal.com API docs
177
+ def self.get_terminal(user_token, access_token, **options)
178
+ ensure_options_validity(options, :container_key, :subdomain)
179
+
180
+ options.merge!(user_token: user_token, access_token: access_token)
181
+
182
+ call('/get_terminal', options)
183
+ end
102
184
 
103
- call('/edit_terminal', options)
104
- end
185
+ # Start a Terminal instance based on a snapshot.
186
+ #
187
+ # @param (see .list_terminals)
188
+ # @param snapshot_id (see .get_snapshot)
189
+ # @param options [Hash] Configuration of the new Terminal.
190
+ # @option options :cpu [String] How much CPU is required.
191
+ # Has to be one of the available {https://www.terminal.com/faq#instanceTypes instance types}
192
+ # and corresponding `:ram` option has to be provided.
193
+ # @option options :ram [String] How much RAM is required.
194
+ # Has to be one of the available {https://www.terminal.com/faq#instanceTypes instance types}
195
+ # and corresponding `:cpu` option has to be provided.
196
+ # @option options :temporary [String] If the Terminal is supposed to be temporary or not.
197
+ # {https://www.terminal.com/faq#temporaryTerminals Temporary Terminals} are automatically
198
+ # deleted on inactivity.
199
+ # @option options :name [String] Terminal name.
200
+ # @option options :autopause [String] Whether the Terminal should be {https://www.terminal.com/faq#idleSettings auto-paused on inactivity}.
201
+ # This can be edited later using {.set_terminal_idle_settings}.
202
+ # @option options :startup_script [String] Shell script to be run once the Terminal is ready.
203
+ # As of now it cannot contain newlines, so setting a different interpreter than `/bin/sh` is impossible.
204
+ # @option options :custom_data [String] Metadata of your Terminal. Anything you need. It will be accessible through {.get_terminal},
205
+ # but not from within the Terminal itself.
206
+ # @return (see .get_snapshot)
207
+ # @raise (see .get_snapshot)
208
+ # @raise [ArgumentError] If either `ram` or `cpu` is specified. These options has to come together.
209
+ #
210
+ # @example
211
+ # response = Terminal.start_snapshot(user_token, access_token, "57eff3574ac8d438224dc3aa1c6431a0dbac849a0c254e89be2e758d8113c234", name: "Test")
212
+ # # {"request_id" => "1418068796272::james@101ideas.cz:create:234509::333c43ab-f6cc-41a3-8307-0fcc4ea3cfb5"}
213
+ # Terminal.request_progress(response['request_id'])
214
+ # # {"operation" => "create", "status" => "success", ... }
215
+ #
216
+ # @since 0.0.1
217
+ # @see https://www.terminal.com/api/docs#start-snapshot Terminal.com API docs
218
+ # @see https://www.terminal.com/faq#instanceTypes Terminal Instance types
219
+ # @see .edit_terminal
220
+ # @see .set_terminal_idle_settings
221
+ def self.start_snapshot(user_token, access_token, snapshot_id, **options)
222
+ ensure_both_cpu_and_ram_are_provided(options)
223
+ ensure_options_validity(options,
224
+ :cpu, :ram, :temporary, :name, :autopause, :startup_script, :custom_data)
225
+
226
+ options.merge!(user_token: user_token, access_token: access_token, snapshot_id: snapshot_id)
227
+
228
+ call('/start_snapshot', options)
229
+ end
105
230
 
106
- ###############################
107
- # CREATE AND MANAGE SNAPSHOTS #
108
- ###############################
231
+ # Delete a Terminal instance.
232
+ #
233
+ # @param (see .list_terminals)
234
+ # @param container_key [String] A valid container key.
235
+ # You can get it through {.list_terminals}.
236
+ # @return (see .get_snapshot)
237
+ # @raise (see .get_snapshot)
238
+ #
239
+ # @since 0.0.1
240
+ # @see https://www.terminal.com/api/docs#delete-terminal Terminal.com API docs
241
+ def self.delete_terminal(user_token, access_token, container_key)
242
+ call('/delete_terminal',
243
+ user_token: user_token, access_token: access_token, container_key: container_key)
244
+ end
109
245
 
110
- # https://www.terminal.com/api/docs#list-snapshots
111
- def list_snapshots(user_token, access_token, **options)
112
- ensure_options_validity(options,
113
- :username, :tag, :featured, :title, :page, :perPage)
246
+ # Reboot a Terminal instance.
247
+ #
248
+ # @param (see .delete_terminal)
249
+ # @return (see .get_snapshot)
250
+ # @raise (see .get_snapshot)
251
+ #
252
+ # @since 0.0.1
253
+ # @see https://www.terminal.com/api/docs#restart-terminal Terminal.com API docs
254
+ def self.restart_terminal(user_token, access_token, container_key)
255
+ call('/restart_terminal',
256
+ user_token: user_token, access_token: access_token, container_key: container_key)
257
+ end
114
258
 
115
- options.merge!(user_token: user_token, access_token: access_token)
259
+ # Pause a Terminal instance. The instance will be offline
260
+ # and inaccessible, and you will not be charged as long as
261
+ # it remains paused.
262
+ #
263
+ # @param (see .delete_terminal)
264
+ # @return (see .get_snapshot)
265
+ # @raise (see .get_snapshot)
266
+ #
267
+ # @since 0.0.1
268
+ # @see https://www.terminal.com/api/docs#pause-terminal Terminal.com API docs
269
+ def self.pause_terminal(user_token, access_token, container_key)
270
+ call('/pause_terminal',
271
+ user_token: user_token, access_token: access_token, container_key: container_key)
272
+ end
116
273
 
117
- call('/list_snapshots', options)
118
- end
274
+ # Continue running a Terminal instance. The Terminal will
275
+ # continue being charged, and will keep running so long
276
+ # as you maintain a positive balance in your account.
277
+ #
278
+ # @param (see .delete_terminal)
279
+ # @return (see .get_snapshot)
280
+ # @raise (see .get_snapshot)
281
+ #
282
+ # @since 0.0.1
283
+ # @see https://www.terminal.com/api/docs#resume-terminal Terminal.com API docs
284
+ def self.resume_terminal(user_token, access_token, container_key)
285
+ call('/resume_terminal',
286
+ user_token: user_token, access_token: access_token, container_key: container_key)
287
+ end
119
288
 
120
- # https://www.terminal.com/api/docs#count-snapshots
121
- def count_snapshots(user_token, access_token, **options)
122
- ensure_options_validity(options,
123
- :username, :tag, :featured, :title)
289
+ # Edit the resources and/or name of a Terminal instance.
290
+ #
291
+ # @param (see .delete_terminal)
292
+ # @param options [Hash] New Terminal configuration.
293
+ # @option options :cpu [String] How much CPU is required.
294
+ # Has to be one of the available {https://www.terminal.com/faq#instanceTypes instance types}
295
+ # and corresponding `:ram` option has to be provided.
296
+ # This option is required.
297
+ # @option options :ram [String] How much RAM is required.
298
+ # Has to be one of the available {https://www.terminal.com/faq#instanceTypes instance types}
299
+ # and corresponding `:cpu` option has to be provided.
300
+ # This option is required.
301
+ # @option options :diskspace [String] How much diskspace is required.
302
+ # If you want to set to more than 20 GB, you need 25 MB of ram per GB.
303
+ # This option is required.
304
+ # @option options :name [String] Terminal name.
305
+ # @return (see .get_snapshot)
306
+ # @raise (see .start_snapshot)
307
+ #
308
+ # @example
309
+ # Terminal.edit_terminal(user_token, access_token, "f9954bd3-5da1-4e17-a688-7791d87ceb6e", cpu: "50", ram: "800", diskspace: "10")
310
+ # # {"status": "success", "request_id": "1418071005245::james@101ideas.cz:edit:234583::d86c5b44-f716-45d1-85d2-9968fdda15d6"}
311
+
312
+ # @since 0.0.1
313
+ # @see https://www.terminal.com/api/docs#edit-terminal Terminal.com API docs
314
+ # @see https://www.terminal.com/faq#instanceTypes Terminal Instance types
315
+ def self.edit_terminal(user_token, access_token, container_key, **options)
316
+ ensure_both_cpu_and_ram_are_provided(options)
317
+ ensure_options_present(options, :cpu, :ram, :diskspace)
318
+
319
+ ensure_options_validity(options,
320
+ :cpu, :ram, :diskspace, :name)
321
+
322
+ options.merge!(user_token: user_token, access_token: access_token, container_key: container_key)
323
+
324
+ call('/edit_terminal', options)
325
+ end
124
326
 
125
- options.merge!(user_token: user_token, access_token: access_token)
327
+ # @!endgroup
328
+ # @!group CREATE AND MANAGE SNAPSHOTS
329
+
330
+ # Get a list of snapshots owned by your account, optionally
331
+ # filtered by the owner's username, a tag, or the snapshot's
332
+ # featured status. You may use a combination of filters.
333
+ #
334
+ # @param (see .list_terminals)
335
+ # @param options [Hash] Filtering and pagination options.
336
+ # @option options (see .list_public_snapshots)
337
+ # @return (see .get_snapshot)
338
+ # @raise (see .get_snapshot)
339
+ #
340
+ # @example Return all the snapshots owned by your account.
341
+ # Terminal.list_snapshots(user_token, access_token)
342
+ # # {"snapshots" => [{"title" => "Decision Tree", "tags" => "python,ipython", ...}, {...}]}
343
+ #
344
+ # @example Return all the featured snapshots owned by your account.
345
+ # Terminal.list_snapshots(user_token, access_token, featured: true)
346
+ #
347
+ # @example Return the first page of the search results with 10 items per page, sorted by date.
348
+ # Terminal.list_snapshots(user_token, access_token, tag: 'ubuntu', page: 1, perPage: 10, sortby: 'date')
349
+ #
350
+ # @since 0.0.1
351
+ # @see https://www.terminal.com/api/docs#list-snapshots Terminal.com API docs
352
+ def self.list_snapshots(user_token, access_token, **options)
353
+ ensure_options_validity(options,
354
+ :username, :tag, :featured, :title, :page, :perPage)
355
+
356
+ options.merge!(user_token: user_token, access_token: access_token)
357
+
358
+ call('/list_snapshots', options)
359
+ end
126
360
 
127
- call('/count_snapshots', options)
128
- end
361
+ # Get a count of snapshots owned by your account, optionally
362
+ # filtered by the owner's username, a tag, or the snapshot's
363
+ # featured status. You may use a combination of filters.
364
+ #
365
+ # @param (see .list_terminals)
366
+ # @param options [Hash] Filtering options.
367
+ # @option options (see .count_public_snapshots)
368
+ # @return (see .get_snapshot)
369
+ # @raise (see .get_snapshot)
370
+ #
371
+ # @example Number of all the snapshots owned by your account.
372
+ # Terminal.count_snapshots(user_token, access_token)
373
+ # # {"snapshot_count" => 12}
374
+ #
375
+ # @example Number of all the featured snapshots owned by your account.
376
+ # Terminal.count_public_snapshots(user_token, access_token, featured: true)
377
+ # # {"snapshot_count" => 2}
378
+ #
379
+ # @since 0.0.1
380
+ # @see https://www.terminal.com/api/docs#count-snapshots Terminal.com API docs
381
+ def self.count_snapshots(user_token, access_token, **options)
382
+ ensure_options_validity(options,
383
+ :username, :tag, :featured, :title)
384
+
385
+ options.merge!(user_token: user_token, access_token: access_token)
386
+
387
+ call('/count_snapshots', options)
388
+ end
129
389
 
130
- # https://www.terminal.com/api/docs#delete-snapshot
131
- def delete_snapshot(user_token, access_token, snapshot_id)
132
- call('/delete_snapshot',
133
- user_token: user_token,
134
- access_token: access_token,
135
- snapshot_id: snapshot_id)
136
- end
390
+ # Delete a snapshot from your account. This cannot be undone.
391
+ #
392
+ # @param (see .list_terminals)
393
+ # @param snapshot_id (see .get_snapshot)
394
+ # @return (see .get_snapshot)
395
+ # @raise (see .get_snapshot)
396
+ #
397
+ # @since 0.0.1
398
+ # @see https://www.terminal.com/api/docs#delete-snapshot Terminal.com API docs
399
+ def self.delete_snapshot(user_token, access_token, snapshot_id)
400
+ call('/delete_snapshot',
401
+ user_token: user_token,
402
+ access_token: access_token,
403
+ snapshot_id: snapshot_id)
404
+ end
137
405
 
138
- # https://www.terminal.com/api/docs#edit-snapshot
139
- def edit_snapshot(user_token, access_token, snapshot_id, **options)
140
- ensure_options_validity(options,
141
- :body, :title, :readme, :tags, :public, :custom_data)
406
+ # Edit the metadata of a snapshot owned by your account.
407
+ #
408
+ # @param (see .delete_snapshots)
409
+ # @param options [Hash] New snapshot metadata.
410
+ # @option options :body [String] The snapshot description.
411
+ # @option options :title [String] The snapshot title.
412
+ # @option options :readme [String] The README.
413
+ # @option options :tags [String] Comma-separated list of tags (i. e. `ubuntu,ruby`).
414
+ # @option options :public [Boolean] Whether the snapshot will be accessible by other users.
415
+ # @option options :custom_data [String] Metadata of your Terminal. Anything you need.
416
+ # It will be accessible through {.get_terminal}, but not from within the Terminal itself.
417
+ # @return (see .get_snapshot)
418
+ # @raise (see .get_snapshot)
419
+ #
420
+ # @since 0.0.1
421
+ # @see https://www.terminal.com/api/docs#edit-snapshot Terminal.com API docs
422
+ def self.edit_snapshot(user_token, access_token, snapshot_id, **options)
423
+ ensure_options_validity(options,
424
+ :body, :title, :readme, :tags, :public, :custom_data)
425
+
426
+ options.merge!(user_token: user_token, access_token: access_token, snapshot_id: snapshot_id)
427
+
428
+ call('/edit_snapshot', options)
429
+ end
142
430
 
143
- options.merge!(user_token: user_token, access_token: access_token, snapshot_id: snapshot_id)
431
+ # Create a snapshot of a Terminal instance.
432
+ #
433
+ # @param (see .delete_terminal)
434
+ # @param options [Hash] Snapshot metadata.
435
+ # @option options (see .edit_snapshot)
436
+ # @return (see .get_snapshot)
437
+ # @raise (see .get_snapshot)
438
+ #
439
+ # @since 0.0.1
440
+ # @see https://www.terminal.com/api/docs#snapshot-terminal Terminal.com API docs
441
+ def self.snapshot_terminal(user_token, access_token, container_key, **options)
442
+ ensure_options_validity(options,
443
+ :body, :title, :readme, :tags, :public)
444
+
445
+ options.merge!(user_token: user_token, access_token: access_token, container_key: container_key)
446
+
447
+ call('/snapshot_terminal', options)
448
+ end
144
449
 
145
- call('/edit_snapshot', options)
146
- end
450
+ # @!endgroup
451
+ # @!group MANAGE TERMINAL ACCESS
452
+
453
+ # Add to the list of your other Terminals who have access
454
+ # to one of your Terminal instances.
455
+ #
456
+ # Currently this feature doesn't have GUI, so don't be surprised
457
+ # if you haven't come across it yet.
458
+ #
459
+ # @param (see .delete_terminal)
460
+ # @param links [Array<Hash>] Links are hashes with keys `port` and `source`.
461
+ # Port is any port number and source is any subdomain (i. e. `botanicus117`).
462
+ # @return (see .get_snapshot)
463
+ # @raise (see .get_snapshot)
464
+ #
465
+ # @example
466
+ # container_key = "1123587c-7aec-4b91-90c1-2de534033989"
467
+ # link = {port: 3000, source: "botanicus117"}
468
+ # Terminal.add_terminal_links(user_token, access_token, container_key, link)
469
+ # # {"status":"success"}
470
+ #
471
+ # @since 0.0.1
472
+ # @see https://www.terminal.com/api/docs#add-terminal-links Terminal.com API docs
473
+ def self.add_terminal_links(user_token, access_token, container_key, *links)
474
+ call('/add_terminal_links',
475
+ user_token: user_token,
476
+ access_token: access_token,
477
+ container_key: container_key,
478
+ links: links)
479
+ end
147
480
 
148
- # https://www.terminal.com/api/docs#snapshot-terminal
149
- def snapshot_terminal(user_token, access_token, container_key, **options)
150
- ensure_options_validity(options,
151
- :body, :title, :readme, :tags, :public)
481
+ # Remove from the list of Terminals who have access to one
482
+ # of your Terminal instances.
483
+ #
484
+ # @param (see .add_terminal_links)
485
+ # @return (see .get_snapshot)
486
+ # @raise (see .get_snapshot)
487
+ #
488
+ # @since 0.0.1
489
+ # @see https://www.terminal.com/api/docs#remove-terminal-links Terminal.com API docs
490
+ def self.remove_terminal_links(user_token, access_token, container_key, *links)
491
+ call('/remove_terminal_links',
492
+ user_token: user_token,
493
+ access_token: access_token,
494
+ container_key: container_key,
495
+ links: links)
496
+ end
152
497
 
153
- options.merge!(user_token: user_token, access_token: access_token, container_key: container_key)
498
+ # List users and emails with view or edit access to one
499
+ # of your Terminal instances.
500
+ #
501
+ # @param (see .delete_terminal)
502
+ # @return (see .get_snapshot)
503
+ # @raise (see .get_snapshot)
504
+ #
505
+ # @example
506
+ # Terminal.list_terminal_access(user_token, access_token, "268b0082-c96c-4c74-bf0a-a5d6d4c16b01")
507
+ # # {"is_public_list" => ["80", "3000"],
508
+ # # "access_rules" => ["3000::*@cloudlabs.io", "*::james@101ideas.cz", "IDE::james@101ideas.cz", "IDE::terminal@cloudlabs.io"],
509
+ # # "links"=>["3000::botanicus117"]}
510
+ #
511
+ # @since 0.0.1
512
+ # @see https://www.terminal.com/api/docs#list-terminal-access Terminal.com API docs
513
+ # @see https://www.terminal.com/faq#terminalAccess Terminal.com FAQ: Terminal access
514
+ def self.list_terminal_access(user_token, access_token, container_key)
515
+ call('/list_terminal_access',
516
+ user_token: user_token,
517
+ access_token: access_token,
518
+ container_key: container_key)
519
+ end
154
520
 
155
- call('/snapshot_terminal', options)
156
- end
521
+ # Edit the list of users and emails who have access to one
522
+ # of your Terminal instances.
523
+ #
524
+ # @param (see .delete_terminal)
525
+ # @param options [Hash] Access rules.
526
+ # @option options :is_public_list [Array] List of open ports.
527
+ # Port `80` is open by default, you can add additional ports.
528
+ # @option options :access_rules [Array] Array of access rules.
529
+ # An access rule is `<port>::<email>`. Port can be a port number,
530
+ # `IDE` or an asterisk and email can contain asterisks.
531
+ # **Examples:** `"3000::*@cloudlabs.io"`, `"*::james@101ideas.cz",
532
+ # `"IDE::james@101ideas.cz"`.
533
+ # @return (see .get_snapshot)
534
+ # @raise (see .get_snapshot)
535
+ #
536
+ # @since 0.0.1
537
+ # @see https://www.terminal.com/api/docs#edit-terminal-access Terminal.com API docs
538
+ # @see https://www.terminal.com/faq#terminalAccess Terminal.com FAQ: Terminal access
539
+ # @see https://www.terminal.com/faq#openPorts Terminal.com FAQ: Opening additional ports
540
+ def self.edit_terminal_access(user_token, access_token, container_key, **options)
541
+ ensure_options_validity(options, :is_public_list, :access_rules)
542
+
543
+ options.merge!(user_token: user_token, access_token: access_token, container_key: container_key)
544
+
545
+ call('/edit_terminal_access', options)
546
+ end
157
547
 
158
- ##########################
159
- # MANAGE TERMINAL ACCESS #
160
- ##########################
161
-
162
- # https://www.terminal.com/api/docs#add-terminal-links
163
- def add_terminal_links(user_token, access_token, container_key, *links)
164
- call('/add_terminal_links',
165
- user_token: user_token,
166
- access_token: access_token,
167
- container_key: container_key,
168
- links: links)
169
- end
548
+ # @!endgroup
549
+ # @!group MANAGE TERMINAL DNS & DOMAINS
550
+
551
+ # Get a list of domains in your CNAME record pool. Domains
552
+ # returned by this call can be associated to your Terminal
553
+ # instances.
554
+ #
555
+ # @param (see .list_terminals)
556
+ # @return (see .get_snapshot)
557
+ # @raise (see .get_snapshot)
558
+ #
559
+ # @example
560
+ # Terminal.get_cname_records(user_token, access_token)
561
+ # # {"available" => ["101ideas.cz", "terminal.101ideas.cz"]], "assigned": []}
562
+ #
563
+ # @since 0.0.1
564
+ # @see https://www.terminal.com/api/docs#get-cname-records Terminal.com API docs
565
+ # @see https://www.terminal.com/faq#cname Terminal.com FAQ: Using my own domains for my Terminals?
566
+ def self.get_cname_records(user_token, access_token)
567
+ call('/get_cname_records',
568
+ user_token: user_token, access_token: access_token)
569
+ end
170
570
 
171
- # https://www.terminal.com/api/docs#remove-terminal-links
172
- def remove_terminal_links(user_token, access_token, container_key, *links)
173
- call('/remove_terminal_links',
174
- user_token: user_token,
175
- access_token: access_token,
176
- container_key: container_key,
177
- links: links)
178
- end
571
+ # Add a domain or subdomain of Terminal.com to your CNAME
572
+ # record pool, making it available to be associated with
573
+ # one of your Terminal instances.
574
+ #
575
+ # @param (see .list_terminals)
576
+ # @param domain [String] A domain (i. e. `101ideas.cz`).
577
+ # @return (see .get_snapshot)
578
+ # @raise (see .get_snapshot)
579
+ #
580
+ # @since 0.0.1
581
+ # @see https://www.terminal.com/api/docs#add-domain-to-pool Terminal.com API docs
582
+ # @see https://www.terminal.com/faq#cname Terminal.com FAQ: Using my own domains for my Terminals?
583
+ def self.add_domain_to_pool(user_token, access_token, domain)
584
+ call('/add_domain_to_pool',
585
+ user_token: user_token, access_token: access_token, domain: domain)
586
+ end
179
587
 
180
- # https://www.terminal.com/api/docs#list-terminal-access
181
- def list_terminal_access(user_token, access_token, container_key)
182
- call('/list_terminal_access',
183
- user_token: user_token,
184
- access_token: access_token,
185
- container_key: container_key)
186
- end
588
+ # Remove a domain or subdomain of Terminal.com from your
589
+ # CNAME record pool.
590
+ #
591
+ # @param (see .add_domain_to_pool)
592
+ # @return (see .get_snapshot)
593
+ # @raise (see .get_snapshot)
594
+ #
595
+ # @since 0.0.1
596
+ # @see https://www.terminal.com/api/docs#remove-domain-from-pool Terminal.com API docs
597
+ # @see https://www.terminal.com/faq#cname Terminal.com FAQ: Using my own domains for my Terminals?
598
+ def self.remove_domain_from_pool(user_token, access_token, domain)
599
+ call('/remove_domain_from_pool',
600
+ user_token: user_token, access_token: access_token, domain: domain)
601
+ end
187
602
 
188
- # https://www.terminal.com/api/docs#edit-terminal-access
189
- def edit_terminal_access(user_token, access_token, container_key, **options)
190
- ensure_options_validity(options, :is_public_list, :access_rules)
603
+ # Map a domain in your CNAME record pool to one of your
604
+ # Terminal instances, making it accessible via that domain.
605
+ #
606
+ # @param (see .add_domain_to_pool)
607
+ # @param subdomain [String] Subdomain of the Terminal you want the domain assigned to.
608
+ # @param port [String] Which port on the Terminal should it point to?
609
+ # This will typically be either `80` if you're using Apache or Nginx
610
+ # or any other number if you're using say Thin or Puma.
611
+ # @return (see .get_snapshot)
612
+ # @raise (see .get_snapshot)
613
+ #
614
+ # @example
615
+ # Terminal.add_cname_record(user_token, access_token, 'terminal.101ideas.cz', 'botanicus117', 3000)
616
+ # # {"available" => [...], "assigned" => [{"domain" => "terminal.101ideas.cz", "subdomain" => "botanicus117", "port" => "3000"}]}
617
+ #
618
+ # @since 0.0.1
619
+ # @see https://www.terminal.com/api/docs#add-cname-record Terminal.com API docs
620
+ # @see https://www.terminal.com/faq#cname Terminal.com FAQ: Using my own domains for my Terminals?
621
+ def self.add_cname_record(user_token, access_token, domain, subdomain, port)
622
+ call('/add_cname_record',
623
+ user_token: user_token,
624
+ access_token: access_token,
625
+ domain: domain,
626
+ subdomain: subdomain,
627
+ port: port)
628
+ end
191
629
 
192
- options.merge!(user_token: user_token, access_token: access_token, container_key: container_key)
630
+ # Remove a domain mapping to one of your Terminal instances.
631
+ # This will mean you can no longer access the Terminal instance
632
+ # from that domain.
633
+ #
634
+ # @param (see .add_domain_to_pool)
635
+ # @return (see .get_snapshot)
636
+ # @raise (see .get_snapshot)
637
+ #
638
+ # @since 0.0.1
639
+ # @see https://www.terminal.com/api/docs#remove-cname-record Terminal.com API docs
640
+ # @see https://www.terminal.com/faq#cname Terminal.com FAQ: Using my own domains for my Terminals?
641
+ def self.remove_cname_record(user_token, access_token, domain)
642
+ call('/remove_cname_record',
643
+ user_token: user_token,
644
+ access_token: access_token,
645
+ domain: domain)
646
+ end
193
647
 
194
- call('/edit_terminal_access', options)
195
- end
648
+ # @!endgroup
649
+ # @!group MANAGE TERMINAL IDLE SETTINGS
650
+
651
+ # Set the {https://www.terminal.com/faq#idleSettings idle settings} for your Terminal.
652
+ #
653
+ # @param (see .delete_terminal)
654
+ # @param action [String] Either `downgrade` or `pause`.
655
+ # @param triggers [Hash<Hash>] Keys can be `cpu_load` or `last_request`.
656
+ # Keys of those can be `timeout` and `last_request`
657
+ # @return (see .get_snapshot)
658
+ # @raise (see .get_snapshot)
659
+ #
660
+ # @example
661
+ # Terminal.set_terminal_idle_settings(user_token, access_token, 'b878c064-fc2b-4f14-81fa-ca10ac9385ff', 'pause', cpu_load: {timeout: 5600})
662
+ # # {"success" => true}
663
+ #
664
+ # @since 0.0.1
665
+ # @see https://www.terminal.com/api/docs#set-terminal-idle-settings Terminal.com API docs
666
+ # @see https://www.terminal.com/faq#idleSettings Terminal.com FAQ: Idle settings
667
+ def self.set_terminal_idle_settings(user_token, access_token, container_key, action, triggers)
668
+ call('/set_terminal_idle_settings',
669
+ user_token: user_token,
670
+ access_token: access_token,
671
+ container_key: container_key,
672
+ action: action,
673
+ triggers: triggers)
674
+ end
196
675
 
197
- #################################
198
- # MANAGE TERMINAL DNS & DOMAINS #
199
- #################################
676
+ # Get the {https://www.terminal.com/faq#idleSettings idle settings} for your terminal.
677
+ #
678
+ # @param (see .delete_terminal)
679
+ # @return (see .get_snapshot)
680
+ # @raise (see .get_snapshot)
681
+ #
682
+ # @example
683
+ # container_key = 'b878c064-fc2b-4f14-81fa-ca10ac9385ff'
684
+ # Terminal.get_terminal_idle_settings(user_token, access_token, container_key)
685
+ # # {"success": true,
686
+ # # "settings": {
687
+ # # "action": "pause",
688
+ # # "triggers": {
689
+ # # "cpu_load": {
690
+ # # "timeout": 3600,
691
+ # # "threshold": 10
692
+ # # },
693
+ # # "last_request": {
694
+ # # "timeout": 3600
695
+ # # }
696
+ # # }
697
+ # # }
698
+ # # }
699
+ #
700
+ # @since 0.0.1
701
+ # @see https://www.terminal.com/api/docs#get-terminal-idle-settings Terminal.com API docs
702
+ # @see https://www.terminal.com/faq#idleSettings Terminal.com FAQ: Idle settings
703
+ def self.get_terminal_idle_settings(user_token, access_token, container_key)
704
+ call('/get_terminal_idle_settings',
705
+ user_token: user_token,
706
+ access_token: access_token,
707
+ container_key: container_key)
708
+ end
200
709
 
201
- # https://www.terminal.com/api/docs#get-cname-records
202
- def get_cname_records(user_token, access_token)
203
- call('/get_cname_records',
204
- user_token: user_token, access_token: access_token)
205
- end
710
+ # @!endgroup
711
+ # @!group MANAGE USAGE & CREDITS
712
+
713
+ # Get a list of the types of Terminals that may be started,
714
+ # and the specifications for each type (CPU, RAM, and pricing).
715
+ #
716
+ # @return (see .get_snapshot)
717
+ # @raise (see .get_snapshot)
718
+ #
719
+ # @example
720
+ # Terminal.instance_types
721
+ # # {"instance_types" => {
722
+ # # "micro" => {"cpu" => "2 (max)", "ram" => 256, "price" => 0.006},
723
+ # # "mini" => {"cpu" => 50, "ram" => 800, "price" => 0.031},
724
+ # # "small" => {"cpu" => 100, "ram" => 1600, "price" => 0.062},
725
+ # # "medium" => {"cpu" => 200, "ram" => 3200, "price" => 0.124},
726
+ # # "xlarge" => {"cpu" => 400, "ram" => 6400, "price" => 0.248},
727
+ # # "2xlarge" => {"cpu" => 800, "ram" => 12800, "price" => 0.496},
728
+ # # "4xlarge" => {"cpu" => 1600, "ram" => 25600, "price" => 0.992},
729
+ # # "8xlarge" => {"cpu" => 3200, "ram" => 51200, "price" => 1.984}}}
730
+ #
731
+ # @since 0.0.1
732
+ # @see https://www.terminal.com/api/docs#instance-types Terminal.com API docs
733
+ def self.instance_types
734
+ call('/instance_types', Hash.new)
735
+ end
206
736
 
207
- # https://www.terminal.com/api/docs#add-domain-to-pool
208
- def add_domain_to_pool(user_token, access_token, domain)
209
- call('/add_domain_to_pool',
210
- user_token: user_token, access_token: access_token, domain: domain)
211
- end
737
+ # Get the hourly pricing for a Terminal instance of a given type.
738
+ # If a instance is stopped, price will be zero.
739
+ #
740
+ # @param instance_type [String] desc.
741
+ # @param status [String] Defaults to `running`. It doesn't make
742
+ # sense to set it to anything else: pause instances are not billed.
743
+ # @return (see .get_snapshot)
744
+ # @raise (see .get_snapshot)
745
+ #
746
+ # @example
747
+ # Terminal.instance_price('micro')
748
+ # # {"price" => 0.006, "units" => "dollars per hour"}
749
+ #
750
+ # @since 0.0.1
751
+ # @see https://www.terminal.com/api/docs#instance-price Terminal.com API docs
752
+ def self.instance_price(instance_type, status = 'running')
753
+ call('/instance_price', instance_type: instance_type, status: status)
754
+ end
212
755
 
213
- # https://www.terminal.com/api/docs#remove-domain-from-pool
214
- def remove_domain_from_pool(user_token, access_token, domain)
215
- call('/remove_domain_from_pool',
216
- user_token: user_token, access_token: access_token, domain: domain)
217
- end
756
+ # Get the current balance of your account.
757
+ #
758
+ # @param (see .list_terminals)
759
+ # @return (see .get_snapshot)
760
+ # @raise (see .get_snapshot)
761
+ #
762
+ # @example
763
+ # Terminal.balance(user_token, access_token)
764
+ # # {"balance" => 675.879}
765
+ #
766
+ # @since 0.0.1
767
+ # @see https://www.terminal.com/api/docs#balance Terminal.com API docs
768
+ def self.balance(user_token, access_token)
769
+ call('/balance', user_token: user_token, access_token: access_token)
770
+ end
218
771
 
219
- # https://www.terminal.com/api/docs#add-cname-record
220
- def add_cname_record(user_token, access_token, domain, subdomain, port)
221
- call('/add_cname_record',
222
- user_token: user_token,
223
- access_token: access_token,
224
- domain: domain,
225
- subdomain: subdomain,
226
- port: port)
227
- end
772
+ # Get a history of credits added to your account balance.
773
+ #
774
+ # @param (see .list_terminals)
775
+ # @return (see .get_snapshot)
776
+ # @raise (see .get_snapshot)
777
+ #
778
+ # @example
779
+ # Terminal.balance_added(user_token, access_token)
780
+ # # {"events" => [{"reason" => "Terminal.com sign up gift!", "amount" => 5, "time" => 1411652507924}], "total" => 5}
781
+ #
782
+ # @since 0.0.1
783
+ # @see https://www.terminal.com/api/docs#balance-added Terminal.com API docs
784
+ def self.balance_added(user_token, access_token)
785
+ call('/balance_added', user_token: user_token, access_token: access_token)
786
+ end
228
787
 
229
- # https://www.terminal.com/api/docs#remove-cname-record
230
- def remove_cname_record(user_token, access_token, domain)
231
- call('/remove_cname_record',
232
- user_token: user_token,
233
- access_token: access_token,
234
- domain: domain)
235
- end
788
+ # Gift some of your credits to another user. Denominated in whole
789
+ # integer US cents ($0.01). You may only gift credits if you have
790
+ # previously purchased credits.
791
+ #
792
+ # @param (see .list_terminals)
793
+ # @param email [String] User email.
794
+ # @param cents [String] US cents.
795
+ # @return (see .get_snapshot)
796
+ # @raise (see .get_snapshot)
797
+ #
798
+ # @since 0.0.1
799
+ # @see https://www.terminal.com/api/docs#gift Terminal.com API docs
800
+ def self.gift(user_token, access_token, email, cents)
801
+ call('/gift',
802
+ user_token: user_token,
803
+ access_token: access_token,
804
+ email: email,
805
+ cents: cents)
806
+ end
236
807
 
237
- #################################
238
- # MANAGE TERMINAL IDLE SETTINGS #
239
- #################################
240
-
241
- # https://www.terminal.com/api/docs#set-terminal-idle-settings
242
- def set_terminal_idle_settings(user_token, access_token, container_key, action, *triggers)
243
- call('/set_terminal_idle_settings',
244
- user_token: user_token,
245
- access_token: access_token,
246
- container_key: container_key,
247
- action: action,
248
- triggers: triggers)
249
- end
808
+ # Get a history of charges to your account balance.
809
+ #
810
+ # @param (see .list_terminals)
811
+ # @return (see .get_snapshot)
812
+ # @raise (see .get_snapshot)
813
+ #
814
+ # @since 0.0.1
815
+ # @see https://www.terminal.com/api/docs#burn-history Terminal.com API docs
816
+ def self.burn_history(user_token, access_token)
817
+ call('/burn_history', user_token: user_token, access_token: access_token)
818
+ end
250
819
 
251
- # https://www.terminal.com/api/docs#get-terminal-idle-settings
252
- def get_terminal_idle_settings(user_token, access_token, container_key)
253
- call('/get_terminal_idle_settings',
254
- user_token: user_token,
255
- access_token: access_token,
256
- container_key: container_key)
257
- end
820
+ # Get a history of your Terminal usage.
821
+ #
822
+ # @param (see .list_terminals)
823
+ # @return (see .get_snapshot)
824
+ # @raise (see .get_snapshot)
825
+ #
826
+ # @since 0.0.1
827
+ # @see https://www.terminal.com/api/docs#terminal-usage-history Terminal.com API docs
828
+ def self.terminal_usage_history(user_token, access_token)
829
+ call('/terminal_usage_history', user_token: user_token, access_token: access_token)
830
+ end
258
831
 
259
- ##########################
260
- # MANAGE USAGE & CREDITS #
261
- ##########################
832
+ # Get a summary of current active charges being billed to your account.
833
+ #
834
+ # @param (see .list_terminals)
835
+ # @return (see .get_snapshot)
836
+ # @raise (see .get_snapshot)
837
+ #
838
+ # @since 0.0.1
839
+ # @see https://www.terminal.com/api/docs#burn-state Terminal.com API docs
840
+ def self.burn_state(user_token, access_token)
841
+ call('/burn_state', user_token: user_token, access_token: access_token)
842
+ end
262
843
 
263
- # https://www.terminal.com/api/docs#instance-types
264
- def instance_types
265
- call('/instance_types', Hash.new)
266
- end
844
+ # Get a summary of the charges to your account, based on each
845
+ # Terminal instance that you have provisioned. Note that inactive
846
+ # and paused terminals do not incur charges.
847
+ #
848
+ # @param (see .list_terminals)
849
+ # @return (see .get_snapshot)
850
+ # @raise (see .get_snapshot)
851
+ #
852
+ # @since 0.0.1
853
+ # @see https://www.terminal.com/api/docs#burn-estimates Terminal.com API docs
854
+ def self.burn_estimates(user_token, access_token)
855
+ call('/burn_estimates', user_token: user_token, access_token: access_token)
856
+ end
267
857
 
268
- # https://www.terminal.com/api/docs#instance-price
269
- def instance_price(instance_type, status = 'running')
270
- call('/instance_price', instance_type: instance_type, status: status)
271
- end
858
+ # @!endgroup
859
+ # @!group MANAGE SSH PUBLIC KEYS
860
+
861
+ # Add an SSH public key to a given Terminal's root user.
862
+ #
863
+ # @param (see .delete_terminal)
864
+ # @param publicKey [String] desc.
865
+ # @return (see .get_snapshot)
866
+ # @raise (see .get_snapshot)
867
+ #
868
+ # @since 0.0.1
869
+ # @see https://www.terminal.com/api/docs#add-authorized-key-to-terminal Terminal.com API docs
870
+ # @see https://www.terminal.com/faq#ssh Using SSH to connect to your Terminals
871
+ def self.add_authorized_key_to_terminal(user_token, access_token, container_key, publicKey)
872
+ call('/add_authorized_key_to_terminal',
873
+ user_token: user_token,
874
+ access_token: access_token,
875
+ container_key: container_key,
876
+ publicKey: publicKey)
877
+ end
272
878
 
273
- # https://www.terminal.com/api/docs#balance
274
- def balance(user_token, access_token)
275
- call('/balance', user_token: user_token, access_token: access_token)
276
- end
879
+ # Add an SSH public key to our SSH proxy.
880
+ #
881
+ # @param (see .list_terminals)
882
+ # @param name [String] desc.
883
+ # @param publicKey [String] desc.
884
+ # @return (see .get_snapshot)
885
+ # @raise (see .get_snapshot)
886
+ #
887
+ # @since 0.0.1
888
+ # @see https://www.terminal.com/api/docs#add-authorized-key-to-ssh-proxy Terminal.com API docs
889
+ # @see https://www.terminal.com/faq#ssh Using SSH to connect to your Terminals
890
+ def self.add_authorized_key_to_ssh_proxy(user_token, access_token, name, publicKey)
891
+ call('/add_authorized_key_to_ssh_proxy',
892
+ user_token: user_token,
893
+ access_token: access_token,
894
+ name: name,
895
+ publicKey: publicKey)
896
+ end
277
897
 
278
- # https://www.terminal.com/api/docs#balance-added
279
- def balance_added(user_token, access_token)
280
- call('/balance_added', user_token: user_token, access_token: access_token)
281
- end
898
+ # Delete an SSH public key from our SSH proxy.
899
+ #
900
+ # @param (see .list_terminals)
901
+ # @param name [String] TODO.
902
+ # @param fingerprint [String] TODO.
903
+ # @return (see .get_snapshot)
904
+ # @raise (see .get_snapshot)
905
+ #
906
+ # @since 0.0.1
907
+ # @see https://www.terminal.com/api/docs#del-authorized-key-from-ssh-proxy Terminal.com API docs
908
+ # @see https://www.terminal.com/faq#ssh Using SSH to connect to your Terminals
909
+ def self.del_authorized_key_from_ssh_proxy(user_token, access_token, name, fingerprint)
910
+ call('/del_authorized_key_from_ssh_proxy',
911
+ user_token: user_token,
912
+ access_token: access_token,
913
+ name: name,
914
+ fingerprint: fingerprint)
915
+ end
282
916
 
283
- # https://www.terminal.com/api/docs#gift
284
- def gift(user_token, access_token, email, cents)
285
- call('/gift',
286
- user_token: user_token,
287
- access_token: access_token,
288
- email: email,
289
- cents: cents)
290
- end
917
+ # List the SSH public key on our SSH proxy.
918
+ #
919
+ # @param (see .list_terminals)
920
+ # @return (see .get_snapshot)
921
+ # @raise (see .get_snapshot)
922
+ #
923
+ # @since 0.0.1
924
+ # @see https://www.terminal.com/api/docs#get-authorized-keys-from-ssh-proxy Terminal.com API docs
925
+ # @see https://www.terminal.com/faq#ssh Using SSH to connect to your Terminals
926
+ def self.get_authorized_keys_from_ssh_proxy(user_token, access_token)
927
+ call('/get_authorized_keys_from_ssh_proxy',
928
+ user_token: user_token, access_token: access_token)
929
+ end
291
930
 
292
- # https://www.terminal.com/api/docs#burn-history
293
- def burn_history(user_token, access_token)
294
- call('/burn_history', user_token: user_token, access_token: access_token)
295
- end
931
+ # @!endgroup
932
+ # @!group OTHER
933
+
934
+ # Get information about yourself! If invalid access/user token
935
+ # provided, returns null (but not an error).
936
+ #
937
+ # @param (see .list_terminals)
938
+ # @return (see .get_snapshot)
939
+ # @raise (see .get_snapshot)
940
+ #
941
+ # @example
942
+ # Terminal.who_am_i(user_token, access_token)
943
+ # # {
944
+ # # "user": {
945
+ # # "name": "James C Russell",
946
+ # # "username": "botanicus",
947
+ # # "url": "https://twitter.com/botanicus",
948
+ # # "company": "",
949
+ # # "location": "London, United Kingdom",
950
+ # # "balance": 675.879,
951
+ # # "email": "james@101ideas.cz",
952
+ # # "is_admin": false,
953
+ # # "profile_image": "//www.gravatar.com/avatar/74c419a50563fa9e5044820c2697ffd6.jpg?s=400&d=mm"
954
+ # # }
955
+ # # }
956
+ #
957
+ # @since 0.0.1
958
+ # @see https://www.terminal.com/api/docs#who-am-i Terminal.com API docs
959
+ def self.who_am_i(user_token, access_token)
960
+ call('/who_am_i', user_token: user_token, access_token: access_token)
961
+ end
296
962
 
297
- # https://www.terminal.com/api/docs#terminal-usage-history
298
- def terminal_usage_history(user_token, access_token)
299
- call('/terminal_usage_history', user_token: user_token, access_token: access_token)
300
- end
963
+ # Get info and status of an API request.
964
+ #
965
+ # @param request_id [String] desc.
966
+ # @return (see .get_snapshot)
967
+ # @raise (see .get_snapshot)
968
+ #
969
+ # @since 0.0.1
970
+ # @see https://www.terminal.com/api/docs#request-progress Terminal.com API docs
971
+ def self.request_progress(request_id)
972
+ call('/request_progress', request_id: request_id)
973
+ end
301
974
 
302
- # https://www.terminal.com/api/docs#burn-state
303
- def burn_state(user_token, access_token)
304
- call('/burn_state', user_token: user_token, access_token: access_token)
305
- end
975
+ # @!endgroup
976
+ # @!group IMPLEMENTATION
306
977
 
307
- # https://www.terminal.com/api/docs#burn-estimates
308
- def burn_estimates(user_token, access_token)
309
- call('/burn_estimates', user_token: user_token, access_token: access_token)
310
- end
978
+ # @api private
979
+ def self.request
980
+ @request ||= Net::HTTP.new('api.terminal.com')
981
+ end
311
982
 
312
- ##########################
313
- # MANAGE SSH PUBLIC KEYS #
314
- ##########################
315
-
316
- # https://www.terminal.com/api/docs#add-authorized-key-to-terminal
317
- def add_authorized_key_to_terminal(user_token, access_token, container_key, publicKey)
318
- call('/add_authorized_key_to_terminal',
319
- user_token: user_token,
320
- access_token: access_token,
321
- container_key: container_key,
322
- publicKey: publicKey)
323
- end
983
+ # Make the HTTP call, retrieve and parse the JSON response.
984
+ # Rewrite this method if you wish to use a different HTTP library.
985
+ #
986
+ # @raise [Terminal::NetworkError] Any network-layer error.
987
+ # It's important that plugins make sure to wrap their potential
988
+ # exceptions in Terminal::NetworkError for predictable behaviour.
989
+ #
990
+ # @api plugin
991
+ # @since 0.0.1
992
+ def self.call(path, data)
993
+ path = "/#{API_VERSION}#{path}"
994
+ json = data.to_json
995
+
996
+ curl_debug(path, data.to_json)
997
+
998
+ response = request.post(path, json, HEADERS)
999
+ status = response.code.to_i
1000
+
1001
+ return parse_json(response.body) if status == 200
1002
+
1003
+ raise "Unexpected status #{status}: #{response.inspect}"
1004
+ rescue SocketError => error
1005
+ raise NetworkError.new(error)
1006
+ end
324
1007
 
325
- # https://www.terminal.com/api/docs#add-authorized-key-to-ssh-proxy
326
- def add_authorized_key_to_ssh_proxy(user_token, access_token, name, publicKey)
327
- call('/add_authorized_key_to_ssh_proxy',
328
- user_token: user_token,
329
- access_token: access_token,
330
- name: name,
331
- publicKey: publicKey)
332
- end
1008
+ # @api private
1009
+ def self.curl_debug(path, json)
1010
+ return if ENV['DBG'].nil?
333
1011
 
334
- # https://www.terminal.com/api/docs#del-authorized-key-from-ssh-proxy
335
- def del_authorized_key_from_ssh_proxy(user_token, access_token, name, fingerprint)
336
- call('/del_authorized_key_from_ssh_proxy',
337
- user_token: user_token,
338
- access_token: access_token,
339
- name: name,
340
- fingerprint: fingerprint)
341
- end
1012
+ headers = HEADERS.reduce(Array.new) do |buffer, (key, value)|
1013
+ buffer << "#{key}: #{value}"
1014
+ end.join(' ')
342
1015
 
343
- # https://www.terminal.com/api/docs#get-authorized-keys-from-ssh-proxy
344
- def get_authorized_keys_from_ssh_proxy(user_token, access_token)
345
- call('/get_authorized_keys_from_ssh_proxy',
346
- user_token: user_token, access_token: access_token)
347
- end
1016
+ STDERR.puts <<-EOF
1017
+ curl -L -X POST -H '#{headers}' -d '#{json}' https://api.terminal.com#{path}
1018
+ EOF
1019
+ end
348
1020
 
349
- #########
350
- # OTHER #
351
- #########
1021
+ # @api private
1022
+ def self.parse_json(json)
1023
+ convert_timestamps_to_time(JSON.parse(json))
1024
+ end
352
1025
 
353
- # https://www.terminal.com/api/docs#who-am-i
354
- def who_am_i(user_token, access_token)
355
- call('/who_am_i', user_token: user_token, access_token: access_token)
1026
+ # We are ignoring timestamps in arrays since there are none in the API.
1027
+ # Also, JSON document doesn't have to be an object, but in Terminal.com API,
1028
+ # they all are.
1029
+ # @api private
1030
+ # TODO: Test it.
1031
+ def self.convert_timestamps_to_time(hash)
1032
+ hash.each do |key, value|
1033
+ if value.is_a?(Hash)
1034
+ convert_timestamps_to_time(value)
1035
+ elsif value.is_a?(String) && value.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z$/)
1036
+ hash[key] = Time.parse(value)
1037
+ end
356
1038
  end
1039
+ end
357
1040
 
358
- # https://www.terminal.com/api/docs#request-progress
359
- def request_progress(request_id)
360
- call('/request_progress', request_id: request_id)
361
- end
1041
+ # @api private
1042
+ def self.ensure_options_validity(options, *valid_keys)
1043
+ unrecognised_options = (options.keys - valid_keys)
362
1044
 
363
- private
364
- def request
365
- @request ||= Net::HTTP.new('api.terminal.com')
1045
+ unless unrecognised_options.empty?
1046
+ raise ArgumentError.new("Unrecognised options: #{unrecognised_options.inspect[1..-2]}")
366
1047
  end
1048
+ end
367
1049
 
368
- def call(path, data)
369
- path = "/#{API_VERSION}#{path}"
370
- response = request.post(path, data.to_json, HEADERS)
371
- status = response.code.to_i
372
- return JSON.parse(response.body) if status == 200
373
-
374
- raise "Unexpected status: #{response.inspect}"
1050
+ # @api private
1051
+ def self.ensure_both_cpu_and_ram_are_provided(options)
1052
+ if (options[:cpu] && ! options[:ram]) || (options[:ram] && ! options[:cpu])
1053
+ raise ArgumentError.new('You have to specify both cpu and ram of the corresponding instance type as described at https://www.terminal.com/faq#instanceTypes')
375
1054
  end
1055
+ end
376
1056
 
377
- def ensure_options_validity(options, *valid_keys)
378
- unrecognised_options = (options.keys - valid_keys)
379
-
380
- unless unrecognised_options.empty?
381
- raise ArgumentError.new("Unrecognised options: #{unrecognised_options}")
1057
+ def self.ensure_options_present(options, *required_keys)
1058
+ required_keys.each do |key|
1059
+ unless options.has_key?(key)
1060
+ raise ArgumentError.new("Option #{key} is required, but is missing.")
382
1061
  end
383
1062
  end
384
1063
  end
1064
+
1065
+ # @!endgroup
385
1066
  end