vagrant_cloud 2.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +145 -39
- data/lib/vagrant_cloud.rb +20 -10
- data/lib/vagrant_cloud/account.rb +86 -164
- data/lib/vagrant_cloud/box.rb +115 -154
- data/lib/vagrant_cloud/box/provider.rb +175 -0
- data/lib/vagrant_cloud/box/version.rb +163 -0
- data/lib/vagrant_cloud/client.rb +449 -39
- data/lib/vagrant_cloud/data.rb +293 -0
- data/lib/vagrant_cloud/error.rb +48 -0
- data/lib/vagrant_cloud/instrumentor.rb +7 -0
- data/lib/vagrant_cloud/instrumentor/collection.rb +123 -0
- data/lib/vagrant_cloud/instrumentor/core.rb +9 -0
- data/lib/vagrant_cloud/instrumentor/logger.rb +97 -0
- data/lib/vagrant_cloud/logger.rb +64 -0
- data/lib/vagrant_cloud/organization.rb +62 -0
- data/lib/vagrant_cloud/response.rb +7 -0
- data/lib/vagrant_cloud/response/create_token.rb +7 -0
- data/lib/vagrant_cloud/response/request_2fa.rb +7 -0
- data/lib/vagrant_cloud/response/search.rb +65 -0
- data/lib/vagrant_cloud/search.rb +113 -15
- data/lib/vagrant_cloud/version.rb +1 -186
- metadata +26 -34
- data/bin/vagrant_cloud +0 -5
- data/lib/vagrant_cloud/errors.rb +0 -25
- data/lib/vagrant_cloud/provider.rb +0 -149
@@ -0,0 +1,163 @@
|
|
1
|
+
module VagrantCloud
|
2
|
+
class Box
|
3
|
+
class Version < Data::Mutable
|
4
|
+
attr_reader :box
|
5
|
+
attr_required :version
|
6
|
+
attr_optional :status, :description_html, :description_markdown,
|
7
|
+
:created_at, :updated_at, :number, :providers, :description
|
8
|
+
|
9
|
+
attr_mutable :description
|
10
|
+
|
11
|
+
def initialize(box:, **opts)
|
12
|
+
if !box.is_a?(Box)
|
13
|
+
raise TypeError, "Expecting type `#{Box.name}` but received `#{box.class.name}`"
|
14
|
+
end
|
15
|
+
@box = box
|
16
|
+
opts[:providers] = Array(opts[:providers]).map do |provider|
|
17
|
+
if provider.is_a?(Provider)
|
18
|
+
provider
|
19
|
+
else
|
20
|
+
Provider.load(version: self, **provider)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
super(opts)
|
24
|
+
clean!
|
25
|
+
end
|
26
|
+
|
27
|
+
# Delete this version
|
28
|
+
#
|
29
|
+
# @return [nil]
|
30
|
+
# @note This will delete the version, and all providers
|
31
|
+
def delete
|
32
|
+
if exist?
|
33
|
+
box.organization.account.client.box_version_delete(
|
34
|
+
username: box.username,
|
35
|
+
name: box.name,
|
36
|
+
version: version
|
37
|
+
)
|
38
|
+
# Remove self from box
|
39
|
+
v = box.versions.dup
|
40
|
+
v.delete(self)
|
41
|
+
box.clean(data: {versions: v})
|
42
|
+
end
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
# Release this version
|
47
|
+
#
|
48
|
+
# @return [self]
|
49
|
+
def release
|
50
|
+
if released?
|
51
|
+
raise Error::BoxError::VersionStatusChangeError,
|
52
|
+
"Version #{version} is already released for box #{box.tag}"
|
53
|
+
end
|
54
|
+
if !exist?
|
55
|
+
raise Error::BoxError::VersionStatusChangeError,
|
56
|
+
"Version #{version} for box #{box.tag} must be saved before release"
|
57
|
+
end
|
58
|
+
result = box.organization.account.client.box_version_release(
|
59
|
+
username: box.username,
|
60
|
+
name: box.name,
|
61
|
+
version: version
|
62
|
+
)
|
63
|
+
clean(data: result, only: :status)
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
# Revoke this version
|
68
|
+
#
|
69
|
+
# @return [self]
|
70
|
+
def revoke
|
71
|
+
if !released?
|
72
|
+
raise Error::BoxError::VersionStatusChangeError,
|
73
|
+
"Version #{version} is not yet released for box #{box.tag}"
|
74
|
+
end
|
75
|
+
result = box.organization.account.client.box_version_revoke(
|
76
|
+
username: box.username,
|
77
|
+
name: box.name,
|
78
|
+
version: version
|
79
|
+
)
|
80
|
+
clean(data: result, only: :status)
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
# @return [Boolean]
|
85
|
+
def released?
|
86
|
+
status == "active"
|
87
|
+
end
|
88
|
+
|
89
|
+
# Add a new provider for this version
|
90
|
+
#
|
91
|
+
# @param [String] pname Name of provider
|
92
|
+
# @return [Provider]
|
93
|
+
def add_provider(pname)
|
94
|
+
if providers.any? { |p| p.name == pname }
|
95
|
+
raise Error::BoxError::VersionProviderExistsError,
|
96
|
+
"Provider #{pname} already exists for box #{box.tag} version #{version}"
|
97
|
+
end
|
98
|
+
pv = Provider.new(version: self, name: pname)
|
99
|
+
clean(data: {providers: providers + [pv]})
|
100
|
+
pv
|
101
|
+
end
|
102
|
+
|
103
|
+
# Check if this instance is dirty
|
104
|
+
#
|
105
|
+
# @param [Boolean] deep Check nested instances
|
106
|
+
# @return [Boolean] instance is dirty
|
107
|
+
def dirty?(key=nil, deep: false)
|
108
|
+
if key
|
109
|
+
super(key)
|
110
|
+
else
|
111
|
+
d = super() || !exist?
|
112
|
+
if deep && !d
|
113
|
+
d = providers.any? { |p| p.dirty?(deep: true) }
|
114
|
+
end
|
115
|
+
d
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# @return [Boolean] version exists remotely
|
120
|
+
def exist?
|
121
|
+
!!created_at
|
122
|
+
end
|
123
|
+
|
124
|
+
# Save the version if any changes have been made
|
125
|
+
#
|
126
|
+
# @return [self]
|
127
|
+
def save
|
128
|
+
save_version if dirty?
|
129
|
+
save_providers if dirty?(deep: true)
|
130
|
+
self
|
131
|
+
end
|
132
|
+
|
133
|
+
protected
|
134
|
+
|
135
|
+
# Save the version
|
136
|
+
#
|
137
|
+
# @return [self]
|
138
|
+
def save_version
|
139
|
+
params = {
|
140
|
+
username: box.username,
|
141
|
+
name: box.name,
|
142
|
+
version: version,
|
143
|
+
description: description
|
144
|
+
}
|
145
|
+
if exist?
|
146
|
+
result = box.organization.account.client.box_version_update(**params)
|
147
|
+
else
|
148
|
+
result = box.organization.account.client.box_version_create(**params)
|
149
|
+
end
|
150
|
+
clean(data: result, ignores: :providers)
|
151
|
+
self
|
152
|
+
end
|
153
|
+
|
154
|
+
# Save the providers if any require saving
|
155
|
+
#
|
156
|
+
# @return [self]
|
157
|
+
def save_providers
|
158
|
+
Array(providers).map(&:save)
|
159
|
+
self
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
data/lib/vagrant_cloud/client.rb
CHANGED
@@ -1,60 +1,470 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
1
|
module VagrantCloud
|
4
2
|
class Client
|
3
|
+
include Logger
|
5
4
|
# Base Vagrant Cloud API URL
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
5
|
+
DEFAULT_URL = 'https://vagrantcloud.com/api/v1'.freeze
|
6
|
+
# Valid methods that can be retried
|
7
|
+
IDEMPOTENT_METHODS = [:get, :head].freeze
|
8
|
+
# Number or allowed retries
|
9
|
+
IDEMPOTENT_RETRIES = 3
|
10
|
+
# Number of seconds to wait between retries
|
11
|
+
IDEMPOTENT_RETRY_INTERVAL = 2
|
12
|
+
# Methods which require query parameters
|
13
|
+
QUERY_PARAMS_METHODS = [:get, :head, :delete].freeze
|
14
|
+
# Default instrumentor
|
15
|
+
DEFAULT_INSTRUMENTOR = Instrumentor::Collection.new
|
17
16
|
|
18
|
-
|
17
|
+
# @return [Instrumentor::Collection]
|
18
|
+
def self.instrumentor
|
19
|
+
DEFAULT_INSTRUMENTOR
|
19
20
|
end
|
20
21
|
|
21
|
-
# @
|
22
|
-
|
23
|
-
# @
|
24
|
-
|
25
|
-
# @return [
|
26
|
-
|
27
|
-
|
22
|
+
# @return [String] Access token for Vagrant Cloud
|
23
|
+
attr_reader :access_token
|
24
|
+
# @return [String] Base request path
|
25
|
+
attr_reader :path_base
|
26
|
+
# @return [String] URL for initializing connection
|
27
|
+
attr_reader :url_base
|
28
|
+
# @return [Integer] Number of retries on idempotent requests
|
29
|
+
attr_reader :retry_count
|
30
|
+
# @return [Integer] Number of seconds to wait between requests
|
31
|
+
attr_reader :retry_interval
|
32
|
+
# @return [Instrumentor::Collection] Instrumentor in use
|
33
|
+
attr_reader :instrumentor
|
34
|
+
|
35
|
+
# Create a new Client instance
|
36
|
+
#
|
37
|
+
# @param [String] access_token Authentication token for API requests
|
38
|
+
# @param [String] url_base URL used to make API requests
|
39
|
+
# @param [Integer] retry_count Number of retries on idempotent requests
|
40
|
+
# @param [Integer] retry_interval Number of seconds to wait between requests
|
41
|
+
# @param [Instrumentor::Core] instrumentor Instrumentor to use
|
42
|
+
# @return [Client]
|
43
|
+
def initialize(access_token: nil, url_base: nil, retry_count: nil, retry_interval: nil, instrumentor: nil)
|
44
|
+
url_base = DEFAULT_URL if url_base.nil?
|
45
|
+
remote_url = URI.parse(url_base)
|
46
|
+
@url_base = "#{remote_url.scheme}://#{remote_url.host}"
|
47
|
+
@path_base = remote_url.path
|
48
|
+
@access_token = access_token.dup.freeze if access_token
|
49
|
+
if !@access_token && ENV["VAGRANT_CLOUD_TOKEN"]
|
50
|
+
@access_token = ENV["VAGRANT_CLOUD_TOKEN"].dup.freeze
|
51
|
+
end
|
52
|
+
@retry_count = retry_count.nil? ? IDEMPOTENT_RETRIES : retry_count.to_i
|
53
|
+
@retry_interval = retry_interval.nil? ? IDEMPOTENT_RETRY_INTERVAL : retry_interval.to_i
|
54
|
+
@instrumentor = instrumentor.nil? ? Instrumentor::Collection.new : instrumentor
|
55
|
+
headers = {}.tap do |h|
|
56
|
+
h["Accept"] = "application/json"
|
57
|
+
h["Authorization"] = "Bearer #{@access_token}" if @access_token
|
58
|
+
h["Content-Type"] = "application/json"
|
59
|
+
end
|
60
|
+
@connection_lock = Mutex.new
|
61
|
+
@connection = Excon.new(url_base,
|
62
|
+
headers: headers,
|
63
|
+
instrumentor: @instrumentor
|
64
|
+
)
|
65
|
+
end
|
28
66
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
67
|
+
# Use the remote connection
|
68
|
+
#
|
69
|
+
# @param [Boolean] wait Wait for the connection to be available
|
70
|
+
# @yieldparam [Excon::Connection]
|
71
|
+
# @return [Object]
|
72
|
+
def with_connection(wait: true)
|
73
|
+
raise ArgumentError,
|
74
|
+
"Block expected but no block given" if !block_given?
|
75
|
+
if !wait
|
76
|
+
raise Error::ClientError::ConnectionLockedError,
|
77
|
+
"Connection is currently locked" if !@connection_lock.try_lock
|
78
|
+
begin
|
79
|
+
yield @connection
|
80
|
+
ensure
|
81
|
+
@connection_lock.unlock
|
82
|
+
end
|
83
|
+
else
|
84
|
+
@connection_lock.synchronize { yield @connection }
|
33
85
|
end
|
86
|
+
end
|
34
87
|
|
35
|
-
|
88
|
+
# Send a request
|
89
|
+
# @param [String, Symbol] method Request method
|
90
|
+
# @param [String, URI] path Path of request
|
91
|
+
# @param [Hash] params Parameters to send with request
|
92
|
+
# @return [Hash]
|
93
|
+
def request(path:, method: :get, params: {})
|
94
|
+
if !path.start_with?(path_base)
|
95
|
+
# Build the full path for the request and clean it
|
96
|
+
path = [path_base, path].compact.join("/").gsub(/\/{2,}/, "/")
|
97
|
+
end
|
98
|
+
method = method.to_s.downcase.to_sym
|
36
99
|
|
100
|
+
# Build base request parameters
|
37
101
|
request_params = {
|
38
102
|
method: method,
|
39
|
-
|
40
|
-
|
41
|
-
ssl_version: 'TLSv1'
|
103
|
+
path: path,
|
104
|
+
expects: [200, 201, 204]
|
42
105
|
}
|
43
106
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
request_params[:
|
107
|
+
# If this is an idempotent request allow it to retry on failure
|
108
|
+
if IDEMPOTENT_METHODS.include?(method)
|
109
|
+
request_params[:idempotent] = true
|
110
|
+
request_params[:retry_limit] = retry_count
|
111
|
+
request_params[:retry_interval] = retry_interval
|
48
112
|
end
|
49
113
|
|
50
|
-
|
51
|
-
|
114
|
+
# If parameters are provided, set them in the expected location
|
115
|
+
if !params.empty?
|
116
|
+
# Copy the parameters so we can freely modify them
|
117
|
+
params = clean_parameters(params)
|
118
|
+
|
119
|
+
if QUERY_PARAMS_METHODS.include?(method)
|
120
|
+
request_params[:query] = params
|
121
|
+
else
|
122
|
+
request_params[:body] = JSON.dump(params)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Set a request ID so we can track request/responses
|
127
|
+
request_params[:headers] = {"X-Request-Id" => SecureRandom.uuid}
|
128
|
+
|
129
|
+
result = with_connection { |c| c.request(request_params) }
|
130
|
+
parse_json(result.body)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Clone this client to create a new instance
|
134
|
+
#
|
135
|
+
# @param [String] access_token Authentication token for API requests
|
136
|
+
# @return [Client]
|
137
|
+
def clone(access_token: nil)
|
138
|
+
self.class.new(access_token: access_token, url_base: url_base,
|
139
|
+
retry_count: retry_count, retry_interval: retry_interval
|
140
|
+
)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Submit a search on Vagrant Cloud
|
144
|
+
#
|
145
|
+
# @param [String] query Search query
|
146
|
+
# @param [String] provider Limit results to only this provider
|
147
|
+
# @param [String] sort Field to sort results ("downloads", "created", or "updated")
|
148
|
+
# @param [String] order Order to return sorted result ("desc" or "asc")
|
149
|
+
# @param [Integer] limit Number of results to return
|
150
|
+
# @param [Integer] page Page number of results to return
|
151
|
+
# @return [Hash]
|
152
|
+
def search(query: Data::Nil, provider: Data::Nil, sort: Data::Nil, order: Data::Nil, limit: Data::Nil, page: Data::Nil)
|
153
|
+
params = {
|
154
|
+
q: query,
|
155
|
+
provider: provider,
|
156
|
+
sort: sort,
|
157
|
+
order: order,
|
158
|
+
limit: limit,
|
159
|
+
page: page
|
160
|
+
}
|
161
|
+
request(method: :get, path: "search", params: params)
|
162
|
+
end
|
163
|
+
|
164
|
+
# Create a new access token
|
165
|
+
#
|
166
|
+
# @param [String] username Vagrant Cloud username
|
167
|
+
# @param [String] password Vagrant Cloud password
|
168
|
+
# @param [String] description Description of token
|
169
|
+
# @param [String] code 2FA code
|
170
|
+
# @return [Hash]
|
171
|
+
def authentication_token_create(username:, password:, description: Data::Nil, code: Data::Nil)
|
172
|
+
params = {
|
173
|
+
user: {
|
174
|
+
login: username,
|
175
|
+
password: password
|
176
|
+
},
|
177
|
+
token: {
|
178
|
+
description: description
|
179
|
+
},
|
180
|
+
two_factor: {
|
181
|
+
code: code
|
182
|
+
}
|
183
|
+
}
|
184
|
+
request(method: :post, path: "authenticate", params: params)
|
185
|
+
end
|
186
|
+
|
187
|
+
# Delete the token currently in use
|
188
|
+
#
|
189
|
+
# @return [Hash] empty
|
190
|
+
def authentication_token_delete
|
191
|
+
request(method: :delete, path: "authenticate")
|
192
|
+
end
|
193
|
+
|
194
|
+
# Request a 2FA code is sent
|
195
|
+
#
|
196
|
+
# @param [String] username Vagrant Cloud username
|
197
|
+
# @param [String] password Vagrant Cloud password
|
198
|
+
# @param [String] delivery_method Delivery method of 2FA
|
199
|
+
# @param [String] password Account password
|
200
|
+
# @return [Hash]
|
201
|
+
def authentication_request_2fa_code(username:, password:, delivery_method:)
|
202
|
+
params = {
|
203
|
+
two_factor: {
|
204
|
+
delivery_method: delivery_method
|
205
|
+
},
|
206
|
+
user: {
|
207
|
+
login: username,
|
208
|
+
password: password
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
request(method: :post, path: "two-factor/request-code", params: params)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Validate the current token
|
216
|
+
#
|
217
|
+
# @return [Hash] emtpy
|
218
|
+
def authentication_token_validate
|
219
|
+
request(method: :get, path: "authenticate")
|
220
|
+
end
|
221
|
+
|
222
|
+
# Get an organization
|
223
|
+
#
|
224
|
+
# @param [String] name Name of organization
|
225
|
+
# @return [Hash] organization information
|
226
|
+
def organization_get(name:)
|
227
|
+
request(method: :get, path: "user/#{name}")
|
228
|
+
end
|
229
|
+
|
230
|
+
# Get an existing box
|
231
|
+
#
|
232
|
+
# @param [String] username Username/organization name to create box under
|
233
|
+
# @param [String] name Box name
|
234
|
+
# @return [Hash] box information
|
235
|
+
def box_get(username:, name:)
|
236
|
+
request(method: :get, path: "/box/#{username}/#{name}")
|
237
|
+
end
|
238
|
+
|
239
|
+
# Create a new box
|
240
|
+
#
|
241
|
+
# @param [String] username Username/organization name to create box under
|
242
|
+
# @param [String] name Box name
|
243
|
+
# @param [String] short_description Short description of box
|
244
|
+
# @param [String] description Long description of box (markdown supported)
|
245
|
+
# @param [Boolean] is_private Set if box is private
|
246
|
+
# @return [Hash] box information
|
247
|
+
def box_create(username:, name:, short_description: Data::Nil, description: Data::Nil, is_private: Data::Nil)
|
248
|
+
request(method: :post, path: '/boxes', params: {
|
249
|
+
username: username,
|
250
|
+
name: name,
|
251
|
+
short_description: short_description,
|
252
|
+
description: description,
|
253
|
+
is_private: is_private
|
254
|
+
})
|
255
|
+
end
|
256
|
+
|
257
|
+
# Update an existing box
|
258
|
+
#
|
259
|
+
# @param [String] username Username/organization name to create box under
|
260
|
+
# @param [String] name Box name
|
261
|
+
# @param [String] short_description Short description of box
|
262
|
+
# @param [String] description Long description of box (markdown supported)
|
263
|
+
# @param [Boolean] is_private Set if box is private
|
264
|
+
# @return [Hash] box information
|
265
|
+
def box_update(username:, name:, short_description: Data::Nil, description: Data::Nil, is_private: Data::Nil)
|
266
|
+
params = {
|
267
|
+
short_description: short_description,
|
268
|
+
description: description,
|
269
|
+
is_private: is_private
|
270
|
+
}
|
271
|
+
request(method: :put, path: "/box/#{username}/#{name}", params: params)
|
272
|
+
end
|
273
|
+
|
274
|
+
# Delete an existing box
|
275
|
+
#
|
276
|
+
# @param [String] username Username/organization name to create box under
|
277
|
+
# @param [String] name Box name
|
278
|
+
# @return [Hash] box information
|
279
|
+
def box_delete(username:, name:)
|
280
|
+
request(method: :delete, path: "/box/#{username}/#{name}")
|
281
|
+
end
|
282
|
+
|
283
|
+
# Get an existing box version
|
284
|
+
#
|
285
|
+
# @param [String] username Username/organization name to create box under
|
286
|
+
# @param [String] name Box name
|
287
|
+
# @param [String] version Box version
|
288
|
+
# @return [Hash] box version information
|
289
|
+
def box_version_get(username:, name:, version:)
|
290
|
+
request(method: :get, path: "/box/#{username}/#{name}/version/#{version}")
|
291
|
+
end
|
292
|
+
|
293
|
+
# Create a new box version
|
294
|
+
#
|
295
|
+
# @param [String] username Username/organization name to create box under
|
296
|
+
# @param [String] name Box name
|
297
|
+
# @param [String] version Box version
|
298
|
+
# @param [String] description Box description
|
299
|
+
# @return [Hash] box version information
|
300
|
+
def box_version_create(username:, name:, version:, description: Data::Nil)
|
301
|
+
request(method: :post, path: "/box/#{username}/#{name}/versions", params: {
|
302
|
+
version: {
|
303
|
+
version: version,
|
304
|
+
description: description
|
305
|
+
}
|
306
|
+
})
|
307
|
+
end
|
308
|
+
|
309
|
+
# Update an existing box version
|
310
|
+
#
|
311
|
+
# @param [String] username Username/organization name to create box under
|
312
|
+
# @param [String] name Box name
|
313
|
+
# @param [String] version Box version
|
314
|
+
# @param [String] description Box description
|
315
|
+
# @return [Hash] box version information
|
316
|
+
def box_version_update(username:, name:, version:, description: Data::Nil)
|
317
|
+
params = {
|
318
|
+
version: {
|
319
|
+
version: version,
|
320
|
+
description: description
|
321
|
+
}
|
322
|
+
}
|
323
|
+
request(method: :put, path: "/box/#{username}/#{name}/version/#{version}", params: params)
|
324
|
+
end
|
325
|
+
|
326
|
+
# Delete an existing box version
|
327
|
+
#
|
328
|
+
# @param [String] username Username/organization name to create box under
|
329
|
+
# @param [String] name Box name
|
330
|
+
# @param [String] version Box version
|
331
|
+
# @return [Hash] box version information
|
332
|
+
def box_version_delete(username:, name:, version:)
|
333
|
+
request(method: :delete, path: "/box/#{username}/#{name}/version/#{version}")
|
334
|
+
end
|
335
|
+
|
336
|
+
# Release an existing box version
|
337
|
+
#
|
338
|
+
# @param [String] username Username/organization name to create box under
|
339
|
+
# @param [String] name Box name
|
340
|
+
# @param [String] version Box version
|
341
|
+
# @return [Hash] box version information
|
342
|
+
def box_version_release(username:, name:, version:)
|
343
|
+
request(method: :put, path: "/box/#{username}/#{name}/version/#{version}/release")
|
344
|
+
end
|
345
|
+
|
346
|
+
# Revoke an existing box version
|
347
|
+
#
|
348
|
+
# @param [String] username Username/organization name to create box under
|
349
|
+
# @param [String] name Box name
|
350
|
+
# @param [String] version Box version
|
351
|
+
# @return [Hash] box version information
|
352
|
+
def box_version_revoke(username:, name:, version:)
|
353
|
+
request(method: :put, path: "/box/#{username}/#{name}/version/#{version}/revoke")
|
354
|
+
end
|
355
|
+
|
356
|
+
# Get an existing box version provider
|
357
|
+
#
|
358
|
+
# @param [String] username Username/organization name to create box under
|
359
|
+
# @param [String] name Box name
|
360
|
+
# @param [String] version Box version
|
361
|
+
# @param [String] provider Provider name
|
362
|
+
# @return [Hash] box version provider information
|
363
|
+
def box_version_provider_get(username:, name:, version:, provider:)
|
364
|
+
request(method: :get, path: "/box/#{username}/#{name}/version/#{version}/provider/#{provider}")
|
365
|
+
end
|
366
|
+
|
367
|
+
# Create a new box version provider
|
368
|
+
#
|
369
|
+
# @param [String] username Username/organization name to create box under
|
370
|
+
# @param [String] name Box name
|
371
|
+
# @param [String] version Box version
|
372
|
+
# @param [String] provider Provider name
|
373
|
+
# @param [String] url Remote URL for box download
|
374
|
+
# @return [Hash] box version provider information
|
375
|
+
def box_version_provider_create(username:, name:, version:, provider:, url: Data::Nil, checksum: Data::Nil, checksum_type: Data::Nil)
|
376
|
+
request(method: :post, path: "/box/#{username}/#{name}/version/#{version}/providers", params: {
|
377
|
+
provider: {
|
378
|
+
name: provider,
|
379
|
+
url: url,
|
380
|
+
checksum: checksum,
|
381
|
+
checksum_type: checksum_type
|
382
|
+
}
|
383
|
+
})
|
384
|
+
end
|
385
|
+
|
386
|
+
# Update an existing box version provider
|
387
|
+
#
|
388
|
+
# @param [String] username Username/organization name to create box under
|
389
|
+
# @param [String] name Box name
|
390
|
+
# @param [String] version Box version
|
391
|
+
# @param [String] provider Provider name
|
392
|
+
# @param [String] url Remote URL for box download
|
393
|
+
# @return [Hash] box version provider information
|
394
|
+
def box_version_provider_update(username:, name:, version:, provider:, url: Data::Nil, checksum: Data::Nil, checksum_type: Data::Nil)
|
395
|
+
params = {
|
396
|
+
provider: {
|
397
|
+
name: provider,
|
398
|
+
url: url,
|
399
|
+
checksum: checksum,
|
400
|
+
checksum_type: checksum_type
|
401
|
+
}
|
402
|
+
}
|
403
|
+
request(method: :put, path: "/box/#{username}/#{name}/version/#{version}/provider/#{provider}", params: params)
|
404
|
+
end
|
405
|
+
|
406
|
+
# Delete an existing box version provider
|
407
|
+
#
|
408
|
+
# @param [String] username Username/organization name to create box under
|
409
|
+
# @param [String] name Box name
|
410
|
+
# @param [String] version Box version
|
411
|
+
# @param [String] provider Provider name
|
412
|
+
# @return [Hash] box version provider information
|
413
|
+
def box_version_provider_delete(username:, name:, version:, provider:)
|
414
|
+
request(method: :delete, path: "/box/#{username}/#{name}/version/#{version}/provider/#{provider}")
|
415
|
+
end
|
416
|
+
|
417
|
+
# Upload a box asset for an existing box version provider
|
418
|
+
#
|
419
|
+
# @param [String] username Username/organization name to create box under
|
420
|
+
# @param [String] name Box name
|
421
|
+
# @param [String] version Box version
|
422
|
+
# @param [String] provider Provider name
|
423
|
+
# @return [Hash] box version provider upload information (contains upload_path entry)
|
424
|
+
def box_version_provider_upload(username:, name:, version:, provider:)
|
425
|
+
request(method: :get, path: "/box/#{username}/#{name}/version/#{version}/provider/#{provider}/upload")
|
426
|
+
end
|
427
|
+
|
428
|
+
# Upload a box asset directly to the backend storage for an existing box version provider
|
429
|
+
#
|
430
|
+
# @param [String] username Username/organization name to create box under
|
431
|
+
# @param [String] name Box name
|
432
|
+
# @param [String] version Box version
|
433
|
+
# @param [String] provider Provider name
|
434
|
+
# @return [Hash] box version provider upload information (contains upload_path and callback entries)
|
435
|
+
def box_version_provider_upload_direct(username:, name:, version:, provider:)
|
436
|
+
request(method: :get, path: "/box/#{username}/#{name}/version/#{version}/provider/#{provider}/upload/direct")
|
437
|
+
end
|
438
|
+
|
439
|
+
protected
|
440
|
+
|
441
|
+
# Parse a string of JSON
|
442
|
+
#
|
443
|
+
# @param [String] string String of JSON data
|
444
|
+
# @return [Object]
|
445
|
+
# @note All keys are symbolized when parsed
|
446
|
+
def parse_json(string)
|
447
|
+
return {} if string.empty?
|
448
|
+
JSON.parse(string, symbolize_names: true)
|
449
|
+
end
|
52
450
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
451
|
+
# Remove any values that have a default value set
|
452
|
+
#
|
453
|
+
# @param [Object] item Item to clean
|
454
|
+
# @return [Object] cleaned item
|
455
|
+
def clean_parameters(item)
|
456
|
+
case item
|
457
|
+
when Array
|
458
|
+
item = item.find_all { |i| i != Data::Nil }
|
459
|
+
item.map! { |i| clean_parameters(i) }
|
460
|
+
when Hash
|
461
|
+
item = item.dup
|
462
|
+
item.delete_if{ |_,v| v == Data::Nil }
|
463
|
+
item.keys.each do |k|
|
464
|
+
item[k] = clean_parameters(item[k])
|
465
|
+
end
|
57
466
|
end
|
467
|
+
item
|
58
468
|
end
|
59
469
|
end
|
60
470
|
end
|