fog-joyent 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rubocop.yml +20 -0
  4. data/.rubocop_todo.yml +436 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +26 -0
  8. data/CONTRIBUTING.md +18 -0
  9. data/CONTRIBUTORS.md +17 -0
  10. data/Gemfile +4 -0
  11. data/LICENSE.md +10 -0
  12. data/README.md +29 -0
  13. data/Rakefile +12 -0
  14. data/fog-joyent.gemspec +29 -0
  15. data/lib/fog/bin/joyent.rb +33 -0
  16. data/lib/fog/joyent.rb +16 -0
  17. data/lib/fog/joyent/analytics.rb +310 -0
  18. data/lib/fog/joyent/compute.rb +272 -0
  19. data/lib/fog/joyent/core.rb +10 -0
  20. data/lib/fog/joyent/errors.rb +91 -0
  21. data/lib/fog/joyent/models/analytics/field.rb +13 -0
  22. data/lib/fog/joyent/models/analytics/fields.rb +24 -0
  23. data/lib/fog/joyent/models/analytics/instrumentation.rb +82 -0
  24. data/lib/fog/joyent/models/analytics/instrumentations.rb +23 -0
  25. data/lib/fog/joyent/models/analytics/joyent_module.rb +13 -0
  26. data/lib/fog/joyent/models/analytics/joyent_modules.rb +24 -0
  27. data/lib/fog/joyent/models/analytics/metric.rb +17 -0
  28. data/lib/fog/joyent/models/analytics/metrics.rb +16 -0
  29. data/lib/fog/joyent/models/analytics/transformation.rb +13 -0
  30. data/lib/fog/joyent/models/analytics/transformations.rb +24 -0
  31. data/lib/fog/joyent/models/analytics/type.rb +16 -0
  32. data/lib/fog/joyent/models/analytics/types.rb +24 -0
  33. data/lib/fog/joyent/models/analytics/value.rb +20 -0
  34. data/lib/fog/joyent/models/compute/datacenter.rb +11 -0
  35. data/lib/fog/joyent/models/compute/datacenters.rb +21 -0
  36. data/lib/fog/joyent/models/compute/flavor.rb +19 -0
  37. data/lib/fog/joyent/models/compute/flavors.rb +21 -0
  38. data/lib/fog/joyent/models/compute/image.rb +26 -0
  39. data/lib/fog/joyent/models/compute/images.rb +30 -0
  40. data/lib/fog/joyent/models/compute/key.rb +19 -0
  41. data/lib/fog/joyent/models/compute/keys.rb +32 -0
  42. data/lib/fog/joyent/models/compute/network.rb +12 -0
  43. data/lib/fog/joyent/models/compute/networks.rb +14 -0
  44. data/lib/fog/joyent/models/compute/server.rb +124 -0
  45. data/lib/fog/joyent/models/compute/servers.rb +35 -0
  46. data/lib/fog/joyent/models/compute/snapshot.rb +44 -0
  47. data/lib/fog/joyent/models/compute/snapshots.rb +35 -0
  48. data/lib/fog/joyent/requests/analytics/create_instrumentation.rb +25 -0
  49. data/lib/fog/joyent/requests/analytics/delete_instrumentation.rb +23 -0
  50. data/lib/fog/joyent/requests/analytics/describe_analytics.rb +26 -0
  51. data/lib/fog/joyent/requests/analytics/get_instrumentation.rb +26 -0
  52. data/lib/fog/joyent/requests/analytics/get_instrumentation_value.rb +30 -0
  53. data/lib/fog/joyent/requests/analytics/list_instrumentations.rb +25 -0
  54. data/lib/fog/joyent/requests/compute/add_machine_tags.rb +19 -0
  55. data/lib/fog/joyent/requests/compute/create_key.rb +54 -0
  56. data/lib/fog/joyent/requests/compute/create_machine.rb +16 -0
  57. data/lib/fog/joyent/requests/compute/create_machine_snapshot.rb +16 -0
  58. data/lib/fog/joyent/requests/compute/delete_all_machine_metadata.rb +16 -0
  59. data/lib/fog/joyent/requests/compute/delete_all_machine_tags.rb +15 -0
  60. data/lib/fog/joyent/requests/compute/delete_key.rb +27 -0
  61. data/lib/fog/joyent/requests/compute/delete_machine.rb +15 -0
  62. data/lib/fog/joyent/requests/compute/delete_machine_metadata.rb +16 -0
  63. data/lib/fog/joyent/requests/compute/delete_machine_snapshot.rb +18 -0
  64. data/lib/fog/joyent/requests/compute/delete_machine_tag.rb +15 -0
  65. data/lib/fog/joyent/requests/compute/get_dataset.rb +27 -0
  66. data/lib/fog/joyent/requests/compute/get_image.rb +28 -0
  67. data/lib/fog/joyent/requests/compute/get_key.rb +29 -0
  68. data/lib/fog/joyent/requests/compute/get_machine.rb +29 -0
  69. data/lib/fog/joyent/requests/compute/get_machine_metadata.rb +24 -0
  70. data/lib/fog/joyent/requests/compute/get_machine_snapshot.rb +15 -0
  71. data/lib/fog/joyent/requests/compute/get_machine_tag.rb +18 -0
  72. data/lib/fog/joyent/requests/compute/get_package.rb +32 -0
  73. data/lib/fog/joyent/requests/compute/list_datacenters.rb +16 -0
  74. data/lib/fog/joyent/requests/compute/list_datasets.rb +24 -0
  75. data/lib/fog/joyent/requests/compute/list_images.rb +25 -0
  76. data/lib/fog/joyent/requests/compute/list_keys.rb +25 -0
  77. data/lib/fog/joyent/requests/compute/list_machine_snapshots.rb +15 -0
  78. data/lib/fog/joyent/requests/compute/list_machine_tags.rb +20 -0
  79. data/lib/fog/joyent/requests/compute/list_machines.rb +26 -0
  80. data/lib/fog/joyent/requests/compute/list_networks.rb +26 -0
  81. data/lib/fog/joyent/requests/compute/list_packages.rb +34 -0
  82. data/lib/fog/joyent/requests/compute/reboot_machine.rb +15 -0
  83. data/lib/fog/joyent/requests/compute/resize_machine.rb +16 -0
  84. data/lib/fog/joyent/requests/compute/start_machine.rb +16 -0
  85. data/lib/fog/joyent/requests/compute/start_machine_from_snapshot.rb +15 -0
  86. data/lib/fog/joyent/requests/compute/stop_machine.rb +16 -0
  87. data/lib/fog/joyent/requests/compute/update_machine_metadata.rb +15 -0
  88. data/lib/fog/joyent/version.rb +5 -0
  89. data/tests/helper.rb +18 -0
  90. data/tests/helpers/mock_helper.rb +16 -0
  91. data/tests/helpers/succeeds_helper.rb +9 -0
  92. data/tests/joyent/models/analytics/field_tests.rb +10 -0
  93. data/tests/joyent/models/analytics/fields_tests.rb +13 -0
  94. data/tests/joyent/models/analytics/instrumentation_tests.rb +13 -0
  95. data/tests/joyent/models/analytics/instrumentations_tests.rb +3 -0
  96. data/tests/joyent/models/analytics/joyent_module_tests.rb +10 -0
  97. data/tests/joyent/models/analytics/joyent_modules_tests.rb +13 -0
  98. data/tests/joyent/models/analytics/metric_tests.rb +10 -0
  99. data/tests/joyent/models/analytics/metrics_tests.rb +20 -0
  100. data/tests/joyent/models/analytics/transformation_tests.rb +10 -0
  101. data/tests/joyent/models/analytics/transformations_tests.rb +13 -0
  102. data/tests/joyent/models/analytics/type_tests.rb +10 -0
  103. data/tests/joyent/models/analytics/types_tests.rb +13 -0
  104. data/tests/joyent/requests/analytics/instrumentation_tests.rb +44 -0
  105. data/tests/joyent/requests/compute/datasets_tests.rb +58 -0
  106. data/tests/joyent/requests/compute/keys_tests.rb +47 -0
  107. data/tests/joyent/requests/compute/machines_tests.rb +66 -0
  108. data/tests/joyent/requests/compute/networks_tests.rb +39 -0
  109. data/tests/joyent/requests/compute/packages_tests.rb +68 -0
  110. 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,10 @@
1
+ require 'fog/core'
2
+ require 'fog/json'
3
+
4
+ module Fog
5
+ module Joyent
6
+ extend Fog::Provider
7
+
8
+ service(:compute, 'Compute')
9
+ end
10
+ 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,13 @@
1
+ require 'fog/core/model'
2
+
3
+ module Fog
4
+ module Joyent
5
+ class Analytics
6
+ class Field < Fog::Model
7
+ attribute :name
8
+ attribute :label
9
+ attribute :type
10
+ end
11
+ end
12
+ end
13
+ 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