fog-joyent 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +20 -0
- data/.rubocop_todo.yml +436 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +26 -0
- data/CONTRIBUTING.md +18 -0
- data/CONTRIBUTORS.md +17 -0
- data/Gemfile +4 -0
- data/LICENSE.md +10 -0
- data/README.md +29 -0
- data/Rakefile +12 -0
- data/fog-joyent.gemspec +29 -0
- data/lib/fog/bin/joyent.rb +33 -0
- data/lib/fog/joyent.rb +16 -0
- data/lib/fog/joyent/analytics.rb +310 -0
- data/lib/fog/joyent/compute.rb +272 -0
- data/lib/fog/joyent/core.rb +10 -0
- data/lib/fog/joyent/errors.rb +91 -0
- data/lib/fog/joyent/models/analytics/field.rb +13 -0
- data/lib/fog/joyent/models/analytics/fields.rb +24 -0
- data/lib/fog/joyent/models/analytics/instrumentation.rb +82 -0
- data/lib/fog/joyent/models/analytics/instrumentations.rb +23 -0
- data/lib/fog/joyent/models/analytics/joyent_module.rb +13 -0
- data/lib/fog/joyent/models/analytics/joyent_modules.rb +24 -0
- data/lib/fog/joyent/models/analytics/metric.rb +17 -0
- data/lib/fog/joyent/models/analytics/metrics.rb +16 -0
- data/lib/fog/joyent/models/analytics/transformation.rb +13 -0
- data/lib/fog/joyent/models/analytics/transformations.rb +24 -0
- data/lib/fog/joyent/models/analytics/type.rb +16 -0
- data/lib/fog/joyent/models/analytics/types.rb +24 -0
- data/lib/fog/joyent/models/analytics/value.rb +20 -0
- data/lib/fog/joyent/models/compute/datacenter.rb +11 -0
- data/lib/fog/joyent/models/compute/datacenters.rb +21 -0
- data/lib/fog/joyent/models/compute/flavor.rb +19 -0
- data/lib/fog/joyent/models/compute/flavors.rb +21 -0
- data/lib/fog/joyent/models/compute/image.rb +26 -0
- data/lib/fog/joyent/models/compute/images.rb +30 -0
- data/lib/fog/joyent/models/compute/key.rb +19 -0
- data/lib/fog/joyent/models/compute/keys.rb +32 -0
- data/lib/fog/joyent/models/compute/network.rb +12 -0
- data/lib/fog/joyent/models/compute/networks.rb +14 -0
- data/lib/fog/joyent/models/compute/server.rb +124 -0
- data/lib/fog/joyent/models/compute/servers.rb +35 -0
- data/lib/fog/joyent/models/compute/snapshot.rb +44 -0
- data/lib/fog/joyent/models/compute/snapshots.rb +35 -0
- data/lib/fog/joyent/requests/analytics/create_instrumentation.rb +25 -0
- data/lib/fog/joyent/requests/analytics/delete_instrumentation.rb +23 -0
- data/lib/fog/joyent/requests/analytics/describe_analytics.rb +26 -0
- data/lib/fog/joyent/requests/analytics/get_instrumentation.rb +26 -0
- data/lib/fog/joyent/requests/analytics/get_instrumentation_value.rb +30 -0
- data/lib/fog/joyent/requests/analytics/list_instrumentations.rb +25 -0
- data/lib/fog/joyent/requests/compute/add_machine_tags.rb +19 -0
- data/lib/fog/joyent/requests/compute/create_key.rb +54 -0
- data/lib/fog/joyent/requests/compute/create_machine.rb +16 -0
- data/lib/fog/joyent/requests/compute/create_machine_snapshot.rb +16 -0
- data/lib/fog/joyent/requests/compute/delete_all_machine_metadata.rb +16 -0
- data/lib/fog/joyent/requests/compute/delete_all_machine_tags.rb +15 -0
- data/lib/fog/joyent/requests/compute/delete_key.rb +27 -0
- data/lib/fog/joyent/requests/compute/delete_machine.rb +15 -0
- data/lib/fog/joyent/requests/compute/delete_machine_metadata.rb +16 -0
- data/lib/fog/joyent/requests/compute/delete_machine_snapshot.rb +18 -0
- data/lib/fog/joyent/requests/compute/delete_machine_tag.rb +15 -0
- data/lib/fog/joyent/requests/compute/get_dataset.rb +27 -0
- data/lib/fog/joyent/requests/compute/get_image.rb +28 -0
- data/lib/fog/joyent/requests/compute/get_key.rb +29 -0
- data/lib/fog/joyent/requests/compute/get_machine.rb +29 -0
- data/lib/fog/joyent/requests/compute/get_machine_metadata.rb +24 -0
- data/lib/fog/joyent/requests/compute/get_machine_snapshot.rb +15 -0
- data/lib/fog/joyent/requests/compute/get_machine_tag.rb +18 -0
- data/lib/fog/joyent/requests/compute/get_package.rb +32 -0
- data/lib/fog/joyent/requests/compute/list_datacenters.rb +16 -0
- data/lib/fog/joyent/requests/compute/list_datasets.rb +24 -0
- data/lib/fog/joyent/requests/compute/list_images.rb +25 -0
- data/lib/fog/joyent/requests/compute/list_keys.rb +25 -0
- data/lib/fog/joyent/requests/compute/list_machine_snapshots.rb +15 -0
- data/lib/fog/joyent/requests/compute/list_machine_tags.rb +20 -0
- data/lib/fog/joyent/requests/compute/list_machines.rb +26 -0
- data/lib/fog/joyent/requests/compute/list_networks.rb +26 -0
- data/lib/fog/joyent/requests/compute/list_packages.rb +34 -0
- data/lib/fog/joyent/requests/compute/reboot_machine.rb +15 -0
- data/lib/fog/joyent/requests/compute/resize_machine.rb +16 -0
- data/lib/fog/joyent/requests/compute/start_machine.rb +16 -0
- data/lib/fog/joyent/requests/compute/start_machine_from_snapshot.rb +15 -0
- data/lib/fog/joyent/requests/compute/stop_machine.rb +16 -0
- data/lib/fog/joyent/requests/compute/update_machine_metadata.rb +15 -0
- data/lib/fog/joyent/version.rb +5 -0
- data/tests/helper.rb +18 -0
- data/tests/helpers/mock_helper.rb +16 -0
- data/tests/helpers/succeeds_helper.rb +9 -0
- data/tests/joyent/models/analytics/field_tests.rb +10 -0
- data/tests/joyent/models/analytics/fields_tests.rb +13 -0
- data/tests/joyent/models/analytics/instrumentation_tests.rb +13 -0
- data/tests/joyent/models/analytics/instrumentations_tests.rb +3 -0
- data/tests/joyent/models/analytics/joyent_module_tests.rb +10 -0
- data/tests/joyent/models/analytics/joyent_modules_tests.rb +13 -0
- data/tests/joyent/models/analytics/metric_tests.rb +10 -0
- data/tests/joyent/models/analytics/metrics_tests.rb +20 -0
- data/tests/joyent/models/analytics/transformation_tests.rb +10 -0
- data/tests/joyent/models/analytics/transformations_tests.rb +13 -0
- data/tests/joyent/models/analytics/type_tests.rb +10 -0
- data/tests/joyent/models/analytics/types_tests.rb +13 -0
- data/tests/joyent/requests/analytics/instrumentation_tests.rb +44 -0
- data/tests/joyent/requests/compute/datasets_tests.rb +58 -0
- data/tests/joyent/requests/compute/keys_tests.rb +47 -0
- data/tests/joyent/requests/compute/machines_tests.rb +66 -0
- data/tests/joyent/requests/compute/networks_tests.rb +39 -0
- data/tests/joyent/requests/compute/packages_tests.rb +68 -0
- metadata +235 -0
@@ -0,0 +1,272 @@
|
|
1
|
+
require 'fog/joyent/core'
|
2
|
+
require 'fog/joyent/errors'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Compute
|
6
|
+
class Joyent < Fog::Service
|
7
|
+
requires :joyent_username
|
8
|
+
|
9
|
+
recognizes :joyent_url
|
10
|
+
|
11
|
+
recognizes :joyent_keyname
|
12
|
+
recognizes :joyent_keyfile
|
13
|
+
recognizes :joyent_keydata
|
14
|
+
recognizes :joyent_keyphrase
|
15
|
+
recognizes :joyent_version
|
16
|
+
|
17
|
+
secrets :joyent_keydata, :joyent_keyphrase
|
18
|
+
|
19
|
+
model_path 'fog/joyent/models/compute'
|
20
|
+
request_path 'fog/joyent/requests/compute'
|
21
|
+
|
22
|
+
request :list_datacenters
|
23
|
+
# request :get_datacenter
|
24
|
+
|
25
|
+
# Datacenters
|
26
|
+
collection :datacenters
|
27
|
+
model :datacenter
|
28
|
+
|
29
|
+
# Keys
|
30
|
+
collection :keys
|
31
|
+
model :key
|
32
|
+
|
33
|
+
request :list_keys
|
34
|
+
request :get_key
|
35
|
+
request :create_key
|
36
|
+
request :delete_key
|
37
|
+
|
38
|
+
# Images
|
39
|
+
collection :images
|
40
|
+
model :image
|
41
|
+
request :list_datasets
|
42
|
+
request :get_dataset
|
43
|
+
request :list_images
|
44
|
+
request :get_image
|
45
|
+
|
46
|
+
# Flavors
|
47
|
+
collection :flavors
|
48
|
+
model :flavor
|
49
|
+
request :list_packages
|
50
|
+
request :get_package
|
51
|
+
|
52
|
+
# Servers
|
53
|
+
collection :servers
|
54
|
+
model :server
|
55
|
+
request :list_machines
|
56
|
+
request :get_machine
|
57
|
+
request :create_machine
|
58
|
+
request :start_machine
|
59
|
+
request :stop_machine
|
60
|
+
request :reboot_machine
|
61
|
+
request :resize_machine
|
62
|
+
request :delete_machine
|
63
|
+
|
64
|
+
# Snapshots
|
65
|
+
collection :snapshots
|
66
|
+
model :snapshot
|
67
|
+
request :create_machine_snapshot
|
68
|
+
request :start_machine_from_snapshot
|
69
|
+
request :list_machine_snapshots
|
70
|
+
request :get_machine_snapshot
|
71
|
+
request :delete_machine_snapshot
|
72
|
+
request :update_machine_metadata
|
73
|
+
request :get_machine_metadata
|
74
|
+
request :delete_machine_metadata
|
75
|
+
request :delete_all_machine_metadata
|
76
|
+
|
77
|
+
# MachineTags
|
78
|
+
request :add_machine_tags
|
79
|
+
request :list_machine_tags
|
80
|
+
request :get_machine_tag
|
81
|
+
request :delete_machine_tag
|
82
|
+
request :delete_all_machine_tags
|
83
|
+
|
84
|
+
# Networks
|
85
|
+
collection :networks
|
86
|
+
model :network
|
87
|
+
request :list_networks
|
88
|
+
|
89
|
+
class Mock
|
90
|
+
def self.data
|
91
|
+
@data ||= Hash.new do |hash, key|
|
92
|
+
hash[key] = {}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def data
|
97
|
+
self.class.data
|
98
|
+
end
|
99
|
+
|
100
|
+
def initialize(options = {})
|
101
|
+
@joyent_username = options[:joyent_username]
|
102
|
+
end
|
103
|
+
|
104
|
+
def request(opts)
|
105
|
+
raise "Not Implemented"
|
106
|
+
end
|
107
|
+
end # Mock
|
108
|
+
|
109
|
+
class Real
|
110
|
+
attr_accessor :joyent_version
|
111
|
+
attr_accessor :joyent_url
|
112
|
+
|
113
|
+
def initialize(options = {})
|
114
|
+
@connection_options = options[:connection_options] || {}
|
115
|
+
@persistent = options[:persistent] || false
|
116
|
+
|
117
|
+
@joyent_url = options[:joyent_url] || 'https://us-sw-1.api.joyentcloud.com'
|
118
|
+
@joyent_version = options[:joyent_version] || '~7'
|
119
|
+
@joyent_username = options[:joyent_username]
|
120
|
+
|
121
|
+
unless @joyent_username
|
122
|
+
raise ArgumentError, "options[:joyent_username] required"
|
123
|
+
end
|
124
|
+
|
125
|
+
if options[:joyent_keyname]
|
126
|
+
begin
|
127
|
+
require "net/ssh"
|
128
|
+
rescue LoadError
|
129
|
+
Fog::Logger.warning("'net/ssh' missing, please install and try again.")
|
130
|
+
exit(1)
|
131
|
+
end
|
132
|
+
@joyent_keyname = options[:joyent_keyname]
|
133
|
+
@joyent_keyphrase = options[:joyent_keyphrase]
|
134
|
+
@key_manager = Net::SSH::Authentication::KeyManager.new(nil, {
|
135
|
+
:keys_only => true,
|
136
|
+
:passphrase => @joyent_keyphrase
|
137
|
+
})
|
138
|
+
|
139
|
+
if options[:joyent_keyfile]
|
140
|
+
if File.exist?(options[:joyent_keyfile])
|
141
|
+
@joyent_keyfile = options[:joyent_keyfile]
|
142
|
+
@key_manager.add(@joyent_keyfile)
|
143
|
+
else
|
144
|
+
raise ArgumentError, "options[:joyent_keyfile] provided does not exist."
|
145
|
+
end
|
146
|
+
elsif options[:joyent_keydata]
|
147
|
+
if options[:joyent_keydata].to_s.empty?
|
148
|
+
raise ArgumentError, 'options[:joyent_keydata] must not be blank'
|
149
|
+
else
|
150
|
+
@joyent_keydata = options[:joyent_keydata]
|
151
|
+
@key_manager.add_key_data(@joyent_keydata)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
else
|
155
|
+
raise ArgumentError, "Must provide a joyent_keyname and joyent_keyfile pair"
|
156
|
+
end
|
157
|
+
|
158
|
+
@connection = Fog::XML::Connection.new(
|
159
|
+
@joyent_url,
|
160
|
+
@persistent,
|
161
|
+
@connection_options
|
162
|
+
)
|
163
|
+
end
|
164
|
+
|
165
|
+
def request(opts = {})
|
166
|
+
opts[:headers] = {
|
167
|
+
"X-Api-Version" => @joyent_version,
|
168
|
+
"Content-Type" => "application/json",
|
169
|
+
"Accept" => "application/json"
|
170
|
+
}.merge(opts[:headers] || {}).merge(header_for_signature_auth)
|
171
|
+
|
172
|
+
if opts[:body]
|
173
|
+
opts[:body] = Fog::JSON.encode(opts[:body])
|
174
|
+
end
|
175
|
+
|
176
|
+
response = @connection.request(opts)
|
177
|
+
if response.headers["Content-Type"] == "application/json"
|
178
|
+
response.body = json_decode(response.body)
|
179
|
+
end
|
180
|
+
|
181
|
+
response
|
182
|
+
rescue Excon::Errors::HTTPStatusError => e
|
183
|
+
if e.response.headers["Content-Type"] == "application/json"
|
184
|
+
e.response.body = json_decode(e.response.body)
|
185
|
+
end
|
186
|
+
raise_if_error!(e.request, e.response)
|
187
|
+
end
|
188
|
+
|
189
|
+
private
|
190
|
+
|
191
|
+
def json_decode(body)
|
192
|
+
parsed = Fog::JSON.decode(body)
|
193
|
+
decode_time_attrs(parsed)
|
194
|
+
end
|
195
|
+
|
196
|
+
def header_for_signature_auth
|
197
|
+
date = Time.now.utc.httpdate
|
198
|
+
|
199
|
+
# Force KeyManager to load the key(s)
|
200
|
+
@key_manager.each_identity {}
|
201
|
+
|
202
|
+
key = @key_manager.known_identities.keys.first
|
203
|
+
|
204
|
+
sig = if key.kind_of? OpenSSL::PKey::RSA
|
205
|
+
@key_manager.sign(key, date)[15..-1]
|
206
|
+
else
|
207
|
+
key = OpenSSL::PKey::DSA.new(File.read(@joyent_keyfile), @joyent_keyphrase)
|
208
|
+
key.sign('sha1', date)
|
209
|
+
end
|
210
|
+
|
211
|
+
key_id = "/#{@joyent_username}/keys/#{@joyent_keyname}"
|
212
|
+
key_type = key.class.to_s.split('::').last.downcase.to_sym
|
213
|
+
|
214
|
+
unless [:rsa, :dsa].include? key_type
|
215
|
+
raise Joyent::Errors::Unauthorized.new('Invalid key type -- only rsa or dsa key is supported')
|
216
|
+
end
|
217
|
+
|
218
|
+
signature = Base64.encode64(sig).delete("\r\n")
|
219
|
+
|
220
|
+
{
|
221
|
+
"Date" => date,
|
222
|
+
"Authorization" => "Signature keyId=\"#{key_id}\",algorithm=\"#{key_type}-sha1\" #{signature}"
|
223
|
+
}
|
224
|
+
rescue Net::SSH::Authentication::KeyManagerError => e
|
225
|
+
raise Joyent::Errors::Unauthorized.new('SSH Signing Error: :#{e.message}', e)
|
226
|
+
end
|
227
|
+
|
228
|
+
def decode_time_attrs(obj)
|
229
|
+
if obj.kind_of?(Hash)
|
230
|
+
obj["created"] = Time.parse(obj["created"]) unless obj["created"].nil? or obj["created"] == ''
|
231
|
+
obj["updated"] = Time.parse(obj["updated"]) unless obj["updated"].nil? or obj["updated"] == ''
|
232
|
+
elsif obj.kind_of?(Array)
|
233
|
+
obj.map do |o|
|
234
|
+
decode_time_attrs(o)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
obj
|
239
|
+
end
|
240
|
+
|
241
|
+
def raise_if_error!(request, response)
|
242
|
+
case response.status
|
243
|
+
when 400 then
|
244
|
+
raise Joyent::Errors::BadRequest.new('Bad Request', request, response)
|
245
|
+
when 401 then
|
246
|
+
raise Joyent::Errors::Unauthorized.new('Invalid credentials were used', request, response)
|
247
|
+
when 403 then
|
248
|
+
raise Joyent::Errors::Forbidden.new('No permissions to the specified resource', request, response)
|
249
|
+
when 404 then
|
250
|
+
raise Joyent::Errors::NotFound.new('Requested resource was not found', request, response)
|
251
|
+
when 405 then
|
252
|
+
raise Joyent::Errors::MethodNotAllowed.new('Method not supported for the given resource', request, response)
|
253
|
+
when 406 then
|
254
|
+
raise Joyent::Errors::NotAcceptable.new('Try sending a different Accept header', request, response)
|
255
|
+
when 409 then
|
256
|
+
raise Joyent::Errors::Conflict.new('Most likely invalid or missing parameters', request, response)
|
257
|
+
when 414 then
|
258
|
+
raise Joyent::Errors::RequestEntityTooLarge.new('You sent too much data', request, response)
|
259
|
+
when 415 then
|
260
|
+
raise Joyent::Errors::UnsupportedMediaType.new('You encoded your request in a format we don\'t understand', request, response)
|
261
|
+
when 420 then
|
262
|
+
raise Joyent::Errors::PolicyNotForfilled.new('You are sending too many requests', request, response)
|
263
|
+
when 449 then
|
264
|
+
raise Joyent::Errors::RetryWith.new('Invalid API Version requested; try with a different API Version', request, response)
|
265
|
+
when 503 then
|
266
|
+
raise Joyent::Errors::ServiceUnavailable.new('Either there\'s no capacity in this datacenter, or we\'re in a maintenance window', request, response)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end # Real
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'fog/joyent/core'
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Compute
|
5
|
+
class Joyent < Fog::Service
|
6
|
+
class Errors
|
7
|
+
module MessageParserMixin
|
8
|
+
def message
|
9
|
+
if response.body["code"] && response.body["message"]
|
10
|
+
"[ERROR #{response.body['code']}] : #{response.body['message']}"
|
11
|
+
else
|
12
|
+
''
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
message
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# https://us-west-1.api.joyentcloud.com/docs#cloudapi-http-responses
|
22
|
+
#
|
23
|
+
# HTTP Status Codes
|
24
|
+
#
|
25
|
+
# Your client should check for each of the following status codes from any API request:
|
26
|
+
#
|
27
|
+
# Response Code Description
|
28
|
+
|
29
|
+
# 400 Bad Request Invalid HTTP Request
|
30
|
+
class BadRequest < Excon::Errors::BadRequest
|
31
|
+
include MessageParserMixin
|
32
|
+
end
|
33
|
+
|
34
|
+
# 401 Unauthorized Either no Authorization header was sent, or invalid credentials were used
|
35
|
+
class Unauthorized < Excon::Errors::Unauthorized
|
36
|
+
include MessageParserMixin
|
37
|
+
end
|
38
|
+
|
39
|
+
# 403 Forbidden No permissions to the specified resource
|
40
|
+
class Forbidden < Excon::Errors::Forbidden
|
41
|
+
include MessageParserMixin
|
42
|
+
end
|
43
|
+
|
44
|
+
# 404 Not Found Something you requested was not found
|
45
|
+
class NotFound < Excon::Errors::NotFound
|
46
|
+
include MessageParserMixin
|
47
|
+
end
|
48
|
+
|
49
|
+
# 405 Method Not Allowed Method not supported for the given resource
|
50
|
+
class MethodNotAllowed < Excon::Errors::MethodNotAllowed
|
51
|
+
include MessageParserMixin
|
52
|
+
end
|
53
|
+
|
54
|
+
# 406 Not Acceptable Try sending a different Accept header
|
55
|
+
class NotAcceptable < Excon::Errors::NotAcceptable
|
56
|
+
include MessageParserMixin
|
57
|
+
end
|
58
|
+
|
59
|
+
# 409 Conflict Most likely invalid or missing parameters
|
60
|
+
class Conflict < Excon::Errors::Conflict
|
61
|
+
include MessageParserMixin
|
62
|
+
end
|
63
|
+
|
64
|
+
# 413 Request Entity Too Large You sent too much data
|
65
|
+
class RequestEntityTooLarge < Excon::Errors::RequestEntityTooLarge
|
66
|
+
include MessageParserMixin
|
67
|
+
end
|
68
|
+
|
69
|
+
# 415 Unsupported Media Type You encoded your request in a format we don't understand
|
70
|
+
class UnsupportedMediaType < Excon::Errors::UnsupportedMediaType
|
71
|
+
include MessageParserMixin
|
72
|
+
end
|
73
|
+
|
74
|
+
# 420 Slow Down You're sending too many requests
|
75
|
+
class PolicyNotForfilled < Excon::Errors::HTTPStatusError
|
76
|
+
include MessageParserMixin
|
77
|
+
end
|
78
|
+
|
79
|
+
# 449 Retry With Invalid Version header; try with a different X-Api-Version string
|
80
|
+
class RetryWith < Excon::Errors::HTTPStatusError
|
81
|
+
include MessageParserMixin
|
82
|
+
end
|
83
|
+
|
84
|
+
# 503 Service Unavailable Either there's no capacity in this datacenter, or we're in a maintenance window
|
85
|
+
class ServiceUnavailable < Excon::Errors::ServiceUnavailable
|
86
|
+
include MessageParserMixin
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'fog/joyent/models/analytics/field'
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Joyent
|
5
|
+
class Analytics
|
6
|
+
class Fields < Fog::Collection
|
7
|
+
model Fog::Joyent::Analytics::Field
|
8
|
+
|
9
|
+
def all
|
10
|
+
data = service.describe_analytics.body['fields']
|
11
|
+
load(data)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Joyent returns an odd data structure like this:
|
15
|
+
# { 'apache' => {'label' => 'Apache'}}
|
16
|
+
# where the key is the name of the module
|
17
|
+
def new(attributes = {})
|
18
|
+
name, other_attributes = attributes
|
19
|
+
super(other_attributes.merge('name' => name))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'fog/core/model'
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Joyent
|
5
|
+
class Analytics
|
6
|
+
class Instrumentation < Fog::Model
|
7
|
+
identity :id
|
8
|
+
attribute :joyent_module, :aliases => 'module'
|
9
|
+
attribute :stat
|
10
|
+
attribute :predicate
|
11
|
+
attribute :decomposition, :type => :array
|
12
|
+
attribute :value_dimension, :aliases => 'value-dimension', :type => :integer
|
13
|
+
attribute :value_arity, :aliases => 'value-arity'
|
14
|
+
attribute :retention_time, :aliases => 'retention-time', :type => :integer
|
15
|
+
attribute :granularity, :type => :integer
|
16
|
+
attribute :idle_max, :aliases => 'idle-max', :type => :integer
|
17
|
+
attribute :transformations, :type => :array
|
18
|
+
attribute :persist_data, :aliases => 'persist-data', :type => :boolean
|
19
|
+
attribute :crtime
|
20
|
+
attribute :value_scope, :aliases => 'value-scope'
|
21
|
+
attribute :uris, :type => :array
|
22
|
+
|
23
|
+
def initialize(attributes={})
|
24
|
+
self.decomposition = []
|
25
|
+
self.value_arity = 'scalar'
|
26
|
+
self.retention_time = 600
|
27
|
+
self.idle_max = 3600
|
28
|
+
self.persist_data = false
|
29
|
+
self.value_scope = 'interval'
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def crtime=(new_crtime)
|
34
|
+
attributes[:crtime] = Time.at(new_crtime.to_i / 1000)
|
35
|
+
end
|
36
|
+
|
37
|
+
def decomposition=(value)
|
38
|
+
attributes[:decomposition] = value
|
39
|
+
self.value_dimension = self.decomposition.size + 1
|
40
|
+
self.decomposition
|
41
|
+
end
|
42
|
+
|
43
|
+
def save
|
44
|
+
requires :joyent_module, :stat
|
45
|
+
munged_attributes = self.attributes.dup
|
46
|
+
remap_attributes(munged_attributes, {
|
47
|
+
:joyent_module => 'module',
|
48
|
+
:value_dimension => 'value-dimension',
|
49
|
+
:value_arity => 'value-arity',
|
50
|
+
:retention_time => 'retention-time',
|
51
|
+
:idle_max => 'idle-max',
|
52
|
+
:persist_data => 'persist-data',
|
53
|
+
:value_scope => 'value-scope'
|
54
|
+
})
|
55
|
+
|
56
|
+
data = service.create_instrumentation(munged_attributes)
|
57
|
+
merge_attributes(data.body)
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
def destroy
|
62
|
+
requires :id
|
63
|
+
service.delete_instrumentation(self.identity)
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
# Get a set of datapoints back for an instrumentation
|
68
|
+
# use start_time and ndatapoints so we can get back a range of datapoints
|
69
|
+
# the interval between datapoints should correspond to the granularity of the instrumentation
|
70
|
+
# @param [Time] start_time
|
71
|
+
# @param [Integer] ndatapoints
|
72
|
+
def values(start_time, ndatapoints)
|
73
|
+
requires :id, :granularity
|
74
|
+
data = service.get_instrumentation_value(self.uris.find {|uri| uri['name'] == 'value_raw'}['uri'], start_time, ndatapoints, self.granularity).body
|
75
|
+
data.map do |datum|
|
76
|
+
Fog::Joyent::Analytics::Value.new(datum)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|