terminal.com 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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